Skip to content

Commit 8875fb9

Browse files
author
Jay Conrod
committed
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>
1 parent 04867cd commit 8875fb9

File tree

4 files changed

+75
-8
lines changed

4 files changed

+75
-8
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,15 @@ func runGet(cmd *base.Command, args []string) {
678678
if *getD || len(pkgPatterns) == 0 {
679679
return
680680
}
681+
// TODO(golang.org/issue/32483): handle paths ending with ".go" consistently
682+
// with 'go build'. When we load packages above, we interpret arguments as
683+
// package patterns, not source files. To preserve that interpretation here,
684+
// we add a trailing slash to any patterns ending with ".go".
685+
for i := range pkgPatterns {
686+
if strings.HasSuffix(pkgPatterns[i], ".go") {
687+
pkgPatterns[i] += "/"
688+
}
689+
}
681690
work.BuildInit()
682691
pkgs := load.PackagesForBuild(pkgPatterns)
683692
work.InstallPackages(pkgPatterns, pkgs)

src/cmd/go/internal/search/search.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -363,30 +363,40 @@ func ImportPathsQuiet(patterns []string) []*Match {
363363

364364
// CleanPatterns returns the patterns to use for the given
365365
// command line. It canonicalizes the patterns but does not
366-
// evaluate any matches.
366+
// evaluate any matches. It preserves text after '@' for commands
367+
// that accept versions.
367368
func CleanPatterns(patterns []string) []string {
368369
if len(patterns) == 0 {
369370
return []string{"."}
370371
}
371372
var out []string
372373
for _, a := range patterns {
374+
var p, v string
375+
if i := strings.IndexByte(a, '@'); i < 0 {
376+
p = a
377+
} else {
378+
p = a[:i]
379+
v = a[i:]
380+
}
381+
373382
// Arguments are supposed to be import paths, but
374383
// as a courtesy to Windows developers, rewrite \ to /
375384
// in command-line arguments. Handles .\... and so on.
376385
if filepath.Separator == '\\' {
377-
a = strings.ReplaceAll(a, `\`, `/`)
386+
p = strings.ReplaceAll(p, `\`, `/`)
378387
}
379388

380389
// Put argument in canonical form, but preserve leading ./.
381-
if strings.HasPrefix(a, "./") {
382-
a = "./" + path.Clean(a)
383-
if a == "./." {
384-
a = "."
390+
if strings.HasPrefix(p, "./") {
391+
p = "./" + path.Clean(p)
392+
if p == "./." {
393+
p = "."
385394
}
386395
} else {
387-
a = path.Clean(a)
396+
p = path.Clean(p)
388397
}
389-
out = append(out, a)
398+
399+
out = append(out, p+v)
390400
}
391401
return out
392402
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
This module's path ends with ".go".
2+
Based on github.com/nats-io/nats.go.
3+
Used in regression tests for golang.org/issue/32483.
4+
5+
-- .mod --
6+
module example.com/dotgo.go
7+
8+
go 1.13
9+
-- .info --
10+
{"Version":"v1.0.0"}
11+
-- go.mod --
12+
module example.com/dotgo.go
13+
14+
go 1.13
15+
-- dotgo.go --
16+
package dotgo
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# go list should fail to load a package ending with ".go" since that denotes
2+
# a source file. However, ".go/" should work.
3+
# TODO(golang.org/issue/32483): perhaps we should treat non-existent paths
4+
# with .go suffixes as package paths instead.
5+
! go list example.com/dotgo.go
6+
go list example.com/dotgo.go/
7+
stdout ^example.com/dotgo.go$
8+
9+
# go get -d should succeed in either case, with or without a version.
10+
# Arguments are interpreted as packages or package patterns with versions,
11+
# not source files.
12+
go get -d example.com/dotgo.go
13+
go get -d example.com/dotgo.go/
14+
go get -d example.com/dotgo.go@v1.0.0
15+
go get -d example.com/dotgo.go/@v1.0.0
16+
17+
# go get (without -d) should also succeed in either case.
18+
# TODO(golang.org/issue/32483): we should be consistent with 'go build',
19+
# 'go list', and other commands. 'go list example.com/dotgo.go' (above) and
20+
# 'go get example.com/dotgo.go' should both succeed or both fail.
21+
[short] skip
22+
go get example.com/dotgo.go
23+
go get example.com/dotgo.go/
24+
go get example.com/dotgo.go@v1.0.0
25+
go get example.com/dotgo.go/@v1.0.0
26+
27+
-- go.mod --
28+
module m
29+
30+
go 1.13
31+
32+
require example.com/dotgo.go v1.0.0

0 commit comments

Comments
 (0)