# This test illustrates a case where downgrading one module may upgrade another. # Compare to the downcross1 test case in cmd/go/internal/mvs/mvs_test.go. # The package import graph used in this test looks like: # # a ---- b # \ \ # \ \ # ----- c ---- d # # The module dependency graph originally looks like: # # a ---- b.2 # \ \ # \ \ # ----- c.1 ---- d.2 # # b.1 ---- c.2 # # If we downgrade module d to version 1, we must downgrade b as well. # If that downgrade selects b version 1, we will upgrade module c to version 2. cp go.mod go.mod.orig go mod tidy cmp go.mod.orig go.mod # Downgrading d to version 1 downgrades b, which upgrades c. go get example.com/d@v0.1.0 go list -m all stdout '^example.com/b v0.1.0 ' stdout '^example.com/c v0.2.0 ' stdout '^example.com/d v0.1.0 ' cmp go.mod go.mod.down1 # Restoring c to version 1 upgrades d to meet c's requirements. go get example.com/c@v0.1.0 go list -m all ! stdout '^example.com/b ' stdout '^example.com/c v0.1.0 ' stdout '^example.com/d v0.2.0 ' cmp go.mod go.mod.down2 # If a user explicitly requests the incompatible versions together, # 'go get' should explain why they are not compatible. ! go get example.com/c@v0.1.0 example.com/d@v0.1.0 stderr '^go: example\.com/c@v0\.1\.0 requires example\.com/d@v0\.2\.0, not example\.com/d@v0\.1\.0' -- go.mod -- module example.com/a go 1.15 require ( example.com/b v0.2.0 example.com/c v0.1.0 ) replace ( example.com/b v0.1.0 => ./b1 example.com/b v0.2.0 => ./b2 example.com/c v0.1.0 => ./c1 example.com/c v0.2.0 => ./c2 example.com/d v0.1.0 => ./d example.com/d v0.2.0 => ./d ) -- go.mod.down1 -- module example.com/a go 1.15 require ( example.com/b v0.1.0 example.com/c v0.2.0 example.com/d v0.1.0 // indirect ) replace ( example.com/b v0.1.0 => ./b1 example.com/b v0.2.0 => ./b2 example.com/c v0.1.0 => ./c1 example.com/c v0.2.0 => ./c2 example.com/d v0.1.0 => ./d example.com/d v0.2.0 => ./d ) -- go.mod.down2 -- module example.com/a go 1.15 require example.com/c v0.1.0 replace ( example.com/b v0.1.0 => ./b1 example.com/b v0.2.0 => ./b2 example.com/c v0.1.0 => ./c1 example.com/c v0.2.0 => ./c2 example.com/d v0.1.0 => ./d example.com/d v0.2.0 => ./d ) -- a.go -- package a import ( _ "example.com/b" _ "example.com/c" ) -- b1/go.mod -- module example.com/b go 1.15 require example.com/c v0.2.0 -- b1/b.go -- package b import _ "example.com/c" -- b2/go.mod -- module example.com/b go 1.15 require example.com/c v0.1.0 -- b2/b.go -- package b import _ "example.com/c" -- c1/go.mod -- module example.com/c go 1.15 require example.com/d v0.2.0 -- c1/c.go -- package c -- c2/go.mod -- module example.com/c go 1.15 -- c2/c.go -- package c -- d/go.mod -- module example.com/d go 1.15