Skip to content

Commit

Permalink
go_repository: add importpath and vcs flags (bazelbuild#313)
Browse files Browse the repository at this point in the history
This change allows fetch_repo to fetch repositories without attempting
to determine the repo root if the user supplies the information
themselves. This allows users to be able to fetch repositories that the
vcs package would otherwise not be able to recognize.

This change also changes the behavior of the --remote flag to match the
git_repository rule.
  • Loading branch information
wlynch committed Mar 20, 2017
1 parent 3299996 commit d13dd16
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 10 deletions.
11 changes: 8 additions & 3 deletions go/private/go_repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ def _go_repository_impl(ctx):

# TODO(yugui): support submodule?
# c.f. https://www.bazel.io/versions/master/docs/be/workspace.html#git_repository.init_submodules
remote = ctx.attr.remote if ctx.attr.remote else ctx.attr.importpath
remote = ctx.attr.remote
vcs = ctx.attr.vcs
importpath = ctx.attr.importpath
result = ctx.execute([
fetch_repo,
'--dest', ctx.path(''),
'--remote', remote,
'--rev', rev])
'--rev', rev,
'--vcs', vcs,
'--importpath', importpath])
if result.return_code:
fail("failed to fetch %s: %s" % (remote, result.stderr))

Expand All @@ -58,8 +62,9 @@ def _new_go_repository_impl(ctx):

_go_repository_attrs = {
"build_file_name": attr.string(),
"importpath": attr.string(mandatory = True),
"importpath": attr.string(),
"remote": attr.string(),
"vcs": attr.string(default="git", values=["git", "hg", "svn", "bzr"]),
"commit": attr.string(),
"tag": attr.string(),
"build_tags": attr.string_list(),
Expand Down
75 changes: 75 additions & 0 deletions go/tools/fetch_repo/fetch_repo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package main

import (
"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 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,
},
{
label: "missing vcs",
remote: "https://github.com/bazeltest/rules_go",
importpath: "github.com/bazeltest/rules_go",
r: root,
},
{
label: "missing remote",
cmd: "git",
importpath: "github.com/bazeltest/rules_go",
r: root,
},
{
label: "old args",
remote: "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)
}
}
}
40 changes: 33 additions & 7 deletions go/tools/fetch_repo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,45 @@ import (
)

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")
)

func getRepoRoot(remote, cmd, importpath string) (*vcs.RepoRoot, error) {
r := &vcs.RepoRoot{
VCS: vcs.ByCmd(cmd),
Repo: remote,
Root: importpath,
}

if remote != "" && importpath == "" && cmd == "" {
// User passed in old-style arguments. Assume old behavior for now, but give a warning.
log.Println("WARNING: --remote should be used with the --vcs flag. If this is an import path, use --importpath instead.")
importpath = remote
}
if cmd == "" || remote == "" {
// User did not give us complete information for VCS / Remote.
// Try to figure out the information from the import path.
var err error
r, err = vcs.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)
}

Expand Down

0 comments on commit d13dd16

Please sign in to comment.