aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/get
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/go/internal/get')
-rw-r--r--src/cmd/go/internal/get/discovery.go7
-rw-r--r--src/cmd/go/internal/get/get.go10
-rw-r--r--src/cmd/go/internal/get/pkg_test.go14
-rw-r--r--src/cmd/go/internal/get/vcs.go34
-rw-r--r--src/cmd/go/internal/get/vcs_test.go43
5 files changed, 101 insertions, 7 deletions
diff --git a/src/cmd/go/internal/get/discovery.go b/src/cmd/go/internal/get/discovery.go
index b2918dbb4f..97aa1d7e8d 100644
--- a/src/cmd/go/internal/get/discovery.go
+++ b/src/cmd/go/internal/get/discovery.go
@@ -55,6 +55,13 @@ func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
continue
}
if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
+ // Ignore VCS type "mod", which is new Go modules.
+ // This code is for old go get and must ignore the new mod lines.
+ // Otherwise matchGoImport will complain about two
+ // different metaImport lines for the same Prefix.
+ if f[1] == "mod" {
+ continue
+ }
imports = append(imports, metaImport{
Prefix: f[0],
VCS: f[1],
diff --git a/src/cmd/go/internal/get/get.go b/src/cmd/go/internal/get/get.go
index e5dda643e4..6495576ab4 100644
--- a/src/cmd/go/internal/get/get.go
+++ b/src/cmd/go/internal/get/get.go
@@ -210,7 +210,7 @@ var downloadRootCache = map[string]bool{}
// download runs the download half of the get command
// for the package named by the argument.
func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) {
- if mode&load.UseVendor != 0 {
+ if mode&load.ResolveImport != 0 {
// Caller is responsible for expanding vendor paths.
panic("internal error: download mode has useVendor set")
}
@@ -218,7 +218,7 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int)
if parent == nil {
return load.LoadPackage(path, stk)
}
- return load.LoadImport(path, parent.Dir, parent, stk, nil, mode)
+ return load.LoadImport(path, parent.Dir, parent, stk, nil, mode|load.ResolveModule)
}
p := load1(arg, mode)
@@ -347,12 +347,12 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int)
base.Errorf("%s", err)
continue
}
- // If this is a test import, apply vendor lookup now.
- // We cannot pass useVendor to download, because
+ // If this is a test import, apply module and vendor lookup now.
+ // We cannot pass ResolveImport to download, because
// download does caching based on the value of path,
// so it must be the fully qualified path already.
if i >= len(p.Imports) {
- path = load.VendoredImportPath(p, path)
+ path = load.ResolveImportPath(p, path)
}
download(path, p, stk, 0)
}
diff --git a/src/cmd/go/internal/get/pkg_test.go b/src/cmd/go/internal/get/pkg_test.go
index b8937a57ec..1179d86693 100644
--- a/src/cmd/go/internal/get/pkg_test.go
+++ b/src/cmd/go/internal/get/pkg_test.go
@@ -48,6 +48,20 @@ var parseMetaGoImportsTests = []struct {
},
},
{
+ `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
+ <meta name="go-import" content="foo/bar mod http://github.com/rsc/baz/quux">`,
+ []metaImport{
+ {"foo/bar", "git", "https://github.com/rsc/foo/bar"},
+ },
+ },
+ {
+ `<meta name="go-import" content="foo/bar mod http://github.com/rsc/baz/quux">
+ <meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
+ []metaImport{
+ {"foo/bar", "git", "https://github.com/rsc/foo/bar"},
+ },
+ },
+ {
`<head>
<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
</head>`,
diff --git a/src/cmd/go/internal/get/vcs.go b/src/cmd/go/internal/get/vcs.go
index 86d2e32efb..dcc7047211 100644
--- a/src/cmd/go/internal/get/vcs.go
+++ b/src/cmd/go/internal/get/vcs.go
@@ -767,8 +767,8 @@ func repoRootForImportDynamic(importPath string, security web.SecurityMode) (*re
}
}
- if !strings.Contains(mmi.RepoRoot, "://") {
- return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, mmi.RepoRoot)
+ if err := validateRepoRootScheme(mmi.RepoRoot); err != nil {
+ return nil, fmt.Errorf("%s: invalid repo root %q: %v", urlStr, mmi.RepoRoot, err)
}
rr := &repoRoot{
vcs: vcsByCmd(mmi.VCS),
@@ -782,6 +782,36 @@ func repoRootForImportDynamic(importPath string, security web.SecurityMode) (*re
return rr, nil
}
+// validateRepoRootScheme returns an error if repoRoot does not seem
+// to have a valid URL scheme. At this point we permit things that
+// aren't valid URLs, although later, if not using -insecure, we will
+// restrict repoRoots to be valid URLs. This is only because we've
+// historically permitted them, and people may depend on that.
+func validateRepoRootScheme(repoRoot string) error {
+ end := strings.Index(repoRoot, "://")
+ if end <= 0 {
+ return errors.New("no scheme")
+ }
+
+ // RFC 3986 section 3.1.
+ for i := 0; i < end; i++ {
+ c := repoRoot[i]
+ switch {
+ case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
+ // OK.
+ case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
+ // OK except at start.
+ if i == 0 {
+ return errors.New("invalid scheme")
+ }
+ default:
+ return errors.New("invalid scheme")
+ }
+ }
+
+ return nil
+}
+
var fetchGroup singleflight.Group
var (
fetchCacheMu sync.Mutex
diff --git a/src/cmd/go/internal/get/vcs_test.go b/src/cmd/go/internal/get/vcs_test.go
index 62d352ae57..31fa9ef430 100644
--- a/src/cmd/go/internal/get/vcs_test.go
+++ b/src/cmd/go/internal/get/vcs_test.go
@@ -390,3 +390,46 @@ func TestMatchGoImport(t *testing.T) {
}
}
}
+
+func TestValidateRepoRootScheme(t *testing.T) {
+ tests := []struct {
+ root string
+ err string
+ }{
+ {
+ root: "",
+ err: "no scheme",
+ },
+ {
+ root: "http://",
+ err: "",
+ },
+ {
+ root: "a://",
+ err: "",
+ },
+ {
+ root: "a#://",
+ err: "invalid scheme",
+ },
+ {
+ root: "-config://",
+ err: "invalid scheme",
+ },
+ }
+
+ for _, test := range tests {
+ err := validateRepoRootScheme(test.root)
+ if err == nil {
+ if test.err != "" {
+ t.Errorf("validateRepoRootScheme(%q) = nil, want %q", test.root, test.err)
+ }
+ } else if test.err == "" {
+ if err != nil {
+ t.Errorf("validateRepoRootScheme(%q) = %q, want nil", test.root, test.err)
+ }
+ } else if err.Error() != test.err {
+ t.Errorf("validateRepoRootScheme(%q) = %q, want %q", test.root, err, test.err)
+ }
+ }
+}