Cherrypicks for 0.3.4 release (#366) Cherrypicked the following changes: * #319 go_repository: add importpath and vcs flags. This allows us to have separate import paths and remote URLs for repositories. * #362 Fetch buildifier from new location. This allows the buildifier zip to be extracted with the new name.
diff --git a/go/tools/fetch_repo/BUILD b/go/tools/fetch_repo/BUILD index af27089..acc536a 100644 --- a/go/tools/fetch_repo/BUILD +++ b/go/tools/fetch_repo/BUILD
@@ -1,7 +1,20 @@ -load("//go:def.bzl", "go_binary") +load("//go:def.bzl", "go_binary", "go_library", "go_test") go_binary( name = "fetch_repo", + library = ":go_default_library", +) + +go_library( + name = "go_default_library", srcs = ["main.go"], + visibility = ["//visibility:private"], + deps = ["@org_golang_x_tools//go/vcs:go_default_library"], +) + +go_test( + name = "go_default_test", + srcs = ["fetch_repo_test.go"], + library = ":go_default_library", deps = ["@org_golang_x_tools//go/vcs:go_default_library"], )
diff --git a/go/tools/fetch_repo/fetch_repo_test.go b/go/tools/fetch_repo/fetch_repo_test.go new file mode 100644 index 0000000..d057349 --- /dev/null +++ b/go/tools/fetch_repo/fetch_repo_test.go
@@ -0,0 +1,96 @@ +package main + +import ( + "os" + "reflect" + "testing" + + "golang.org/x/tools/go/vcs" +) + +var ( + root = &vcs.RepoRoot{ + VCS: vcs.ByCmd("git"), + Repo: "https://github.com/bazeltest/rules_go", + Root: "github.com/bazeltest/rules_go", + } +) + +func TestMain(m *testing.M) { + // Replace vcs.RepoRootForImportPath to disable any network calls. + repoRootForImportPath = func(_ string, _ bool) (*vcs.RepoRoot, error) { + return root, nil + } + os.Exit(m.Run()) +} + +func TestGetRepoRoot(t *testing.T) { + for _, tc := range []struct { + label string + remote string + cmd string + importpath string + r *vcs.RepoRoot + }{ + { + label: "all", + remote: "https://github.com/bazeltest/rules_go", + cmd: "git", + importpath: "github.com/bazeltest/rules_go", + r: root, + }, + { + label: "different remote", + remote: "https://example.com/rules_go", + cmd: "git", + importpath: "github.com/bazeltest/rules_go", + r: &vcs.RepoRoot{ + VCS: vcs.ByCmd("git"), + Repo: "https://example.com/rules_go", + Root: "github.com/bazeltest/rules_go", + }, + }, + { + label: "only importpath", + importpath: "github.com/bazeltest/rules_go", + r: root, + }, + } { + r, err := getRepoRoot(tc.remote, tc.cmd, tc.importpath) + if err != nil { + t.Errorf("[%s] %v", tc.label, err) + } + if !reflect.DeepEqual(r, tc.r) { + t.Errorf("[%s] Expected %+v, got %+v", tc.label, tc.r, r) + } + } +} + +func TestGetRepoRoot_error(t *testing.T) { + for _, tc := range []struct { + label string + remote string + cmd string + importpath string + }{ + { + label: "importpath as remote", + remote: "github.com/bazeltest/rules_go", + }, + { + label: "missing vcs", + remote: "https://github.com/bazeltest/rules_go", + importpath: "github.com/bazeltest/rules_go", + }, + { + label: "missing remote", + cmd: "git", + importpath: "github.com/bazeltest/rules_go", + }, + } { + r, err := getRepoRoot(tc.remote, tc.cmd, tc.importpath) + if err == nil { + t.Errorf("[%s] expected error. Got %+v", tc.label, r) + } + } +}
diff --git a/go/tools/fetch_repo/main.go b/go/tools/fetch_repo/main.go index 92e6d76..d399320 100644 --- a/go/tools/fetch_repo/main.go +++ b/go/tools/fetch_repo/main.go
@@ -19,19 +19,50 @@ ) var ( - remote = flag.String("remote", "", "Go importpath to the repository fetch") - rev = flag.String("rev", "", "target revision") - dest = flag.String("dest", "", "destination directory") + remote = flag.String("remote", "", "The URI of the remote repository. Must be used with the --vcs flag.") + cmd = flag.String("vcs", "", "Version control system to use to fetch the repository. Should be one of: git,hg,svn,bzr. Must be used with the --remote flag.") + rev = flag.String("rev", "", "target revision") + dest = flag.String("dest", "", "destination directory") + importpath = flag.String("importpath", "", "Go importpath to the repository fetch") + + // Used for overriding in tests to disable network calls. + repoRootForImportPath = vcs.RepoRootForImportPath ) +func getRepoRoot(remote, cmd, importpath string) (*vcs.RepoRoot, error) { + if (cmd == "") != (remote == "") { + return nil, fmt.Errorf("--remote should be used with the --vcs flag. If this is an import path, use --importpath instead.") + } + + if cmd != "" && remote != "" { + v := vcs.ByCmd(cmd) + if v == nil { + return nil, fmt.Errorf("invalid VCS type: %s", cmd) + } + return &vcs.RepoRoot{ + VCS: v, + Repo: remote, + Root: importpath, + }, nil + } + + // User did not give us complete information for VCS / Remote. + // Try to figure out the information from the import path. + r, err := repoRootForImportPath(importpath, true) + if err != nil { + return nil, err + } + if importpath != r.Root { + return nil, fmt.Errorf("not a root of a repository: %s", importpath) + } + return r, nil +} + func run() error { - r, err := vcs.RepoRootForImportPath(*remote, true) + r, err := getRepoRoot(*remote, *cmd, *importpath) if err != nil { return err } - if *remote != r.Root { - return fmt.Errorf("not a root of a repository: %s", *remote) - } return r.VCS.CreateAtRev(*dest, r.Repo, *rev) }