override-generator: allow users to specify default values
diff --git a/tools/override-generator/main.go b/tools/override-generator/main.go
index b93fa7e..c0c2aa4 100644
--- a/tools/override-generator/main.go
+++ b/tools/override-generator/main.go
@@ -31,18 +31,15 @@
// attribute constants that are used multiple times.
const (
- _buildFileGenerationAttr = "build_file_generation"
- _buildFileProtoModeAttr = "build_file_proto_mode"
- _patchArgsAttr = "patch_args"
- _buildDirectivesAttr = "build_directives"
- _directivesAttr = "directives"
+ _buildFileGenerationAttr = "build_file_generation"
+ _buildFileProtoModeAttr = "build_file_proto_mode"
+ _patchArgsAttr = "patch_args"
+ _buildDirectivesAttr = "build_directives"
+ _directivesAttr = "directives"
+ _buildFileProtoModeDefault = "default"
+ _buildFileGenerationModeDefault = "auto"
)
-var _defaultValues = map[string]string{
- _buildFileGenerationAttr: "auto",
- _buildFileProtoModeAttr: "default",
-}
-
var _mapAttrToOverride = map[string]string{
_buildDirectivesAttr: _gazelleOverride,
_buildFileGenerationAttr: _gazelleOverride,
@@ -66,6 +63,9 @@
defName string
outputFile string
gazelleRepoName string
+
+ defaultBuildFileGeneration string
+ defaultBuildFileProtoMode string
}
func main() {
@@ -91,6 +91,8 @@
flag.StringVar(&a.defName, "def_name", "", "name of the macro definition")
flag.StringVar(&a.outputFile, "output", "", "path to the output file")
flag.StringVar(&a.gazelleRepoName, "gazelle_repo_name", "@bazel_gazelle", "name of the gazelle repo to load go_deps, (default: @bazel_gazelle)")
+ flag.StringVar(&a.defaultBuildFileGeneration, "default_build_file_generation", "auto", "the default value for build_file_generation attribute")
+ flag.StringVar(&a.defaultBuildFileProtoMode, "default_build_file_proto_mode", "default", "the default value for build_file_proto_mode attribute")
flag.Parse(osArgs)
if a.macroPath != "" && a.workspace != "" {
@@ -137,7 +139,7 @@
// will be deterministic.
for _, r := range repos {
if r.Kind() == "go_repository" {
- repoOverrides := goRepositoryToOverrideSet(r)
+ repoOverrides := goRepositoryToOverrideSet(r, a.defaultBuildFileGeneration, a.defaultBuildFileProtoMode)
outputOverrides = append(outputOverrides, setToOverridesSlice(repoOverrides)...)
}
}
@@ -162,7 +164,7 @@
return nil
}
-func goRepositoryToOverrideSet(r *rule.Rule) overrideSet {
+func goRepositoryToOverrideSet(r *rule.Rule, defaultBuildFileGeneration, defaultBuildFileProtoMode string) overrideSet {
// each repo has its own override set, and can't have multiple
// duplicate overrides. This set is created to be populated and read
set := make(overrideSet)
@@ -176,7 +178,7 @@
}
attrValue := r.Attr(attr)
- if attrValue == nil || attr == _buildFileProtoModeAttr {
+ if attrValue == nil || attr == _buildFileProtoModeAttr || attr == _buildFileGenerationAttr {
continue
}
@@ -194,10 +196,6 @@
attr = k
}
- if def, ok := _defaultValues[attr]; def == r.AttrString(attr) && ok {
- continue
- }
-
if val != nil {
switch v := val.(type) {
case *build.StringExpr:
@@ -216,31 +214,86 @@
set[kind] = override
}
- // Since "build_file_proto_mode" is added to the "directives", we need
- // to run it after the fact to make sure that "directives" is set.
- applyBuildFileProtoMode(r, set)
+ // If the user default doesn't match the global default, but there's a gazelle override, we need to still apply
+ // it to the individual overrides.
+ // Also, since "build_file_proto_mode" is added to the "directives", we need
+ // to apply it last to make sure "directives" is set.
+ applyBuildFileGeneration(r, set, defaultBuildFileGeneration)
+ applyBuildFileProtoMode(r, set, defaultBuildFileProtoMode, defaultBuildFileGeneration)
return set
}
-func applyBuildFileProtoMode(r *rule.Rule, set overrideSet) {
- if r.Attr(_buildFileProtoModeAttr) == nil {
+func applyBuildFileGeneration(r *rule.Rule, set overrideSet, userDefaultGeneration string) {
+ ruleGeneration := r.AttrString(_buildFileGenerationAttr)
+ o, ok := set[_gazelleOverride]
+ if !ok {
+ if ruleGeneration == "" || ruleGeneration == userDefaultGeneration {
+ return
+ }
+ set[_gazelleOverride] = newGenerationOverride(userDefaultGeneration)
return
}
- if def, ok := _defaultValues[_buildFileProtoModeAttr]; def == r.AttrString(_buildFileProtoModeAttr) && ok {
+ if ruleGeneration == "" {
+ ruleGeneration = userDefaultGeneration
+ }
+
+ if ruleGeneration == _buildFileGenerationModeDefault {
return
}
- directive := "gazelle:proto " + r.AttrString(_buildFileProtoModeAttr)
- kind := _gazelleOverride
- override := rule.NewRule(kind, "")
- if o, ok := set[kind]; ok {
- override = o
+ o.SetAttr(_buildFileGenerationAttr, ruleGeneration)
+ set[_gazelleOverride] = o
+ return
+}
+
+
+func newGenerationOverride(userDefaultGeneration string) *rule.Rule {
+ override := rule.NewRule(_gazelleOverride, "")
+ override.SetAttr(_buildFileGenerationAttr, userDefaultGeneration)
+ return override
+}
+
+func applyBuildFileProtoMode(r *rule.Rule, set overrideSet, userDefaultProtoMode, userDefaultGeneration string) {
+ protoMode := r.AttrString(_buildFileProtoModeAttr)
+
+ // If the gazelle_override doesn't exist. We only need to apply the proto mode
+ // if it does not match the user default proto mode.
+ gazelleOverride, ok := set[_gazelleOverride]
+ if !ok {
+ if protoMode == "" || protoMode == userDefaultProtoMode {
+ return
+ }
+ set[_gazelleOverride] = newProtoOverride(protoMode, userDefaultGeneration)
+ return
}
- directives := override.AttrStrings(_directivesAttr)
+
+ // If the gazelle_override exists, we need to apply the proto mode if the user default
+ // or the provided value doesn't match the tag default.
+ if protoMode == "" {
+ protoMode = userDefaultProtoMode
+ }
+
+ if protoMode == _buildFileProtoModeDefault {
+ return
+ }
+
+ directive := "gazelle:proto " + protoMode
+ directives := gazelleOverride.AttrStrings(_directivesAttr)
directives = append(directives, directive)
+ gazelleOverride.SetAttr(_directivesAttr, directives)
+ set[_gazelleOverride] = gazelleOverride
+ return
+}
+
+func newProtoOverride(protoMode, userDefaultGeneration string) *rule.Rule {
+ override := rule.NewRule(_gazelleOverride, "")
+ directives := []string{"gazelle:proto " + protoMode}
override.SetAttr(_directivesAttr, directives)
- set[kind] = override
+ if userDefaultGeneration != _buildFileGenerationModeDefault {
+ override.SetAttr(_buildFileGenerationAttr, userDefaultGeneration)
+ }
+ return override
}
func setPatchArgs(patchArgs []string, override *rule.Rule) {
diff --git a/tools/override-generator/main_test.go b/tools/override-generator/main_test.go
index 6eed305..617fae3 100644
--- a/tools/override-generator/main_test.go
+++ b/tools/override-generator/main_test.go
@@ -170,8 +170,197 @@
}
args := &mainArgs{
- workspace: testWorkspace,
- outputFile: filepath.Join(w, "output.bzl"),
+ workspace: testWorkspace,
+ outputFile: filepath.Join(w, "output.bzl"),
+ defaultBuildFileGeneration: "auto",
+ defaultBuildFileProtoMode: "default",
+ }
+
+ if err := run(*args, io.Discard); err != nil {
+ t.Errorf("run() error = %v, want no error", err)
+ }
+
+ if tt.want == "" {
+ return
+ }
+
+ content, err := os.ReadFile(args.outputFile)
+ if err != nil {
+ t.Errorf("error reading output file: %v", err)
+ }
+
+ if !isEqualContent(string(content), tt.want) {
+ fmt.Fprintf(os.Stderr, "output = %v, want %v", string(content), tt.want)
+ t.Errorf("output = %v, want %v", string(content), tt.want)
+ }
+ })
+ }
+}
+
+func TestBzlmodOverrideNewDefaults(t *testing.T) {
+ tests := []struct {
+ name string
+ give string
+ want string
+ }{
+ {
+ name: "simple no override",
+ give: `load("@bazel_gazelle//:deps.bzl", "go_repository")
+
+ go_repository(
+ name = "com_github_apache_thrift",
+ build_file_generation = "on",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/apache/thrift",
+ sum = "h1:cMd2aj52n+8VoAtvSvLn4kDC3aZ6IAkBuqWQ2IDu7wo=",
+ version = "v0.17.0",
+ )`,
+ want: "",
+ },
+ {
+ name: "simple override",
+ give: `load("@bazel_gazelle//:deps.bzl", "go_repository")
+
+ go_repository(
+ name = "com_github_apache_thrift",
+ build_extra_args = ["-go_naming_convention_external=go_default_library"],
+ build_file_generation = "on",
+ build_file_proto_mode = "disable_global",
+ importpath = "github.com/apache/thrift",
+ sum = "h1:cMd2aj52n+8VoAtvSvLn4kDC3aZ6IAkBuqWQ2IDu7wo=",
+ version = "v0.17.0",
+ )`,
+ want: `go_deps = use_extension("//:extensions.bzl", "go_deps")
+
+ go_deps.gazelle_override(
+ build_extra_args = ["-go_naming_convention_external=go_default_library"],
+ build_file_generation = "on",
+ directives = ["gazelle:proto disable_global"],
+ path = "github.com/apache/thrift",
+ )`,
+ },
+ {
+ name: "module override and gazelle",
+ give: `load("@bazel_gazelle//:deps.bzl", "go_repository")
+
+ go_repository(
+ name = "com_github_bazelbuild_bazel_watcher",
+ build_extra_args = ["-go_naming_convention_external=go_default_library"],
+ build_file_generation = "off", # keep
+ build_file_proto_mode = "disable",
+ importpath = "github.com/bazelbuild/bazel-watcher",
+ patch_args = ["-p1"],
+ patches = [
+ # Remove it after they release this PR https://github.com/bazelbuild/bazel-watcher/pull/627
+ "//patches:com_github_bazelbuild_bazel_watcher-go-embed.patch",
+ ],
+ sum = "h1:EfJzkMxJuNBGMVdEvkhiW7pAMwhaegbmAMaFCjLjyTw=",
+ version = "v0.23.7",
+ )`,
+ want: `go_deps = use_extension("//:extensions.bzl", "go_deps")
+
+ go_deps.gazelle_override(
+ build_extra_args = ["-go_naming_convention_external=go_default_library"],
+ build_file_generation = "off",
+ directives = ["gazelle:proto disable"],
+ path = "github.com/bazelbuild/bazel-watcher",
+ )
+
+ go_deps.module_override(
+ patch_strip = 1,
+ patches = [
+ # Remove it after they release this PR https://github.com/bazelbuild/bazel-watcher/pull/627
+ "//patches:com_github_bazelbuild_bazel_watcher-go-embed.patch",
+ ],
+ path = "github.com/bazelbuild/bazel-watcher",
+ )`,
+ },
+ {
+ name: "directives and proto args",
+ give: `go_repository(
+ name = "com_github_clickhouse_clickhouse_go_v2",
+ build_directives = [
+ "gazelle:resolve go github.com/ClickHouse/clickhouse-go/v2/external @com_github_clickhouse_clickhouse_go_v2//external",
+ ],
+ build_extra_args = ["-go_naming_convention_external=go_default_library"],
+ build_file_generation = "auto",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/ClickHouse/clickhouse-go/v2",
+ sum = "h1:Nbl/NZwoM6LGJm7smNBgvtdr/rxjlIssSW3eG/Nmb9E=",
+ version = "v2.0.12",
+ )`,
+ want: `go_deps = use_extension("//:extensions.bzl", "go_deps")
+
+ go_deps.gazelle_override(
+ build_extra_args = ["-go_naming_convention_external=go_default_library"],
+ directives = [
+ "gazelle:resolve go github.com/ClickHouse/clickhouse-go/v2/external @com_github_clickhouse_clickhouse_go_v2//external",
+ "gazelle:proto disable",
+ ],
+ path = "github.com/ClickHouse/clickhouse-go/v2",
+ )`,
+ },
+ {
+ name: "archive overrides",
+ give: `go_repository(
+ name = "org_golang_x_tools_cmd_goimports",
+ build_extra_args = [
+ "-go_prefix=golang.org/x/tools",
+ "-exclude=**/testdata",
+ ],
+ build_file_generation = "on",
+ build_file_proto_mode = "disable",
+ importpath = "golang.org/x/tools/cmd/goimports",
+ patch_args = ["-p1"],
+ strip_prefix = "golang.org/x/tools@v0.0.0-20200512131952-2bc93b1c0c88",
+ sha256 = "4a6497e0bf1f19c8089dd02e7ba1351ba787f434d62971ff14fb627e57914939",
+ patches = [
+ "//patches:org_golang_x_tools_cmd_goimports.patch",
+ ],
+ urls = [
+ "https://goproxy.uberinternal.com/golang.org/x/tools/@v/v0.0.0-20200512131952-2bc93b1c0c88.zip",
+ ],
+ )`,
+ want: `go_deps = use_extension("//:extensions.bzl", "go_deps")
+
+ go_deps.archive_override(
+ patch_strip = 1,
+ patches = [
+ "//patches:org_golang_x_tools_cmd_goimports.patch",
+ ],
+ path = "golang.org/x/tools/cmd/goimports",
+ sha256 = "4a6497e0bf1f19c8089dd02e7ba1351ba787f434d62971ff14fb627e57914939",
+ strip_prefix = "golang.org/x/tools@v0.0.0-20200512131952-2bc93b1c0c88",
+ urls = [
+ "https://goproxy.uberinternal.com/golang.org/x/tools/@v/v0.0.0-20200512131952-2bc93b1c0c88.zip",
+ ],
+ )
+
+ go_deps.gazelle_override(
+ build_extra_args = [
+ "-go_prefix=golang.org/x/tools",
+ "-exclude=**/testdata",
+ ],
+ build_file_generation = "on",
+ directives = ["gazelle:proto disable"],
+ path = "golang.org/x/tools/cmd/goimports",
+ )`,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ w := t.TempDir()
+ testWorkspace := filepath.Join(w, "WORKSPACE")
+ if err := os.WriteFile(testWorkspace, []byte(removeTabsAndTrimLines(tt.give)), 0644); err != nil {
+ t.Errorf("error writing test workspace file: %v", err)
+ }
+
+ args := &mainArgs{
+ workspace: testWorkspace,
+ outputFile: filepath.Join(w, "output.bzl"),
+ defaultBuildFileGeneration: "on",
+ defaultBuildFileProtoMode: "disable",
}
if err := run(*args, io.Discard); err != nil {