1
0
mirror of https://github.com/golang/go synced 2024-11-18 15:04:44 -07:00

cmd/go: strip trailing slash from versioned arguments

'go get' accepts arguments of the form path@version, and it passes
them through search.CleanPatterns before querying proxies. With this
change, CleanPatterns preserves text after '@' and will strip trailing
slashes from the patn.

Previously, we did not strip trailing slashes when a version was
present, which caused proxy base URL validation to fail. Module paths
that end with ".go" (for example, github.com/nats-io/nats.go) use
trailing slashes to prevent 'go build' and other commands from
interpreting packages as source file names, so this caused unnecessary
problems for them.

Updates #32483

Change-Id: Id3730c52089e52f1cac446617c20132a3021a808
Reviewed-on: https://go-review.googlesource.com/c/go/+/194600
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
Jay Conrod 2019-09-10 16:06:12 -04:00
parent 04867cd891
commit 8875fb97c5
4 changed files with 75 additions and 8 deletions

View File

@ -678,6 +678,15 @@ func runGet(cmd *base.Command, args []string) {
if *getD || len(pkgPatterns) == 0 {
return
}
// TODO(golang.org/issue/32483): handle paths ending with ".go" consistently
// with 'go build'. When we load packages above, we interpret arguments as
// package patterns, not source files. To preserve that interpretation here,
// we add a trailing slash to any patterns ending with ".go".
for i := range pkgPatterns {
if strings.HasSuffix(pkgPatterns[i], ".go") {
pkgPatterns[i] += "/"
}
}
work.BuildInit()
pkgs := load.PackagesForBuild(pkgPatterns)
work.InstallPackages(pkgPatterns, pkgs)

View File

@ -363,30 +363,40 @@ func ImportPathsQuiet(patterns []string) []*Match {
// CleanPatterns returns the patterns to use for the given
// command line. It canonicalizes the patterns but does not
// evaluate any matches.
// evaluate any matches. It preserves text after '@' for commands
// that accept versions.
func CleanPatterns(patterns []string) []string {
if len(patterns) == 0 {
return []string{"."}
}
var out []string
for _, a := range patterns {
var p, v string
if i := strings.IndexByte(a, '@'); i < 0 {
p = a
} else {
p = a[:i]
v = a[i:]
}
// Arguments are supposed to be import paths, but
// as a courtesy to Windows developers, rewrite \ to /
// in command-line arguments. Handles .\... and so on.
if filepath.Separator == '\\' {
a = strings.ReplaceAll(a, `\`, `/`)
p = strings.ReplaceAll(p, `\`, `/`)
}
// Put argument in canonical form, but preserve leading ./.
if strings.HasPrefix(a, "./") {
a = "./" + path.Clean(a)
if a == "./." {
a = "."
if strings.HasPrefix(p, "./") {
p = "./" + path.Clean(p)
if p == "./." {
p = "."
}
} else {
a = path.Clean(a)
p = path.Clean(p)
}
out = append(out, a)
out = append(out, p+v)
}
return out
}

View File

@ -0,0 +1,16 @@
This module's path ends with ".go".
Based on github.com/nats-io/nats.go.
Used in regression tests for golang.org/issue/32483.
-- .mod --
module example.com/dotgo.go
go 1.13
-- .info --
{"Version":"v1.0.0"}
-- go.mod --
module example.com/dotgo.go
go 1.13
-- dotgo.go --
package dotgo

View File

@ -0,0 +1,32 @@
# go list should fail to load a package ending with ".go" since that denotes
# a source file. However, ".go/" should work.
# TODO(golang.org/issue/32483): perhaps we should treat non-existent paths
# with .go suffixes as package paths instead.
! go list example.com/dotgo.go
go list example.com/dotgo.go/
stdout ^example.com/dotgo.go$
# go get -d should succeed in either case, with or without a version.
# Arguments are interpreted as packages or package patterns with versions,
# not source files.
go get -d example.com/dotgo.go
go get -d example.com/dotgo.go/
go get -d example.com/dotgo.go@v1.0.0
go get -d example.com/dotgo.go/@v1.0.0
# go get (without -d) should also succeed in either case.
# TODO(golang.org/issue/32483): we should be consistent with 'go build',
# 'go list', and other commands. 'go list example.com/dotgo.go' (above) and
# 'go get example.com/dotgo.go' should both succeed or both fail.
[short] skip
go get example.com/dotgo.go
go get example.com/dotgo.go/
go get example.com/dotgo.go@v1.0.0
go get example.com/dotgo.go/@v1.0.0
-- go.mod --
module m
go 1.13
require example.com/dotgo.go v1.0.0