github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/cmd/gazelle/integration_test.go (about)

     1  /* Copyright 2017 The Bazel Authors. All rights reserved.
     2  
     3  Licensed under the Apache License, Version 2.0 (the "License");
     4  you may not use this file except in compliance with the License.
     5  You may obtain a copy of the License at
     6  
     7     http://www.apache.org/licenses/LICENSE-2.0
     8  
     9  Unless required by applicable law or agreed to in writing, software
    10  distributed under the License is distributed on an "AS IS" BASIS,
    11  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  See the License for the specific language governing permissions and
    13  limitations under the License.
    14  */
    15  
    16  // This file contains integration tests for all of Gazelle. It's meant to test
    17  // common usage patterns and check for errors that are difficult to test in
    18  // unit tests.
    19  
    20  package main
    21  
    22  import (
    23  	"bytes"
    24  	"flag"
    25  	"log"
    26  	"os"
    27  	"path/filepath"
    28  	"strings"
    29  	"testing"
    30  
    31  	"github.com/bazelbuild/bazel-gazelle/config"
    32  	"github.com/bazelbuild/bazel-gazelle/internal/wspace"
    33  	"github.com/bazelbuild/bazel-gazelle/testtools"
    34  	"github.com/google/go-cmp/cmp"
    35  )
    36  
    37  // skipIfWorkspaceVisible skips the test if the WORKSPACE file for the
    38  // repository is visible. This happens in newer Bazel versions when tests
    39  // are run without sandboxing, since temp directories may be inside the
    40  // exec root.
    41  func skipIfWorkspaceVisible(t *testing.T, dir string) {
    42  	if parent, err := wspace.FindRepoRoot(dir); err == nil {
    43  		t.Skipf("WORKSPACE visible in parent %q of tmp %q", parent, dir)
    44  	}
    45  }
    46  
    47  func runGazelle(wd string, args []string) error {
    48  	return run(wd, args)
    49  }
    50  
    51  // TestHelp checks that help commands do not panic due to nil flag values.
    52  // Verifies #256.
    53  func TestHelp(t *testing.T) {
    54  	for _, args := range [][]string{
    55  		{"help"},
    56  		{"fix", "-h"},
    57  		{"update", "-h"},
    58  		{"update-repos", "-h"},
    59  	} {
    60  		t.Run(args[0], func(t *testing.T) {
    61  			if err := runGazelle(".", args); err == nil {
    62  				t.Errorf("%s: got success, want flag.ErrHelp", args[0])
    63  			} else if err != flag.ErrHelp {
    64  				t.Errorf("%s: got %v, want flag.ErrHelp", args[0], err)
    65  			}
    66  		})
    67  	}
    68  }
    69  
    70  func TestNoRepoRootOrWorkspace(t *testing.T) {
    71  	dir, cleanup := testtools.CreateFiles(t, nil)
    72  	defer cleanup()
    73  	skipIfWorkspaceVisible(t, dir)
    74  	want := "-repo_root not specified"
    75  	if err := runGazelle(dir, nil); err == nil {
    76  		t.Fatalf("got success; want %q", want)
    77  	} else if !strings.Contains(err.Error(), want) {
    78  		t.Fatalf("got %q; want %q", err, want)
    79  	}
    80  }
    81  
    82  func TestNoGoPrefixArgOrRule(t *testing.T) {
    83  	dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{
    84  		{Path: "WORKSPACE", Content: ""},
    85  		{Path: "hello.go", Content: "package hello"},
    86  	})
    87  	defer cleanup()
    88  	buf := new(bytes.Buffer)
    89  	log.SetOutput(buf)
    90  	defer log.SetOutput(os.Stderr)
    91  	if err := runGazelle(dir, nil); err != nil {
    92  		t.Fatalf("got %#v; want success", err)
    93  	}
    94  	want := "go prefix is not set"
    95  	if !strings.Contains(buf.String(), want) {
    96  		t.Errorf("log does not contain %q\n--begin--\n%s--end--\n", want, buf.String())
    97  	}
    98  }
    99  
   100  // TestSelectLabelsSorted checks that string lists in srcs and deps are sorted
   101  // using buildifier order, even if they are inside select expressions.
   102  // This applies to both new and existing lists and should preserve comments.
   103  // buildifier does not do this yet bazelbuild/buildtools#122, so we do this
   104  // in addition to calling build.Rewrite.
   105  func TestSelectLabelsSorted(t *testing.T) {
   106  	dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{
   107  		{Path: "WORKSPACE"},
   108  		{
   109  			Path: "BUILD",
   110  			Content: `
   111  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   112  
   113  go_library(
   114      name = "go_default_library",
   115      srcs = select({
   116          "@io_bazel_rules_go//go/platform:linux": [
   117              # foo comment
   118              "foo.go",  # side comment
   119              # bar comment
   120              "bar.go",
   121          ],
   122          "//conditions:default": [],
   123      }),
   124      importpath = "example.com/foo",
   125  )
   126  `,
   127  		},
   128  		{
   129  			Path: "foo.go",
   130  			Content: `
   131  // +build linux
   132  
   133  package foo
   134  
   135  import (
   136      _ "example.com/foo/outer"
   137      _ "example.com/foo/outer/inner"
   138      _ "github.com/jr_hacker/tools"
   139  )
   140  `,
   141  		},
   142  		{
   143  			Path: "foo_android_build_tag.go",
   144  			Content: `
   145  // +build android
   146  
   147  package foo
   148  
   149  import (
   150      _ "example.com/foo/outer_android_build_tag"
   151  )
   152  `,
   153  		},
   154  		{
   155  			Path: "foo_android.go",
   156  			Content: `
   157  package foo
   158  
   159  import (
   160      _ "example.com/foo/outer_android_suffix"
   161  )
   162  `,
   163  		},
   164  		{
   165  			Path: "bar.go",
   166  			Content: `// +build linux
   167  
   168  package foo
   169  `,
   170  		},
   171  		{Path: "outer/outer.go", Content: "package outer"},
   172  		{Path: "outer_android_build_tag/outer.go", Content: "package outer_android_build_tag"},
   173  		{Path: "outer_android_suffix/outer.go", Content: "package outer_android_suffix"},
   174  		{Path: "outer/inner/inner.go", Content: "package inner"},
   175  	})
   176  	want := `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   177  
   178  go_library(
   179      name = "go_default_library",
   180      srcs = [
   181          # bar comment
   182          "bar.go",
   183          # foo comment
   184          "foo.go",  # side comment
   185          "foo_android.go",
   186          "foo_android_build_tag.go",
   187      ],
   188      importpath = "example.com/foo",
   189      visibility = ["//visibility:public"],
   190      deps = select({
   191          "@io_bazel_rules_go//go/platform:android": [
   192              "//outer:go_default_library",
   193              "//outer/inner:go_default_library",
   194              "//outer_android_build_tag:go_default_library",
   195              "//outer_android_suffix:go_default_library",
   196              "@com_github_jr_hacker_tools//:go_default_library",
   197          ],
   198          "@io_bazel_rules_go//go/platform:linux": [
   199              "//outer:go_default_library",
   200              "//outer/inner:go_default_library",
   201              "@com_github_jr_hacker_tools//:go_default_library",
   202          ],
   203          "//conditions:default": [],
   204      }),
   205  )
   206  `
   207  	defer cleanup()
   208  
   209  	if err := runGazelle(dir, []string{"-go_prefix", "example.com/foo"}); err != nil {
   210  		t.Fatal(err)
   211  	}
   212  	if got, err := os.ReadFile(filepath.Join(dir, "BUILD")); err != nil {
   213  		t.Fatal(err)
   214  	} else if string(got) != want {
   215  		t.Fatalf("got %s ; want %s", string(got), want)
   216  	}
   217  }
   218  
   219  func TestFixAndUpdateChanges(t *testing.T) {
   220  	files := []testtools.FileSpec{
   221  		{Path: "WORKSPACE"},
   222  		{
   223  			Path: "BUILD",
   224  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix")
   225  load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_test")
   226  
   227  go_prefix("example.com/foo")
   228  
   229  go_library(
   230      name = "go_default_library",
   231      srcs = [
   232          "extra.go",
   233          "pure.go",
   234      ],
   235      library = ":cgo_default_library",
   236      visibility = ["//visibility:default"],
   237  )
   238  
   239  cgo_library(
   240      name = "cgo_default_library",
   241      srcs = ["cgo.go"],
   242  )
   243  `,
   244  		},
   245  		{
   246  			Path:    "pure.go",
   247  			Content: "package foo",
   248  		},
   249  		{
   250  			Path: "cgo.go",
   251  			Content: `package foo
   252  
   253  import "C"
   254  `,
   255  		},
   256  	}
   257  
   258  	cases := []struct {
   259  		cmd, want string
   260  	}{
   261  		{
   262  			cmd: "update",
   263  			want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library", "go_prefix")
   264  
   265  go_prefix("example.com/foo")
   266  
   267  go_library(
   268      name = "go_default_library",
   269      srcs = [
   270          "cgo.go",
   271          "pure.go",
   272      ],
   273      cgo = True,
   274      importpath = "example.com/foo",
   275      visibility = ["//visibility:default"],
   276  )
   277  
   278  cgo_library(
   279      name = "cgo_default_library",
   280      srcs = ["cgo.go"],
   281  )
   282  `,
   283  		}, {
   284  			cmd: "fix",
   285  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix")
   286  
   287  go_prefix("example.com/foo")
   288  
   289  go_library(
   290      name = "go_default_library",
   291      srcs = [
   292          "cgo.go",
   293          "pure.go",
   294      ],
   295      cgo = True,
   296      importpath = "example.com/foo",
   297      visibility = ["//visibility:default"],
   298  )
   299  `,
   300  		},
   301  	}
   302  
   303  	for _, c := range cases {
   304  		t.Run(c.cmd, func(t *testing.T) {
   305  			dir, cleanup := testtools.CreateFiles(t, files)
   306  			defer cleanup()
   307  
   308  			if err := runGazelle(dir, []string{c.cmd}); err != nil {
   309  				t.Fatal(err)
   310  			}
   311  			if got, err := os.ReadFile(filepath.Join(dir, "BUILD")); err != nil {
   312  				t.Fatal(err)
   313  			} else if string(got) != c.want {
   314  				t.Fatalf("got %s ; want %s", string(got), c.want)
   315  			}
   316  		})
   317  	}
   318  }
   319  
   320  func TestFixUnlinkedCgoLibrary(t *testing.T) {
   321  	files := []testtools.FileSpec{
   322  		{Path: "WORKSPACE"},
   323  		{
   324  			Path: "BUILD",
   325  			Content: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library")
   326  
   327  cgo_library(
   328      name = "cgo_default_library",
   329      srcs = ["cgo.go"],
   330  )
   331  
   332  go_library(
   333      name = "go_default_library",
   334      srcs = ["pure.go"],
   335      importpath = "example.com/foo",
   336      visibility = ["//visibility:public"],
   337  )
   338  `,
   339  		},
   340  		{
   341  			Path:    "pure.go",
   342  			Content: "package foo",
   343  		},
   344  	}
   345  
   346  	dir, cleanup := testtools.CreateFiles(t, files)
   347  	defer cleanup()
   348  
   349  	want := `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   350  
   351  go_library(
   352      name = "go_default_library",
   353      srcs = ["pure.go"],
   354      importpath = "example.com/foo",
   355      visibility = ["//visibility:public"],
   356  )
   357  `
   358  	if err := runGazelle(dir, []string{"fix", "-go_prefix", "example.com/foo"}); err != nil {
   359  		t.Fatal(err)
   360  	}
   361  	if got, err := os.ReadFile(filepath.Join(dir, "BUILD")); err != nil {
   362  		t.Fatal(err)
   363  	} else if string(got) != want {
   364  		t.Fatalf("got %s ; want %s", string(got), want)
   365  	}
   366  }
   367  
   368  // TestMultipleDirectories checks that all directories in a repository are
   369  // indexed but only directories listed on the command line are updated.
   370  func TestMultipleDirectories(t *testing.T) {
   371  	files := []testtools.FileSpec{
   372  		{Path: "WORKSPACE"},
   373  		{
   374  			Path: "a/BUILD.bazel",
   375  			Content: `# This file shouldn't be modified.
   376  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   377  
   378  go_library(
   379      name = "go_default_library",
   380      srcs = ["a.go"],
   381      importpath = "example.com/foo/x",
   382  )
   383  `,
   384  		},
   385  		{
   386  			Path:    "a/a.go",
   387  			Content: "package a",
   388  		},
   389  		{
   390  			Path: "b/b.go",
   391  			Content: `
   392  package b
   393  
   394  import _ "example.com/foo/x"
   395  `,
   396  		},
   397  	}
   398  	dir, cleanup := testtools.CreateFiles(t, files)
   399  	defer cleanup()
   400  
   401  	args := []string{"-go_prefix", "example.com/foo", "b"}
   402  	if err := runGazelle(dir, args); err != nil {
   403  		t.Fatal(err)
   404  	}
   405  
   406  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
   407  		files[1], // should not change
   408  		{
   409  			Path: "b/BUILD.bazel",
   410  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   411  
   412  go_library(
   413      name = "go_default_library",
   414      srcs = ["b.go"],
   415      importpath = "example.com/foo/b",
   416      visibility = ["//visibility:public"],
   417      deps = ["//a:go_default_library"],
   418  )
   419  `,
   420  		},
   421  	})
   422  }
   423  
   424  func TestErrorOutsideWorkspace(t *testing.T) {
   425  	files := []testtools.FileSpec{
   426  		{Path: "a/"},
   427  		{Path: "b/"},
   428  	}
   429  	dir, cleanup := testtools.CreateFiles(t, files)
   430  	defer cleanup()
   431  	skipIfWorkspaceVisible(t, dir)
   432  
   433  	cases := []struct {
   434  		name, dir, want string
   435  		args            []string
   436  	}{
   437  		{
   438  			name: "outside workspace",
   439  			dir:  dir,
   440  			args: nil,
   441  			want: "WORKSPACE cannot be found",
   442  		}, {
   443  			name: "outside repo_root",
   444  			dir:  filepath.Join(dir, "a"),
   445  			args: []string{"-repo_root", filepath.Join(dir, "b")},
   446  			want: "not a subdirectory of repo root",
   447  		},
   448  	}
   449  	for _, c := range cases {
   450  		t.Run(c.name, func(t *testing.T) {
   451  			if err := runGazelle(c.dir, c.args); err == nil {
   452  				t.Fatalf("got success; want %q", c.want)
   453  			} else if !strings.Contains(err.Error(), c.want) {
   454  				t.Fatalf("got %q; want %q", err, c.want)
   455  			}
   456  		})
   457  	}
   458  }
   459  
   460  func TestBuildFileNameIgnoresBuild(t *testing.T) {
   461  	files := []testtools.FileSpec{
   462  		{Path: "WORKSPACE"},
   463  		{Path: "BUILD/"},
   464  		{
   465  			Path:    "a/BUILD",
   466  			Content: "!!! parse error",
   467  		},
   468  		{
   469  			Path:    "a.go",
   470  			Content: "package a",
   471  		},
   472  	}
   473  	dir, cleanup := testtools.CreateFiles(t, files)
   474  	defer cleanup()
   475  
   476  	args := []string{"-go_prefix", "example.com/foo", "-build_file_name", "BUILD.bazel"}
   477  	if err := runGazelle(dir, args); err != nil {
   478  		t.Fatal(err)
   479  	}
   480  	if _, err := os.Stat(filepath.Join(dir, "BUILD.bazel")); err != nil {
   481  		t.Errorf("BUILD.bazel not created: %v", err)
   482  	}
   483  }
   484  
   485  func TestExternalVendor(t *testing.T) {
   486  	files := []testtools.FileSpec{
   487  		{
   488  			Path:    "WORKSPACE",
   489  			Content: `workspace(name = "banana")`,
   490  		}, {
   491  			Path: "a.go",
   492  			Content: `package foo
   493  
   494  import _ "golang.org/x/bar"
   495  `,
   496  		}, {
   497  			Path: "vendor/golang.org/x/bar/bar.go",
   498  			Content: `package bar
   499  
   500  import _ "golang.org/x/baz"
   501  `,
   502  		}, {
   503  			Path:    "vendor/golang.org/x/baz/baz.go",
   504  			Content: "package baz",
   505  		},
   506  	}
   507  	dir, cleanup := testtools.CreateFiles(t, files)
   508  	defer cleanup()
   509  
   510  	args := []string{"-go_prefix", "example.com/foo", "-external", "vendored"}
   511  	if err := runGazelle(dir, args); err != nil {
   512  		t.Fatal(err)
   513  	}
   514  
   515  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
   516  		{
   517  			Path: config.DefaultValidBuildFileNames[0],
   518  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   519  
   520  go_library(
   521      name = "foo",
   522      srcs = ["a.go"],
   523      importpath = "example.com/foo",
   524      visibility = ["//visibility:public"],
   525      deps = ["//vendor/golang.org/x/bar"],
   526  )
   527  `,
   528  		}, {
   529  			Path: "vendor/golang.org/x/bar/" + config.DefaultValidBuildFileNames[0],
   530  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   531  
   532  go_library(
   533      name = "bar",
   534      srcs = ["bar.go"],
   535      importmap = "example.com/foo/vendor/golang.org/x/bar",
   536      importpath = "golang.org/x/bar",
   537      visibility = ["//visibility:public"],
   538      deps = ["//vendor/golang.org/x/baz"],
   539  )
   540  `,
   541  		},
   542  	})
   543  }
   544  
   545  func TestMigrateProtoRules(t *testing.T) {
   546  	files := []testtools.FileSpec{
   547  		{Path: "WORKSPACE"},
   548  		{
   549  			Path: config.DefaultValidBuildFileNames[0],
   550  			Content: `
   551  load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
   552  
   553  filegroup(
   554      name = "go_default_library_protos",
   555      srcs = ["foo.proto"],
   556      visibility = ["//visibility:public"],
   557  )
   558  
   559  go_proto_library(
   560      name = "go_default_library",
   561      srcs = [":go_default_library_protos"],
   562  )
   563  `,
   564  		},
   565  		{
   566  			Path: "foo.proto",
   567  			Content: `syntax = "proto3";
   568  
   569  option go_package = "example.com/repo";
   570  `,
   571  		},
   572  		{
   573  			Path:    "foo.pb.go",
   574  			Content: `package repo`,
   575  		},
   576  	}
   577  
   578  	for _, tc := range []struct {
   579  		args []string
   580  		want string
   581  	}{
   582  		{
   583  			args: []string{"update", "-go_prefix", "example.com/repo"},
   584  			want: `
   585  load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
   586  
   587  filegroup(
   588      name = "go_default_library_protos",
   589      srcs = ["foo.proto"],
   590      visibility = ["//visibility:public"],
   591  )
   592  
   593  go_proto_library(
   594      name = "go_default_library",
   595      srcs = [":go_default_library_protos"],
   596  )
   597  `,
   598  		}, {
   599  			args: []string{"fix", "-go_prefix", "example.com/repo"},
   600  			want: `
   601  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   602  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   603  load("@rules_proto//proto:defs.bzl", "proto_library")
   604  
   605  proto_library(
   606      name = "repo_proto",
   607      srcs = ["foo.proto"],
   608      visibility = ["//visibility:public"],
   609  )
   610  
   611  go_proto_library(
   612      name = "repo_go_proto",
   613      importpath = "example.com/repo",
   614      proto = ":repo_proto",
   615      visibility = ["//visibility:public"],
   616  )
   617  
   618  go_library(
   619      name = "go_default_library",
   620      embed = [":repo_go_proto"],
   621      importpath = "example.com/repo",
   622      visibility = ["//visibility:public"],
   623  )
   624  `,
   625  		},
   626  	} {
   627  		t.Run(tc.args[0], func(t *testing.T) {
   628  			dir, cleanup := testtools.CreateFiles(t, files)
   629  			defer cleanup()
   630  
   631  			if err := runGazelle(dir, tc.args); err != nil {
   632  				t.Fatal(err)
   633  			}
   634  
   635  			testtools.CheckFiles(t, dir, []testtools.FileSpec{{
   636  				Path:    config.DefaultValidBuildFileNames[0],
   637  				Content: tc.want,
   638  			}})
   639  		})
   640  	}
   641  }
   642  
   643  func TestRemoveProtoDeletesRules(t *testing.T) {
   644  	files := []testtools.FileSpec{
   645  		{Path: "WORKSPACE"},
   646  		{
   647  			Path: config.DefaultValidBuildFileNames[0],
   648  			Content: `
   649  load("@rules_proto//proto:defs.bzl", "proto_library")
   650  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   651  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   652  
   653  filegroup(
   654      name = "go_default_library_protos",
   655      srcs = ["foo.proto"],
   656      visibility = ["//visibility:public"],
   657  )
   658  
   659  proto_library(
   660      name = "repo_proto",
   661      srcs = ["foo.proto"],
   662      visibility = ["//visibility:public"],
   663  )
   664  
   665  go_proto_library(
   666      name = "repo_go_proto",
   667      importpath = "example.com/repo",
   668      proto = ":repo_proto",
   669      visibility = ["//visibility:public"],
   670  )
   671  
   672  go_library(
   673      name = "go_default_library",
   674      srcs = ["extra.go"],
   675      embed = [":repo_go_proto"],
   676      importpath = "example.com/repo",
   677      visibility = ["//visibility:public"],
   678  )
   679  `,
   680  		},
   681  		{
   682  			Path:    "extra.go",
   683  			Content: `package repo`,
   684  		},
   685  	}
   686  	dir, cleanup := testtools.CreateFiles(t, files)
   687  	defer cleanup()
   688  
   689  	args := []string{"fix", "-go_prefix", "example.com/repo"}
   690  	if err := runGazelle(dir, args); err != nil {
   691  		t.Fatal(err)
   692  	}
   693  
   694  	testtools.CheckFiles(t, dir, []testtools.FileSpec{{
   695  		Path: config.DefaultValidBuildFileNames[0],
   696  		Content: `
   697  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   698  
   699  go_library(
   700      name = "go_default_library",
   701      srcs = ["extra.go"],
   702      importpath = "example.com/repo",
   703      visibility = ["//visibility:public"],
   704  )
   705  `,
   706  	}})
   707  }
   708  
   709  func TestAddServiceConvertsToGrpc(t *testing.T) {
   710  	files := []testtools.FileSpec{
   711  		{Path: "WORKSPACE"},
   712  		{
   713  			Path: config.DefaultValidBuildFileNames[0],
   714  			Content: `
   715  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   716  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   717  load("@rules_proto//proto:defs.bzl", "proto_library")
   718  
   719  proto_library(
   720      name = "repo_proto",
   721      srcs = ["foo.proto"],
   722      visibility = ["//visibility:public"],
   723  )
   724  
   725  go_proto_library(
   726      name = "repo_go_proto",
   727      importpath = "example.com/repo",
   728      proto = ":repo_proto",
   729      visibility = ["//visibility:public"],
   730  )
   731  
   732  go_library(
   733      name = "go_default_library",
   734      embed = [":repo_go_proto"],
   735      importpath = "example.com/repo",
   736      visibility = ["//visibility:public"],
   737  )
   738  `,
   739  		},
   740  		{
   741  			Path: "foo.proto",
   742  			Content: `syntax = "proto3";
   743  
   744  option go_package = "example.com/repo";
   745  
   746  service TestService {}
   747  `,
   748  		},
   749  	}
   750  
   751  	dir, cleanup := testtools.CreateFiles(t, files)
   752  	defer cleanup()
   753  
   754  	args := []string{"-go_prefix", "example.com/repo"}
   755  	if err := runGazelle(dir, args); err != nil {
   756  		t.Fatal(err)
   757  	}
   758  
   759  	testtools.CheckFiles(t, dir, []testtools.FileSpec{{
   760  		Path: config.DefaultValidBuildFileNames[0],
   761  		Content: `
   762  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   763  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   764  load("@rules_proto//proto:defs.bzl", "proto_library")
   765  
   766  proto_library(
   767      name = "repo_proto",
   768      srcs = ["foo.proto"],
   769      visibility = ["//visibility:public"],
   770  )
   771  
   772  go_proto_library(
   773      name = "repo_go_proto",
   774      compilers = ["@io_bazel_rules_go//proto:go_grpc"],
   775      importpath = "example.com/repo",
   776      proto = ":repo_proto",
   777      visibility = ["//visibility:public"],
   778  )
   779  
   780  go_library(
   781      name = "go_default_library",
   782      embed = [":repo_go_proto"],
   783      importpath = "example.com/repo",
   784      visibility = ["//visibility:public"],
   785  )
   786  `,
   787  	}})
   788  }
   789  
   790  func TestProtoImportPrefix(t *testing.T) {
   791  	files := []testtools.FileSpec{
   792  		{Path: "WORKSPACE"},
   793  		{
   794  			Path: config.DefaultValidBuildFileNames[0],
   795  			Content: `
   796  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   797  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   798  load("@rules_proto//proto:defs.bzl", "proto_library")
   799  
   800  proto_library(
   801      name = "foo_proto",
   802      srcs = ["foo.proto"],
   803      visibility = ["//visibility:public"],
   804  )
   805  
   806  go_proto_library(
   807      name = "repo_go_proto",
   808      importpath = "example.com/repo",
   809      proto = ":foo_proto",
   810      visibility = ["//visibility:public"],
   811  )
   812  
   813  go_library(
   814      name = "go_default_library",
   815      embed = [":repo_go_proto"],
   816      importpath = "example.com/repo",
   817      visibility = ["//visibility:public"],
   818  )
   819  `,
   820  		},
   821  		{
   822  			Path:    "foo.proto",
   823  			Content: `syntax = "proto3";`,
   824  		},
   825  	}
   826  
   827  	dir, cleanup := testtools.CreateFiles(t, files)
   828  	defer cleanup()
   829  
   830  	args := []string{
   831  		"update", "-go_prefix", "example.com/repo",
   832  		"-proto_import_prefix", "/bar",
   833  	}
   834  	if err := runGazelle(dir, args); err != nil {
   835  		t.Fatal(err)
   836  	}
   837  
   838  	testtools.CheckFiles(t, dir, []testtools.FileSpec{{
   839  		Path: config.DefaultValidBuildFileNames[0],
   840  		Content: `
   841  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   842  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   843  load("@rules_proto//proto:defs.bzl", "proto_library")
   844  
   845  proto_library(
   846      name = "foo_proto",
   847      srcs = ["foo.proto"],
   848      import_prefix = "/bar",
   849      visibility = ["//visibility:public"],
   850  )
   851  
   852  go_proto_library(
   853      name = "repo_go_proto",
   854      importpath = "example.com/repo",
   855      proto = ":foo_proto",
   856      visibility = ["//visibility:public"],
   857  )
   858  
   859  go_library(
   860      name = "go_default_library",
   861      embed = [":repo_go_proto"],
   862      importpath = "example.com/repo",
   863      visibility = ["//visibility:public"],
   864  )
   865  `,
   866  	}})
   867  }
   868  
   869  func TestEmptyGoPrefix(t *testing.T) {
   870  	files := []testtools.FileSpec{
   871  		{Path: "WORKSPACE"},
   872  		{
   873  			Path:    "foo/foo.go",
   874  			Content: "package foo",
   875  		},
   876  		{
   877  			Path: "bar/bar.go",
   878  			Content: `
   879  package bar
   880  
   881  import (
   882  	_ "fmt"
   883  	_ "foo"
   884  )
   885  `,
   886  		},
   887  	}
   888  
   889  	dir, cleanup := testtools.CreateFiles(t, files)
   890  	defer cleanup()
   891  
   892  	args := []string{"-go_prefix", ""}
   893  	if err := runGazelle(dir, args); err != nil {
   894  		t.Fatal(err)
   895  	}
   896  
   897  	testtools.CheckFiles(t, dir, []testtools.FileSpec{{
   898  		Path: filepath.Join("bar", config.DefaultValidBuildFileNames[0]),
   899  		Content: `
   900  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   901  
   902  go_library(
   903      name = "bar",
   904      srcs = ["bar.go"],
   905      importpath = "bar",
   906      visibility = ["//visibility:public"],
   907      deps = ["//foo"],
   908  )
   909  `,
   910  	}})
   911  }
   912  
   913  // TestResolveKeptImportpath checks that Gazelle can resolve dependencies
   914  // against a library with a '# keep' comment on its importpath attribute
   915  // when the importpath doesn't match what Gazelle would infer.
   916  func TestResolveKeptImportpath(t *testing.T) {
   917  	files := []testtools.FileSpec{
   918  		{Path: "WORKSPACE"},
   919  		{
   920  			Path: "foo/foo.go",
   921  			Content: `
   922  package foo
   923  
   924  import _ "example.com/alt/baz"
   925  `,
   926  		},
   927  		{
   928  			Path: "bar/BUILD.bazel",
   929  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   930  
   931  go_library(
   932      name = "go_default_library",
   933      srcs = ["bar.go"],
   934      importpath = "example.com/alt/baz",  # keep
   935      visibility = ["//visibility:public"],
   936  )
   937  `,
   938  		},
   939  		{
   940  			Path:    "bar/bar.go",
   941  			Content: "package bar",
   942  		},
   943  	}
   944  
   945  	dir, cleanup := testtools.CreateFiles(t, files)
   946  	defer cleanup()
   947  
   948  	args := []string{"-go_prefix", "example.com/repo"}
   949  	if err := runGazelle(dir, args); err != nil {
   950  		t.Fatal(err)
   951  	}
   952  
   953  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
   954  		{
   955  			Path: "foo/BUILD.bazel",
   956  			Content: `
   957  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   958  
   959  go_library(
   960      name = "go_default_library",
   961      srcs = ["foo.go"],
   962      importpath = "example.com/repo/foo",
   963      visibility = ["//visibility:public"],
   964      deps = ["//bar:go_default_library"],
   965  )
   966  `,
   967  		}, {
   968  			Path: "bar/BUILD.bazel",
   969  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   970  
   971  go_library(
   972      name = "go_default_library",
   973      srcs = ["bar.go"],
   974      importpath = "example.com/alt/baz",  # keep
   975      visibility = ["//visibility:public"],
   976  )
   977  `,
   978  		},
   979  	})
   980  }
   981  
   982  // TestResolveVendorSubdirectory checks that Gazelle can resolve libraries
   983  // in a vendor directory which is not at the repository root.
   984  func TestResolveVendorSubdirectory(t *testing.T) {
   985  	files := []testtools.FileSpec{
   986  		{Path: "WORKSPACE"},
   987  		{
   988  			Path:    "sub/vendor/example.com/foo/foo.go",
   989  			Content: "package foo",
   990  		},
   991  		{
   992  			Path: "sub/bar/bar.go",
   993  			Content: `
   994  package bar
   995  
   996  import _ "example.com/foo"
   997  `,
   998  		},
   999  	}
  1000  	dir, cleanup := testtools.CreateFiles(t, files)
  1001  	defer cleanup()
  1002  
  1003  	args := []string{"-go_prefix", "example.com/repo"}
  1004  	if err := runGazelle(dir, args); err != nil {
  1005  		t.Fatal(err)
  1006  	}
  1007  
  1008  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1009  		{
  1010  			Path: "sub/vendor/example.com/foo/BUILD.bazel",
  1011  			Content: `
  1012  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1013  
  1014  go_library(
  1015      name = "foo",
  1016      srcs = ["foo.go"],
  1017      importmap = "example.com/repo/sub/vendor/example.com/foo",
  1018      importpath = "example.com/foo",
  1019      visibility = ["//visibility:public"],
  1020  )
  1021  `,
  1022  		}, {
  1023  			Path: "sub/bar/BUILD.bazel",
  1024  			Content: `
  1025  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1026  
  1027  go_library(
  1028      name = "bar",
  1029      srcs = ["bar.go"],
  1030      importpath = "example.com/repo/sub/bar",
  1031      visibility = ["//visibility:public"],
  1032      deps = ["//sub/vendor/example.com/foo"],
  1033  )
  1034  `,
  1035  		},
  1036  	})
  1037  }
  1038  
  1039  // TestDeleteProtoWithDeps checks that Gazelle will delete proto rules with
  1040  // dependencies after the proto sources are removed.
  1041  func TestDeleteProtoWithDeps(t *testing.T) {
  1042  	files := []testtools.FileSpec{
  1043  		{Path: "WORKSPACE"},
  1044  		{
  1045  			Path: "foo/BUILD.bazel",
  1046  			Content: `
  1047  load("@rules_proto//proto:defs.bzl", "proto_library")
  1048  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  1049  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1050  
  1051  go_library(
  1052      name = "go_default_library",
  1053      srcs = ["extra.go"],
  1054      embed = [":scratch_go_proto"],
  1055      importpath = "example.com/repo/foo",
  1056      visibility = ["//visibility:public"],
  1057  )
  1058  
  1059  proto_library(
  1060      name = "foo_proto",
  1061      srcs = ["foo.proto"],
  1062      visibility = ["//visibility:public"],
  1063      deps = ["//foo/bar:bar_proto"],
  1064  )
  1065  
  1066  go_proto_library(
  1067      name = "foo_go_proto",
  1068      importpath = "example.com/repo/foo",
  1069      proto = ":foo_proto",
  1070      visibility = ["//visibility:public"],
  1071      deps = ["//foo/bar:go_default_library"],
  1072  )
  1073  `,
  1074  		},
  1075  		{
  1076  			Path:    "foo/extra.go",
  1077  			Content: "package foo",
  1078  		},
  1079  		{
  1080  			Path: "foo/bar/bar.proto",
  1081  			Content: `
  1082  syntax = "proto3";
  1083  
  1084  option go_package = "example.com/repo/foo/bar";
  1085  
  1086  message Bar {};
  1087  `,
  1088  		},
  1089  	}
  1090  	dir, cleanup := testtools.CreateFiles(t, files)
  1091  	defer cleanup()
  1092  
  1093  	args := []string{"-go_prefix", "example.com/repo"}
  1094  	if err := runGazelle(dir, args); err != nil {
  1095  		t.Fatal(err)
  1096  	}
  1097  
  1098  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1099  		{
  1100  			Path: "foo/BUILD.bazel",
  1101  			Content: `
  1102  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1103  
  1104  go_library(
  1105      name = "go_default_library",
  1106      srcs = ["extra.go"],
  1107      importpath = "example.com/repo/foo",
  1108      visibility = ["//visibility:public"],
  1109  )
  1110  `,
  1111  		},
  1112  	})
  1113  }
  1114  
  1115  func TestCustomRepoNamesMain(t *testing.T) {
  1116  	files := []testtools.FileSpec{
  1117  		{
  1118  			Path: "WORKSPACE",
  1119  			Content: `
  1120  go_repository(
  1121      name = "custom_repo",
  1122      importpath = "example.com/bar",
  1123      commit = "123456",
  1124  )
  1125  `,
  1126  		}, {
  1127  			Path: "foo.go",
  1128  			Content: `
  1129  package foo
  1130  
  1131  import _ "example.com/bar"
  1132  `,
  1133  		},
  1134  	}
  1135  	dir, cleanup := testtools.CreateFiles(t, files)
  1136  	defer cleanup()
  1137  
  1138  	args := []string{"-go_prefix", "example.com/foo"}
  1139  	if err := runGazelle(dir, args); err != nil {
  1140  		t.Fatal(err)
  1141  	}
  1142  
  1143  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1144  		{
  1145  			Path: "BUILD.bazel",
  1146  			Content: `
  1147  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1148  
  1149  go_library(
  1150      name = "foo",
  1151      srcs = ["foo.go"],
  1152      importpath = "example.com/foo",
  1153      visibility = ["//visibility:public"],
  1154      deps = ["@custom_repo//:bar"],
  1155  )
  1156  `,
  1157  		},
  1158  	})
  1159  }
  1160  
  1161  func TestCustomRepoNamesExternal(t *testing.T) {
  1162  	files := []testtools.FileSpec{
  1163  		{
  1164  			Path: "main/WORKSPACE",
  1165  			Content: `go_repository(
  1166      name = "custom_repo",
  1167      importpath = "example.com/bar",
  1168      commit = "123456",
  1169  )
  1170  `,
  1171  		}, {
  1172  			Path:    "ext/WORKSPACE",
  1173  			Content: "",
  1174  		}, {
  1175  			Path: "ext/foo.go",
  1176  			Content: `
  1177  package foo
  1178  
  1179  import _ "example.com/bar"
  1180  `,
  1181  		},
  1182  	}
  1183  	dir, cleanup := testtools.CreateFiles(t, files)
  1184  	defer cleanup()
  1185  
  1186  	extDir := filepath.Join(dir, "ext")
  1187  	args := []string{
  1188  		"-go_prefix=example.com/foo",
  1189  		"-go_naming_convention=import_alias",
  1190  		"-mode=fix",
  1191  		"-repo_root=" + extDir,
  1192  		"-repo_config=" + filepath.Join(dir, "main", "WORKSPACE"),
  1193  	}
  1194  	if err := runGazelle(extDir, args); err != nil {
  1195  		t.Fatal(err)
  1196  	}
  1197  
  1198  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1199  		{
  1200  			Path: "ext/BUILD.bazel",
  1201  			Content: `
  1202  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1203  
  1204  go_library(
  1205      name = "foo",
  1206      srcs = ["foo.go"],
  1207      importpath = "example.com/foo",
  1208      visibility = ["//visibility:public"],
  1209      deps = ["@custom_repo//:bar"],
  1210  )
  1211  
  1212  alias(
  1213      name = "go_default_library",
  1214      actual = ":foo",
  1215      visibility = ["//visibility:public"],
  1216  )
  1217  `,
  1218  		},
  1219  	})
  1220  }
  1221  
  1222  func TestUpdateReposWithQueryToWorkspace(t *testing.T) {
  1223  	files := []testtools.FileSpec{
  1224  		{
  1225  			Path: "WORKSPACE",
  1226  			Content: `
  1227  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  1228  
  1229  http_archive(
  1230      name = "io_bazel_rules_go",
  1231      sha256 = "8df59f11fb697743cbb3f26cfb8750395f30471e9eabde0d174c3aebc7a1cd39",
  1232      urls = [
  1233          "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/0.19.1/rules_go-0.19.1.tar.gz",
  1234          "https://github.com/bazelbuild/rules_go/releases/download/0.19.1/rules_go-0.19.1.tar.gz",
  1235      ],
  1236  )
  1237  
  1238  http_archive(
  1239      name = "bazel_gazelle",
  1240      sha256 = "be9296bfd64882e3c08e3283c58fcb461fa6dd3c171764fcc4cf322f60615a9b",
  1241      urls = [
  1242          "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz",
  1243          "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz",
  1244      ],
  1245  )
  1246  
  1247  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  1248  
  1249  go_rules_dependencies()
  1250  
  1251  go_register_toolchains(nogo = "@bazel_gazelle//:nogo")
  1252  
  1253  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  1254  
  1255  gazelle_dependencies()
  1256  `,
  1257  		},
  1258  	}
  1259  
  1260  	dir, cleanup := testtools.CreateFiles(t, files)
  1261  	defer cleanup()
  1262  
  1263  	args := []string{"update-repos", "github.com/sirupsen/logrus@v1.3.0"}
  1264  	if err := runGazelle(dir, args); err != nil {
  1265  		t.Fatal(err)
  1266  	}
  1267  
  1268  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1269  		{
  1270  			Path: "WORKSPACE",
  1271  			Content: `
  1272  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  1273  
  1274  http_archive(
  1275      name = "io_bazel_rules_go",
  1276      sha256 = "8df59f11fb697743cbb3f26cfb8750395f30471e9eabde0d174c3aebc7a1cd39",
  1277      urls = [
  1278          "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/0.19.1/rules_go-0.19.1.tar.gz",
  1279          "https://github.com/bazelbuild/rules_go/releases/download/0.19.1/rules_go-0.19.1.tar.gz",
  1280      ],
  1281  )
  1282  
  1283  http_archive(
  1284      name = "bazel_gazelle",
  1285      sha256 = "be9296bfd64882e3c08e3283c58fcb461fa6dd3c171764fcc4cf322f60615a9b",
  1286      urls = [
  1287          "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz",
  1288          "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz",
  1289      ],
  1290  )
  1291  
  1292  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  1293  
  1294  go_rules_dependencies()
  1295  
  1296  go_register_toolchains(nogo = "@bazel_gazelle//:nogo")
  1297  
  1298  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
  1299  
  1300  go_repository(
  1301      name = "com_github_sirupsen_logrus",
  1302      importpath = "github.com/sirupsen/logrus",
  1303      sum = "h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=",
  1304      version = "v1.3.0",
  1305  )
  1306  
  1307  gazelle_dependencies()
  1308  `,
  1309  		},
  1310  	})
  1311  }
  1312  
  1313  func TestDeleteRulesInEmptyDir(t *testing.T) {
  1314  	files := []testtools.FileSpec{
  1315  		{Path: "WORKSPACE"},
  1316  		{
  1317  			Path: "BUILD.bazel",
  1318  			Content: `
  1319  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_binary")
  1320  
  1321  go_library(
  1322      name = "go_default_library",
  1323      srcs = [
  1324          "bar.go",
  1325          "foo.go",
  1326      ],
  1327      importpath = "example.com/repo",
  1328      visibility = ["//visibility:private"],
  1329  )
  1330  
  1331  go_binary(
  1332      name = "cmd",
  1333      embed = [":go_default_library"],
  1334      visibility = ["//visibility:public"],
  1335  )
  1336  `,
  1337  		},
  1338  	}
  1339  	dir, cleanup := testtools.CreateFiles(t, files)
  1340  	defer cleanup()
  1341  
  1342  	args := []string{"-go_prefix=example.com/repo"}
  1343  	if err := runGazelle(dir, args); err != nil {
  1344  		t.Fatal(err)
  1345  	}
  1346  
  1347  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1348  		{
  1349  			Path:    "BUILD.bazel",
  1350  			Content: "",
  1351  		},
  1352  	})
  1353  }
  1354  
  1355  func TestFixWorkspaceWithoutGazelle(t *testing.T) {
  1356  	files := []testtools.FileSpec{
  1357  		{
  1358  			Path: "WORKSPACE",
  1359  			Content: `
  1360  load("@io_bazel_rules_go//go:def.bzl", "go_repository")
  1361  
  1362  go_repository(
  1363      name = "com_example_repo",
  1364      importpath = "example.com/repo",
  1365      tag = "1.2.3",
  1366  )
  1367  `,
  1368  		},
  1369  	}
  1370  	dir, cleanup := testtools.CreateFiles(t, files)
  1371  	defer cleanup()
  1372  
  1373  	if err := runGazelle(dir, []string{"fix", "-go_prefix="}); err == nil {
  1374  		t.Error("got success; want error")
  1375  	} else if want := "bazel_gazelle is not declared"; !strings.Contains(err.Error(), want) {
  1376  		t.Errorf("got error %v; want error containing %q", err, want)
  1377  	}
  1378  }
  1379  
  1380  // TestFixGazelle checks that loads of the gazelle macro from the old location
  1381  // in rules_go are replaced with the new location in @bazel_gazelle.
  1382  func TestFixGazelle(t *testing.T) {
  1383  	files := []testtools.FileSpec{
  1384  		{
  1385  			Path: "WORKSPACE",
  1386  		}, {
  1387  			Path: "BUILD.bazel",
  1388  			Content: `
  1389  load("@io_bazel_rules_go//go:def.bzl", "gazelle", "go_library")
  1390  
  1391  gazelle(name = "gazelle")
  1392  
  1393  # keep
  1394  go_library(name = "go_default_library")
  1395  `,
  1396  		},
  1397  	}
  1398  	dir, cleanup := testtools.CreateFiles(t, files)
  1399  	defer cleanup()
  1400  
  1401  	if err := runGazelle(dir, nil); err != nil {
  1402  		t.Fatal(err)
  1403  	}
  1404  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1405  		{
  1406  			Path: "BUILD.bazel",
  1407  			Content: `
  1408  load("@bazel_gazelle//:def.bzl", "gazelle")
  1409  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1410  
  1411  gazelle(name = "gazelle")
  1412  
  1413  # keep
  1414  go_library(name = "go_default_library")
  1415  `,
  1416  		},
  1417  	})
  1418  }
  1419  
  1420  // TestKeepDeps checks rules with keep comments on the rule or on the deps
  1421  // attribute will not be modified during dependency resolution. Verifies #212.
  1422  func TestKeepDeps(t *testing.T) {
  1423  	files := []testtools.FileSpec{
  1424  		{
  1425  			Path: "WORKSPACE",
  1426  		}, {
  1427  			Path: "BUILD.bazel",
  1428  			Content: `
  1429  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
  1430  
  1431  # gazelle:prefix example.com/repo
  1432  
  1433  # keep
  1434  go_library(
  1435      name = "go_default_library",
  1436      srcs = ["lib.go"],
  1437      importpath = "example.com/repo",
  1438      deps = [":dont_remove"],
  1439  )
  1440  
  1441  go_test(
  1442      name = "go_default_test",
  1443      # keep
  1444      srcs = ["lib_test.go"],
  1445      # keep
  1446      embed = [":go_default_library"],
  1447      # keep
  1448      deps = [":dont_remove"],
  1449  )
  1450  `,
  1451  		},
  1452  	}
  1453  	dir, cleanup := testtools.CreateFiles(t, files)
  1454  	defer cleanup()
  1455  
  1456  	if err := runGazelle(dir, nil); err != nil {
  1457  		t.Fatal(err)
  1458  	}
  1459  
  1460  	testtools.CheckFiles(t, dir, files)
  1461  }
  1462  
  1463  func TestDontCreateBuildFileInEmptyDir(t *testing.T) {
  1464  	files := []testtools.FileSpec{
  1465  		{Path: "WORKSPACE"},
  1466  		{Path: "sub/"},
  1467  	}
  1468  	dir, cleanup := testtools.CreateFiles(t, files)
  1469  	defer cleanup()
  1470  
  1471  	if err := runGazelle(dir, nil); err != nil {
  1472  		t.Error(err)
  1473  	}
  1474  	for _, f := range []string{"BUILD.bazel", "sub/BUILD.bazel"} {
  1475  		path := filepath.Join(dir, filepath.FromSlash(f))
  1476  		_, err := os.Stat(path)
  1477  		if err == nil {
  1478  			t.Errorf("%s: build file was created", f)
  1479  		}
  1480  	}
  1481  }
  1482  
  1483  // TestNoIndex checks that gazelle does not index existing or generated
  1484  // library rules with the flag -index=false. Verifies #384.
  1485  func TestNoIndex(t *testing.T) {
  1486  	files := []testtools.FileSpec{
  1487  		{Path: "WORKSPACE"},
  1488  		{
  1489  			Path: "foo/foo.go",
  1490  			Content: `
  1491  package foo
  1492  
  1493  import _ "example.com/bar"
  1494  `,
  1495  		},
  1496  		{
  1497  			Path:    "third_party/example.com/bar/bar.go",
  1498  			Content: "package bar",
  1499  		},
  1500  		{
  1501  			Path:    "third_party/BUILD.bazel",
  1502  			Content: "# gazelle:prefix",
  1503  		},
  1504  		{
  1505  			Path: "third_party/example.com/bar/BUILD.bazel",
  1506  			Content: `
  1507  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1508  
  1509  go_library(
  1510      name = "bar",
  1511      srcs = ["bar.go"],
  1512      importpath = "example.com/bar",
  1513      visibility = ["//visibility:public"],
  1514  )
  1515  `,
  1516  		},
  1517  	}
  1518  	dir, cleanup := testtools.CreateFiles(t, files)
  1519  	defer cleanup()
  1520  
  1521  	args := []string{
  1522  		"-go_prefix=example.com/repo",
  1523  		"-external=vendored",
  1524  		"-index=false",
  1525  	}
  1526  	if err := runGazelle(dir, args); err != nil {
  1527  		t.Fatal(err)
  1528  	}
  1529  
  1530  	testtools.CheckFiles(t, dir, []testtools.FileSpec{{
  1531  		Path: "foo/BUILD.bazel",
  1532  		Content: `
  1533  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1534  
  1535  go_library(
  1536      name = "foo",
  1537      srcs = ["foo.go"],
  1538      importpath = "example.com/repo/foo",
  1539      visibility = ["//visibility:public"],
  1540      deps = ["//vendor/example.com/bar"],
  1541  )
  1542  `,
  1543  	}})
  1544  }
  1545  
  1546  // TestNoIndexNoRecurse checks that gazelle behaves correctly with the flags
  1547  // -r=false -index=false. Gazelle should not generate build files in
  1548  // subdirectories and should not resolve dependencies to local libraries.
  1549  func TestNoIndexNoRecurse(t *testing.T) {
  1550  	barBuildFile := testtools.FileSpec{
  1551  		Path:    "foo/bar/BUILD.bazel",
  1552  		Content: "# this should not be updated because -r=false",
  1553  	}
  1554  	files := []testtools.FileSpec{
  1555  		{Path: "WORKSPACE"},
  1556  		{
  1557  			Path: "foo/foo.go",
  1558  			Content: `package foo
  1559  
  1560  import (
  1561  	_ "example.com/dep/baz"
  1562  )
  1563  `,
  1564  		},
  1565  		barBuildFile,
  1566  		{
  1567  			Path:    "foo/bar/bar.go",
  1568  			Content: "package bar",
  1569  		},
  1570  		{
  1571  			Path: "third_party/baz/BUILD.bazel",
  1572  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1573  
  1574  # this should be ignored because -index=false
  1575  go_library(
  1576      name = "baz",
  1577      srcs = ["baz.go"],
  1578      importpath = "example.com/dep/baz",
  1579      visibility = ["//visibility:public"],
  1580  )
  1581  `,
  1582  		},
  1583  		{
  1584  			Path:    "third_party/baz/baz.go",
  1585  			Content: "package baz",
  1586  		},
  1587  	}
  1588  	dir, cleanup := testtools.CreateFiles(t, files)
  1589  	defer cleanup()
  1590  
  1591  	args := []string{
  1592  		"-go_prefix=example.com/repo",
  1593  		"-external=vendored",
  1594  		"-r=false",
  1595  		"-index=false",
  1596  		"foo",
  1597  	}
  1598  	if err := runGazelle(dir, args); err != nil {
  1599  		t.Fatal(err)
  1600  	}
  1601  
  1602  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1603  		{
  1604  			Path: "foo/BUILD.bazel",
  1605  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1606  
  1607  go_library(
  1608      name = "foo",
  1609      srcs = ["foo.go"],
  1610      importpath = "example.com/repo/foo",
  1611      visibility = ["//visibility:public"],
  1612      deps = ["//vendor/example.com/dep/baz"],
  1613  )
  1614  `,
  1615  		},
  1616  		barBuildFile,
  1617  	})
  1618  }
  1619  
  1620  // TestNoIndexRecurse checks that gazelle behaves correctly with the flags
  1621  // -r=true -index=false. Gazelle should generate build files in directories
  1622  // and subdirectories, but should not resolve dependencies to local libraries.
  1623  func TestNoIndexRecurse(t *testing.T) {
  1624  	files := []testtools.FileSpec{
  1625  		{Path: "WORKSPACE"}, {
  1626  			Path: "foo/foo.go",
  1627  			Content: `package foo
  1628  
  1629  import (
  1630  	_ "example.com/dep/baz"
  1631  )
  1632  `,
  1633  		}, {
  1634  			Path:    "foo/bar/bar.go",
  1635  			Content: "package bar",
  1636  		}, {
  1637  			Path: "third_party/baz/BUILD.bazel",
  1638  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1639  
  1640  # this should be ignored because -index=false
  1641  go_library(
  1642      name = "baz",
  1643      srcs = ["baz.go"],
  1644      importpath = "example.com/dep/baz",
  1645      visibility = ["//visibility:public"],
  1646  )
  1647  `,
  1648  		}, {
  1649  			Path:    "third_party/baz/baz.go",
  1650  			Content: "package baz",
  1651  		},
  1652  	}
  1653  	dir, cleanup := testtools.CreateFiles(t, files)
  1654  	defer cleanup()
  1655  
  1656  	args := []string{
  1657  		"-go_prefix=example.com/repo",
  1658  		"-external=vendored",
  1659  		"-r=true",
  1660  		"-index=false",
  1661  		"foo",
  1662  	}
  1663  	if err := runGazelle(dir, args); err != nil {
  1664  		t.Fatal(err)
  1665  	}
  1666  
  1667  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1668  		{
  1669  			Path: "foo/BUILD.bazel",
  1670  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1671  
  1672  go_library(
  1673      name = "foo",
  1674      srcs = ["foo.go"],
  1675      importpath = "example.com/repo/foo",
  1676      visibility = ["//visibility:public"],
  1677      deps = ["//vendor/example.com/dep/baz"],
  1678  )
  1679  `,
  1680  		}, {
  1681  			Path: "foo/bar/BUILD.bazel",
  1682  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1683  
  1684  go_library(
  1685      name = "bar",
  1686      srcs = ["bar.go"],
  1687      importpath = "example.com/repo/foo/bar",
  1688      visibility = ["//visibility:public"],
  1689  )
  1690  `,
  1691  		},
  1692  	})
  1693  }
  1694  
  1695  // TestSubdirectoryPrefixExternal checks that directives set in subdirectories
  1696  // may be used in dependency resolution. Verifies #412.
  1697  func TestSubdirectoryPrefixExternal(t *testing.T) {
  1698  	files := []testtools.FileSpec{
  1699  		{
  1700  			Path: "WORKSPACE",
  1701  		}, {
  1702  			Path:    "BUILD.bazel",
  1703  			Content: "# gazelle:prefix",
  1704  		}, {
  1705  			Path:    "sub/BUILD.bazel",
  1706  			Content: "# gazelle:prefix example.com/sub",
  1707  		}, {
  1708  			Path: "sub/sub.go",
  1709  			Content: `
  1710  package sub
  1711  
  1712  import (
  1713  	_ "example.com/sub/missing"
  1714  	_ "example.com/external"
  1715  )
  1716  `,
  1717  		},
  1718  	}
  1719  	dir, cleanup := testtools.CreateFiles(t, files)
  1720  	defer cleanup()
  1721  
  1722  	if err := runGazelle(dir, []string{"-external=vendored", "-index=false"}); err != nil {
  1723  		t.Fatal(err)
  1724  	}
  1725  
  1726  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1727  		{
  1728  			Path: "sub/BUILD.bazel",
  1729  			Content: `
  1730  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1731  
  1732  # gazelle:prefix example.com/sub
  1733  
  1734  go_library(
  1735      name = "sub",
  1736      srcs = ["sub.go"],
  1737      importpath = "example.com/sub",
  1738      visibility = ["//visibility:public"],
  1739      deps = [
  1740          "//sub/missing",
  1741          "//vendor/example.com/external",
  1742      ],
  1743  )
  1744  `,
  1745  		},
  1746  	})
  1747  }
  1748  
  1749  func TestGoGrpcProtoFlag(t *testing.T) {
  1750  	files := []testtools.FileSpec{
  1751  		{
  1752  			Path: "WORKSPACE",
  1753  		}, {
  1754  			Path: "BUILD.bazel",
  1755  			Content: `
  1756  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  1757  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1758  load("@rules_proto//proto:defs.bzl", "proto_library")
  1759  
  1760  go_proto_library(
  1761      name = "foo_go_proto",
  1762      importpath = "example.com/repo/foo",
  1763      proto = ":foo_proto",
  1764      visibility = ["//visibility:public"],
  1765  )
  1766  
  1767  proto_library(
  1768      name = "foo_proto",
  1769      srcs = ["foo.proto"],
  1770      visibility = ["//visibility:public"],
  1771  )
  1772  
  1773  go_library(
  1774      name = "go_default_library",
  1775      embed = [":foo_go_proto"],
  1776      importpath = "example.com/repo/foo",
  1777      visibility = ["//visibility:public"],
  1778  )
  1779  `,
  1780  		}, {
  1781  			Path: "foo.proto",
  1782  			Content: `
  1783  syntax = "proto3";
  1784  
  1785  option go_package = "example.com/repo/foo";
  1786  
  1787  message Bar {};
  1788  `,
  1789  		}, {
  1790  			Path: "service/BUILD.bazel",
  1791  			Content: `
  1792  load("@rules_proto//proto:defs.bzl", "proto_library")
  1793  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  1794  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1795  
  1796  go_proto_library(
  1797      name = "service_go_proto",
  1798      compilers = ["@io_bazel_rules_go//proto:go_grpc"],
  1799      importpath = "example.com/repo/service",
  1800      proto = ":service_proto",
  1801      visibility = ["//visibility:public"],
  1802  )
  1803  
  1804  proto_library(
  1805      name = "service_proto",
  1806      srcs = ["service.proto"],
  1807      visibility = ["//visibility:public"],
  1808  )
  1809  
  1810  go_library(
  1811      name = "go_default_library",
  1812      embed = [":service_go_proto"],
  1813      importpath = "example.com/repo/service",
  1814      visibility = ["//visibility:public"],
  1815  )
  1816  `,
  1817  		}, {
  1818  			Path: "service/service.proto",
  1819  			Content: `
  1820  syntax = "proto3";
  1821  
  1822  option go_package = "example.com/repo/service";
  1823  
  1824  service TestService {}
  1825  `,
  1826  		},
  1827  	}
  1828  	dir, cleanup := testtools.CreateFiles(t, files)
  1829  	defer cleanup()
  1830  
  1831  	args := []string{"update", "-go_grpc_compiler", "//foo", "-go_proto_compiler", "//bar"}
  1832  	if err := runGazelle(dir, args); err != nil {
  1833  		t.Fatal(err)
  1834  	}
  1835  
  1836  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  1837  		{
  1838  			Path: "BUILD.bazel",
  1839  			Content: `
  1840  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1841  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  1842  load("@rules_proto//proto:defs.bzl", "proto_library")
  1843  
  1844  go_proto_library(
  1845      name = "foo_go_proto",
  1846      compilers = ["//bar"],
  1847      importpath = "example.com/repo/foo",
  1848      proto = ":foo_proto",
  1849      visibility = ["//visibility:public"],
  1850  )
  1851  
  1852  proto_library(
  1853      name = "foo_proto",
  1854      srcs = ["foo.proto"],
  1855      visibility = ["//visibility:public"],
  1856  )
  1857  
  1858  go_library(
  1859      name = "go_default_library",
  1860      embed = [":foo_go_proto"],
  1861      importpath = "example.com/repo/foo",
  1862      visibility = ["//visibility:public"],
  1863  )
  1864  `,
  1865  		},
  1866  		{
  1867  			Path: "service/BUILD.bazel",
  1868  			Content: `
  1869  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1870  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  1871  load("@rules_proto//proto:defs.bzl", "proto_library")
  1872  
  1873  go_proto_library(
  1874      name = "service_go_proto",
  1875      compilers = ["//foo"],
  1876      importpath = "example.com/repo/service",
  1877      proto = ":service_proto",
  1878      visibility = ["//visibility:public"],
  1879  )
  1880  
  1881  proto_library(
  1882      name = "service_proto",
  1883      srcs = ["service.proto"],
  1884      visibility = ["//visibility:public"],
  1885  )
  1886  
  1887  go_library(
  1888      name = "go_default_library",
  1889      embed = [":service_go_proto"],
  1890      importpath = "example.com/repo/service",
  1891      visibility = ["//visibility:public"],
  1892  )
  1893  `,
  1894  		},
  1895  	})
  1896  }
  1897  
  1898  // TestMapKind tests the gazelle:map_kind directive.
  1899  // Verifies #448
  1900  func TestMapKind(t *testing.T) {
  1901  	files := []testtools.FileSpec{
  1902  		{
  1903  			Path: "WORKSPACE",
  1904  		},
  1905  		{
  1906  			Path: "BUILD.bazel",
  1907  			Content: `
  1908  # gazelle:prefix example.com/mapkind
  1909  # gazelle:go_naming_convention go_default_library
  1910  `,
  1911  		},
  1912  		{
  1913  			Path:    "root_lib.go",
  1914  			Content: `package mapkind`,
  1915  		},
  1916  		{
  1917  			Path:    "enabled/BUILD.bazel",
  1918  			Content: "# gazelle:map_kind go_library my_library //tools/go:def.bzl",
  1919  		},
  1920  		{
  1921  			Path:    "enabled/enabled_lib.go",
  1922  			Content: `package enabled`,
  1923  		},
  1924  		{
  1925  			Path: "enabled/inherited/BUILD.bazel",
  1926  		},
  1927  		{
  1928  			Path:    "enabled/inherited/inherited_lib.go",
  1929  			Content: `package inherited`,
  1930  		},
  1931  		{
  1932  			Path: "enabled/existing_rules/mapped/BUILD.bazel",
  1933  			Content: `
  1934  load("//tools/go:def.bzl", "my_library")
  1935  
  1936  # An existing rule with a mapped type is updated
  1937  my_library(
  1938      name = "go_default_library",
  1939      srcs = ["deleted_file.go", "mapped_lib.go"],
  1940      importpath = "example.com/mapkind/enabled/existing_rules/mapped",
  1941      visibility = ["//visibility:public"],
  1942  )
  1943  `,
  1944  		},
  1945  		{
  1946  			Path:    "enabled/existing_rules/mapped/mapped_lib.go",
  1947  			Content: `package mapped`,
  1948  		},
  1949  		{
  1950  			Path:    "enabled/existing_rules/mapped/mapped_lib2.go",
  1951  			Content: `package mapped`,
  1952  		},
  1953  		{
  1954  			Path: "enabled/existing_rules/unmapped/BUILD.bazel",
  1955  			Content: `
  1956  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1957  
  1958  # An existing rule with an unmapped type is updated
  1959  go_library(
  1960      name = "go_default_library",
  1961      srcs = ["unmapped_lib.go"],
  1962      importpath = "example.com/mapkind/enabled/existing_rules/unmapped",
  1963      visibility = ["//visibility:public"],
  1964  )
  1965  `,
  1966  		},
  1967  		{
  1968  			Path:    "enabled/existing_rules/unmapped/unmapped_lib.go",
  1969  			Content: `package unmapped`,
  1970  		},
  1971  		{
  1972  			Path: "enabled/existing_rules/clean/BUILD.bazel",
  1973  			Content: `load("//tools/go:def.bzl", "my_go_library")
  1974  
  1975  # gazelle:go_naming_convention import
  1976  # gazelle:map_kind go_library my_go_library //tools/go:def.bzl
  1977  
  1978  my_go_library(
  1979      name = "clean",
  1980      srcs = [
  1981          "foo.go",
  1982          "bar.go",
  1983          "buz.go",
  1984      ],
  1985      importpath = "example.com/mapkind/enabled/existing_rules/clean",
  1986      visibility = ["//visibility:private"],
  1987  )
  1988  `,
  1989  		},
  1990  		{
  1991  			Path: "enabled/existing_rules/clean_binary/BUILD.bazel",
  1992  			Content: `load("//tools/go:def.bzl", "my_go_binary", "my_go_library")
  1993  
  1994  # gazelle:go_naming_convention import
  1995  # gazelle:map_kind go_binary my_go_binary //tools/go:def.bzl
  1996  # gazelle:map_kind go_library my_go_library //tools/go:def.bzl
  1997  
  1998  my_go_library(
  1999      name = "clean_binary_lib",
  2000      srcs = ["main.go"],
  2001      importpath = "example.com/mapkind/enabled/existing_rules/clean_binary",
  2002      visibility = ["//visibility:private"],
  2003  )
  2004  
  2005  my_go_binary(
  2006      name = "clean_binary",
  2007      embed = [":clean_binary_lib"],
  2008      visibility = ["//visibility:public"],
  2009  )
  2010  `,
  2011  		},
  2012  		{
  2013  			Path:    "enabled/existing_rules/nobuild/nobuild_lib.go",
  2014  			Content: `package nobuild`,
  2015  		},
  2016  		{
  2017  			Path:    "enabled/overridden/BUILD.bazel",
  2018  			Content: "# gazelle:map_kind go_library overridden_library //tools/overridden:def.bzl",
  2019  		},
  2020  		{
  2021  			Path:    "enabled/overridden/overridden_lib.go",
  2022  			Content: `package overridden`,
  2023  		},
  2024  		{
  2025  			Path: "disabled/BUILD.bazel",
  2026  		},
  2027  		{
  2028  			Path:    "disabled/disabled_lib.go",
  2029  			Content: `package disabled`,
  2030  		},
  2031  		{
  2032  			Path: "enabled/multiple_mappings/BUILD.bazel",
  2033  			Content: `
  2034  # gazelle:map_kind go_binary go_binary //tools/go:def.bzl
  2035  # gazelle:map_kind go_library go_library //tools/go:def.bzl
  2036  `,
  2037  		},
  2038  		{
  2039  			Path: "enabled/multiple_mappings/multiple_mappings.go",
  2040  			Content: `
  2041  package main
  2042  
  2043  func main() {}`,
  2044  		},
  2045  		{
  2046  			Path: "depend_on_mapped_kind/lib.go",
  2047  			Content: `package depend_on_mapped_kind
  2048  import (
  2049  	_ "example.com/mapkind/disabled"
  2050  	_ "example.com/mapkind/enabled"
  2051  	_ "example.com/mapkind/enabled/existing_rules/mapped"
  2052  	_ "example.com/mapkind/enabled/existing_rules/unmapped"
  2053  	_ "example.com/mapkind/enabled/overridden"
  2054  )`,
  2055  		},
  2056  	}
  2057  	dir, cleanup := testtools.CreateFiles(t, files)
  2058  	defer cleanup()
  2059  
  2060  	if err := runGazelle(dir, []string{"-external=vendored"}); err != nil {
  2061  		t.Fatal(err)
  2062  	}
  2063  
  2064  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  2065  		{
  2066  			Path: "BUILD.bazel",
  2067  			Content: `
  2068  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2069  
  2070  # gazelle:prefix example.com/mapkind
  2071  # gazelle:go_naming_convention go_default_library
  2072  
  2073  go_library(
  2074      name = "go_default_library",
  2075      srcs = ["root_lib.go"],
  2076      importpath = "example.com/mapkind",
  2077      visibility = ["//visibility:public"],
  2078  )
  2079  `,
  2080  		},
  2081  		{
  2082  			Path: "enabled/BUILD.bazel",
  2083  			Content: `
  2084  load("//tools/go:def.bzl", "my_library")
  2085  
  2086  # gazelle:map_kind go_library my_library //tools/go:def.bzl
  2087  
  2088  my_library(
  2089      name = "go_default_library",
  2090      srcs = ["enabled_lib.go"],
  2091      importpath = "example.com/mapkind/enabled",
  2092      visibility = ["//visibility:public"],
  2093  )
  2094  `,
  2095  		},
  2096  		{
  2097  			Path: "enabled/inherited/BUILD.bazel",
  2098  			Content: `
  2099  load("//tools/go:def.bzl", "my_library")
  2100  
  2101  my_library(
  2102      name = "go_default_library",
  2103      srcs = ["inherited_lib.go"],
  2104      importpath = "example.com/mapkind/enabled/inherited",
  2105      visibility = ["//visibility:public"],
  2106  )
  2107  `,
  2108  		},
  2109  		{
  2110  			Path: "enabled/overridden/BUILD.bazel",
  2111  			Content: `
  2112  load("//tools/overridden:def.bzl", "overridden_library")
  2113  
  2114  # gazelle:map_kind go_library overridden_library //tools/overridden:def.bzl
  2115  
  2116  overridden_library(
  2117      name = "go_default_library",
  2118      srcs = ["overridden_lib.go"],
  2119      importpath = "example.com/mapkind/enabled/overridden",
  2120      visibility = ["//visibility:public"],
  2121  )
  2122  `,
  2123  		},
  2124  		{
  2125  			Path: "disabled/BUILD.bazel",
  2126  			Content: `
  2127  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2128  
  2129  go_library(
  2130      name = "go_default_library",
  2131      srcs = ["disabled_lib.go"],
  2132      importpath = "example.com/mapkind/disabled",
  2133      visibility = ["//visibility:public"],
  2134  )
  2135  `,
  2136  		},
  2137  		{
  2138  			Path: "enabled/existing_rules/mapped/BUILD.bazel",
  2139  			Content: `
  2140  load("//tools/go:def.bzl", "my_library")
  2141  
  2142  # An existing rule with a mapped type is updated
  2143  my_library(
  2144      name = "go_default_library",
  2145      srcs = [
  2146          "mapped_lib.go",
  2147          "mapped_lib2.go",
  2148      ],
  2149      importpath = "example.com/mapkind/enabled/existing_rules/mapped",
  2150      visibility = ["//visibility:public"],
  2151  )
  2152  `,
  2153  		},
  2154  		{
  2155  			Path: "enabled/existing_rules/unmapped/BUILD.bazel",
  2156  			Content: `
  2157  load("//tools/go:def.bzl", "my_library")
  2158  
  2159  # An existing rule with an unmapped type is updated
  2160  my_library(
  2161      name = "go_default_library",
  2162      srcs = ["unmapped_lib.go"],
  2163      importpath = "example.com/mapkind/enabled/existing_rules/unmapped",
  2164      visibility = ["//visibility:public"],
  2165  )
  2166  `,
  2167  		},
  2168  		{
  2169  			Path: "enabled/existing_rules/clean/BUILD.bazel",
  2170  			Content: `
  2171  # gazelle:go_naming_convention import
  2172  # gazelle:map_kind go_library my_go_library //tools/go:def.bzl
  2173  `,
  2174  		},
  2175  		{
  2176  			Path: "enabled/existing_rules/clean_binary/BUILD.bazel",
  2177  			Content: `
  2178  # gazelle:go_naming_convention import
  2179  # gazelle:map_kind go_binary my_go_binary //tools/go:def.bzl
  2180  # gazelle:map_kind go_library my_go_library //tools/go:def.bzl
  2181  `,
  2182  		},
  2183  		{
  2184  			Path: "enabled/existing_rules/nobuild/BUILD.bazel",
  2185  			Content: `
  2186  load("//tools/go:def.bzl", "my_library")
  2187  
  2188  my_library(
  2189      name = "go_default_library",
  2190      srcs = ["nobuild_lib.go"],
  2191      importpath = "example.com/mapkind/enabled/existing_rules/nobuild",
  2192      visibility = ["//visibility:public"],
  2193  )
  2194  `,
  2195  		},
  2196  		{
  2197  			Path: "enabled/multiple_mappings/BUILD.bazel",
  2198  			Content: `
  2199  load("//tools/go:def.bzl", "go_binary", "go_library")
  2200  
  2201  # gazelle:map_kind go_binary go_binary //tools/go:def.bzl
  2202  # gazelle:map_kind go_library go_library //tools/go:def.bzl
  2203  
  2204  go_library(
  2205      name = "go_default_library",
  2206      srcs = ["multiple_mappings.go"],
  2207      importpath = "example.com/mapkind/enabled/multiple_mappings",
  2208      visibility = ["//visibility:private"],
  2209  )
  2210  
  2211  go_binary(
  2212      name = "multiple_mappings",
  2213      embed = [":go_default_library"],
  2214      visibility = ["//visibility:public"],
  2215  )
  2216  `,
  2217  		},
  2218  		{
  2219  			Path: "depend_on_mapped_kind/BUILD.bazel",
  2220  			Content: `
  2221  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2222  
  2223  go_library(
  2224      name = "go_default_library",
  2225      srcs = ["lib.go"],
  2226      importpath = "example.com/mapkind/depend_on_mapped_kind",
  2227      visibility = ["//visibility:public"],
  2228      deps = [
  2229          "//disabled:go_default_library",
  2230          "//enabled:go_default_library",
  2231          "//enabled/existing_rules/mapped:go_default_library",
  2232          "//enabled/existing_rules/unmapped:go_default_library",
  2233          "//enabled/overridden:go_default_library",
  2234      ],
  2235  )
  2236  `,
  2237  		},
  2238  	})
  2239  }
  2240  
  2241  func TestMapKindEdgeCases(t *testing.T) {
  2242  	for name, tc := range map[string]struct {
  2243  		before []testtools.FileSpec
  2244  		after  []testtools.FileSpec
  2245  	}{
  2246  		"new generated rule applies map_kind": {
  2247  			before: []testtools.FileSpec{
  2248  				{
  2249  					Path: "WORKSPACE",
  2250  				},
  2251  				{
  2252  					Path: "BUILD.bazel",
  2253  					Content: `# gazelle:prefix example.com/mapkind
  2254  # gazelle:go_naming_convention go_default_library
  2255  # gazelle:map_kind go_library go_library //custom:def.bzl
  2256  `,
  2257  				},
  2258  				{
  2259  					Path:    "dir/file.go",
  2260  					Content: "package dir",
  2261  				},
  2262  			},
  2263  			after: []testtools.FileSpec{
  2264  				{
  2265  					Path: "dir/BUILD.bazel",
  2266  					Content: `load("//custom:def.bzl", "go_library")
  2267  
  2268  go_library(
  2269      name = "go_default_library",
  2270      srcs = ["file.go"],
  2271      importpath = "example.com/mapkind/dir",
  2272      visibility = ["//visibility:public"],
  2273  )
  2274  `,
  2275  				},
  2276  			},
  2277  		},
  2278  		"existing generated rule with non-renaming mapping applied applies map_kind": {
  2279  			before: []testtools.FileSpec{
  2280  				{
  2281  					Path: "WORKSPACE",
  2282  				},
  2283  				{
  2284  					Path: "BUILD.bazel",
  2285  					Content: `# gazelle:prefix example.com/mapkind
  2286  # gazelle:go_naming_convention go_default_library
  2287  # gazelle:map_kind go_library go_library //custom:def.bzl
  2288  `,
  2289  				},
  2290  				{
  2291  					Path: "dir/BUILD.bazel",
  2292  					Content: `load("//custom:def.bzl", "go_library")
  2293  
  2294  go_library(
  2295      name = "go_default_library",
  2296      srcs = ["file.go"],
  2297      importpath = "example.com/mapkind/dir",
  2298      visibility = ["//visibility:public"],
  2299  )
  2300  `,
  2301  				},
  2302  				{
  2303  					Path:    "dir/file.go",
  2304  					Content: "package dir",
  2305  				},
  2306  			},
  2307  			after: []testtools.FileSpec{
  2308  				{
  2309  					Path: "dir/BUILD.bazel",
  2310  					Content: `load("//custom:def.bzl", "go_library")
  2311  
  2312  go_library(
  2313      name = "go_default_library",
  2314      srcs = ["file.go"],
  2315      importpath = "example.com/mapkind/dir",
  2316      visibility = ["//visibility:public"],
  2317  )
  2318  `,
  2319  				},
  2320  			},
  2321  		},
  2322  		"existing generated rule without non-renaming mapping applied applies map_kind": {
  2323  			before: []testtools.FileSpec{
  2324  				{
  2325  					Path: "WORKSPACE",
  2326  				},
  2327  				{
  2328  					Path: "BUILD.bazel",
  2329  					Content: `# gazelle:prefix example.com/mapkind
  2330  # gazelle:go_naming_convention go_default_library
  2331  # gazelle:map_kind go_library go_library //custom:def.bzl
  2332  `,
  2333  				},
  2334  				{
  2335  					Path: "dir/BUILD.bazel",
  2336  					Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2337  
  2338  go_library(
  2339      name = "go_default_library",
  2340      srcs = ["file.go"],
  2341      importpath = "example.com/mapkind/dir",
  2342      visibility = ["//visibility:public"],
  2343  )
  2344  `,
  2345  				},
  2346  				{
  2347  					Path:    "dir/file.go",
  2348  					Content: "package dir",
  2349  				},
  2350  			},
  2351  			after: []testtools.FileSpec{
  2352  				{
  2353  					Path: "dir/BUILD.bazel",
  2354  					Content: `load("//custom:def.bzl", "go_library")
  2355  
  2356  go_library(
  2357      name = "go_default_library",
  2358      srcs = ["file.go"],
  2359      importpath = "example.com/mapkind/dir",
  2360      visibility = ["//visibility:public"],
  2361  )
  2362  `,
  2363  				},
  2364  			},
  2365  		},
  2366  		"existing generated rule without renaming mapping applied applies map_kind": {
  2367  			before: []testtools.FileSpec{
  2368  				{
  2369  					Path: "WORKSPACE",
  2370  				},
  2371  				{
  2372  					Path: "BUILD.bazel",
  2373  					Content: `# gazelle:prefix example.com/mapkind
  2374  # gazelle:go_naming_convention go_default_library
  2375  # gazelle:map_kind go_library custom_go_library //custom:def.bzl
  2376  `,
  2377  				},
  2378  				{
  2379  					Path: "dir/BUILD.bazel",
  2380  					Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2381  
  2382  go_library(
  2383      name = "go_default_library",
  2384      srcs = ["file.go"],
  2385      importpath = "example.com/mapkind/dir",
  2386      visibility = ["//visibility:public"],
  2387  )
  2388  `,
  2389  				},
  2390  				{
  2391  					Path:    "dir/file.go",
  2392  					Content: "package dir",
  2393  				},
  2394  			},
  2395  			after: []testtools.FileSpec{
  2396  				{
  2397  					Path: "dir/BUILD.bazel",
  2398  					Content: `load("//custom:def.bzl", "custom_go_library")
  2399  
  2400  custom_go_library(
  2401      name = "go_default_library",
  2402      srcs = ["file.go"],
  2403      importpath = "example.com/mapkind/dir",
  2404      visibility = ["//visibility:public"],
  2405  )
  2406  `,
  2407  				},
  2408  			},
  2409  		},
  2410  		"existing generated rule with renaming mapping applied preserves map_kind": {
  2411  			before: []testtools.FileSpec{
  2412  				{
  2413  					Path: "WORKSPACE",
  2414  				},
  2415  				{
  2416  					Path: "BUILD.bazel",
  2417  					Content: `# gazelle:prefix example.com/mapkind
  2418  # gazelle:go_naming_convention go_default_library
  2419  # gazelle:map_kind go_library custom_go_library //custom:def.bzl
  2420  `,
  2421  				},
  2422  				{
  2423  					Path: "dir/BUILD.bazel",
  2424  					Content: `load("//custom:def.bzl", "custom_go_library")
  2425  
  2426  custom_go_library(
  2427      name = "go_default_library",
  2428      srcs = ["file.go"],
  2429      importpath = "example.com/mapkind/dir",
  2430      visibility = ["//visibility:public"],
  2431  )
  2432  `,
  2433  				},
  2434  				{
  2435  					Path:    "dir/file.go",
  2436  					Content: "package dir",
  2437  				},
  2438  			},
  2439  			after: []testtools.FileSpec{
  2440  				{
  2441  					Path: "dir/BUILD.bazel",
  2442  					Content: `load("//custom:def.bzl", "custom_go_library")
  2443  
  2444  custom_go_library(
  2445      name = "go_default_library",
  2446      srcs = ["file.go"],
  2447      importpath = "example.com/mapkind/dir",
  2448      visibility = ["//visibility:public"],
  2449  )
  2450  `,
  2451  				},
  2452  			},
  2453  		},
  2454  		"unrelated non-generated non-map_kind'd rule of same kind applies map_kind if other rule is generated": {
  2455  			before: []testtools.FileSpec{
  2456  				{
  2457  					Path: "WORKSPACE",
  2458  				},
  2459  				{
  2460  					Path: "BUILD.bazel",
  2461  					Content: `# gazelle:prefix example.com/mapkind
  2462  # gazelle:go_naming_convention go_default_library
  2463  # gazelle:map_kind go_library go_library //custom:def.bzl
  2464  		`,
  2465  				},
  2466  				{
  2467  					Path:    "dir/file.go",
  2468  					Content: "package dir",
  2469  				},
  2470  				{
  2471  					Path: "dir/BUILD.bazel",
  2472  					Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2473  
  2474  go_library(
  2475      name = "custom_lib",
  2476      srcs = ["custom_lib.go"],
  2477  )
  2478  `,
  2479  				},
  2480  			},
  2481  			after: []testtools.FileSpec{
  2482  				{
  2483  					Path: "dir/BUILD.bazel",
  2484  					Content: `load("//custom:def.bzl", "go_library")
  2485  
  2486  go_library(
  2487      name = "custom_lib",
  2488      srcs = ["custom_lib.go"],
  2489  )
  2490  
  2491  go_library(
  2492      name = "go_default_library",
  2493      srcs = ["file.go"],
  2494      importpath = "example.com/mapkind/dir",
  2495      visibility = ["//visibility:public"],
  2496  )
  2497  `,
  2498  				},
  2499  			},
  2500  		},
  2501  		"unrelated non-generated non-renaming map_kind'd rule of same kind keeps map_kind if other rule is generated": {
  2502  			before: []testtools.FileSpec{
  2503  				{
  2504  					Path: "WORKSPACE",
  2505  				},
  2506  				{
  2507  					Path: "BUILD.bazel",
  2508  					Content: `# gazelle:prefix example.com/mapkind
  2509  # gazelle:go_naming_convention go_default_library
  2510  # gazelle:map_kind go_library go_library //custom:def.bzl
  2511  		`,
  2512  				},
  2513  				{
  2514  					Path:    "dir/file.go",
  2515  					Content: "package dir",
  2516  				},
  2517  				{
  2518  					Path: "dir/BUILD.bazel",
  2519  					Content: `load("//custom:def.bzl", "go_library")
  2520  
  2521  go_library(
  2522      name = "custom_lib",
  2523      srcs = ["custom_lib.go"],
  2524  )
  2525  `,
  2526  				},
  2527  			},
  2528  			after: []testtools.FileSpec{
  2529  				{
  2530  					Path: "dir/BUILD.bazel",
  2531  					Content: `load("//custom:def.bzl", "go_library")
  2532  
  2533  go_library(
  2534      name = "custom_lib",
  2535      srcs = ["custom_lib.go"],
  2536  )
  2537  
  2538  go_library(
  2539      name = "go_default_library",
  2540      srcs = ["file.go"],
  2541      importpath = "example.com/mapkind/dir",
  2542      visibility = ["//visibility:public"],
  2543  )
  2544  `,
  2545  				},
  2546  			},
  2547  		},
  2548  		"unrelated non-generated non-renaming map_kind'd rule keeps map_kind if other generated rule is newly generated": {
  2549  			before: []testtools.FileSpec{
  2550  				{
  2551  					Path: "WORKSPACE",
  2552  				},
  2553  				{
  2554  					Path: "BUILD.bazel",
  2555  					Content: `# gazelle:prefix example.com/mapkind
  2556  # gazelle:go_naming_convention go_default_library
  2557  # gazelle:map_kind go_library go_library //custom:def.bzl
  2558  # gazelle:map_kind go_test go_test //custom:def.bzl
  2559  		`,
  2560  				},
  2561  				{
  2562  					Path:    "dir/file.go",
  2563  					Content: "package dir",
  2564  				},
  2565  				{
  2566  					Path: "dir/BUILD.bazel",
  2567  					Content: `load("//custom:def.bzl", "go_test")
  2568  
  2569  go_test(
  2570      name = "custom_test",
  2571      srcs = ["custom_test.java"],
  2572  )
  2573  `,
  2574  				},
  2575  			},
  2576  			after: []testtools.FileSpec{
  2577  				{
  2578  					Path: "dir/BUILD.bazel",
  2579  					Content: `load("//custom:def.bzl", "go_library", "go_test")
  2580  
  2581  go_test(
  2582      name = "custom_test",
  2583      srcs = ["custom_test.java"],
  2584  )
  2585  
  2586  go_library(
  2587      name = "go_default_library",
  2588      srcs = ["file.go"],
  2589      importpath = "example.com/mapkind/dir",
  2590      visibility = ["//visibility:public"],
  2591  )
  2592  `,
  2593  				},
  2594  			},
  2595  		},
  2596  		"unrelated non-generated non-renaming map_kind'd rule keeps map_kind if other generated rule already existed": {
  2597  			before: []testtools.FileSpec{
  2598  				{
  2599  					Path: "WORKSPACE",
  2600  				},
  2601  				{
  2602  					Path: "BUILD.bazel",
  2603  					Content: `# gazelle:prefix example.com/mapkind
  2604  # gazelle:go_naming_convention go_default_library
  2605  # gazelle:map_kind go_library go_library //custom:def.bzl
  2606  # gazelle:map_kind go_test go_test //custom:def.bzl
  2607  `,
  2608  				},
  2609  				{
  2610  					Path:    "dir/file.go",
  2611  					Content: "package dir",
  2612  				},
  2613  				{
  2614  					Path: "dir/BUILD.bazel",
  2615  					Content: `load("//custom:def.bzl", "go_library", "go_test")
  2616  
  2617  go_test(
  2618      name = "custom_test",
  2619      srcs = ["custom_test.java"],
  2620  )
  2621  
  2622  go_library(
  2623      name = "go_default_library",
  2624      srcs = ["file.go"],
  2625      importpath = "example.com/mapkind/dir",
  2626      visibility = ["//visibility:public"],
  2627  )
  2628  `,
  2629  				},
  2630  			},
  2631  			after: []testtools.FileSpec{
  2632  				{
  2633  					Path: "dir/BUILD.bazel",
  2634  					Content: `load("//custom:def.bzl", "go_library", "go_test")
  2635  
  2636  go_test(
  2637      name = "custom_test",
  2638      srcs = ["custom_test.java"],
  2639  )
  2640  
  2641  go_library(
  2642      name = "go_default_library",
  2643      srcs = ["file.go"],
  2644      importpath = "example.com/mapkind/dir",
  2645      visibility = ["//visibility:public"],
  2646  )
  2647  `,
  2648  				},
  2649  			},
  2650  		},
  2651  		"transitive remappings are applied": {
  2652  			before: []testtools.FileSpec{
  2653  				{
  2654  					Path: "WORKSPACE",
  2655  				},
  2656  				{
  2657  					Path: "BUILD.bazel",
  2658  					Content: `# gazelle:prefix example.com/mapkind
  2659  # gazelle:go_naming_convention go_default_library
  2660  # gazelle:map_kind go_library custom_go_library //custom:def.bzl
  2661  		`,
  2662  				},
  2663  				{
  2664  					Path:    "dir/file.go",
  2665  					Content: "package dir",
  2666  				},
  2667  				{
  2668  					Path: "dir/BUILD.bazel",
  2669  					Content: `# gazelle:map_kind custom_go_library other_custom_go_library //another/custom:def.bzl
  2670  `,
  2671  				},
  2672  			},
  2673  			after: []testtools.FileSpec{
  2674  				{
  2675  					Path: "dir/BUILD.bazel",
  2676  					Content: `load("//another/custom:def.bzl", "other_custom_go_library")
  2677  
  2678  # gazelle:map_kind custom_go_library other_custom_go_library //another/custom:def.bzl
  2679  
  2680  other_custom_go_library(
  2681      name = "go_default_library",
  2682      srcs = ["file.go"],
  2683      importpath = "example.com/mapkind/dir",
  2684      visibility = ["//visibility:public"],
  2685  )
  2686  `,
  2687  				},
  2688  			},
  2689  		},
  2690  	} {
  2691  		t.Run(name, func(t *testing.T) {
  2692  			dir, cleanup := testtools.CreateFiles(t, tc.before)
  2693  			t.Cleanup(cleanup)
  2694  			if err := runGazelle(dir, []string{"-external=vendored"}); err != nil {
  2695  				t.Fatal(err)
  2696  			}
  2697  			testtools.CheckFiles(t, dir, tc.after)
  2698  		})
  2699  	}
  2700  }
  2701  
  2702  func TestMapKindLoop(t *testing.T) {
  2703  	dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{
  2704  		{
  2705  			Path: "WORKSPACE",
  2706  		},
  2707  		{
  2708  			Path: "BUILD.bazel",
  2709  			Content: `# gazelle:prefix example.com/mapkind
  2710  # gazelle:go_naming_convention go_default_library
  2711  # gazelle:map_kind go_library custom_go_library //custom:def.bzl
  2712  		`,
  2713  		},
  2714  		{
  2715  			Path:    "dir/file.go",
  2716  			Content: "package dir",
  2717  		},
  2718  		{
  2719  			Path: "dir/BUILD.bazel",
  2720  			Content: `# gazelle:map_kind custom_go_library go_library @io_bazel_rules_go//go:def.bzl
  2721  `,
  2722  		},
  2723  	})
  2724  	t.Cleanup(cleanup)
  2725  	err := runGazelle(dir, []string{"-external=vendored"})
  2726  	if err == nil {
  2727  		t.Fatal("Expected error running gazelle with map_kind loop")
  2728  	}
  2729  	msg := err.Error()
  2730  	if !strings.Contains(msg, "looking up mapped kind: found loop of map_kind replacements: go_library -> custom_go_library -> go_library") {
  2731  		t.Fatalf("Expected error to contain useful descriptors but was %q", msg)
  2732  	}
  2733  }
  2734  
  2735  // TestMapKindEmbeddedResolve tests the gazelle:map_kind properly resolves
  2736  // dependencies for embedded rules (see #1162).
  2737  func TestMapKindEmbeddedResolve(t *testing.T) {
  2738  	files := []testtools.FileSpec{
  2739  		{
  2740  			Path: "WORKSPACE",
  2741  		}, {
  2742  			Path: "BUILD.bazel",
  2743  			Content: `
  2744  # gazelle:prefix example.com/mapkind
  2745  # gazelle:map_kind go_library my_go_library //:my.bzl
  2746  `,
  2747  		}, {
  2748  			Path: "a/a.proto",
  2749  			Content: `
  2750  syntax = "proto3";
  2751  
  2752  package test;
  2753  option go_package = "example.com/mapkind/a";
  2754  `,
  2755  		}, {
  2756  			Path: "b/b.proto",
  2757  			Content: `
  2758  syntax = "proto3";
  2759  
  2760  package test;
  2761  option go_package = "example.com/mapkind/b";
  2762  
  2763  import "a/a.proto";
  2764  `,
  2765  		},
  2766  	}
  2767  	dir, cleanup := testtools.CreateFiles(t, files)
  2768  	defer cleanup()
  2769  
  2770  	if err := runGazelle(dir, []string{"-external=vendored"}); err != nil {
  2771  		t.Fatal(err)
  2772  	}
  2773  
  2774  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  2775  		{
  2776  			Path: "a/BUILD.bazel",
  2777  			Content: `
  2778  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  2779  load("@rules_proto//proto:defs.bzl", "proto_library")
  2780  load("//:my.bzl", "my_go_library")
  2781  
  2782  proto_library(
  2783      name = "a_proto",
  2784      srcs = ["a.proto"],
  2785      visibility = ["//visibility:public"],
  2786  )
  2787  
  2788  go_proto_library(
  2789      name = "a_go_proto",
  2790      importpath = "example.com/mapkind/a",
  2791      proto = ":a_proto",
  2792      visibility = ["//visibility:public"],
  2793  )
  2794  
  2795  my_go_library(
  2796      name = "a",
  2797      embed = [":a_go_proto"],
  2798      importpath = "example.com/mapkind/a",
  2799      visibility = ["//visibility:public"],
  2800  )
  2801  `,
  2802  		},
  2803  		{
  2804  			Path: "b/BUILD.bazel",
  2805  			Content: `
  2806  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  2807  load("@rules_proto//proto:defs.bzl", "proto_library")
  2808  load("//:my.bzl", "my_go_library")
  2809  
  2810  proto_library(
  2811      name = "b_proto",
  2812      srcs = ["b.proto"],
  2813      visibility = ["//visibility:public"],
  2814      deps = ["//a:a_proto"],
  2815  )
  2816  
  2817  go_proto_library(
  2818      name = "b_go_proto",
  2819      importpath = "example.com/mapkind/b",
  2820      proto = ":b_proto",
  2821      visibility = ["//visibility:public"],
  2822      deps = ["//a"],
  2823  )
  2824  
  2825  my_go_library(
  2826      name = "b",
  2827      embed = [":b_go_proto"],
  2828      importpath = "example.com/mapkind/b",
  2829      visibility = ["//visibility:public"],
  2830  )
  2831  `,
  2832  		},
  2833  	})
  2834  }
  2835  
  2836  // TestMinimalModuleCompatibilityAliases checks that importpath_aliases
  2837  // are emitted for go_libraries when needed. This can't easily be checked
  2838  // in language/go because the generator tests don't support running at
  2839  // the repository root or with additional flags, both of which are required.
  2840  func TestMinimalModuleCompatibilityAliases(t *testing.T) {
  2841  	files := []testtools.FileSpec{
  2842  		{
  2843  			Path:    "go.mod",
  2844  			Content: "module example.com/foo/v2",
  2845  		}, {
  2846  			Path:    "foo.go",
  2847  			Content: "package foo",
  2848  		}, {
  2849  			Path:    "bar/bar.go",
  2850  			Content: "package bar",
  2851  		},
  2852  	}
  2853  	dir, cleanup := testtools.CreateFiles(t, files)
  2854  	defer cleanup()
  2855  
  2856  	args := []string{"update", "-repo_root", dir, "-go_prefix", "example.com/foo/v2", "-go_repository_mode", "-go_repository_module_mode"}
  2857  	if err := runGazelle(dir, args); err != nil {
  2858  		t.Fatal(err)
  2859  	}
  2860  
  2861  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  2862  		{
  2863  			Path: "BUILD.bazel",
  2864  			Content: `
  2865  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2866  
  2867  go_library(
  2868      name = "foo",
  2869      srcs = ["foo.go"],
  2870      importpath = "example.com/foo/v2",
  2871      importpath_aliases = ["example.com/foo"],
  2872      visibility = ["//visibility:public"],
  2873  )
  2874  `,
  2875  		}, {
  2876  			Path: "bar/BUILD.bazel",
  2877  			Content: `
  2878  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2879  
  2880  go_library(
  2881      name = "bar",
  2882      srcs = ["bar.go"],
  2883      importpath = "example.com/foo/v2/bar",
  2884      importpath_aliases = ["example.com/foo/bar"],
  2885      visibility = ["//visibility:public"],
  2886  )
  2887  `,
  2888  		},
  2889  	})
  2890  }
  2891  
  2892  // TestGoImportVisibility checks that submodules implicitly declared with
  2893  // go_repository rules in the repo config file (WORKSPACE) have visibility
  2894  // for rules generated in internal directories where appropriate.
  2895  // Verifies #619.
  2896  func TestGoImportVisibility(t *testing.T) {
  2897  	files := []testtools.FileSpec{
  2898  		{
  2899  			Path: "WORKSPACE",
  2900  			Content: `
  2901  go_repository(
  2902  		name = "com_example_m_logging",
  2903      importpath = "example.com/m/logging",
  2904  )
  2905  `,
  2906  		}, {
  2907  			Path:    "internal/version/version.go",
  2908  			Content: "package version",
  2909  		}, {
  2910  			Path:    "internal/version/version_test.go",
  2911  			Content: "package version",
  2912  		},
  2913  	}
  2914  	dir, cleanup := testtools.CreateFiles(t, files)
  2915  	defer cleanup()
  2916  
  2917  	args := []string{"update", "-go_prefix", "example.com/m"}
  2918  	if err := runGazelle(dir, args); err != nil {
  2919  		t.Fatal(err)
  2920  	}
  2921  
  2922  	testtools.CheckFiles(t, dir, []testtools.FileSpec{{
  2923  		Path: "internal/version/BUILD.bazel",
  2924  		Content: `
  2925  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
  2926  
  2927  go_library(
  2928      name = "version",
  2929      srcs = ["version.go"],
  2930      importpath = "example.com/m/internal/version",
  2931      visibility = [
  2932          "//:__subpackages__",
  2933          "@com_example_m_logging//:__subpackages__",
  2934      ],
  2935  )
  2936  
  2937  go_test(
  2938      name = "version_test",
  2939      srcs = ["version_test.go"],
  2940      embed = [":version"],
  2941  )
  2942  `,
  2943  	}})
  2944  }
  2945  
  2946  // TestGoInternalVisibility_TopLevel checks that modules that are
  2947  // named internal/ expand visibility to repos that have a sibling
  2948  // importpath.
  2949  //
  2950  // Verifies #960
  2951  func TestGoInternalVisibility_TopLevel(t *testing.T) {
  2952  	files := []testtools.FileSpec{
  2953  		{
  2954  			Path:    "WORKSPACE",
  2955  			Content: `go_repository(name="org_modernc_ccgo", importpath="modernc.org/ccgo")`,
  2956  		}, {
  2957  			Path:    "BUILD.bazel",
  2958  			Content: `# gazelle:prefix modernc.org/internal`,
  2959  		}, {
  2960  			Path:    "internal.go",
  2961  			Content: "package internal",
  2962  		}, {
  2963  			Path:    "buffer/buffer.go",
  2964  			Content: "package buffer",
  2965  		},
  2966  	}
  2967  	dir, cleanup := testtools.CreateFiles(t, files)
  2968  	defer cleanup()
  2969  
  2970  	args := []string{"update"}
  2971  	if err := runGazelle(dir, args); err != nil {
  2972  		t.Fatal(err)
  2973  	}
  2974  
  2975  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  2976  		{
  2977  			Path: "BUILD.bazel",
  2978  			Content: `
  2979  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2980  
  2981  # gazelle:prefix modernc.org/internal
  2982  
  2983  go_library(
  2984      name = "internal",
  2985      srcs = ["internal.go"],
  2986      importpath = "modernc.org/internal",
  2987      visibility = [
  2988          "//:__subpackages__",
  2989          "@org_modernc_ccgo//:__subpackages__",
  2990      ],
  2991  )
  2992  `,
  2993  		},
  2994  		{
  2995  			Path: "buffer/BUILD.bazel",
  2996  			Content: `
  2997  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  2998  
  2999  go_library(
  3000      name = "buffer",
  3001      srcs = ["buffer.go"],
  3002      importpath = "modernc.org/internal/buffer",
  3003      visibility = [
  3004          "//:__subpackages__",
  3005          "@org_modernc_ccgo//:__subpackages__",
  3006      ],
  3007  )
  3008  `,
  3009  		},
  3010  	})
  3011  }
  3012  
  3013  func TestImportCollision(t *testing.T) {
  3014  	files := []testtools.FileSpec{
  3015  		{
  3016  			Path: "WORKSPACE",
  3017  		},
  3018  		{
  3019  			Path: "go.mod",
  3020  			Content: `
  3021  module example.com/importcases
  3022  
  3023  go 1.13
  3024  
  3025  require (
  3026  	github.com/Selvatico/go-mocket v1.0.7
  3027  	github.com/selvatico/go-mocket v1.0.7
  3028  )
  3029  `,
  3030  		},
  3031  		{
  3032  			Path: "go.sum",
  3033  			Content: `
  3034  github.com/Selvatico/go-mocket v1.0.7/go.mod h1:4gO2v+uQmsL+jzQgLANy3tyEFzaEzHlymVbZ3GP2Oes=
  3035  github.com/selvatico/go-mocket v1.0.7/go.mod h1:7bSWzuNieCdUlanCVu3w0ppS0LvDtPAZmKBIlhoTcp8=
  3036  `,
  3037  		},
  3038  	}
  3039  	dir, cleanup := testtools.CreateFiles(t, files)
  3040  	defer cleanup()
  3041  
  3042  	args := []string{"update-repos", "--from_file=go.mod"}
  3043  	errMsg := "imports github.com/Selvatico/go-mocket and github.com/selvatico/go-mocket resolve to the same repository rule name com_github_selvatico_go_mocket"
  3044  	if err := runGazelle(dir, args); err == nil {
  3045  		t.Fatal("expected error, got nil")
  3046  	} else if err.Error() != errMsg {
  3047  		t.Errorf("want %s, got %s", errMsg, err.Error())
  3048  	}
  3049  }
  3050  
  3051  func TestImportCollisionWithReplace(t *testing.T) {
  3052  	files := []testtools.FileSpec{
  3053  		{
  3054  			Path:    "WORKSPACE",
  3055  			Content: "# gazelle:repo bazel_gazelle",
  3056  		},
  3057  		{
  3058  			Path: "go.mod",
  3059  			Content: `
  3060  module github.com/linzhp/go_examples/importcases
  3061  
  3062  go 1.13
  3063  
  3064  require (
  3065  	github.com/Selvatico/go-mocket v1.0.7
  3066  	github.com/selvatico/go-mocket v0.0.0-00010101000000-000000000000
  3067  )
  3068  
  3069  replace github.com/selvatico/go-mocket => github.com/Selvatico/go-mocket v1.0.7
  3070  `,
  3071  		},
  3072  		{
  3073  			Path: "go.sum",
  3074  			Content: `
  3075  github.com/Selvatico/go-mocket v1.0.7/go.mod h1:4gO2v+uQmsL+jzQgLANy3tyEFzaEzHlymVbZ3GP2Oes=
  3076  `,
  3077  		},
  3078  	}
  3079  	dir, cleanup := testtools.CreateFiles(t, files)
  3080  	defer cleanup()
  3081  
  3082  	args := []string{"update-repos", "--from_file=go.mod"}
  3083  	if err := runGazelle(dir, args); err != nil {
  3084  		t.Fatal(err)
  3085  	}
  3086  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3087  		{
  3088  			Path: "WORKSPACE",
  3089  			Content: `
  3090  load("@bazel_gazelle//:deps.bzl", "go_repository")
  3091  
  3092  # gazelle:repo bazel_gazelle
  3093  
  3094  go_repository(
  3095      name = "com_github_selvatico_go_mocket",
  3096      importpath = "github.com/selvatico/go-mocket",
  3097      replace = "github.com/Selvatico/go-mocket",
  3098      sum = "h1:sXuFMnMfVL9b/Os8rGXPgbOFbr4HJm8aHsulD/uMTUk=",
  3099      version = "v1.0.7",
  3100  )
  3101  `,
  3102  		},
  3103  	})
  3104  }
  3105  
  3106  // TestUpdateReposWithGlobalBuildTags is a regresion test for issue #711.
  3107  // It also ensures that existings build_tags get merged with requested build_tags.
  3108  func TestUpdateReposWithGlobalBuildTags(t *testing.T) {
  3109  	files := []testtools.FileSpec{
  3110  		{
  3111  			Path: "WORKSPACE",
  3112  			Content: `
  3113  load("@bazel_gazelle//:deps.bzl", "go_repository")
  3114  
  3115  # gazelle:repo bazel_gazelle
  3116  
  3117  go_repository(
  3118      name = "com_github_selvatico_go_mocket",
  3119      build_tags = [
  3120          "bar",
  3121      ],
  3122      importpath = "github.com/selvatico/go-mocket",
  3123      replace = "github.com/Selvatico/go-mocket",
  3124      sum = "h1:sXuFMnMfVL9b/Os8rGXPgbOFbr4HJm8aHsulD/uMTUk=",
  3125      version = "v1.0.7",
  3126  )
  3127  `,
  3128  		},
  3129  		{
  3130  			Path: "go.mod",
  3131  			Content: `
  3132  module github.com/linzhp/go_examples/importcases
  3133  
  3134  go 1.13
  3135  
  3136  require (
  3137  	github.com/Selvatico/go-mocket v1.0.7
  3138  	github.com/selvatico/go-mocket v0.0.0-00010101000000-000000000000
  3139  )
  3140  
  3141  replace github.com/selvatico/go-mocket => github.com/Selvatico/go-mocket v1.0.7
  3142  `,
  3143  		},
  3144  		{
  3145  			Path: "go.sum",
  3146  			Content: `
  3147  github.com/Selvatico/go-mocket v1.0.7/go.mod h1:4gO2v+uQmsL+jzQgLANy3tyEFzaEzHlymVbZ3GP2Oes=
  3148  `,
  3149  		},
  3150  	}
  3151  	dir, cleanup := testtools.CreateFiles(t, files)
  3152  	defer cleanup()
  3153  
  3154  	args := []string{"update-repos", "--from_file=go.mod", "--build_tags=bar,foo"}
  3155  	if err := runGazelle(dir, args); err != nil {
  3156  		t.Fatal(err)
  3157  	}
  3158  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3159  		{
  3160  			Path: "WORKSPACE",
  3161  			Content: `
  3162  load("@bazel_gazelle//:deps.bzl", "go_repository")
  3163  
  3164  # gazelle:repo bazel_gazelle
  3165  
  3166  go_repository(
  3167      name = "com_github_selvatico_go_mocket",
  3168      build_tags = [
  3169          "bar",
  3170          "foo",
  3171      ],
  3172      importpath = "github.com/selvatico/go-mocket",
  3173      replace = "github.com/Selvatico/go-mocket",
  3174      sum = "h1:sXuFMnMfVL9b/Os8rGXPgbOFbr4HJm8aHsulD/uMTUk=",
  3175      version = "v1.0.7",
  3176  )
  3177  `,
  3178  		},
  3179  	})
  3180  }
  3181  
  3182  func TestMatchProtoLibrary(t *testing.T) {
  3183  	files := []testtools.FileSpec{
  3184  		{
  3185  			Path: "WORKSPACE",
  3186  		},
  3187  		{
  3188  			Path: "proto/BUILD.bazel",
  3189  			Content: `
  3190  load("@rules_proto//proto:defs.bzl", "proto_library")
  3191  # gazelle:prefix example.com/foo
  3192  
  3193  proto_library(
  3194  	name = "existing_proto",
  3195  	srcs = ["foo.proto"],
  3196  )
  3197  `,
  3198  		},
  3199  		{
  3200  			Path:    "proto/foo.proto",
  3201  			Content: `syntax = "proto3";`,
  3202  		},
  3203  	}
  3204  	dir, cleanup := testtools.CreateFiles(t, files)
  3205  	defer cleanup()
  3206  
  3207  	args := []string{"update"}
  3208  	if err := runGazelle(dir, args); err != nil {
  3209  		t.Fatal(err)
  3210  	}
  3211  
  3212  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3213  		{
  3214  			Path: "proto/BUILD.bazel",
  3215  			Content: `
  3216  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  3217  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  3218  load("@rules_proto//proto:defs.bzl", "proto_library")
  3219  # gazelle:prefix example.com/foo
  3220  
  3221  proto_library(
  3222      name = "existing_proto",
  3223      srcs = ["foo.proto"],
  3224      visibility = ["//visibility:public"],
  3225  )
  3226  
  3227  go_proto_library(
  3228      name = "foo_go_proto",
  3229      importpath = "example.com/foo",
  3230      proto = ":existing_proto",
  3231      visibility = ["//visibility:public"],
  3232  )
  3233  
  3234  go_library(
  3235      name = "foo",
  3236      embed = [":foo_go_proto"],
  3237      importpath = "example.com/foo",
  3238      visibility = ["//visibility:public"],
  3239  )`,
  3240  		},
  3241  	})
  3242  }
  3243  
  3244  func TestConfigLang(t *testing.T) {
  3245  	// Gazelle is run with "-lang=proto".
  3246  	files := []testtools.FileSpec{
  3247  		{Path: "WORKSPACE"},
  3248  
  3249  		// Verify that Gazelle does not create a BUILD file.
  3250  		{Path: "foo/foo.go", Content: "package foo"},
  3251  
  3252  		// Verify that Gazelle only creates the proto rule.
  3253  		{Path: "pb/pb.go", Content: "package pb"},
  3254  		{Path: "pb/pb.proto", Content: `syntax = "proto3";`},
  3255  
  3256  		// Verify that Gazelle does create a BUILD file, because of the override.
  3257  		{Path: "bar/BUILD.bazel", Content: "# gazelle:lang"},
  3258  		{Path: "bar/bar.go", Content: "package bar"},
  3259  		{Path: "baz/BUILD.bazel", Content: "# gazelle:lang go,proto"},
  3260  		{Path: "baz/baz.go", Content: "package baz"},
  3261  
  3262  		// Verify that Gazelle does not index go_library rules in // or //baz/protos.
  3263  		// In those directories, lang is set to proto by flag and directive, respectively.
  3264  		// Confirm it does index and resolve a rule in a directory where go is activated.
  3265  		{Path: "invisible1.go", Content: "package invisible1"},
  3266  		{Path: "BUILD.bazel", Content: `
  3267  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  3268  
  3269  # gazelle:prefix root
  3270  
  3271  go_library(
  3272      name = "go_default_library",
  3273      srcs = ["invisible1.go"],
  3274      importpath = "root",
  3275      visibility = ["//visibility:public"],
  3276  )
  3277  `},
  3278  		{Path: "baz/protos/invisible2.go", Content: "package invisible2"},
  3279  		{Path: "baz/protos/BUILD.bazel", Content: `
  3280  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  3281  
  3282  # gazelle:lang proto
  3283  # gazelle:prefix github.com/rule_indexing/invisible2
  3284  
  3285  go_library(
  3286      name = "go_default_library",
  3287      srcs = ["invisible2.go"],
  3288      importpath = "github.com/rule_indexing/invisible2",
  3289      visibility = ["//visibility:public"],
  3290  )
  3291  `},
  3292  		{Path: "visible/visible.go", Content: "package visible"},
  3293  		{Path: "visible/BUILD.bazel", Content: `
  3294  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  3295  
  3296  # gazelle:lang go,proto
  3297  # gazelle:prefix github.com/rule_indexing/visible
  3298  
  3299  go_library(
  3300      name = "go_default_library",
  3301      srcs = ["visible.go"],
  3302      importpath = "github.com/rule_indexing/visible",
  3303      visibility = ["//visibility:public"],
  3304  )
  3305  `},
  3306  		{Path: "baz/test_no_index/test_no_index.go", Content: `
  3307  package test_no_index
  3308  
  3309  import (
  3310  	_ "github.com/rule_indexing/invisible1"
  3311  	_ "github.com/rule_indexing/invisible2"
  3312  	_ "github.com/rule_indexing/visible"
  3313  )
  3314  `},
  3315  	}
  3316  
  3317  	dir, cleanup := testtools.CreateFiles(t, files)
  3318  	defer cleanup()
  3319  
  3320  	args := []string{"-lang", "proto"}
  3321  	if err := runGazelle(dir, args); err != nil {
  3322  		t.Fatal(err)
  3323  	}
  3324  
  3325  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3326  		{
  3327  			Path:     filepath.Join("foo", "BUILD.bazel"),
  3328  			NotExist: true,
  3329  		},
  3330  		{
  3331  			Path: filepath.Join("pb", "BUILD.bazel"),
  3332  			Content: `
  3333  load("@rules_proto//proto:defs.bzl", "proto_library")
  3334  
  3335  proto_library(
  3336      name = "pb_proto",
  3337      srcs = ["pb.proto"],
  3338      visibility = ["//visibility:public"],
  3339  )`,
  3340  		},
  3341  		{
  3342  			Path: filepath.Join("bar", "BUILD.bazel"),
  3343  			Content: `
  3344  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  3345  
  3346  # gazelle:lang
  3347  
  3348  go_library(
  3349      name = "go_default_library",
  3350      srcs = ["bar.go"],
  3351      importpath = "root/bar",
  3352      visibility = ["//visibility:public"],
  3353  )`,
  3354  		},
  3355  		{
  3356  			Path: filepath.Join("baz", "BUILD.bazel"),
  3357  			Content: `
  3358  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  3359  
  3360  # gazelle:lang go,proto
  3361  
  3362  go_library(
  3363      name = "go_default_library",
  3364      srcs = ["baz.go"],
  3365      importpath = "root/baz",
  3366      visibility = ["//visibility:public"],
  3367  )`,
  3368  		},
  3369  
  3370  		{Path: "baz/test_no_index/BUILD.bazel", Content: `
  3371  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  3372  
  3373  go_library(
  3374      name = "go_default_library",
  3375      srcs = ["test_no_index.go"],
  3376      importpath = "root/baz/test_no_index",
  3377      visibility = ["//visibility:public"],
  3378      deps = [
  3379          "//visible:go_default_library",
  3380          "@com_github_rule_indexing_invisible1//:go_default_library",
  3381          "@com_github_rule_indexing_invisible2//:go_default_library",
  3382      ],
  3383  )
  3384  `},
  3385  	})
  3386  }
  3387  
  3388  func TestUpdateRepos_LangFilter(t *testing.T) {
  3389  	dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{
  3390  		{Path: "WORKSPACE"},
  3391  	})
  3392  	defer cleanup()
  3393  
  3394  	args := []string{"update-repos", "-lang=proto", "github.com/sirupsen/logrus@v1.3.0"}
  3395  	err := runGazelle(dir, args)
  3396  	if err == nil {
  3397  		t.Fatal("expected an error, got none")
  3398  	}
  3399  	if !strings.Contains(err.Error(), "no languages can update repositories") {
  3400  		t.Fatalf("unexpected error: %+v", err)
  3401  	}
  3402  }
  3403  
  3404  func TestGoGenerateProto(t *testing.T) {
  3405  	files := []testtools.FileSpec{
  3406  		{
  3407  			Path: "WORKSPACE",
  3408  		},
  3409  		{
  3410  			Path: "proto/BUILD.bazel",
  3411  			Content: `# gazelle:go_generate_proto false
  3412  # gazelle:prefix example.com/proto
  3413  `,
  3414  		},
  3415  		{
  3416  			Path:    "proto/foo.proto",
  3417  			Content: `syntax = "proto3";`,
  3418  		},
  3419  		{
  3420  			Path:    "proto/foo.pb.go",
  3421  			Content: "package proto",
  3422  		},
  3423  	}
  3424  	dir, cleanup := testtools.CreateFiles(t, files)
  3425  	defer cleanup()
  3426  
  3427  	args := []string{"update"}
  3428  	if err := runGazelle(dir, args); err != nil {
  3429  		t.Fatal(err)
  3430  	}
  3431  
  3432  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3433  		{
  3434  			Path: "proto/BUILD.bazel",
  3435  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  3436  load("@rules_proto//proto:defs.bzl", "proto_library")
  3437  
  3438  # gazelle:go_generate_proto false
  3439  # gazelle:prefix example.com/proto
  3440  
  3441  proto_library(
  3442      name = "foo_proto",
  3443      srcs = ["foo.proto"],
  3444      visibility = ["//visibility:public"],
  3445  )
  3446  
  3447  go_library(
  3448      name = "proto",
  3449      srcs = ["foo.pb.go"],
  3450      importpath = "example.com/proto",
  3451      visibility = ["//visibility:public"],
  3452  )`,
  3453  		},
  3454  	})
  3455  }
  3456  
  3457  func TestGoMainLibraryRemoved(t *testing.T) {
  3458  	files := []testtools.FileSpec{
  3459  		{
  3460  			Path: "WORKSPACE",
  3461  		},
  3462  		{
  3463  			Path: "BUILD.bazel",
  3464  			Content: `
  3465  # gazelle:prefix example.com
  3466  # gazelle:go_naming_convention import
  3467  `,
  3468  		},
  3469  		{
  3470  			Path: "cmd/foo/BUILD.bazel",
  3471  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
  3472  
  3473  go_library(
  3474  		name = "foo_lib",
  3475  		srcs = ["foo.go"],
  3476  		importpath = "example.com/cmd/foo",
  3477  		visibility = ["//visibility:private"],
  3478  )
  3479  
  3480  go_binary(
  3481  		name = "foo",
  3482  		embed = [":foo_lib"],
  3483  		visibility = ["//visibility:public"],
  3484  )
  3485  `,
  3486  		},
  3487  	}
  3488  	dir, cleanup := testtools.CreateFiles(t, files)
  3489  	defer cleanup()
  3490  
  3491  	args := []string{"update"}
  3492  	if err := runGazelle(dir, args); err != nil {
  3493  		t.Fatal(err)
  3494  	}
  3495  
  3496  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3497  		{
  3498  			Path:    "cmd/foo/BUILD.bazel",
  3499  			Content: "",
  3500  		},
  3501  	})
  3502  }
  3503  
  3504  func TestUpdateReposOldBoilerplateNewRepo(t *testing.T) {
  3505  	files := []testtools.FileSpec{
  3506  		{
  3507  			Path: "WORKSPACE",
  3508  			Content: `
  3509  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3510  
  3511  http_archive(
  3512      name = "io_bazel_rules_go",
  3513      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3514      urls = [
  3515          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3516          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3517      ],
  3518  )
  3519  
  3520  http_archive(
  3521      name = "bazel_gazelle",
  3522      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3523      urls = [
  3524          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3525          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3526      ],
  3527  )
  3528  
  3529  load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
  3530  
  3531  go_rules_dependencies()
  3532  
  3533  go_register_toolchains()
  3534  
  3535  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  3536  
  3537  gazelle_dependencies()
  3538  `,
  3539  		},
  3540  	}
  3541  
  3542  	dir, cleanup := testtools.CreateFiles(t, files)
  3543  	defer cleanup()
  3544  
  3545  	args := []string{"update-repos", "golang.org/x/mod@v0.3.0"}
  3546  	if err := runGazelle(dir, args); err != nil {
  3547  		t.Fatal(err)
  3548  	}
  3549  
  3550  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3551  		{
  3552  			Path: "WORKSPACE",
  3553  			Content: `
  3554  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3555  
  3556  http_archive(
  3557      name = "io_bazel_rules_go",
  3558      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3559      urls = [
  3560          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3561          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3562      ],
  3563  )
  3564  
  3565  http_archive(
  3566      name = "bazel_gazelle",
  3567      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3568      urls = [
  3569          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3570          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3571      ],
  3572  )
  3573  
  3574  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  3575  
  3576  go_rules_dependencies()
  3577  
  3578  go_register_toolchains()
  3579  
  3580  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
  3581  
  3582  go_repository(
  3583      name = "org_golang_x_mod",
  3584      importpath = "golang.org/x/mod",
  3585      sum = "h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=",
  3586      version = "v0.3.0",
  3587  )
  3588  
  3589  gazelle_dependencies()
  3590  `,
  3591  		},
  3592  	})
  3593  }
  3594  
  3595  func TestUpdateReposSkipsDirectiveRepo(t *testing.T) {
  3596  	files := []testtools.FileSpec{
  3597  		{
  3598  			Path: "WORKSPACE",
  3599  			Content: `
  3600  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3601  
  3602  http_archive(
  3603      name = "io_bazel_rules_go",
  3604      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3605      urls = [
  3606          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3607          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3608      ],
  3609  )
  3610  
  3611  http_archive(
  3612      name = "bazel_gazelle",
  3613      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3614      urls = [
  3615          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3616          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3617      ],
  3618  )
  3619  
  3620  load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
  3621  
  3622  go_rules_dependencies()
  3623  
  3624  go_register_toolchains()
  3625  
  3626  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  3627  
  3628  gazelle_dependencies()
  3629  
  3630  # gazelle:repository go_repository name=org_golang_x_mod importpath=golang.org/x/mod
  3631  `,
  3632  		},
  3633  	}
  3634  
  3635  	dir, cleanup := testtools.CreateFiles(t, files)
  3636  	defer cleanup()
  3637  
  3638  	args := []string{"update-repos", "golang.org/x/mod@v0.3.0"}
  3639  	if err := runGazelle(dir, args); err != nil {
  3640  		t.Fatal(err)
  3641  	}
  3642  
  3643  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3644  		{
  3645  			Path: "WORKSPACE",
  3646  			Content: `
  3647  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3648  
  3649  http_archive(
  3650      name = "io_bazel_rules_go",
  3651      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3652      urls = [
  3653          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3654          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3655      ],
  3656  )
  3657  
  3658  http_archive(
  3659      name = "bazel_gazelle",
  3660      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3661      urls = [
  3662          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3663          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3664      ],
  3665  )
  3666  
  3667  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  3668  
  3669  go_rules_dependencies()
  3670  
  3671  go_register_toolchains()
  3672  
  3673  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  3674  
  3675  gazelle_dependencies()
  3676  
  3677  # gazelle:repository go_repository name=org_golang_x_mod importpath=golang.org/x/mod
  3678  `,
  3679  		},
  3680  	})
  3681  }
  3682  
  3683  func TestUpdateReposOldBoilerplateNewMacro(t *testing.T) {
  3684  	files := []testtools.FileSpec{
  3685  		{
  3686  			Path: "WORKSPACE",
  3687  			Content: `
  3688  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3689  
  3690  http_archive(
  3691      name = "io_bazel_rules_go",
  3692      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3693      urls = [
  3694          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3695          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3696      ],
  3697  )
  3698  
  3699  http_archive(
  3700      name = "bazel_gazelle",
  3701      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3702      urls = [
  3703          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3704          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3705      ],
  3706  )
  3707  
  3708  load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
  3709  
  3710  go_rules_dependencies()
  3711  
  3712  go_register_toolchains()
  3713  
  3714  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  3715  
  3716  gazelle_dependencies()
  3717  `,
  3718  		},
  3719  	}
  3720  
  3721  	dir, cleanup := testtools.CreateFiles(t, files)
  3722  	defer cleanup()
  3723  
  3724  	args := []string{"update-repos", "-to_macro=deps.bzl%deps", "golang.org/x/mod@v0.3.0"}
  3725  	if err := runGazelle(dir, args); err != nil {
  3726  		t.Fatal(err)
  3727  	}
  3728  
  3729  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3730  		{
  3731  			Path: "WORKSPACE",
  3732  			Content: `
  3733  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3734  
  3735  http_archive(
  3736      name = "io_bazel_rules_go",
  3737      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3738      urls = [
  3739          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3740          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3741      ],
  3742  )
  3743  
  3744  http_archive(
  3745      name = "bazel_gazelle",
  3746      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3747      urls = [
  3748          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3749          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3750      ],
  3751  )
  3752  
  3753  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  3754  
  3755  go_rules_dependencies()
  3756  
  3757  go_register_toolchains()
  3758  
  3759  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  3760  load("//:deps.bzl", "deps")
  3761  
  3762  # gazelle:repository_macro deps.bzl%deps
  3763  deps()
  3764  
  3765  gazelle_dependencies()
  3766  `,
  3767  		},
  3768  	})
  3769  }
  3770  
  3771  func TestUpdateReposNewBoilerplateNewRepo(t *testing.T) {
  3772  	files := []testtools.FileSpec{
  3773  		{
  3774  			Path: "WORKSPACE",
  3775  			Content: `
  3776  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3777  
  3778  http_archive(
  3779      name = "io_bazel_rules_go",
  3780      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3781      urls = [
  3782          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3783          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3784      ],
  3785  )
  3786  
  3787  http_archive(
  3788      name = "bazel_gazelle",
  3789      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3790      urls = [
  3791          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3792          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3793      ],
  3794  )
  3795  
  3796  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  3797  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  3798  
  3799  go_rules_dependencies()
  3800  
  3801  go_register_toolchains()
  3802  
  3803  gazelle_dependencies()
  3804  `,
  3805  		},
  3806  	}
  3807  
  3808  	dir, cleanup := testtools.CreateFiles(t, files)
  3809  	defer cleanup()
  3810  
  3811  	args := []string{"update-repos", "golang.org/x/mod@v0.3.0"}
  3812  	if err := runGazelle(dir, args); err != nil {
  3813  		t.Fatal(err)
  3814  	}
  3815  
  3816  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3817  		{
  3818  			Path: "WORKSPACE",
  3819  			Content: `
  3820  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3821  
  3822  http_archive(
  3823      name = "io_bazel_rules_go",
  3824      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3825      urls = [
  3826          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3827          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3828      ],
  3829  )
  3830  
  3831  http_archive(
  3832      name = "bazel_gazelle",
  3833      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3834      urls = [
  3835          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3836          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3837      ],
  3838  )
  3839  
  3840  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
  3841  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  3842  
  3843  go_repository(
  3844      name = "org_golang_x_mod",
  3845      importpath = "golang.org/x/mod",
  3846      sum = "h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=",
  3847      version = "v0.3.0",
  3848  )
  3849  
  3850  go_rules_dependencies()
  3851  
  3852  go_register_toolchains()
  3853  
  3854  gazelle_dependencies()
  3855  `,
  3856  		},
  3857  	})
  3858  }
  3859  
  3860  func TestUpdateReposNewBoilerplateNewMacro(t *testing.T) {
  3861  	files := []testtools.FileSpec{
  3862  		{
  3863  			Path: "WORKSPACE",
  3864  			Content: `
  3865  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3866  
  3867  http_archive(
  3868      name = "io_bazel_rules_go",
  3869      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3870      urls = [
  3871          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3872          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3873      ],
  3874  )
  3875  
  3876  http_archive(
  3877      name = "bazel_gazelle",
  3878      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3879      urls = [
  3880          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3881          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3882      ],
  3883  )
  3884  
  3885  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  3886  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  3887  
  3888  go_rules_dependencies()
  3889  
  3890  go_register_toolchains()
  3891  
  3892  gazelle_dependencies()
  3893  `,
  3894  		},
  3895  	}
  3896  
  3897  	dir, cleanup := testtools.CreateFiles(t, files)
  3898  	defer cleanup()
  3899  
  3900  	args := []string{"update-repos", "-to_macro=deps.bzl%deps", "golang.org/x/mod@v0.3.0"}
  3901  	if err := runGazelle(dir, args); err != nil {
  3902  		t.Fatal(err)
  3903  	}
  3904  
  3905  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3906  		{
  3907  			Path: "WORKSPACE",
  3908  			Content: `
  3909  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  3910  
  3911  http_archive(
  3912      name = "io_bazel_rules_go",
  3913      sha256 = "2697f6bc7c529ee5e6a2d9799870b9ec9eaeb3ee7d70ed50b87a2c2c97e13d9e",
  3914      urls = [
  3915          "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3916          "https://github.com/bazelbuild/rules_go/releases/download/v0.23.8/rules_go-v0.23.8.tar.gz",
  3917      ],
  3918  )
  3919  
  3920  http_archive(
  3921      name = "bazel_gazelle",
  3922      sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
  3923      urls = [
  3924          "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3925          "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
  3926      ],
  3927  )
  3928  
  3929  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  3930  load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
  3931  load("//:deps.bzl", "deps")
  3932  
  3933  # gazelle:repository_macro deps.bzl%deps
  3934  deps()
  3935  
  3936  go_rules_dependencies()
  3937  
  3938  go_register_toolchains()
  3939  
  3940  gazelle_dependencies()
  3941  `,
  3942  		},
  3943  	})
  3944  }
  3945  
  3946  func TestExternalOnly(t *testing.T) {
  3947  	files := []testtools.FileSpec{
  3948  		{
  3949  			Path: "WORKSPACE",
  3950  		},
  3951  		{
  3952  			Path: "foo/foo.go",
  3953  			Content: `package foo
  3954  import _ "golang.org/x/baz"
  3955  `,
  3956  		},
  3957  		{
  3958  			Path: "foo/foo_test.go",
  3959  			Content: `package foo_test
  3960  import _ "golang.org/x/baz"
  3961  import _ "example.com/foo"
  3962  `,
  3963  		},
  3964  		{
  3965  			Path: "foo/BUILD.bazel",
  3966  			Content: `# gazelle:prefix example.com/foo
  3967  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
  3968  
  3969  go_library(
  3970      name = "foo",
  3971      srcs = ["foo.go"],
  3972      importpath = "example.com/foo",
  3973      visibility = ["//visibility:public"],
  3974      deps = ["@org_golang_x_baz//:go_default_library"],
  3975  )
  3976  
  3977  go_test(
  3978      name = "foo_test",
  3979      srcs = ["foo_test.go"],
  3980      embed = [":foo"],
  3981  )`,
  3982  		},
  3983  	}
  3984  	dir, cleanup := testtools.CreateFiles(t, files)
  3985  	defer cleanup()
  3986  
  3987  	var args []string
  3988  	if err := runGazelle(dir, args); err != nil {
  3989  		t.Fatal(err)
  3990  	}
  3991  
  3992  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  3993  		{
  3994  			Path: "foo/BUILD.bazel",
  3995  			Content: `# gazelle:prefix example.com/foo
  3996  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
  3997  
  3998  go_library(
  3999      name = "foo",
  4000      srcs = ["foo.go"],
  4001      importpath = "example.com/foo",
  4002      visibility = ["//visibility:public"],
  4003      deps = ["@org_golang_x_baz//:go_default_library"],
  4004  )
  4005  
  4006  go_test(
  4007      name = "foo_test",
  4008      srcs = ["foo_test.go"],
  4009      deps = [
  4010          ":foo",
  4011          "@org_golang_x_baz//:go_default_library",
  4012      ],
  4013  )`,
  4014  		},
  4015  	})
  4016  }
  4017  
  4018  func TestFindRulesGoVersionWithWORKSPACE(t *testing.T) {
  4019  	files := []testtools.FileSpec{
  4020  		{
  4021  			Path: "WORKSPACE",
  4022  			Content: `
  4023  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  4024  
  4025  http_archive(
  4026      name = "io_bazel_rules_go",
  4027      sha256 = "7b9bbe3ea1fccb46dcfa6c3f3e29ba7ec740d8733370e21cdc8937467b4a4349",
  4028      urls = [
  4029          "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/v0.22.4/rules_go-v0.22.4.tar.gz",
  4030          "https://github.com/bazelbuild/rules_go/releases/download/v0.22.4/rules_go-v0.22.4.tar.gz",
  4031      ],
  4032  )
  4033  `,
  4034  		},
  4035  		{
  4036  			Path: "foo_illumos.go",
  4037  			Content: `
  4038  // illumos not supported in rules_go v0.22.4
  4039  package foo
  4040  `,
  4041  		},
  4042  		{
  4043  			Path: "BUILD.bazel",
  4044  			Content: `
  4045  # gazelle:prefix example.com/foo
  4046  `,
  4047  		},
  4048  	}
  4049  
  4050  	dir, cleanup := testtools.CreateFiles(t, files)
  4051  	defer cleanup()
  4052  
  4053  	if err := runGazelle(dir, []string{"update"}); err != nil {
  4054  		t.Fatal(err)
  4055  	}
  4056  
  4057  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  4058  		{
  4059  			Path: "BUILD.bazel",
  4060  			Content: `
  4061  # gazelle:prefix example.com/foo
  4062  `,
  4063  		},
  4064  	})
  4065  }
  4066  
  4067  func TestPlatformSpecificEmbedsrcs(t *testing.T) {
  4068  	files := []testtools.FileSpec{
  4069  		{
  4070  			Path: "WORKSPACE",
  4071  		},
  4072  		{
  4073  			Path: "BUILD.bazel",
  4074  			Content: `
  4075  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  4076  
  4077  # gazelle:prefix example.com/foo
  4078  
  4079  go_library(
  4080      name = "foo",
  4081      embedsrcs = ["deleted.txt"],
  4082      importpath = "example.com/foo",
  4083      srcs = ["foo.go"],
  4084  )
  4085  `,
  4086  		},
  4087  		{
  4088  			Path: "foo.go",
  4089  			Content: `
  4090  // +build windows
  4091  
  4092  package foo
  4093  
  4094  import _ "embed"
  4095  
  4096  //go:embed windows.txt
  4097  var s string
  4098  `,
  4099  		},
  4100  		{
  4101  			Path: "windows.txt",
  4102  		},
  4103  	}
  4104  
  4105  	dir, cleanup := testtools.CreateFiles(t, files)
  4106  	defer cleanup()
  4107  
  4108  	if err := runGazelle(dir, []string{"update"}); err != nil {
  4109  		t.Fatal(err)
  4110  	}
  4111  
  4112  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  4113  		{
  4114  			Path: "BUILD.bazel",
  4115  			Content: `
  4116  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  4117  
  4118  # gazelle:prefix example.com/foo
  4119  
  4120  go_library(
  4121      name = "foo",
  4122      srcs = ["foo.go"],
  4123      embedsrcs = select({
  4124          "@io_bazel_rules_go//go/platform:windows": [
  4125              "windows.txt",
  4126          ],
  4127          "//conditions:default": [],
  4128      }),
  4129      importpath = "example.com/foo",
  4130      visibility = ["//visibility:public"],
  4131  )
  4132  `,
  4133  		},
  4134  	})
  4135  }
  4136  
  4137  // Checks that go:embed directives with spaces and quotes are parsed correctly.
  4138  // This probably belongs in //language/go:go_test, but we need file names with
  4139  // spaces, and Bazel doesn't allow those in runfiles, which that test depends
  4140  // on.
  4141  func TestQuotedEmbedsrcs(t *testing.T) {
  4142  	files := []testtools.FileSpec{
  4143  		{
  4144  			Path: "WORKSPACE",
  4145  		},
  4146  		{
  4147  			Path:    "BUILD.bazel",
  4148  			Content: "# gazelle:prefix example.com/foo",
  4149  		},
  4150  		{
  4151  			Path: "foo.go",
  4152  			Content: strings.Join([]string{
  4153  				"package foo",
  4154  				"import \"embed\"",
  4155  				"//go:embed q1.txt q2.txt \"q 3.txt\" `q 4.txt`",
  4156  				"var fs embed.FS",
  4157  			}, "\n"),
  4158  		},
  4159  		{
  4160  			Path: "q1.txt",
  4161  		},
  4162  		{
  4163  			Path: "q2.txt",
  4164  		},
  4165  		{
  4166  			Path: "q 3.txt",
  4167  		},
  4168  		{
  4169  			Path: "q 4.txt",
  4170  		},
  4171  	}
  4172  	dir, cleanup := testtools.CreateFiles(t, files)
  4173  	defer cleanup()
  4174  
  4175  	if err := runGazelle(dir, []string{"update"}); err != nil {
  4176  		t.Fatal(err)
  4177  	}
  4178  
  4179  	testtools.CheckFiles(t, dir, []testtools.FileSpec{{
  4180  		Path: "BUILD.bazel",
  4181  		Content: `
  4182  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  4183  
  4184  # gazelle:prefix example.com/foo
  4185  
  4186  go_library(
  4187      name = "foo",
  4188      srcs = ["foo.go"],
  4189      embedsrcs = [
  4190          "q 3.txt",
  4191          "q 4.txt",
  4192          "q1.txt",
  4193          "q2.txt",
  4194      ],
  4195      importpath = "example.com/foo",
  4196      visibility = ["//visibility:public"],
  4197  )
  4198  `,
  4199  	}})
  4200  }
  4201  
  4202  // TestUpdateReposDoesNotModifyGoSum verifies that commands executed by
  4203  // update-repos do not modify go.sum, particularly 'go mod download' when
  4204  // a sum is missing. Verifies #990.
  4205  //
  4206  // This could also be tested in language/go/update_import_test.go, but that
  4207  // test relies on stubs for speed, and it's important to run the real
  4208  // go command here.
  4209  func TestUpdateReposDoesNotModifyGoSum(t *testing.T) {
  4210  	if testing.Short() {
  4211  		// Test may download small files over network.
  4212  		t.Skip()
  4213  	}
  4214  	goSumFile := testtools.FileSpec{
  4215  		// go.sum only contains the sum for the mod file, not the content.
  4216  		// This is common for transitive dependencies not needed by the main module.
  4217  		Path:    "go.sum",
  4218  		Content: "golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n",
  4219  	}
  4220  	files := []testtools.FileSpec{
  4221  		{
  4222  			Path:    "WORKSPACE",
  4223  			Content: "# gazelle:repo bazel_gazelle",
  4224  		},
  4225  		{
  4226  			Path: "go.mod",
  4227  			Content: `
  4228  module test
  4229  
  4230  go 1.16
  4231  
  4232  require golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
  4233  `,
  4234  		},
  4235  		goSumFile,
  4236  	}
  4237  	dir, cleanup := testtools.CreateFiles(t, files)
  4238  	defer cleanup()
  4239  
  4240  	if err := runGazelle(dir, []string{"update-repos", "-from_file=go.mod"}); err != nil {
  4241  		t.Fatal(err)
  4242  	}
  4243  	testtools.CheckFiles(t, dir, []testtools.FileSpec{goSumFile})
  4244  }
  4245  
  4246  func TestResolveGoStaticFromGoMod(t *testing.T) {
  4247  	dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{
  4248  		{Path: "WORKSPACE"},
  4249  		{
  4250  			Path: "go.mod",
  4251  			Content: `
  4252  module example.com/use
  4253  
  4254  go 1.19
  4255  
  4256  require example.com/dep v1.0.0
  4257  `,
  4258  		},
  4259  		{
  4260  			Path: "use.go",
  4261  			Content: `
  4262  package use
  4263  
  4264  import _ "example.com/dep/pkg"
  4265  `,
  4266  		},
  4267  	})
  4268  	defer cleanup()
  4269  
  4270  	args := []string{
  4271  		"-go_prefix=example.com/use",
  4272  		"-external=static",
  4273  		"-go_naming_convention_external=import",
  4274  	}
  4275  	if err := runGazelle(dir, args); err != nil {
  4276  		t.Fatal(err)
  4277  	}
  4278  
  4279  	testtools.CheckFiles(t, dir, []testtools.FileSpec{
  4280  		{
  4281  			Path: "BUILD.bazel",
  4282  			Content: `
  4283  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  4284  
  4285  go_library(
  4286      name = "use",
  4287      srcs = ["use.go"],
  4288      importpath = "example.com/use",
  4289      visibility = ["//visibility:public"],
  4290      deps = ["@com_example_dep//pkg"],
  4291  )
  4292  `,
  4293  		},
  4294  	})
  4295  }
  4296  
  4297  func TestMigrateSelectFromWorkspaceToBzlmod(t *testing.T) {
  4298  	dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{
  4299  		{Path: "WORKSPACE"},
  4300  		{
  4301  			Path:    "MODULE.bazel",
  4302  			Content: `bazel_dep(name = "rules_go", version = "0.39.1", repo_name = "my_rules_go")`,
  4303  		},
  4304  		{
  4305  			Path: "BUILD",
  4306  			Content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  4307  
  4308  go_library(
  4309      name = "foo",
  4310      srcs = [
  4311          "bar.go",
  4312          "foo.go",
  4313          "foo_android.go",
  4314          "foo_android_build_tag.go",
  4315      ],
  4316      importpath = "example.com/foo",
  4317      visibility = ["//visibility:public"],
  4318      deps = select({
  4319          "@io_bazel_rules_go//go/platform:android": [
  4320              "//outer",
  4321              "//outer/inner",
  4322              "//outer_android_build_tag",
  4323              "//outer_android_suffix",
  4324              "@com_github_jr_hacker_tools//:go_default_library",
  4325          ],
  4326          "@io_bazel_rules_go//go/platform:linux": [
  4327              "//outer",
  4328              "//outer/inner",
  4329              "@com_github_jr_hacker_tools//:go_default_library",
  4330          ],
  4331          "//conditions:default": [],
  4332      }),
  4333  )
  4334  `,
  4335  		},
  4336  		{
  4337  			Path: "foo.go",
  4338  			Content: `
  4339  // +build linux
  4340  
  4341  package foo
  4342  
  4343  import (
  4344      _ "example.com/foo/outer"
  4345      _ "example.com/foo/outer/inner"
  4346      _ "github.com/jr_hacker/tools"
  4347  )
  4348  `,
  4349  		},
  4350  		{
  4351  			Path: "foo_android_build_tag.go",
  4352  			Content: `
  4353  // +build android
  4354  
  4355  package foo
  4356  
  4357  import (
  4358      _ "example.com/foo/outer_android_build_tag"
  4359  )
  4360  `,
  4361  		},
  4362  		{
  4363  			Path: "foo_android.go",
  4364  			Content: `
  4365  package foo
  4366  
  4367  import (
  4368      _ "example.com/foo/outer_android_suffix"
  4369  )
  4370  `,
  4371  		},
  4372  		{
  4373  			Path: "bar.go",
  4374  			Content: `// +build linux
  4375  
  4376  package foo
  4377  `,
  4378  		},
  4379  		{Path: "outer/outer.go", Content: "package outer"},
  4380  		{Path: "outer_android_build_tag/outer.go", Content: "package outer_android_build_tag"},
  4381  		{Path: "outer_android_suffix/outer.go", Content: "package outer_android_suffix"},
  4382  		{Path: "outer/inner/inner.go", Content: "package inner"},
  4383  	})
  4384  	want := `load("@io_bazel_rules_go//go:def.bzl", "go_library")
  4385  
  4386  go_library(
  4387      name = "foo",
  4388      srcs = [
  4389          "bar.go",
  4390          "foo.go",
  4391          "foo_android.go",
  4392          "foo_android_build_tag.go",
  4393      ],
  4394      importpath = "example.com/foo",
  4395      visibility = ["//visibility:public"],
  4396      deps = select({
  4397          "@my_rules_go//go/platform:android": [
  4398              "//outer",
  4399              "//outer/inner",
  4400              "//outer_android_build_tag",
  4401              "//outer_android_suffix",
  4402              "@com_github_jr_hacker_tools//:go_default_library",
  4403          ],
  4404          "@my_rules_go//go/platform:linux": [
  4405              "//outer",
  4406              "//outer/inner",
  4407              "@com_github_jr_hacker_tools//:go_default_library",
  4408          ],
  4409          "//conditions:default": [],
  4410      }),
  4411  )
  4412  `
  4413  	defer cleanup()
  4414  
  4415  	if err := runGazelle(dir, []string{"-go_prefix", "example.com/foo"}); err != nil {
  4416  		t.Fatal(err)
  4417  	}
  4418  	if got, err := os.ReadFile(filepath.Join(dir, "BUILD")); err != nil {
  4419  		t.Fatal(err)
  4420  	} else if string(got) != want {
  4421  		t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want))
  4422  	}
  4423  }
  4424  
  4425  func TestUpdateReposWithBzlmodWithToMacro(t *testing.T) {
  4426  	dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{
  4427  		{Path: "WORKSPACE"},
  4428  		{
  4429  			Path: "go.mod",
  4430  			Content: `
  4431  module example.com/foo/v2
  4432  
  4433  go 1.19
  4434  
  4435  require (
  4436  	github.com/stretchr/testify v1.8.4
  4437  )
  4438  `,
  4439  		},
  4440  	})
  4441  
  4442  	t.Cleanup(cleanup)
  4443  
  4444  	args := []string{
  4445  		"update-repos",
  4446  		"-from_file=go.mod",
  4447  		"-to_macro=go_deps.bzl%my_go_deps",
  4448  		"-bzlmod",
  4449  	}
  4450  	if err := runGazelle(dir, args); err != nil {
  4451  		t.Fatal(err)
  4452  	}
  4453  
  4454  	// Confirm that the WORKSPACE is still empty
  4455  	want := ""
  4456  	if got, err := os.ReadFile(filepath.Join(dir, "WORKSPACE")); err != nil {
  4457  		t.Fatal(err)
  4458  	} else if string(got) != want {
  4459  		t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want))
  4460  	}
  4461  
  4462  	// Confirm that the macro file was written
  4463  	want = `load("@bazel_gazelle//:deps.bzl", "go_repository")
  4464  
  4465  def my_go_deps():
  4466      go_repository(
  4467          name = "com_github_stretchr_testify",
  4468          importpath = "github.com/stretchr/testify",
  4469          sum = "h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=",
  4470          version = "v1.8.4",
  4471      )
  4472  `
  4473  	if got, err := os.ReadFile(filepath.Join(dir, "go_deps.bzl")); err != nil {
  4474  		t.Fatal(err)
  4475  	} else if string(got) != want {
  4476  		t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want))
  4477  	}
  4478  }
  4479  
  4480  func TestUpdateReposWithBzlmodWithoutToMacro(t *testing.T) {
  4481  	dir, cleanup := testtools.CreateFiles(t, []testtools.FileSpec{
  4482  		{Path: "WORKSPACE"},
  4483  		{
  4484  			Path: "go.mod",
  4485  			Content: `
  4486  module example.com/foo/v2
  4487  
  4488  go 1.19
  4489  
  4490  require (
  4491  	github.com/stretchr/testify v1.8.4
  4492  )
  4493  `,
  4494  		},
  4495  	})
  4496  
  4497  	t.Cleanup(cleanup)
  4498  
  4499  	args := []string{
  4500  		"update-repos",
  4501  		"-from_file=go.mod",
  4502  		"-bzlmod",
  4503  	}
  4504  	if err := runGazelle(dir, args); err != nil {
  4505  		t.Fatal(err)
  4506  	}
  4507  
  4508  	// Confirm that the WORKSPACE is still empty
  4509  	want := ""
  4510  	if got, err := os.ReadFile(filepath.Join(dir, "WORKSPACE")); err != nil {
  4511  		t.Fatal(err)
  4512  	} else if string(got) != want {
  4513  		t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want))
  4514  	}
  4515  }