fix: support gazelle generation_mode:update_only (#2708)
This just fixes a crash when `generation_mode: update_only` causes
`GenerateRules` to not be invoked for 100% of directories.
Fix #2707
diff --git a/gazelle/pythonconfig/pythonconfig.go b/gazelle/pythonconfig/pythonconfig.go
index 2183ec6..23c0cfd 100644
--- a/gazelle/pythonconfig/pythonconfig.go
+++ b/gazelle/pythonconfig/pythonconfig.go
@@ -22,8 +22,8 @@
"github.com/emirpasic/gods/lists/singlylinkedlist"
- "github.com/bazelbuild/bazel-gazelle/label"
"github.com/bazel-contrib/rules_python/gazelle/manifest"
+ "github.com/bazelbuild/bazel-gazelle/label"
)
// Directives
@@ -125,21 +125,28 @@
// defaultIgnoreFiles is the list of default values used in the
// python_ignore_files option.
-var defaultIgnoreFiles = map[string]struct{}{
-}
+var defaultIgnoreFiles = map[string]struct{}{}
// Configs is an extension of map[string]*Config. It provides finding methods
// on top of the mapping.
type Configs map[string]*Config
// ParentForPackage returns the parent Config for the given Bazel package.
-func (c *Configs) ParentForPackage(pkg string) *Config {
- dir := path.Dir(pkg)
- if dir == "." {
- dir = ""
+func (c Configs) ParentForPackage(pkg string) *Config {
+ for {
+ dir := path.Dir(pkg)
+ if dir == "." {
+ dir = ""
+ }
+ parent := (map[string]*Config)(c)[dir]
+ if parent != nil {
+ return parent
+ }
+ if dir == "" {
+ return nil
+ }
+ pkg = dir
}
- parent := (map[string]*Config)(*c)[dir]
- return parent
}
// Config represents a config extension for a specific Bazel package.
diff --git a/gazelle/pythonconfig/pythonconfig_test.go b/gazelle/pythonconfig/pythonconfig_test.go
index 7cdb9af..fe21ce2 100644
--- a/gazelle/pythonconfig/pythonconfig_test.go
+++ b/gazelle/pythonconfig/pythonconfig_test.go
@@ -248,3 +248,35 @@
})
}
}
+
+func TestConfigsMap(t *testing.T) {
+ t.Run("only root", func(t *testing.T) {
+ configs := Configs{"": New("root/dir", "")}
+
+ if configs.ParentForPackage("") == nil {
+ t.Fatal("expected non-nil for root config")
+ }
+
+ if configs.ParentForPackage("a/b/c") != configs[""] {
+ t.Fatal("expected root for subpackage")
+ }
+ })
+
+ t.Run("sparse child configs", func(t *testing.T) {
+ configs := Configs{"": New("root/dir", "")}
+ configs["a"] = configs[""].NewChild()
+ configs["a/b/c"] = configs["a"].NewChild()
+
+ if configs.ParentForPackage("a/b/c/d") != configs["a/b/c"] {
+ t.Fatal("child should match direct parent")
+ }
+
+ if configs.ParentForPackage("a/b/c/d/e") != configs["a/b/c"] {
+ t.Fatal("grandchild should match first parant")
+ }
+
+ if configs.ParentForPackage("other/root/path") != configs[""] {
+ t.Fatal("non-configured subpackage should match root")
+ }
+ })
+}