Skip to content

Commit 1d70fc4

Browse files
committed
Remove invalid srcs in gazelle
Update with invalid sources Update Update with py_binary kind only address comments update update test address comments Update PR update with changelog Update Update Address comments Update update
1 parent 46167f5 commit 1d70fc4

File tree

13 files changed

+110
-2
lines changed

13 files changed

+110
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ END_UNRELEASED_TEMPLATE
118118
([#3262](https://github.com/bazel-contrib/rules_python/issues/3262)).
119119
* (rules) {obj}`py_console_script_binary` is now compatible with symbolic macros
120120
([#3195](https://github.com/bazel-contrib/rules_python/pull/3195)).
121+
* (gazelle) Remove py_binary targets with invalid srcs. This includes files
122+
that are not generated or regular files.
121123

122124
{#v1-7-0-added}
123125
### Added
@@ -1982,4 +1984,4 @@ Breaking changes:
19821984
* (pip) Create all_data_requirements alias
19831985
* Expose Python C headers through the toolchain.
19841986

1985-
[0.24.0]: https://github.com/bazel-contrib/rules_python/releases/tag/0.24.0
1987+
[0.24.0]: https://github.com/bazel-contrib/rules_python/releases/tag/0.24.0

gazelle/python/generate.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,14 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
231231
}
232232

233233
collisionErrors := singlylinkedlist.New()
234+
// Create a validFilesMap of mainModules to validate if python macros have valid srcs.
235+
validFilesMap := make(map[string]struct{})
234236

235237
appendPyLibrary := func(srcs *treeset.Set, pyLibraryTargetName string) {
236238
allDeps, mainModules, annotations, err := parser.parse(srcs)
239+
for name := range mainModules {
240+
validFilesMap[name] = struct{}{}
241+
}
237242
if err != nil {
238243
log.Fatalf("ERROR: %v\n", err)
239244
}
@@ -363,6 +368,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
363368
setAnnotations(*annotations).
364369
generateImportsAttribute()
365370

371+
366372
pyBinary := pyBinaryTarget.build()
367373

368374
result.Gen = append(result.Gen, pyBinary)
@@ -490,7 +496,8 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
490496
result.Gen = append(result.Gen, pyTest)
491497
result.Imports = append(result.Imports, pyTest.PrivateAttr(config.GazelleImportsKey))
492498
}
493-
499+
emptyRules := py.getRulesWithInvalidSrcs(args, validFilesMap)
500+
result.Empty = append(result.Empty, emptyRules...)
494501
if !collisionErrors.Empty() {
495502
it := collisionErrors.Iterator()
496503
for it.Next() {
@@ -502,6 +509,42 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
502509
return result
503510
}
504511

512+
// getRulesWithInvalidSrcs checks existing Python rules in the BUILD file and return the rules with invalid source files.
513+
// Invalid source files are files that do not exist or not a target.
514+
func (py *Python) getRulesWithInvalidSrcs(args language.GenerateArgs, validFilesMap map[string]struct{}) (invalidRules []*rule.Rule) {
515+
if args.File == nil {
516+
return
517+
}
518+
for _, file := range args.GenFiles {
519+
validFilesMap[file] = struct{}{}
520+
}
521+
522+
isTarget := func(src string) bool {
523+
return strings.HasPrefix(src, "@") || strings.HasPrefix(src, "//") || strings.HasPrefix(src, ":")
524+
}
525+
for _, existingRule := range args.File.Rules {
526+
actualPyBinaryKind := GetActualKindName(pyBinaryKind, args)
527+
if existingRule.Kind() != actualPyBinaryKind {
528+
continue
529+
}
530+
var hasValidSrcs bool
531+
for _, src := range existingRule.AttrStrings("srcs") {
532+
if isTarget(src) {
533+
hasValidSrcs = true
534+
break
535+
}
536+
if _, ok := validFilesMap[src]; ok {
537+
hasValidSrcs = true
538+
break
539+
}
540+
}
541+
if !hasValidSrcs {
542+
invalidRules = append(invalidRules, newTargetBuilder(pyBinaryKind, existingRule.Name(), "", "", nil, false).build())
543+
}
544+
}
545+
return invalidRules
546+
}
547+
505548
// isBazelPackage determines if the directory is a Bazel package by probing for
506549
// the existence of a known BUILD file name.
507550
func isBazelPackage(dir string) bool {

gazelle/python/kinds.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ var pyKinds = map[string]rule.KindInfo{
4646
SubstituteAttrs: map[string]bool{},
4747
MergeableAttrs: map[string]bool{
4848
"srcs": true,
49+
"imports": true,
4950
},
5051
ResolveAttrs: map[string]bool{
5152
"deps": true,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
2+
3+
py_library(
4+
name = "keep_library",
5+
deps = ["//keep_binary:foo"],
6+
)
7+
py_binary(
8+
name = "remove_invalid_binary",
9+
srcs = ["__main__.py"],
10+
data = ["testdata/test.txt"],
11+
visibility = ["//:__subpackages__"],
12+
)
13+
14+
py_binary(
15+
name = "another_removed_binary",
16+
srcs = ["foo.py"], # eg a now-deleted file that used to have `if __name__` block
17+
imports = ["."],
18+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
load("@rules_python//python:defs.bzl", "py_library")
2+
3+
py_library(
4+
name = "keep_library",
5+
deps = ["//keep_binary:foo"],
6+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Remove invalid binary
2+
3+
This test case asserts that `py_binary` should be deleted if invalid (no source files).

gazelle/python/testdata/remove_invalid_binary/WORKSPACE

Whitespace-only changes.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
2+
3+
py_binary(
4+
name = "foo",
5+
srcs = ["foo.py"],
6+
visibility = ["//:__subpackages__"],
7+
)
8+
9+
py_library(
10+
name = "keep_binary",
11+
srcs = ["foo.py"],
12+
visibility = ["//:__subpackages__"],
13+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
2+
3+
py_binary(
4+
name = "foo",
5+
srcs = ["foo.py"],
6+
visibility = ["//:__subpackages__"],
7+
)
8+
9+
py_library(
10+
name = "keep_binary",
11+
srcs = ["foo.py"],
12+
visibility = ["//:__subpackages__"],
13+
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
if __name__ == "__main__":
2+
print("foo")

0 commit comments

Comments
 (0)