}
opts.AllowPackage = func(ctx context.Context, path string, m module.Version) error {
- if m.Path == "" || m.Version == "" && modload.MainModules.Contains(m.Path) {
+ if m.Path == "" || m.Version == "" {
// Packages in the standard library and main modules are already at their
// latest (and only) available versions.
return nil
pruning modPruning
// rootModules is the set of root modules of the graph, sorted and capped to
- // length. It may contain duplicates, and may contain multiple versions for a
+ // length. It may contain duplicates, and may contain multiple versions for a
// given module path. The root modules of the groph are the set of main
// modules in workspace mode, and the main module's direct requirements
// outside workspace mode.
// requirements.
var rootPaths []string
for _, m := range mustSelect {
- if !MainModules.Contains(m.Path) && m.Version != "none" {
+ if m.Version != "none" && !MainModules.Contains(m.Path) {
rootPaths = append(rootPaths, m.Path)
}
}
if err != nil {
return nil, false, err
}
- initial = mg.BuildList()[1:]
+ initial = mg.BuildList()[MainModules.Len():]
} else {
initial = rs.rootModules
}
break
}
if changed {
- // Don't resolve missing imports until the module graph have stabilized.
+ // Don't resolve missing imports until the module graph has stabilized.
// If the roots are still changing, they may turn out to specify a
// requirement on the missing package(s), and we would rather use a
// version specified by a new root than add a new dependency on an
}
func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
- if MainModules.Contains(mod.Path) {
+ if mod.Version == "" && MainModules.Contains(mod.Path) {
// Use the build list as it existed when r was constructed, not the current
// global build list.
return r.roots, nil
// previousVersion returns the tagged version of m.Path immediately prior to
// m.Version, or version "none" if no prior version is tagged.
//
-// Since the version of Target is not found in the version list,
+// Since the version of a main module is not found in the version list,
// it has no previous version.
func previousVersion(m module.Version) (module.Version, error) {
// TODO(golang.org/issue/38714): thread tracing context through MVS.
- if MainModules.Contains(m.Path) {
+ if m.Version == "" && MainModules.Contains(m.Path) {
return module.Version{Path: m.Path, Version: "none"}, nil
}
--- /dev/null
+# Regression test for https://golang.org/issue/48511:
+# requirement minimization was accidentally replacing previous
+# versions of the main module, causing dependencies to be
+# spuriously dropping during requirement minimization and
+# leading to an infinite loop.
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod go.mod.orig
+
+go get -u=patch ./...
+cmp go.mod go.mod.want
+
+-- go.mod --
+module example.net/m
+
+go 1.16
+
+replace (
+ example.net/a v0.1.0 => ./a
+ example.net/b v0.1.0 => ./b
+ example.net/b v0.1.1 => ./b
+ example.net/m v0.1.0 => ./m1
+)
+
+require example.net/a v0.1.0
+-- go.mod.want --
+module example.net/m
+
+go 1.16
+
+replace (
+ example.net/a v0.1.0 => ./a
+ example.net/b v0.1.0 => ./b
+ example.net/b v0.1.1 => ./b
+ example.net/m v0.1.0 => ./m1
+)
+
+require (
+ example.net/a v0.1.0
+ example.net/b v0.1.1 // indirect
+)
+-- m.go --
+package m
+
+import "example.net/a"
+-- m1/go.mod --
+module example.net/m
+
+go 1.16
+
+require example.net/b v0.1.0
+-- a/go.mod --
+module example.net/a
+
+go 1.16
+
+require example.net/m v0.1.0
+-- a/a.go --
+package a
+
+import "example.net/b"
+-- b/go.mod --
+module example.net/b
+
+go 1.16
+-- b/b.go --
+package b