]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: allow querying other versions of the main module
authorJay Conrod <jayconrod@google.com>
Mon, 16 Nov 2020 21:27:19 +0000 (16:27 -0500)
committerJay Conrod <jayconrod@google.com>
Tue, 17 Nov 2020 18:28:55 +0000 (18:28 +0000)
'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 <jayconrod@google.com>
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
src/cmd/go/internal/modcmd/download.go
src/cmd/go/internal/modload/query.go
src/cmd/go/testdata/script/mod_download.txt
src/cmd/go/testdata/script/mod_get_main.txt
src/cmd/go/testdata/script/mod_query_main.txt [new file with mode: 0644]

index e2e8ba682555b9dae9bd933da4e50ef2cc5c8d67..ef1ad780c81bec3070f7bd8957cc5f8bee8ffb71 100644 (file)
@@ -88,12 +88,11 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
                args = []string{"all"}
        } else if modload.HasModRoot() {
                modload.LoadModFile(ctx) // to fill Target
-               targetAtLatest := modload.Target.Path + "@latest"
                targetAtUpgrade := modload.Target.Path + "@upgrade"
                targetAtPatch := modload.Target.Path + "@patch"
                for _, arg := range args {
                        switch arg {
-                       case modload.Target.Path, targetAtLatest, targetAtUpgrade, targetAtPatch:
+                       case modload.Target.Path, targetAtUpgrade, targetAtPatch:
                                os.Stderr.WriteString("go mod download: skipping argument " + arg + " that resolves to the main module\n")
                        }
                }
@@ -170,7 +169,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
                for _, m := range mods {
                        b, err := json.MarshalIndent(m, "", "\t")
                        if err != nil {
-                               base.Fatalf("%v", err)
+                               base.Fatalf("go mod download: %v", err)
                        }
                        os.Stdout.Write(append(b, '\n'))
                        if m.Error != "" {
@@ -180,7 +179,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
        } else {
                for _, m := range mods {
                        if m.Error != "" {
-                               base.Errorf("%s", m.Error)
+                               base.Errorf("go mod download: %v", m.Error)
                        }
                }
                base.ExitIfErrors()
index d4a1e850415bd3a9db278e105e94c6a1963505e4..e35e0fc16e29b7f19790125b04b2e103d8272ec2 100644 (file)
@@ -109,10 +109,7 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
                allowed = func(context.Context, module.Version) error { return nil }
        }
 
-       if path == Target.Path {
-               if query != "upgrade" && query != "patch" {
-                       return nil, &QueryMatchesMainModuleError{Pattern: path, Query: query}
-               }
+       if path == Target.Path && (query == "upgrade" || query == "patch") {
                if err := allowed(ctx, Target); err != nil {
                        return nil, fmt.Errorf("internal error: main module version is not allowed: %w", err)
                }
@@ -582,6 +579,7 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
                }
        }
 
+       var queryMatchesMainModule bool
        if HasModRoot() {
                m := match(Target, modRoot, true)
                if len(m.Pkgs) > 0 {
@@ -605,7 +603,11 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
                        return nil, nil, err
                }
 
-               if query != "upgrade" && query != "patch" && matchPattern(Target.Path) {
+               if matchPattern(Target.Path) {
+                       queryMatchesMainModule = true
+               }
+
+               if (query == "upgrade" || query == "patch") && queryMatchesMainModule {
                        if err := allowed(ctx, Target); err == nil {
                                modOnly = &QueryResult{
                                        Mod: Target,
@@ -620,14 +622,20 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
                candidateModules = modulePrefixesExcludingTarget(base)
        )
        if len(candidateModules) == 0 {
-               if modOnly == nil {
+               if modOnly != nil {
+                       return nil, modOnly, nil
+               } else if queryMatchesMainModule {
+                       return nil, nil, &QueryMatchesMainModuleError{
+                               Pattern: pattern,
+                               Query:   query,
+                       }
+               } else {
                        return nil, nil, &PackageNotInModuleError{
                                Mod:     Target,
                                Query:   query,
                                Pattern: pattern,
                        }
                }
-               return nil, modOnly, nil
        }
 
        err = modfetch.TryProxies(func(proxy string) error {
@@ -675,6 +683,12 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
                return err
        })
 
+       if queryMatchesMainModule && len(results) == 0 && modOnly == nil && errors.Is(err, fs.ErrNotExist) {
+               return nil, nil, &QueryMatchesMainModuleError{
+                       Pattern: pattern,
+                       Query:   query,
+               }
+       }
        return results[:len(results):len(results)], modOnly, err
 }
 
index 2775fca44ee5daef927ccd20d79afdbdcd7916a6..8a9faffe4e009beedf0d080b6643030f880bb6bf 100644 (file)
@@ -93,11 +93,11 @@ exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip
 
 # download reports errors encountered when locating modules
 ! go mod download bad/path
-stderr '^module bad/path: not a known dependency$'
+stderr '^go mod download: module bad/path: not a known dependency$'
 ! go mod download bad/path@latest
-stderr '^bad/path@latest: malformed module path "bad/path": missing dot in first path element$'
+stderr '^go mod download: bad/path@latest: malformed module path "bad/path": missing dot in first path element$'
 ! go mod download rsc.io/quote@v1.999.999
-stderr '^rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$'
+stderr '^go mod download: rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$'
 ! go mod download -json bad/path
 stdout '^\t"Error": "module bad/path: not a known dependency"'
 
@@ -105,7 +105,7 @@ stdout '^\t"Error": "module bad/path: not a known dependency"'
 go mod download m
 stderr '^go mod download: skipping argument m that resolves to the main module\n'
 ! go mod download m@latest
-stderr 'm@latest: can''t request version "latest" of the main module \(m\)'
+stderr '^go mod download: m@latest: malformed module path "m": missing dot in first path element$'
 
 # download updates go.mod and populates go.sum
 cd update
index eeaa92d8ca52d4dfffa54d531d89522f57602a89..50b2fee9ae1bfd82cd66feecfd420a324c5a10f7 100644 (file)
@@ -30,10 +30,14 @@ grep 'rsc.io/quote v1.5.1' go.mod
 
 
 # The main module cannot be updated to a specific version.
+! go get -d rsc.io@v0.1.0
+stderr '^go get: can''t request version "v0.1.0" of the main module \(rsc.io\)$'
+
+# A package in the main module can't be upgraded either.
 ! go get -d rsc.io/x@v0.1.0
 stderr '^go get: package rsc.io/x is in the main module, so can''t request version v0.1.0$'
 
-# The main module cannot be updated to @latest, which is a specific version.
+# Nor can a pattern matching packages in the main module.
 ! go get -d rsc.io/x/...@latest
 stderr '^go get: pattern rsc.io/x/... matches package rsc.io/x in the main module, so can''t request version latest$'
 
diff --git a/src/cmd/go/testdata/script/mod_query_main.txt b/src/cmd/go/testdata/script/mod_query_main.txt
new file mode 100644 (file)
index 0000000..39e5841
--- /dev/null
@@ -0,0 +1,43 @@
+# 'go mod download' can download specific versions of the main module.
+go mod download rsc.io/quote@5d9f230b
+go mod download rsc.io/quote@v1.5.2
+go mod download rsc.io/quote@latest
+
+# 'go mod download' will not download @upgrade or @patch, since they always
+# resolve to the main module.
+go mod download rsc.io/quote@upgrade
+stderr '^go mod download: skipping argument rsc.io/quote@upgrade that resolves to the main module$'
+go mod download rsc.io/quote@patch
+stderr '^go mod download: skipping argument rsc.io/quote@patch that resolves to the main module$'
+
+# 'go list -m' can show a version of the main module.
+go list -m rsc.io/quote@5d9f230b
+stdout '^rsc.io/quote v0.0.0-20180710144737-5d9f230bcfba$'
+go list -m rsc.io/quote@v1.5.2
+stdout '^rsc.io/quote v1.5.2$'
+go list -m rsc.io/quote@latest
+stdout '^rsc.io/quote v1.5.2$'
+
+# 'go list -m -versions' shows available versions.
+go list -m -versions rsc.io/quote
+stdout '^rsc.io/quote.*v1.5.2'
+
+# 'go list -m' resolves @upgrade and @patch to the main module.
+go list -m rsc.io/quote@upgrade
+stdout '^rsc.io/quote$'
+go list -m rsc.io/quote@patch
+stdout '^rsc.io/quote$'
+
+# 'go get' will not attempt to upgrade the main module to any specific version.
+# See also: mod_get_main.txt.
+! go get rsc.io/quote@5d9f230b
+stderr '^go get: can''t request version "5d9f230b" of the main module \(rsc.io/quote\)$'
+! go get rsc.io/quote@v1.5.2
+stderr '^go get: can''t request version "v1.5.2" of the main module \(rsc.io/quote\)$'
+! go get rsc.io/quote@latest
+stderr '^go get: can''t request version "latest" of the main module \(rsc.io/quote\)$'
+
+-- go.mod --
+module rsc.io/quote
+
+go 1.16