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 {
--- /dev/null
+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()
+}
# 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'
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
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