Skip to content

Commit b6f3402

Browse files
committed
Add 'go_naming_convention' support.
Add directive 'go_naming_convention' to control the name of generated Go rules. go_default_library: Legacy behaviour. import: Name targets after their import path. import_alias: Same as import, but generate alias targets to maintain backwards compatibility with go_default_library. We also add a `build_naming_convention` attribute to `go_repository` rules, allowing per-external control over the naming convention. gazelle fix is augmented to migrate between the different styles, both forwards and backwards. FIXES=bazel-contrib#5
1 parent 2c4ab51 commit b6f3402

34 files changed

+1371
-38
lines changed

README.rst

+21
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ The following flags are accepted:
336336
| See `Predefined plugins`_ for available options; commonly used options include |
337337
| ``@io_bazel_rules_go//proto:gofast_grpc`` and ``@io_bazel_rules_go//proto:gogofaster_grpc``. |
338338
+--------------------------------------------------------------+----------------------------------------+
339+
| :flag:`-go_naming_convention` | |
340+
+--------------------------------------------------------------+----------------------------------------+
341+
| Controls the names of generated Go targets. Equivalent to the |
342+
| # gazelle:go_naming_convention directive. |
343+
+--------------------------------------------------------------+----------------------------------------+
339344
| :flag:`-go_prefix example.com/repo` | |
340345
+--------------------------------------------------------------+----------------------------------------+
341346
| A prefix of import paths for libraries in the repository that corresponds to |
@@ -575,6 +580,22 @@ The following directives are recognized:
575580
| ``@io_bazel_rules_go//proto:gofast_grpc`` and |
576581
| ``@io_bazel_rules_go//proto:gogofaster_grpc``. |
577582
+---------------------------------------------------+----------------------------------------+
583+
| :direc:`# gazelle:go_naming_convention` | n/a |
584+
+---------------------------------------------------+----------------------------------------+
585+
| Controls the names of generated Go targets. By default, library targets are named |
586+
| `go_default_library` and test targets `go_default_test`. |
587+
| Valid values are: |
588+
| * ``go_default_library``: Library targets are named ``go_default_library``, test targets |
589+
| are named ``go_default_test``. |
590+
| * ``import``: Library and test targets are named after the last segment of their import |
591+
| path. |
592+
| For example, ``example.repo/foo`` is named ``foo``, and the test target is ``foo_test``. |
593+
| Major version suffixes like ``/v2`` are dropped. |
594+
| For a main package with a binary ``foobin``, the names are instead ``foobin_lib`` and |
595+
| ``foobin_test``. |
596+
| * ``import_alias``: Same as ``import``, but an ``alias`` target is generated named |
597+
| ``go_default_library`` to ensure backwards compatibility. |
598+
+---------------------------------------------------+----------------------------------------+
578599
| :direc:`# gazelle:go_proto_compilers` | ``@io_bazel_rules_go//proto:go_proto`` |
579600
+---------------------------------------------------+----------------------------------------+
580601
| The protocol buffers compiler(s) to use for building go bindings. |

cmd/gazelle/fix-update.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,15 @@ func (ucr *updateConfigurer) CheckFlags(fs *flag.FlagSet, c *config.Config) erro
147147
GoPrefix: imp,
148148
})
149149
}
150+
goRepos := make(map[string]repo.Repo)
150151
for _, r := range c.Repos {
151152
if r.Kind() == "go_repository" {
152-
uc.repos = append(uc.repos, repo.Repo{
153-
Name: r.Name(),
154-
GoPrefix: r.AttrString("importpath"),
155-
})
153+
gr := repo.Repo{
154+
Name: r.Name(),
155+
GoPrefix: r.AttrString("importpath"),
156+
}
157+
uc.repos = append(uc.repos, gr)
158+
goRepos[r.Name()] = gr
156159
}
157160
}
158161

internal/go_repository.bzl

