# https://golang.org/issue/45094: 'go mod tidy' now accepts a '-go' flag # to change the language version in use. # # The package import graph used in this test looks like: # # m --- a --- b # | # b_test --- c # | # c_test --- d # # The module diagram looks like: # # m --- a --- b # | # + --- c # | # + --- d # # Module b omits its dependency on c, and module c omits its dependency on d. # # In go 1.15, the tidy main module must require a (because it is direct), # c (because it is a missing test dependency of an imported package), # and d (because it is a missing transitive test dependency). # # In go 1.16, the tidy main module can omit d because it is no longer # included in "all". # # In go 1.17, the main module must explicitly require b # (because it is transitively imported by the main module). cp go.mod go.mod.orig # An invalid argument should be rejected. ! go mod tidy -go=bananas stderr '^invalid value "bananas" for flag -go: expecting a Go version like "'$goversion'"$' cmp go.mod go.mod.orig ! go mod tidy -go=0.9 stderr '^invalid value "0.9" for flag -go: expecting a Go version like "'$goversion'"$' ! go mod tidy -go=2000.0 stderr '^invalid value "2000.0" for flag -go: maximum supported Go version is '$goversion'$' # Supported versions should change the go.mod file to be tidy according to the # indicated version. go mod tidy -go=1.15 cmp go.mod go.mod.115 go mod tidy cmp go.mod go.mod.115 go mod tidy -go=1.16 cmp go.mod go.mod.116 go mod tidy cmp go.mod go.mod.116 go mod tidy -go=1.17 cmp go.mod go.mod.117 go mod tidy cmp go.mod go.mod.117 # If we downgrade back to 1.15, we should re-resolve d to v0.2.0 instead # of the original v0.1.0 (because the original requirement is lost). go mod tidy -go=1.15 cmp go.mod go.mod.115-2 # -go= (with an empty argument) maintains the existing version or adds the # default version (just like omitting the flag). go mod tidy -go='' cmp go.mod go.mod.115-2 cp go.mod.orig go.mod go mod tidy -go='' cmpenv go.mod go.mod.latest -- go.mod -- module example.com/m require example.net/a v0.1.0 require ( example.net/c v0.1.0 // indirect example.net/d v0.1.0 // indirect ) replace ( example.net/a v0.1.0 => ./a example.net/a v0.2.0 => ./a example.net/b v0.1.0 => ./b example.net/b v0.2.0 => ./b example.net/c v0.1.0 => ./c example.net/c v0.2.0 => ./c example.net/d v0.1.0 => ./d example.net/d v0.2.0 => ./d ) -- m.go -- package m import _ "example.net/a" -- go.mod.115 -- module example.com/m go 1.15 require example.net/a v0.1.0 require ( example.net/c v0.1.0 // indirect example.net/d v0.1.0 // indirect ) replace ( example.net/a v0.1.0 => ./a example.net/a v0.2.0 => ./a example.net/b v0.1.0 => ./b example.net/b v0.2.0 => ./b example.net/c v0.1.0 => ./c example.net/c v0.2.0 => ./c example.net/d v0.1.0 => ./d example.net/d v0.2.0 => ./d ) -- go.mod.115-2 -- module example.com/m go 1.15 require example.net/a v0.1.0 require ( example.net/c v0.1.0 // indirect example.net/d v0.2.0 // indirect ) replace ( example.net/a v0.1.0 => ./a example.net/a v0.2.0 => ./a example.net/b v0.1.0 => ./b example.net/b v0.2.0 => ./b example.net/c v0.1.0 => ./c example.net/c v0.2.0 => ./c example.net/d v0.1.0 => ./d example.net/d v0.2.0 => ./d ) -- go.mod.116 -- module example.com/m go 1.16 require example.net/a v0.1.0 require example.net/c v0.1.0 // indirect replace ( example.net/a v0.1.0 => ./a example.net/a v0.2.0 => ./a example.net/b v0.1.0 => ./b example.net/b v0.2.0 => ./b example.net/c v0.1.0 => ./c example.net/c v0.2.0 => ./c example.net/d v0.1.0 => ./d example.net/d v0.2.0 => ./d ) -- go.mod.117 -- module example.com/m go 1.17 require example.net/a v0.1.0 require ( example.net/b v0.1.0 // indirect example.net/c v0.1.0 // indirect ) replace ( example.net/a v0.1.0 => ./a example.net/a v0.2.0 => ./a example.net/b v0.1.0 => ./b example.net/b v0.2.0 => ./b example.net/c v0.1.0 => ./c example.net/c v0.2.0 => ./c example.net/d v0.1.0 => ./d example.net/d v0.2.0 => ./d ) -- go.mod.latest -- module example.com/m go $goversion require example.net/a v0.1.0 require ( example.net/b v0.1.0 // indirect example.net/c v0.1.0 // indirect ) replace ( example.net/a v0.1.0 => ./a example.net/a v0.2.0 => ./a example.net/b v0.1.0 => ./b example.net/b v0.2.0 => ./b example.net/c v0.1.0 => ./c example.net/c v0.2.0 => ./c example.net/d v0.1.0 => ./d example.net/d v0.2.0 => ./d ) -- a/go.mod -- module example.net/a go 1.15 require example.net/b v0.1.0 -- a/a.go -- package a import _ "example.net/b" -- b/go.mod -- module example.net/b go 1.15 -- b/b.go -- package b -- b/b_test.go -- package b_test import _ "example.net/c" -- c/go.mod -- module example.net/c go 1.15 -- c/c.go -- package c -- c/c_test.go -- package c_test import _ "example.net/d" -- d/go.mod -- module example.net/d go 1.15 -- d/d.go -- package d