Add flag for explicitly specifying build tag directives in Gazelle. (#224)

The parameters are a comma-delimited list of build tags.
If no build_tags are specified, GOOS and GOARCH are the default build tags.
If build_tags are specified, they are used explicitly.

Add attribute to new_go_repository definition to allow using explicit build tags.
diff --git a/go/private/go_repository.bzl b/go/private/go_repository.bzl
index 3ba70ae..5a9141b 100644
--- a/go/private/go_repository.bzl
+++ b/go/private/go_repository.bzl
@@ -41,7 +41,8 @@
   _go_repository_impl(ctx)
   gazelle = ctx.path(ctx.attr._gazelle)
 
-  cmds = [gazelle, '--go_prefix', ctx.attr.importpath, '--mode', 'fix']
+  cmds = [gazelle, '--go_prefix', ctx.attr.importpath, '--mode', 'fix',
+          "--build_tags", ",".join(ctx.attr.build_tags)]
   if ctx.attr.rules_go_repo_only_for_internal_use:
     cmds += ["--go_rules_bzl_only_for_internal_use",
              "%s//go:def.bzl" % ctx.attr.rules_go_repo_only_for_internal_use]
@@ -58,7 +59,7 @@
     "remote": attr.string(),
     "commit": attr.string(),
     "tag": attr.string(),
-
+    "build_tags": attr.string_list(),
     "_fetch_repo": attr.label(
         default = Label("@io_bazel_rules_go_repository_tools//:bin/fetch_repo"),
         allow_files = True,
diff --git a/go/tools/gazelle/gazelle/BUILD b/go/tools/gazelle/gazelle/BUILD
index cd25547..a7365df 100644
--- a/go/tools/gazelle/gazelle/BUILD
+++ b/go/tools/gazelle/gazelle/BUILD
@@ -24,6 +24,7 @@
 
 go_test(
     name = "gazelle_test",
+    size = "small",
     srcs = ["fix_test.go"],
     library = ":go_default_library",
 )
diff --git a/go/tools/gazelle/gazelle/main.go b/go/tools/gazelle/gazelle/main.go
index 5aaa7ac..369df92 100644
--- a/go/tools/gazelle/gazelle/main.go
+++ b/go/tools/gazelle/gazelle/main.go
@@ -33,11 +33,11 @@
 )
 
 var (
-	goPrefix  = flag.String("go_prefix", "", "go_prefix of the target workspace")
-	repoRoot  = flag.String("repo_root", "", "path to a directory which corresponds to go_prefix, otherwise gazelle searches for it.")
-	mode      = flag.String("mode", "fix", "print: prints all of the updated BUILD files\n\tfix: rewrites all of the BUILD files in place\n\tdiff: computes the rewrite but then just does a diff")
-	buildName = flag.String("build_name", "BUILD", "name of output build files to generate, defaults to 'BUILD'")
-
+	buildName       = flag.String("build_name", "BUILD", "name of output build files to generate, defaults to 'BUILD'")
+	buildTags       = flag.String("build_tags", "", "comma-separated list of build tags. If not specified, GOOS and GOARCH are used.")
+	goPrefix        = flag.String("go_prefix", "", "go_prefix of the target workspace")
+	repoRoot        = flag.String("repo_root", "", "path to a directory which corresponds to go_prefix, otherwise gazelle searches for it.")
+	mode            = flag.String("mode", "fix", "print: prints all of the updated BUILD files\n\tfix: rewrites all of the BUILD files in place\n\tdiff: computes the rewrite but then just does a diff")
 	validBuildNames = map[string]bool{
 		"BUILD":       true,
 		"BUILD.bazel": true,
@@ -57,7 +57,7 @@
 }
 
 func run(dirs []string, emit func(*bzl.File) error) error {
-	g, err := generator.New(*repoRoot, *goPrefix, *buildName)
+	g, err := generator.New(*repoRoot, *goPrefix, *buildName, *buildTags)
 	if err != nil {
 		return err
 	}
diff --git a/go/tools/gazelle/generator/BUILD b/go/tools/gazelle/generator/BUILD
index 27aa1c5..2b21997 100644
--- a/go/tools/gazelle/generator/BUILD
+++ b/go/tools/gazelle/generator/BUILD
@@ -5,14 +5,15 @@
     srcs = ["generator.go"],
     visibility = ["//visibility:public"],
     deps = [
-        "@io_bazel_buildifier//core:go_default_library",
         "//go/tools/gazelle/packages:go_default_library",
         "//go/tools/gazelle/rules:go_default_library",
+        "@io_bazel_buildifier//core:go_default_library",
     ],
 )
 
 go_test(
     name = "go_default_test",
+    size = "small",
     srcs = ["generator_test.go"],
     library = ":go_default_library",
     deps = [
diff --git a/go/tools/gazelle/generator/generator.go b/go/tools/gazelle/generator/generator.go
index 677d61c..dece8ea 100644
--- a/go/tools/gazelle/generator/generator.go
+++ b/go/tools/gazelle/generator/generator.go
@@ -50,22 +50,31 @@
 //
 // "repoRoot" is a path to the root directory of the repository.
 // "goPrefix" is the go_prefix corresponding to the repository root directory.
+// "buildTags" is a comma-delimited set of build tags to set in the build context.
 // See also https://github.com/bazelbuild/rules_go#go_prefix.
-func New(repoRoot, goPrefix, buildName string) (*Generator, error) {
+func New(repoRoot, goPrefix, buildName, buildTags string) (*Generator, error) {
 	bctx := build.Default
 	// Ignore source files in $GOROOT and $GOPATH
 	bctx.GOROOT = ""
 	bctx.GOPATH = ""
 
-	// Do not import all files, use platform tags if any.
-	bctx.UseAllFiles = false
-	// Many open-source Go projects depend on these tags being used to filter.
-	bctx.BuildTags = []string{bctx.GOARCH, bctx.GOOS}
-
 	repoRoot, err := filepath.Abs(repoRoot)
 	if err != nil {
 		return nil, err
 	}
+
+	// Explicitly do not import all files, use tags.
+	bctx.UseAllFiles = false
+
+	// By default, set build tags based on GOOS and GOARCH.
+	bctx.BuildTags = []string{bctx.GOARCH, bctx.GOOS}
+
+	// If we received custom buildTags, override the defaults with their comma-separated values.
+	// NOTE: GOOS and GOARCH will not be included as build tags automatically in this case.
+	if len(buildTags) != 0 {
+		bctx.BuildTags = strings.Split(buildTags, ",")
+	}
+
 	return &Generator{
 		repoRoot:  filepath.Clean(repoRoot),
 		goPrefix:  goPrefix,
diff --git a/go/tools/gazelle/generator/generator_test.go b/go/tools/gazelle/generator/generator_test.go
index 2a3f63e..5118f27 100644
--- a/go/tools/gazelle/generator/generator_test.go
+++ b/go/tools/gazelle/generator/generator_test.go
@@ -32,6 +32,19 @@
 	buildTagRepoPath = "cgolib_with_build_tags"
 )
 
+func TestBuildTagOverride(t *testing.T) {
+	repo := filepath.Join(testdata.Dir(), "repo")
+	g, err := New(repo, "example.com/repo", "BUILD", "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z")
+	if err != nil {
+		t.Errorf(`New(%q, "example.com/repo") failed with %v; want success`, repo, err)
+		return
+	}
+
+	if len(g.bctx.BuildTags) != 26 {
+		t.Errorf("Got %d build tags; want 26", len(g.bctx.BuildTags))
+	}
+}
+
 func TestGenerator(t *testing.T) {
 	testGenerator(t, "BUILD")
 }
@@ -161,7 +174,7 @@
 	}
 
 	repo := filepath.Join(testdata.Dir(), "repo")
-	g, err := New(repo, "example.com/repo", buildName)
+	g, err := New(repo, "example.com/repo", buildName, "")
 	if err != nil {
 		t.Errorf(`New(%q, "example.com/repo") failed with %v; want success`, repo, err)
 		return