]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: in workspace mode, resolve replacements relative to their go.mod files
authorBryan C. Mills <bcmills@google.com>
Tue, 15 Feb 2022 19:23:45 +0000 (14:23 -0500)
committerBryan Mills <bcmills@google.com>
Tue, 15 Feb 2022 22:28:43 +0000 (22:28 +0000)
Fixes #51204

Change-Id: I41106b7d04120be5ba68573bd25fd33e985688de
Reviewed-on: https://go-review.googlesource.com/c/go/+/385994
Trust: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/go/internal/modload/init.go
src/cmd/go/testdata/script/work_issue51204.txt [new file with mode: 0644]
src/cmd/go/testdata/script/work_replace_conflict.txt

index e5de101ed6bdac403309e3597ad6ff6eb15ffa4b..523be8c473f97dc3ade1c1aef43af0c2fef24f46 100644 (file)
@@ -1033,11 +1033,25 @@ func makeMainModules(ms []module.Version, rootDirs []string, modFiles []*modfile
                        for _, r := range modFiles[i].Replace {
                                if replacedByWorkFile[r.Old.Path] {
                                        continue
-                               } else if prev, ok := replacements[r.Old]; ok && !curModuleReplaces[r.Old] && prev != r.New {
-                                       base.Fatalf("go: conflicting replacements for %v:\n\t%v\n\t%v\nuse \"go work edit -replace %v=[override]\" to resolve", r.Old, prev, r.New, r.Old)
+                               }
+                               var newV module.Version = r.New
+                               if WorkFilePath() != "" && newV.Version == "" && !filepath.IsAbs(newV.Path) {
+                                       // Since we are in a workspace, we may be loading replacements from
+                                       // multiple go.mod files. Relative paths in those replacement are
+                                       // relative to the go.mod file, not the workspace, so the same string
+                                       // may refer to two different paths and different strings may refer to
+                                       // the same path. Convert them all to be absolute instead.
+                                       //
+                                       // (We could do this outside of a workspace too, but it would mean that
+                                       // replacement paths in error strings needlessly differ from what's in
+                                       // the go.mod file.)
+                                       newV.Path = filepath.Join(rootDirs[i], newV.Path)
+                               }
+                               if prev, ok := replacements[r.Old]; ok && !curModuleReplaces[r.Old] && prev != newV {
+                                       base.Fatalf("go: conflicting replacements for %v:\n\t%v\n\t%v\nuse \"go work edit -replace %v=[override]\" to resolve", r.Old, prev, newV, r.Old)
                                }
                                curModuleReplaces[r.Old] = true
-                               replacements[r.Old] = r.New
+                               replacements[r.Old] = newV
 
                                v, ok := mainModules.highestReplaced[r.Old.Path]
                                if !ok || semver.Compare(r.Old.Version, v) > 0 {
diff --git a/src/cmd/go/testdata/script/work_issue51204.txt b/src/cmd/go/testdata/script/work_issue51204.txt
new file mode 100644 (file)
index 0000000..d483002
--- /dev/null
@@ -0,0 +1,57 @@
+go work sync
+
+go list -f '{{.Dir}}' example.com/test
+stdout '^'$PWD${/}test'$'
+
+-- go.work --
+go 1.18
+
+use (
+       ./test2
+       ./test2/sub
+)
+-- test/go.mod --
+module example.com/test
+
+go 1.18
+-- test/file.go --
+package test
+
+func DoSomething() {
+}
+-- test2/go.mod --
+module example.com/test2
+
+go 1.18
+
+replace example.com/test => ../test
+
+require example.com/test v0.0.0-00010101000000-000000000000
+-- test2/file.go --
+package test2
+
+import (
+       "example.com/test"
+)
+
+func DoSomething() {
+       test.DoSomething()
+}
+-- test2/sub/go.mod --
+module example.com/test2/sub
+
+go 1.18
+
+replace example.com/test => ../../test
+
+require example.com/test v0.0.0
+-- test2/sub/file.go --
+package test2
+
+import (
+       "example.com/test"
+)
+
+func DoSomething() {
+       test.DoSomething()
+}
index 81d1fcb04356b1902974a1cd3cefd42eca89439f..7b71b0fbd78cfa8148bc64cebd145b8520e09900 100644 (file)
@@ -2,7 +2,7 @@
 # overriding it in the go.work file.
 
 ! go list -m example.com/dep
-stderr 'go: conflicting replacements for example.com/dep@v1.0.0:\n\t./dep1\n\t./dep2\nuse "go work edit -replace example.com/dep@v1.0.0=\[override\]" to resolve'
+stderr 'go: conflicting replacements for example.com/dep@v1.0.0:\n\t'$PWD${/}'dep1\n\t'$PWD${/}'dep2\nuse "go work edit -replace example.com/dep@v1.0.0=\[override\]" to resolve'
 go work edit -replace example.com/dep@v1.0.0=./dep1
 go list -m example.com/dep
 stdout 'example.com/dep v1.0.0 => ./dep1'
@@ -15,7 +15,7 @@ use n
 module example.com/m
 
 require example.com/dep v1.0.0
-replace example.com/dep v1.0.0 => ./dep1
+replace example.com/dep v1.0.0 => ../dep1
 -- m/m.go --
 package m
 
@@ -28,7 +28,7 @@ func F() {
 module example.com/n
 
 require example.com/dep v1.0.0
-replace example.com/dep v1.0.0 => ./dep2
+replace example.com/dep v1.0.0 => ../dep2
 -- n/n.go --
 package n