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 '^go: localhost.fail imports\n\tw: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$'
stderr '^go: 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
