cmd/go: in workspace mode, resolve replacements relative to their go.mod files

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>
This commit is contained in:
Bryan C. Mills 2022-02-15 14:23:45 -05:00 коммит произвёл Bryan Mills
Родитель 08ed4882aa
Коммит d199ceffa8
3 изменённых файлов: 77 добавлений и 6 удалений

Просмотреть файл

@ -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 {

57
src/cmd/go/testdata/script/work_issue51204.txt поставляемый Normal file
Просмотреть файл

@ -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()
}

Просмотреть файл

@ -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