Skip to content

Commit 578cafb

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
1 parent 3262233 commit 578cafb

File tree

10 files changed

+96
-1
lines changed

10 files changed

+96
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ END_UNRELEASED_TEMPLATE
106106
* (toolchains) use "command -v" to find interpreter in `$PATH`
107107
([#3150](https://github.com/bazel-contrib/rules_python/pull/3150)).
108108
* (pypi) `bazel vendor` now works in `bzlmod` ({gh-issue}`3079`).
109+
* (gazelle) Remove py_binary targets with invalid srcs. This includes files
110+
that are not generated or regular files.
109111

110112
{#v0-0-0-added}
111113
### Added

gazelle/python/generate.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
490490
result.Gen = append(result.Gen, pyTest)
491491
result.Imports = append(result.Imports, pyTest.PrivateAttr(config.GazelleImportsKey))
492492
}
493-
493+
if !cfg.CoarseGrainedGeneration() {
494+
emptyRules := py.getRulesWithInvalidSrcs(cfg, args)
495+
result.Empty = append(result.Empty, emptyRules...)
496+
}
494497
if !collisionErrors.Empty() {
495498
it := collisionErrors.Iterator()
496499
for it.Next() {
@@ -502,6 +505,48 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
502505
return result
503506
}
504507

508+
// getRulesWithInvalidSrcs checks existing Python rules in the BUILD file and return the rules with invalid source files.
509+
// Invalid source files are files that do not exist or not a target.
510+
func (py *Python) getRulesWithInvalidSrcs(cfg *pythonconfig.Config, args language.GenerateArgs) (invalidRules []*rule.Rule) {
511+
if args.File == nil {
512+
return
513+
}
514+
filesMap := make(map[string]struct{})
515+
for _, file := range args.RegularFiles {
516+
if cfg.IgnoresFile(filepath.Base(file)) {
517+
continue
518+
}
519+
filesMap[file] = struct{}{}
520+
}
521+
for _, file := range args.GenFiles {
522+
filesMap[file] = struct{}{}
523+
}
524+
525+
isTarget := func(src string) bool {
526+
return strings.HasPrefix(src, "@") || strings.HasPrefix(src, "//") || strings.HasPrefix(src, ":")
527+
}
528+
for _, existingRule := range args.File.Rules {
529+
if existingRule.Kind() != pyBinaryKind {
530+
continue
531+
}
532+
var hasValidSrcs bool
533+
for _, src := range existingRule.AttrStrings("srcs") {
534+
if isTarget(src) {
535+
hasValidSrcs = true
536+
break
537+
}
538+
if _, ok := filesMap[src]; ok {
539+
hasValidSrcs = true
540+
break
541+
}
542+
}
543+
if !hasValidSrcs {
544+
invalidRules = append(invalidRules, newTargetBuilder(existingRule.Kind(), existingRule.Name(), args.Config.RepoRoot, args.Rel, nil).build())
545+
}
546+
}
547+
return invalidRules
548+
}
549+
505550
// isBazelPackage determines if the directory is a Bazel package by probing for
506551
// the existence of a known BUILD file name.
507552
func isBazelPackage(dir string) bool {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
load("@rules_python//python:defs.bzl", "py_binary")
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+
visibility = ["//:__subpackages__"],
11+
)
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")

gazelle/python/testdata/remove_invalid_binary/test.yaml

Whitespace-only changes.

0 commit comments

Comments
 (0)