+8-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ go_repository = repository_rule(
191191
attrs = {
192192
# Fundamental attributes of a go repository
193193
"importpath": attr.string(mandatory = True),
194-
195194
# Attributes for a repository that should be checked out from VCS
196195
"commit": attr.string(),
197196
"tag": attr.string(),
@@ -235,6 +234,14 @@ go_repository = repository_rule(
235234
"off",
236235
],
237236
),
237+
"build_naming_convention": attr.string(
238+
values = [
239+
"",
240+
"go_default_library",
241+
"import",
242+
"import_alias",
243+
],
244+
),
238245
"build_tags": attr.string_list(),
239246
"build_file_proto_mode": attr.string(
240247
values = [

language/go/config.go

+89-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ type goConfig struct {
7777
// goGenerateProto indicates whether to generate go_proto_library
7878
goGenerateProto bool
7979

80+
// goNamingConvention controls the name of generated targets
81+
goNamingConvention namingConvention
82+
8083
// goProtoCompilers is the protocol buffers compiler(s) to use for go code.
8184
goProtoCompilers []string
8285

@@ -104,6 +107,10 @@ type goConfig struct {
104107
// resolved differently (also depending on goRepositoryMode).
105108
moduleMode bool
106109

110+
// map between external repo names and their `build_naming_convention`
111+
// attribute.
112+
repoNamingConvention map[string]namingConvention
113+
107114
// submodules is a list of modules which have the current module's path
108115
// as a prefix of their own path. This affects visibility attributes
109116
// in internal packages.
@@ -171,6 +178,15 @@ func (gc *goConfig) setBuildTags(tags string) error {
171178
return nil
172179
}
173180

181+
func (gc *goConfig) setNamingConvention(s string) error {
182+
if nc, err := namingConventionFromString(s); err == nil {
183+
gc.goNamingConvention = nc
184+
return nil
185+
} else {
186+
return err
187+
}
188+
}
189+
174190
func getProtoMode(c *config.Config) proto.Mode {
175191
if gc := getGoConfig(c); !gc.goGenerateProto {
176192
return proto.DisableMode
@@ -236,6 +252,59 @@ func (f tagsFlag) String() string {
236252
return ""
237253
}
238254

255+
type namingConventionFlag func(string) error
256+
257+
func (f namingConventionFlag) Set(value string) error {
258+
return f(value)
259+
}
260+
261+
func (f namingConventionFlag) String() string {
262+
return ""
263+
}
264+
265+
// namingConvention determines how go targets are named.
266+
type namingConvention int
267+
268+
const (
269+
// 'go_default_library' and 'go_default_test'
270+
goDefaultLibraryNamingConvention = iota
271+
272+
// For an import path that ends with foo, the go_library rules target is
273+
// named 'foo', the go_test is named 'foo_test'.
274+
// For a main package, the go_binary takes the 'foo' name, the library
275+
// is named 'foo_lib', and the go_test is named 'foo_test'.
276+
importNamingConvention
277+
278+
// Same as importNamingConvention, but generate alias rules for libraries that have
279+
// the legacy 'go_default_library' name.
280+
importAliasNamingConvention
281+
)
282+
283+
func (nc namingConvention) String() string {
284+
switch nc {
285+
case goDefaultLibraryNamingConvention:
286+
return "go_default_library"
287+
case importNamingConvention:
288+
return "import"
289+
case importAliasNamingConvention:
290+
return "import_alias"
291+
}
292+
return ""
293+
}
294+
295+
func namingConventionFromString(s string) (namingConvention, error) {
296+
switch s {
297+
case "go_default_library":
298+
return goDefaultLibraryNamingConvention, nil
299+
case "import":
300+
return importNamingConvention, nil
301+
case "import_alias":
302+
return importAliasNamingConvention, nil
303+
default:
304+
return goDefaultLibraryNamingConvention, fmt.Errorf("unknown naming convention %q", s)
305+
}
306+
}
307+
239308
type moduleRepo struct {
240309
repoName, modulePath string
241310
}
@@ -249,6 +318,7 @@ func (*goLang) KnownDirectives() []string {
249318
"build_tags",
250319
"go_generate_proto",
251320
"go_grpc_compilers",
321+
"go_naming_convention",
252322
"go_proto_compilers",
253323
"go_visibility",
254324
"importmap_prefix",
@@ -290,6 +360,10 @@ func (*goLang) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {
290360
"go_repository_module_mode",
291361
false,
292362
"set when gazelle is invoked by go_repository in module mode")
363+
fs.Var(
364+
namingConventionFlag(gc.setNamingConvention),
365+
"go_naming_convention",
366+
"controls generated library names. One of (go_default_library, import, import_alias)")
293367

294368
case "update-repos":
295369
fs.Var(&gzflag.AllowedStringFlag{Value: &gc.buildExternalAttr, Allowed: validBuildExternalAttr},
@@ -372,6 +446,17 @@ Update io_bazel_rules_go to a newer version in your WORKSPACE file.`
372446
log.Printf("Found RULES_GO_VERSION %s. Minimum compatible version is %s.\n%s", gc.rulesGoVersion, minimumRulesGoVersion, message)
373447
}
374448
}
449+
repoNamingConvention := map[string]namingConvention{}
450+
for _, repo := range c.Repos {
451+
if repo.Kind() == "go_repository" {
452+
if nc, err := namingConventionFromString(repo.AttrString("build_naming_convention")); err == nil {
453+
repoNamingConvention[repo.Name()] = nc
454+
} else {
455+
log.Printf("%v\n", err)
456+
}
457+
}
458+
}
459+
gc.repoNamingConvention = repoNamingConvention
375460
}
376461

377462
if !gc.moduleMode {
@@ -408,12 +493,15 @@ Update io_bazel_rules_go to a newer version in your WORKSPACE file.`
408493
gc.preprocessTags()
409494
gc.setBuildTags(d.Value)
410495
case "go_generate_proto":
411-
412496
if goGenerateProto, err := strconv.ParseBool(d.Value); err == nil {
413497
gc.goGenerateProto = goGenerateProto
414498
} else {
415499
log.Printf("parsing go_generate_proto: %v", err)
416500
}
501+
case "go_naming_convention":
502+
if err := gc.setNamingConvention(d.Value); err != nil {
503+
log.Print(err)
504+
}
417505
case "go_grpc_compilers":
418506
// Special syntax (empty value) to reset directive.
419507
if d.Value == "" {

language/go/config_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ func TestCommandLine(t *testing.T) {
6464
t,
6565
"-build_tags=foo,bar",
6666
"-go_prefix=example.com/repo",
67+
"-go_naming_convention=import_alias",
6768
"-external=vendored",
6869
"-repo_root=.")
6970
gc := getGoConfig(c)
@@ -78,6 +79,9 @@ func TestCommandLine(t *testing.T) {
7879
if gc.depMode != vendorMode {
7980
t.Errorf("got dep mode %v; want %v", gc.depMode, vendorMode)
8081
}
82+
if gc.goNamingConvention != importAliasNamingConvention {
83+
t.Errorf("got naming convention %v; want %v", gc.goNamingConvention, importAliasNamingConvention)
84+
}
8185
}
8286

8387
func TestDirectives(t *testing.T) {

0 commit comments

Comments
 (0)