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")
}
}
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 != "" {
} else {
for _, m := range mods {
if m.Error != "" {
- base.Errorf("%s", m.Error)
+ base.Errorf("go mod download: %v", m.Error)
}
}
base.ExitIfErrors()
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)
}
}
}
+ var queryMatchesMainModule bool
if HasModRoot() {
m := match(Target, modRoot, true)
if len(m.Pkgs) > 0 {
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,
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 {
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
}
# 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"'
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
# 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$'
--- /dev/null
+# '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