Skip to content

Commit 01df2fe

Browse files
author
Jay Conrod
committed
cmd/go: allow querying other versions of the main module
'go mod download' and a few other commands can now query specific versions of the main module. 'go get' still reports an error when attempting to update the main module. Fixes #42524 Change-Id: Ia93ef8f5f34443e938667c48a0db432200108c63 Reviewed-on: https://go-review.googlesource.com/c/go/+/270520 Trust: Jay Conrod <[email protected]> Run-TryBot: Jay Conrod <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent 0968d2d commit 01df2fe

File tree

5 files changed

+76
-16
lines changed

5 files changed

+76
-16
lines changed

src/cmd/go/internal/modcmd/download.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,11 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
8888
args = []string{"all"}
8989
} else if modload.HasModRoot() {
9090
modload.LoadModFile(ctx) // to fill Target
91-
targetAtLatest := modload.Target.Path + "@latest"
9291
targetAtUpgrade := modload.Target.Path + "@upgrade"
9392
targetAtPatch := modload.Target.Path + "@patch"
9493
for _, arg := range args {
9594
switch arg {
96-
case modload.Target.Path, targetAtLatest, targetAtUpgrade, targetAtPatch:
95+
case modload.Target.Path, targetAtUpgrade, targetAtPatch:
9796
os.Stderr.WriteString("go mod download: skipping argument " + arg + " that resolves to the main module\n")
9897
}
9998
}
@@ -170,7 +169,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
170169
for _, m := range mods {
171170
b, err := json.MarshalIndent(m, "", "\t")
172171
if err != nil {
173-
base.Fatalf("%v", err)
172+
base.Fatalf("go mod download: %v", err)
174173
}
175174
os.Stdout.Write(append(b, '\n'))
176175
if m.Error != "" {
@@ -180,7 +179,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
180179
} else {
181180
for _, m := range mods {
182181
if m.Error != "" {
183-
base.Errorf("%s", m.Error)
182+
base.Errorf("go mod download: %v", m.Error)
184183
}
185184
}
186185
base.ExitIfErrors()

src/cmd/go/internal/modload/query.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,7 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
109109
allowed = func(context.Context, module.Version) error { return nil }
110110
}
111111

112-
if path == Target.Path {
113-
if query != "upgrade" && query != "patch" {
114-
return nil, &QueryMatchesMainModuleError{Pattern: path, Query: query}
115-
}
112+
if path == Target.Path && (query == "upgrade" || query == "patch") {
116113
if err := allowed(ctx, Target); err != nil {
117114
return nil, fmt.Errorf("internal error: main module version is not allowed: %w", err)
118115
}
@@ -582,6 +579,7 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
582579
}
583580
}
584581

582+
var queryMatchesMainModule bool
585583
if HasModRoot() {
586584
m := match(Target, modRoot, true)
587585
if len(m.Pkgs) > 0 {
@@ -605,7 +603,11 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
605603
return nil, nil, err
606604
}
607605

608-
if query != "upgrade" && query != "patch" && matchPattern(Target.Path) {
606+
if matchPattern(Target.Path) {
607+
queryMatchesMainModule = true
608+
}
609+
610+
if (query == "upgrade" || query == "patch") && queryMatchesMainModule {
609611
if err := allowed(ctx, Target); err == nil {
610612
modOnly = &QueryResult{
611613
Mod: Target,
@@ -620,14 +622,20 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
620622
candidateModules = modulePrefixesExcludingTarget(base)
621623
)
622624
if len(candidateModules) == 0 {
623-
if modOnly == nil {
625+
if modOnly != nil {
626+
return nil, modOnly, nil
627+
} else if queryMatchesMainModule {
628+
return nil, nil, &QueryMatchesMainModuleError{
629+
Pattern: pattern,
630+
Query: query,
631+
}
632+
} else {
624633
return nil, nil, &PackageNotInModuleError{
625634
Mod: Target,
626635
Query: query,
627636
Pattern: pattern,
628637
}
629638
}
630-
return nil, modOnly, nil
631639
}
632640

633641
err = modfetch.TryProxies(func(proxy string) error {
@@ -675,6 +683,12 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
675683
return err
676684
})
677685

686+
if queryMatchesMainModule && len(results) == 0 && modOnly == nil && errors.Is(err, fs.ErrNotExist) {
687+
return nil, nil, &QueryMatchesMainModuleError{
688+
Pattern: pattern,
689+
Query: query,
690+
}
691+
}
678692
return results[:len(results):len(results)], modOnly, err
679693
}
680694

src/cmd/go/testdata/script/mod_download.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,19 @@ exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip
9393

9494
# download reports errors encountered when locating modules
9595
! go mod download bad/path
96-
stderr '^module bad/path: not a known dependency$'
96+
stderr '^go mod download: module bad/path: not a known dependency$'
9797
! go mod download bad/path@latest
98-
stderr '^bad/path@latest: malformed module path "bad/path": missing dot in first path element$'
98+
stderr '^go mod download: bad/path@latest: malformed module path "bad/path": missing dot in first path element$'
9999
! go mod download rsc.io/[email protected]
100-
stderr '^rsc.io/[email protected]: reading .*/v1.999.999.info: 404 Not Found$'
100+
stderr '^go mod download: rsc.io/[email protected]: reading .*/v1.999.999.info: 404 Not Found$'
101101
! go mod download -json bad/path
102102
stdout '^\t"Error": "module bad/path: not a known dependency"'
103103

104104
# download main module produces a warning or error
105105
go mod download m
106106
stderr '^go mod download: skipping argument m that resolves to the main module\n'
107107
! go mod download m@latest
108-
stderr 'm@latest: can''t request version "latest" of the main module \(m\)'
108+
stderr '^go mod download: m@latest: malformed module path "m": missing dot in first path element$'
109109

110110
# download updates go.mod and populates go.sum
111111
cd update

src/cmd/go/testdata/script/mod_get_main.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ grep 'rsc.io/quote v1.5.1' go.mod
3030

3131

3232
# The main module cannot be updated to a specific version.
33+
! go get -d [email protected]
34+
stderr '^go get: can''t request version "v0.1.0" of the main module \(rsc.io\)$'
35+
36+
# A package in the main module can't be upgraded either.
3337
! go get -d rsc.io/[email protected]
3438
stderr '^go get: package rsc.io/x is in the main module, so can''t request version v0.1.0$'
3539

36-
# The main module cannot be updated to @latest, which is a specific version.
40+
# Nor can a pattern matching packages in the main module.
3741
! go get -d rsc.io/x/...@latest
3842
stderr '^go get: pattern rsc.io/x/... matches package rsc.io/x in the main module, so can''t request version latest$'
3943

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# 'go mod download' can download specific versions of the main module.
2+
go mod download rsc.io/quote@5d9f230b
3+
go mod download rsc.io/[email protected]
4+
go mod download rsc.io/quote@latest
5+
6+
# 'go mod download' will not download @upgrade or @patch, since they always
7+
# resolve to the main module.
8+
go mod download rsc.io/quote@upgrade
9+
stderr '^go mod download: skipping argument rsc.io/quote@upgrade that resolves to the main module$'
10+
go mod download rsc.io/quote@patch
11+
stderr '^go mod download: skipping argument rsc.io/quote@patch that resolves to the main module$'
12+
13+
# 'go list -m' can show a version of the main module.
14+
go list -m rsc.io/quote@5d9f230b
15+
stdout '^rsc.io/quote v0.0.0-20180710144737-5d9f230bcfba$'
16+
go list -m rsc.io/[email protected]
17+
stdout '^rsc.io/quote v1.5.2$'
18+
go list -m rsc.io/quote@latest
19+
stdout '^rsc.io/quote v1.5.2$'
20+
21+
# 'go list -m -versions' shows available versions.
22+
go list -m -versions rsc.io/quote
23+
stdout '^rsc.io/quote.*v1.5.2'
24+
25+
# 'go list -m' resolves @upgrade and @patch to the main module.
26+
go list -m rsc.io/quote@upgrade
27+
stdout '^rsc.io/quote$'
28+
go list -m rsc.io/quote@patch
29+
stdout '^rsc.io/quote$'
30+
31+
# 'go get' will not attempt to upgrade the main module to any specific version.
32+
# See also: mod_get_main.txt.
33+
! go get rsc.io/quote@5d9f230b
34+
stderr '^go get: can''t request version "5d9f230b" of the main module \(rsc.io/quote\)$'
35+
! go get rsc.io/[email protected]
36+
stderr '^go get: can''t request version "v1.5.2" of the main module \(rsc.io/quote\)$'
37+
! go get rsc.io/quote@latest
38+
stderr '^go get: can''t request version "latest" of the main module \(rsc.io/quote\)$'
39+
40+
-- go.mod --
41+
module rsc.io/quote
42+
43+
go 1.16

0 commit comments

Comments
 (0)