Skip to content

Commit 47fb1fb

Browse files
author
Bryan C. Mills
committed
cmd/go/internal/get: move wildcard-trimming to before CheckImportPath
Previously, RepoRootForImportPath trimmed certain "..." wildcards from package patterns (even though its name suggests that the argument must be an actual import path). It trimmed at the first path element that was literally "..." (although wildcards in general may appear within a larger path element), and relied on a subsequent check in RepoRootForImportPath to catch confusing resolutions. However, that causes 'go get' with wildcard patterns in fresh paths to fail as of CL 154101: a wildcard pattern is not a valid import path, and fails the path check. (The existing Test{Vendor,Go}Get* packages in go_test.go and vendor_test.go catch the failure, but they are all skipped when the "-short" flag is set — including in all.bash — and we had forgotten to run them separately.) We now trim the path before any element that contains a wildcard, and perform the path check (and repo resolution) on only that prefix. It is possible that the expanded path after fetching the repo will be invalid, but a repository can contain directories that are not valid import paths in general anyway. Fixes #29241 Change-Id: I70fb2f7fc6603b7d339fd6c02e8cdeacfc93fc4b Reviewed-on: https://go-review.googlesource.com/c/154108 Reviewed-by: Russ Cox <[email protected]>
1 parent 976bab6 commit 47fb1fb

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

src/cmd/go/internal/get/get.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ var downloadCache = map[string]bool{}
232232
var downloadRootCache = map[string]bool{}
233233

234234
// download runs the download half of the get command
235-
// for the package named by the argument.
235+
// for the package or pattern named by the argument.
236236
func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) {
237237
if mode&load.ResolveImport != 0 {
238238
// Caller is responsible for expanding vendor paths.
@@ -402,7 +402,20 @@ func downloadPackage(p *load.Package) error {
402402
security = web.Insecure
403403
}
404404

405-
if err := CheckImportPath(p.ImportPath); err != nil {
405+
// p can be either a real package, or a pseudo-package whose “import path” is
406+
// actually a wildcard pattern.
407+
// Trim the path at the element containing the first wildcard,
408+
// and hope that it applies to the wildcarded parts too.
409+
// This makes 'go get rsc.io/pdf/...' work in a fresh GOPATH.
410+
importPrefix := p.ImportPath
411+
if i := strings.Index(importPrefix, "..."); i >= 0 {
412+
slash := strings.LastIndexByte(importPrefix[:i], '/')
413+
if slash < 0 {
414+
return fmt.Errorf("cannot expand ... in %q", p.ImportPath)
415+
}
416+
importPrefix = importPrefix[:slash]
417+
}
418+
if err := CheckImportPath(importPrefix); err != nil {
406419
return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, err)
407420
}
408421

@@ -425,7 +438,7 @@ func downloadPackage(p *load.Package) error {
425438
}
426439
repo = remote
427440
if !*getF && err == nil {
428-
if rr, err := RepoRootForImportPath(p.ImportPath, IgnoreMod, security); err == nil {
441+
if rr, err := RepoRootForImportPath(importPrefix, IgnoreMod, security); err == nil {
429442
repo := rr.Repo
430443
if rr.vcs.resolveRepo != nil {
431444
resolved, err := rr.vcs.resolveRepo(rr.vcs, dir, repo)
@@ -442,7 +455,7 @@ func downloadPackage(p *load.Package) error {
442455
} else {
443456
// Analyze the import path to determine the version control system,
444457
// repository, and the import path for the root of the repository.
445-
rr, err := RepoRootForImportPath(p.ImportPath, IgnoreMod, security)
458+
rr, err := RepoRootForImportPath(importPrefix, IgnoreMod, security)
446459
if err != nil {
447460
return err
448461
}

src/cmd/go/internal/get/vcs.go

+2-8
Original file line numberDiff line numberDiff line change
@@ -647,14 +647,7 @@ const (
647647
func RepoRootForImportPath(importPath string, mod ModuleMode, security web.SecurityMode) (*RepoRoot, error) {
648648
rr, err := repoRootFromVCSPaths(importPath, "", security, vcsPaths)
649649
if err == errUnknownSite {
650-
// If there are wildcards, look up the thing before the wildcard,
651-
// hoping it applies to the wildcarded parts too.
652-
// This makes 'go get rsc.io/pdf/...' work in a fresh GOPATH.
653-
lookup := strings.TrimSuffix(importPath, "/...")
654-
if i := strings.Index(lookup, "/.../"); i >= 0 {
655-
lookup = lookup[:i]
656-
}
657-
rr, err = repoRootForImportDynamic(lookup, mod, security)
650+
rr, err = repoRootForImportDynamic(importPath, mod, security)
658651
if err != nil {
659652
err = fmt.Errorf("unrecognized import path %q (%v)", importPath, err)
660653
}
@@ -667,6 +660,7 @@ func RepoRootForImportPath(importPath string, mod ModuleMode, security web.Secur
667660
}
668661
}
669662

663+
// Should have been taken care of above, but make sure.
670664
if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.Root, "...") {
671665
// Do not allow wildcards in the repo root.
672666
rr = nil

0 commit comments

Comments
 (0)