env GO111MODULE=on # 'go list' should not add requirements even if they can be resolved locally. cp go.mod go.mod.orig ! go list all cmp go.mod go.mod.orig # 'go list' should resolve imports using replacements. go get go list all stdout 'example.com/a/b$' stdout 'example.com/x/v3$' stdout 'example.com/y/z/w$' stdout 'example.com/v' # The selected modules should prefer longer paths, # but should try shorter paths if needed. # Modules with a major-version suffix should have a corresponding pseudo-version. # Replacements that specify a version should use the latest such version. go list -m all stdout 'example.com/a/b v0.0.0-00010101000000-000000000000 => ./b' stdout 'example.com/y v0.0.0-00010101000000-000000000000 => ./y' stdout 'example.com/x/v3 v3.0.0-00010101000000-000000000000 => ./v3' stdout 'example.com/v v1.12.0 => ./v12' # The go command should print an informative error when the matched # module does not contain a package. # TODO(#26909): Ideally these errors should include line numbers for the imports within the main module. cd fail ! go mod tidy stderr '^localhost.fail imports\n\tw: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' stderr '^localhost.fail imports\n\tnonexist: nonexist@v0.1.0: replacement directory ../nonexist does not exist$' -- go.mod -- module example.com/m replace ( example.com/a => ./a example.com/a/b => ./b ) replace ( example.com/x => ./x example.com/x/v3 => ./v3 ) replace ( example.com/y/z/w => ./w example.com/y => ./y ) replace ( example.com/v v1.11.0 => ./v11 example.com/v v1.12.0 => ./v12 example.com/v => ./v ) replace ( example.com/i v2.0.0+incompatible => ./i2 ) -- m.go -- package main import ( _ "example.com/a/b" _ "example.com/x/v3" _ "example.com/y/z/w" _ "example.com/v" _ "example.com/i" ) func main() {} -- a/go.mod -- module a.localhost -- a/a.go -- package a -- a/b/b.go-- package b -- b/go.mod -- module a.localhost/b -- b/b.go -- package b -- x/go.mod -- module x.localhost -- x/x.go -- package x -- x/v3.go -- package v3 import _ "x.localhost/v3" -- v3/go.mod -- module x.localhost/v3 -- v3/x.go -- package x -- w/go.mod -- module w.localhost -- w/skip/skip.go -- // Package skip is nested below nonexistent package w. package skip -- y/go.mod -- module y.localhost -- y/z/w/w.go -- package w -- v12/go.mod -- module v.localhost -- v12/v.go -- package v -- v11/go.mod -- module v.localhost -- v11/v.go -- package v -- v/go.mod -- module v.localhost -- v/v.go -- package v -- i2/go.mod -- module example.com/i -- i2/i.go -- package i -- fail/m.go -- package main import ( _ "w" _ "nonexist" ) func main() {} -- fail/go.mod -- module localhost.fail replace w => ../w replace nonexist v0.1.0 => ../nonexist