diff --git a/go/vcs/vcs.go b/go/vcs/vcs.go index 501c8942545..89319be04b9 100644 --- a/go/vcs/vcs.go +++ b/go/vcs/vcs.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "log" + "net/url" "os" "os/exec" "path/filepath" @@ -566,8 +567,8 @@ func RepoRootForImportDynamic(importPath string, verbose bool) (*RepoRoot, error } } - if !strings.Contains(metaImport.RepoRoot, "://") { - return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, metaImport.RepoRoot) + if err := validateRepoRoot(metaImport.RepoRoot); err != nil { + return nil, fmt.Errorf("%s: invalid repo root %q: %v", urlStr, metaImport.RepoRoot, err) } rr := &RepoRoot{ VCS: ByCmd(metaImport.VCS), @@ -580,6 +581,19 @@ func RepoRootForImportDynamic(importPath string, verbose bool) (*RepoRoot, error return rr, nil } +// validateRepoRoot returns an error if repoRoot does not seem to be +// a valid URL with scheme. +func validateRepoRoot(repoRoot string) error { + url, err := url.Parse(repoRoot) + if err != nil { + return err + } + if url.Scheme == "" { + return errors.New("no scheme") + } + return nil +} + // metaImport represents the parsed tags from HTML files. type metaImport struct { diff --git a/go/vcs/vcs_test.go b/go/vcs/vcs_test.go index 8f36cac70c7..ee422e8c4f2 100644 --- a/go/vcs/vcs_test.go +++ b/go/vcs/vcs_test.go @@ -140,3 +140,47 @@ func TestParseMetaGoImports(t *testing.T) { } } } + +func TestValidateRepoRoot(t *testing.T) { + tests := []struct { + root string + ok bool + }{ + { + root: "", + ok: false, + }, + { + root: "http://", + ok: true, + }, + { + root: "git+ssh://", + ok: true, + }, + { + root: "http#://", + ok: false, + }, + { + root: "-config", + ok: false, + }, + { + root: "-config://", + ok: false, + }, + } + + for _, test := range tests { + err := validateRepoRoot(test.root) + ok := err == nil + if ok != test.ok { + want := "error" + if test.ok { + want = "nil" + } + t.Errorf("validateRepoRoot(%q) = %q, want %s", test.root, err, want) + } + } +}