Skip to content

Commit

Permalink
language/go: add go_naming_convention_extern flag and directive (#868)
Browse files Browse the repository at this point in the history
Allows the user to set the default Go naming convention used when
resolving imports of packages in external repositories with unknown
naming conventions.

For #5
  • Loading branch information
Jay Conrod authored Aug 11, 2020
1 parent a0d8484 commit 11c3759
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 15 deletions.
12 changes: 12 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,12 @@ The following flags are accepted:
| Controls the names of generated Go targets. Equivalent to the |
| ``# gazelle:go_naming_convention`` directive. |
+--------------------------------------------------------------+----------------------------------------+
| :flag:`-go_naming_convention_extern` | |
+--------------------------------------------------------------+----------------------------------------+
| Controls the default naming convention used when resolving libraries in |
| external repositories with unknown naming conventions. Equivalent to the |
| ``# gazelle:go_naming_convention_extern`` directive. |
+--------------------------------------------------------------+----------------------------------------+
| :flag:`-go_prefix example.com/repo` | |
+--------------------------------------------------------------+----------------------------------------+
| A prefix of import paths for libraries in the repository that corresponds to |
Expand Down Expand Up @@ -602,6 +608,12 @@ The following directives are recognized:
| * ``import_alias``: Same as ``import``, but an ``alias`` target is generated named |
| ``go_default_library`` to ensure backwards compatibility. |
+---------------------------------------------------+----------------------------------------+
| :direc:`# gazelle:go_naming_convention_extern` | n/a |
+---------------------------------------------------+----------------------------------------+
| Controls the default naming convention used when resolving libraries in |
| external repositories with unknown naming conventions. Accepts the same values |
| as ``go_naming_convention``. |
+---------------------------------------------------+----------------------------------------+
| :direc:`# gazelle:go_proto_compilers` | ``@io_bazel_rules_go//proto:go_proto`` |
+---------------------------------------------------+----------------------------------------+
| The protocol buffers compiler(s) to use for building go bindings. |
Expand Down
19 changes: 19 additions & 0 deletions language/go/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ type goConfig struct {
// goNamingConvention controls the name of generated targets
goNamingConvention namingConvention

// goNamingConventionExtern controls the default naming convention for
// imports in external repositories with unknown naming conventions.
goNamingConventionExtern namingConvention

// goProtoCompilers is the protocol buffers compiler(s) to use for go code.
goProtoCompilers []string

Expand Down Expand Up @@ -326,6 +330,7 @@ func (*goLang) KnownDirectives() []string {
"go_generate_proto",
"go_grpc_compilers",
"go_naming_convention",
"go_naming_convention_extern",
"go_proto_compilers",
"go_visibility",
"importmap_prefix",
Expand Down Expand Up @@ -371,6 +376,10 @@ func (*goLang) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {
&namingConventionFlag{&gc.goNamingConvention},
"go_naming_convention",
"controls generated library names. One of (go_default_library, import, import_alias)")
fs.Var(
&namingConventionFlag{&gc.goNamingConventionExtern},
"go_naming_convention_extern",
"controls naming convention used when resolving libraries in external repositories with unknown conventions")

case "update-repos":
fs.StringVar(&gc.buildDirectivesAttr,
Expand Down Expand Up @@ -510,18 +519,28 @@ Update io_bazel_rules_go to a newer version in your WORKSPACE file.`
}
gc.preprocessTags()
gc.setBuildTags(d.Value)

case "go_generate_proto":
if goGenerateProto, err := strconv.ParseBool(d.Value); err == nil {
gc.goGenerateProto = goGenerateProto
} else {
log.Printf("parsing go_generate_proto: %v", err)
}

case "go_naming_convention":
if nc, err := namingConventionFromString(d.Value); err == nil {
gc.goNamingConvention = nc
} else {
log.Print(err)
}

case "go_naming_convention_extern":
if nc, err := namingConventionFromString(d.Value); err == nil {
gc.goNamingConventionExtern = nc
} else {
log.Print(err)
}

case "go_grpc_compilers":
// Special syntax (empty value) to reset directive.
if d.Value == "" {
Expand Down
27 changes: 18 additions & 9 deletions language/go/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,24 @@ func resolveExternal(c *config.Config, rc *repo.RemoteCache, imp string) (label.

// Determine what naming convention is used by the repository.
// If there is no known repository, it's probably declared in an http_archive
// somewhere like go_rules_dependencies. Use the old naming convention.
nc, ok := gc.repoNamingConvention[repo]
if !ok {
nc = goDefaultLibraryNamingConvention
}
if nc == importAliasNamingConvention {
// If the repository is compatible with either naming convention, use
// whichever is preferred in this directory to avoid churn.
nc = gc.goNamingConvention
// somewhere like go_rules_dependencies, so use the old naming convention,
// unless the user has explicitly told us otherwise.
// If the repository uses the import_alias convention (default for
// go_repository), use the convention from the current directory unless the
// user has told us otherwise.
nc := gc.repoNamingConvention[repo]
if nc == unknownNamingConvention {
if gc.goNamingConventionExtern != unknownNamingConvention {
nc = gc.goNamingConventionExtern
} else {
nc = goDefaultLibraryNamingConvention
}
} else if nc == importAliasNamingConvention {
if gc.goNamingConventionExtern != unknownNamingConvention {
nc = gc.goNamingConventionExtern
} else {
nc = gc.goNamingConvention
}
}

name := libNameByConvention(nc, imp, "")
Expand Down
32 changes: 26 additions & 6 deletions language/go/resolve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1084,12 +1084,13 @@ func TestResolveExternal(t *testing.T) {
ix.Finish()
gl := langs[1].(*goLang)
for _, tc := range []struct {
desc, importpath string
repos []repo.Repo
moduleMode bool
namingConvention namingConvention
repoNamingConvention map[string]namingConvention
want string
desc, importpath string
repos []repo.Repo
moduleMode bool
namingConvention namingConvention
namingConventionExtern namingConvention
repoNamingConvention map[string]namingConvention
want string
}{
{
desc: "top",
Expand Down Expand Up @@ -1142,6 +1143,24 @@ func TestResolveExternal(t *testing.T) {
},
importpath: "example.com/repo/lib",
want: "@custom_repo_name//lib",
}, {
desc: "custom_repo_naming_convention_extern_import",
repos: []repo.Repo{{
Name: "custom_repo_name",
GoPrefix: "example.com/repo",
}},
namingConventionExtern: importNamingConvention,
importpath: "example.com/repo/lib",
want: "@custom_repo_name//lib",
}, {
desc: "custom_repo_naming_convention_extern_default",
repos: []repo.Repo{{
Name: "custom_repo_name",
GoPrefix: "example.com/repo",
}},
namingConventionExtern: goDefaultLibraryNamingConvention,
importpath: "example.com/repo/lib",
want: "@custom_repo_name//lib:go_default_library",
}, {
desc: "qualified",
importpath: "example.com/repo.git/lib",
Expand Down Expand Up @@ -1200,6 +1219,7 @@ func TestResolveExternal(t *testing.T) {
t.Run(tc.desc, func(t *testing.T) {
gc.moduleMode = tc.moduleMode
gc.goNamingConvention = tc.namingConvention
gc.goNamingConventionExtern = tc.namingConventionExtern
gc.repoNamingConvention = tc.repoNamingConvention
rc := testRemoteCache(tc.repos)
r := rule.NewRule("go_library", "x")
Expand Down

0 comments on commit 11c3759

Please sign in to comment.