diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /src/cmd/go/testdata/script | |
parent | Initial commit. (diff) | |
download | golang-1.16-upstream.tar.xz golang-1.16-upstream.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/go/testdata/script')
519 files changed, 26097 insertions, 0 deletions
diff --git a/src/cmd/go/testdata/script/README b/src/cmd/go/testdata/script/README new file mode 100644 index 0000000..d658ceb --- /dev/null +++ b/src/cmd/go/testdata/script/README @@ -0,0 +1,310 @@ +This directory holds test scripts *.txt run during 'go test cmd/go'. +To run a specific script foo.txt + + go test cmd/go -run=Script/^foo$ + +In general script files should have short names: a few words, not whole sentences. +The first word should be the general category of behavior being tested, +often the name of a go subcommand (list, build, test, ...) or concept (vendor, pattern). + +Each script is a text archive (go doc cmd/go/internal/txtar). +The script begins with an actual command script to run +followed by the content of zero or more supporting files to +create in the script's temporary file system before it starts executing. + +As an example, run_hello.txt says: + + # hello world + go run hello.go + stderr 'hello world' + ! stdout . + + -- hello.go -- + package main + func main() { println("hello world") } + +Each script runs in a fresh temporary work directory tree, available to scripts as $WORK. +Scripts also have access to these other environment variables: + + GOARCH=<target GOARCH> + GOCACHE=<actual GOCACHE being used outside the test> + GOEXE=<executable file suffix: .exe on Windows, empty on other systems> + GOEXPSTRING=<value of objabi.Expstring(), from GOEXPERIMENT when toolchain built> + GOOS=<target GOOS> + GOPATH=$WORK/gopath + GOPROXY=<local module proxy serving from cmd/go/testdata/mod> + GOROOT=<actual GOROOT> + GOROOT_FINAL=<actual GOROOT_FINAL> + TESTGO_GOROOT=<GOROOT used to build cmd/go, for use in tests that may change GOROOT> + HOME=/no-home + PATH=<actual PATH> + TMPDIR=$WORK/tmp + GODEBUG=<actual GODEBUG> + devnull=<value of os.DevNull> + goversion=<current Go version; for example, 1.12> + :=<OS-specific path list separator> + +The scripts' supporting files are unpacked relative to $GOPATH/src (aka $WORK/gopath/src) +and then the script begins execution in that directory as well. Thus the example above runs +in $WORK/gopath/src with GOPATH=$WORK/gopath and $WORK/gopath/src/hello.go +containing the listed contents. + +The lines at the top of the script are a sequence of commands to be executed +by a tiny script engine in ../../script_test.go (not the system shell). +The script stops and the overall test fails if any particular command fails. + +Each line is parsed into a sequence of space-separated command words, +with environment variable expansion and # marking an end-of-line comment. +Adding single quotes around text keeps spaces in that text from being treated +as word separators and also disables environment variable expansion. +Inside a single-quoted block of text, a repeated single quote indicates +a literal single quote, as in: + + 'Don''t communicate by sharing memory.' + +A line beginning with # is a comment and conventionally explains what is +being done or tested at the start of a new phase in the script. + +The command prefix ! indicates that the command on the rest of the line +(typically go or a matching predicate) must fail, not succeed. Only certain +commands support this prefix. They are indicated below by [!] in the synopsis. + +The command prefix ? indicates that the command on the rest of the line +may or may not succeed, but the test should continue regardless. +Commands that support this prefix are indicated by [?]. + +The command prefix [cond] indicates that the command on the rest of the line +should only run when the condition is satisfied. The available conditions are: + + - GOOS and GOARCH values, like [386], [windows], and so on. + - Compiler names, like [gccgo], [gc]. + - Test environment details: + - [short] for testing.Short() + - [cgo], [msan], [race] for whether cgo, msan, and the race detector can be used + - [net] for whether the external network can be used + - [link] for testenv.HasLink() + - [root] for os.Geteuid() == 0 + - [symlink] for testenv.HasSymlink() + - [case-sensitive] for whether the file system is case-sensitive + - [exec:prog] for whether prog is available for execution (found by exec.LookPath) + - [GODEBUG:value] for whether value is one of the comma-separated entries in the GODEBUG variable + - [buildmode:value] for whether -buildmode=value is supported + +A condition can be negated: [!short] means to run the rest of the line +when testing.Short() is false. Multiple conditions may be given for a single +command, for example, '[linux] [amd64] skip'. The command will run if all conditions +are satisfied. + +The commands are: + +- [! | ?] cc args... [&] + Run the C compiler, the platform specific flags (i.e. `go env GOGCCFLAGS`) will be + added automatically before args. + +- cd dir + Change to the given directory for future commands. + +- chmod perm path... + Change the permissions of the files or directories named by the path arguments + to be equal to perm. Only numerical permissions are supported. + +- cmp file1 file2 + Check that the named files have the same content. + By convention, file1 is the actual data and file2 the expected data. + File1 can be "stdout" or "stderr" to use the standard output or standard error + from the most recent exec or go command. + (If the files have differing content, the failure prints a diff.) + +- cmpenv file1 file2 + Like cmp, but environment variables are substituted in the file contents + before the comparison. For example, $GOOS is replaced by the target GOOS. + +- [! | ?] cp src... dst + Copy the listed files to the target file or existing directory. + src can include "stdout" or "stderr" to use the standard output or standard error + from the most recent exec or go command. + +- env [-r] [key=value...] + With no arguments, print the environment to stdout + (useful for debugging and for verifying initial state). + Otherwise add the listed key=value pairs to the environment. + The -r flag causes the values to be escaped using regexp.QuoteMeta + before being recorded. + +- [! | ?] exec program [args...] [&] + Run the given executable program with the arguments. + It must (or must not) succeed. + Note that 'exec' does not terminate the script (unlike in Unix shells). + + If the last token is '&', the program executes in the background. The standard + output and standard error of the previous command is cleared, but the output + of the background process is buffered — and checking of its exit status is + delayed — until the next call to 'wait', 'skip', or 'stop' or the end of the + test. If any background processes remain at the end of the test, they + are terminated using os.Interrupt (if supported) or os.Kill and the test + must not depend upon their exit status. + +- [!] exists [-readonly] [-exec] file... + Each of the listed files or directories must (or must not) exist. + If -readonly is given, the files or directories must be unwritable. + If -exec is given, the files or directories must be executable. + +- [! | ?] go args... [&] + Run the (test copy of the) go command with the given arguments. + It must (or must not) succeed. + +- [!] grep [-count=N] [-q] pattern file + The file's content must (or must not) match the regular expression pattern. + For positive matches, -count=N specifies an exact number of matches to require. + The -q flag disables printing the file content on a mismatch. + +- mkdir path... + Create the listed directories, if they do not already exists. + +- rm file... + Remove the listed files or directories. + +- skip [message] + Mark the test skipped, including the message if given. + +- [!] stale path... + The packages named by the path arguments must (or must not) + be reported as "stale" by the go command. + +- [!] stderr [-count=N] pattern + Apply the grep command (see above) to the standard error + from the most recent exec, go, or wait command. + +- [!] stdout [-count=N] pattern + Apply the grep command (see above) to the standard output + from the most recent exec, go, wait, or env command. + +- stop [message] + Stop the test early (marking it as passing), including the message if given. + +- symlink file -> target + Create file as a symlink to target. The -> (like in ls -l output) is required. + +- wait + Wait for all 'exec' and 'go' commands started in the background (with the '&' + token) to exit, and display success or failure status for them. + After a call to wait, the 'stderr' and 'stdout' commands will apply to the + concatenation of the corresponding streams of the background commands, + in the order in which those commands were started. + +When TestScript runs a script and the script fails, by default TestScript shows +the execution of the most recent phase of the script (since the last # comment) +and only shows the # comments for earlier phases. For example, here is a +multi-phase script with a bug in it: + + # GOPATH with p1 in d2, p2 in d2 + env GOPATH=$WORK/d1${:}$WORK/d2 + + # build & install p1 + env + go install -i p1 + ! stale p1 + ! stale p2 + + # modify p2 - p1 should appear stale + cp $WORK/p2x.go $WORK/d2/src/p2/p2.go + stale p1 p2 + + # build & install p1 again + go install -i p11 + ! stale p1 + ! stale p2 + + -- $WORK/d1/src/p1/p1.go -- + package p1 + import "p2" + func F() { p2.F() } + -- $WORK/d2/src/p2/p2.go -- + package p2 + func F() {} + -- $WORK/p2x.go -- + package p2 + func F() {} + func G() {} + +The bug is that the final phase installs p11 instead of p1. The test failure looks like: + + $ go test -run=Script + --- FAIL: TestScript (3.75s) + --- FAIL: TestScript/install_rebuild_gopath (0.16s) + script_test.go:223: + # GOPATH with p1 in d2, p2 in d2 (0.000s) + # build & install p1 (0.087s) + # modify p2 - p1 should appear stale (0.029s) + # build & install p1 again (0.022s) + > go install -i p11 + [stderr] + can't load package: package p11: cannot find package "p11" in any of: + /Users/rsc/go/src/p11 (from $GOROOT) + $WORK/d1/src/p11 (from $GOPATH) + $WORK/d2/src/p11 + [exit status 1] + FAIL: unexpected go command failure + + script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src + + FAIL + exit status 1 + FAIL cmd/go 4.875s + $ + +Note that the commands in earlier phases have been hidden, so that the relevant +commands are more easily found, and the elapsed time for a completed phase +is shown next to the phase heading. To see the entire execution, use "go test -v", +which also adds an initial environment dump to the beginning of the log. + +Note also that in reported output, the actual name of the per-script temporary directory +has been consistently replaced with the literal string $WORK. + +The cmd/go test flag -testwork (which must appear on the "go test" command line after +standard test flags) causes each test to log the name of its $WORK directory and other +environment variable settings and also to leave that directory behind when it exits, +for manual debugging of failing tests: + + $ go test -run=Script -work + --- FAIL: TestScript (3.75s) + --- FAIL: TestScript/install_rebuild_gopath (0.16s) + script_test.go:223: + WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath + GOARCH= + GOCACHE=/Users/rsc/Library/Caches/go-build + GOOS= + GOPATH=$WORK/gopath + GOROOT=/Users/rsc/go + HOME=/no-home + TMPDIR=$WORK/tmp + exe= + + # GOPATH with p1 in d2, p2 in d2 (0.000s) + # build & install p1 (0.085s) + # modify p2 - p1 should appear stale (0.030s) + # build & install p1 again (0.019s) + > go install -i p11 + [stderr] + can't load package: package p11: cannot find package "p11" in any of: + /Users/rsc/go/src/p11 (from $GOROOT) + $WORK/d1/src/p11 (from $GOPATH) + $WORK/d2/src/p11 + [exit status 1] + FAIL: unexpected go command failure + + script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src + + FAIL + exit status 1 + FAIL cmd/go 4.875s + $ + + $ WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath + $ cd $WORK/d1/src/p1 + $ cat p1.go + package p1 + import "p2" + func F() { p2.F() } + $ + diff --git a/src/cmd/go/testdata/script/bug.txt b/src/cmd/go/testdata/script/bug.txt new file mode 100644 index 0000000..b9bbaaa --- /dev/null +++ b/src/cmd/go/testdata/script/bug.txt @@ -0,0 +1,46 @@ +# Verify that go bug creates the appropriate URL issue body + +[!linux] skip + +go install +env BROWSER=$GOPATH/bin/browser +go bug +exists $TMPDIR/browser +grep '^go version' $TMPDIR/browser +grep '^GOROOT/bin/go version: go version' $TMPDIR/browser +grep '^GOROOT/bin/go tool compile -V: compile version' $TMPDIR/browser +grep '^uname -sr: Linux' $TMPDIR/browser + +-- go.mod -- +module browser + +-- main.go -- +package main + +import ( + "fmt" + "net/url" + "os" + "path/filepath" +) + +func main() { + u, err := url.Parse(os.Args[1]) + if err != nil { + panic(err) + } + body, err := url.PathUnescape(u.Query().Get("body")) + if err != nil { + panic(err) + } + out := filepath.Join(os.TempDir(), "browser") + f, err := os.Create(out) + if err != nil { + panic(err) + } + fmt.Fprintln(f, body) + if err := f.Close(); err != nil { + panic(err) + } +} + diff --git a/src/cmd/go/testdata/script/build_GOTMPDIR.txt b/src/cmd/go/testdata/script/build_GOTMPDIR.txt new file mode 100644 index 0000000..1073517 --- /dev/null +++ b/src/cmd/go/testdata/script/build_GOTMPDIR.txt @@ -0,0 +1,50 @@ +# Set GOCACHE to a clean directory to ensure that 'go build' has work to report. +[!windows] env GOCACHE=$WORK/gocache +[windows] env GOCACHE=$WORK\gocache + +# 'go build' should use GOTMPDIR if set. +[!windows] env GOTMPDIR=$WORK/my-favorite-tmpdir +[windows] env GOTMPDIR=$WORK\my-favorite-tmpdir +mkdir $GOTMPDIR +go build -x hello.go +stderr ^WORK=.*my-favorite-tmpdir + +# Make GOTMPDIR a regular file. This prevents the creation of work directories, +# so we can check that certain commands don't create them. +# This simulates running on a full disk or a read-only volume. +rm $GOTMPDIR +cp hello.go $GOTMPDIR # any file will do + +# 'go build' should fail if GOTMPDIR is read-only. +! go build -x . +stderr '^go: creating work dir: \w+ '$GOTMPDIR + +# 'go list' should only fail if it needs to build something. +go list -x . +! stderr 'creating work dir' +stdout m +go list -m all +stdout m +! go list -x -export . +stderr '^go: creating work dir: \w+ '$GOTMPDIR + +# 'go clean -cache' and 'go clean -modcache' should not fail. +go clean -x -cache +! stderr 'creating work dir' +go clean -x -modcache +! stderr 'creating work dir' + +# 'go env' should not fail for specific variables. +# Without arguments, it needs to initialize a builder to load cgo flags, and +# that uses a temporary directory. +! go env +stderr '^go: creating work dir: \w+ '$GOTMPDIR +go env GOROOT + +-- go.mod -- +module m + +go 1.15 +-- hello.go -- +package main +func main() { println("hello") } diff --git a/src/cmd/go/testdata/script/build_acl_windows.txt b/src/cmd/go/testdata/script/build_acl_windows.txt new file mode 100644 index 0000000..13a3ba2 --- /dev/null +++ b/src/cmd/go/testdata/script/build_acl_windows.txt @@ -0,0 +1,44 @@ +[!windows] stop +[!exec:icacls] skip +[!exec:powershell] skip + +# Create $WORK\guest and give the Guests group full access. +# Files created within that directory will have different security attributes by default. +mkdir $WORK\guest +exec icacls $WORK\guest /grant '*S-1-5-32-546:(oi)(ci)f' + +env TMP=$WORK\guest +env TEMP=$WORK\guest + +# Build a binary using the guest directory as an intermediate +cd TestACL +go build -o main.exe main.go +# Build the same binary, but write it to the guest directory. +go build -o $TMP\main.exe main.go + +# Read ACLs for the files. +exec powershell -Command 'Get-Acl main.exe | Select -expand AccessToString' +cp stdout $WORK\exe-acl.txt +exec powershell -Command 'Get-Acl main.go | Select -expand AccessToString' +cp stdout $WORK\src-acl.txt +cd $TMP +exec powershell -Command 'Get-Acl main.exe | Select -expand AccessToString' +cp stdout $WORK\guest-acl.txt + +cd $WORK + +# The executable written to the source directory should have the same ACL as the source file. +cmp $WORK\exe-acl.txt $WORK\src-acl.txt + +# The file written to the guest-allowed directory should give Guests control. +grep 'BUILTIN\\Guests\s+Allow' $WORK\guest-acl.txt + +# The file written to the ordinary directory should not. +! grep 'BUILTIN\\Guests\s+Allow' $WORK\exe-acl.txt + + +-- TestACL/go.mod -- +module TestACL +-- TestACL/main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/build_arm.txt b/src/cmd/go/testdata/script/build_arm.txt new file mode 100644 index 0000000..ff2a364 --- /dev/null +++ b/src/cmd/go/testdata/script/build_arm.txt @@ -0,0 +1,13 @@ +[short] skip 'skipping cross-compile in short mode' + +env GOARCH=arm +env GOOS=linux +env GOARM=5 + +go build hello.go +! stderr 'unable to find math.a' + +-- hello.go -- +package main + +func main() {}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_cache_arch_mode.txt b/src/cmd/go/testdata/script/build_cache_arch_mode.txt new file mode 100644 index 0000000..931827f --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_arch_mode.txt @@ -0,0 +1,21 @@ +# Issue 9737: verify that GOARM affects the computed build ID + +[short] skip + +# arm +env GOOS=linux +env GOARCH=arm +env GOARM=5 +go install mycmd +env GOARM=7 +stale mycmd + + +-- go.mod -- +module mycmd + +go 1.16 +-- x.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/build_cache_compile.txt b/src/cmd/go/testdata/script/build_cache_compile.txt new file mode 100644 index 0000000..64b391f --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_compile.txt @@ -0,0 +1,21 @@ +env GO111MODULE=off +[short] skip + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Building trivial non-main package should run compiler the first time. +go build -x lib.go +stderr '(compile|gccgo)( |\.exe).*lib\.go' + +# ... but not again ... +go build -x lib.go +! stderr '(compile|gccgo)( |\.exe).*lib\.go' + +# ... unless we use -a. +go build -a -x lib.go +stderr '(compile|gccgo)( |\.exe)' + +-- lib.go -- +package lib diff --git a/src/cmd/go/testdata/script/build_cache_disabled.txt b/src/cmd/go/testdata/script/build_cache_disabled.txt new file mode 100644 index 0000000..8b005c8 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_disabled.txt @@ -0,0 +1,50 @@ +# The build cache is required to build anything. It also may be needed to +# initialize the build system, which is needed for commands like 'go env'. +# However, there are lots of commands the cache is not needed for, and we +# shouldn't require it when it won't be used. +# +# TODO(golang.org/issue/39882): commands below should work, too. +# * go clean -modcache +# * go env +# * go fix +# * go fmt +# * go generate +# * go get -d +# * go list (without -export or -compiled) + +env GOCACHE=off + +# Commands that don't completely load packages should work. +go doc fmt +stdout Printf + +! go tool compile -h +stderr usage: + +go version +stdout '^go version' + + +# Module commands that don't load packages should work. +go mod init m +exists go.mod + +go mod edit -require rsc.io/quote@v1.5.2 + +go mod download rsc.io/quote + +go mod graph +stdout rsc.io/quote + +go mod verify + + +# Commands that load but don't build packages should work. +go fmt . + +go doc . + +-- main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/build_cache_gomips.txt b/src/cmd/go/testdata/script/build_cache_gomips.txt new file mode 100644 index 0000000..0cbf16a --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_gomips.txt @@ -0,0 +1,40 @@ +env GO111MODULE=off +[short] skip # rebuilds std for mips + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Building for mipsle without setting GOMIPS will use floating point registers. +env GOARCH=mipsle +env GOOS=linux +go build -gcflags=-S f.go +stderr ADDD.F[0-9]+,.F[0-9]+,.F[0-9]+ + +# Clean cache +go clean -cache + +# Building with GOMIPS=softfloat will not use floating point registers +env GOMIPS=softfloat +go build -gcflags=-S f.go +! stderr ADDD.F[0-9]+,.F[0-9]+,.F[0-9]+ + +# Clean cache +go clean -cache + +# Build without setting GOMIPS +env GOMIPS= +go build -gcflags=-S f.go +stderr ADDD.F[0-9]+,.F[0-9]+,.F[0-9]+ + +# Building with GOMIPS should still not use floating point registers. +env GOMIPS=softfloat +go build -gcflags=-S f.go +! stderr ADDD.F[0-9]+,.F[0-9]+,.F[0-9]+ + +-- f.go -- +package f + +func F(x float64) float64 { + return x + x +} diff --git a/src/cmd/go/testdata/script/build_cache_link.txt b/src/cmd/go/testdata/script/build_cache_link.txt new file mode 100644 index 0000000..b9c740a --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_link.txt @@ -0,0 +1,26 @@ +env GO111MODULE=off +[short] skip + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Building a main package should run the compiler and linker ... +go build -o $devnull -x main.go +stderr '(compile|gccgo)( |\.exe).*main\.go' +stderr '(link|gccgo)( |\.exe)' + +# ... and then the linker again ... +go build -o $devnull -x main.go +! stderr '(compile|gccgo)( |\.exe).*main\.go' +stderr '(link|gccgo)( |\.exe)' + +# ... but the output binary can serve as a cache. +go build -o main$GOEXE -x main.go +stderr '(link|gccgo)( |\.exe)' +go build -o main$GOEXE -x main.go +! stderr '(link|gccgo)( |\.exe)' + +-- main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/build_cache_output.txt b/src/cmd/go/testdata/script/build_cache_output.txt new file mode 100644 index 0000000..0d94bf6 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_output.txt @@ -0,0 +1,67 @@ +env GO111MODULE=off +env GODEBUG=gocachetest=1 + +[!gc] skip +[short] skip # clears cache, rebuilds too much + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Building a trivial non-main package should run compiler the first time. +go build -x -gcflags=-m lib.go +stderr 'compile( |\.exe"?)' +stderr 'lib.go:2.* can inline f' + +# ... but not the second, even though it still prints the compiler output. +go build -x -gcflags=-m lib.go +! stderr 'compile( |\.exe"?)' +stderr 'lib.go:2.* can inline f' + +# Building a trivial main package should run the compiler and linker the first time. +go build -x -gcflags=-m -ldflags='-v -w' main.go +stderr 'compile( |\.exe"?)' +stderr 'main.go:2.* can inline main' # from compiler +stderr 'link(\.exe"?)? -' +stderr '\d+ symbols' # from linker + +# ... but not the second, even though it still prints the compiler and linker output. +go build -x -gcflags=-m -ldflags='-v -w' main.go +! stderr 'compile( |\.exe"?)' +stderr 'main.go:2.* can inline main' # from compiler +! stderr 'link(\.exe"?)? -' +stderr '\d+ symbols' # from linker + +# Running a test should run the compiler, linker, and the test the first time. +go test -v -x -gcflags=-m -ldflags=-v p +stderr 'compile( |\.exe"?)' +stderr 'p_test.go:.*can inline Test' # from compile of p_test +stderr 'testmain\.go:.*inlin' # from compile of testmain +stderr 'link(\.exe"?)? -' +stderr '\d+ symbols' # from linker +stderr 'p\.test( |\.exe"?)' +stdout 'TEST' # from test + +# ... but not the second, even though it still prints the compiler, linker, and test output. +go test -v -x -gcflags=-m -ldflags=-v p +! stderr 'compile( |\.exe"?)' +stderr 'p_test.go:.*can inline Test' # from compile of p_test +stderr 'testmain\.go:.*inlin' # from compile of testmain +! stderr 'link(\.exe"?)? -' +stderr '\d+ symbols' # from linker +! stderr 'p\.test( |\.exe"?)' +stdout 'TEST' # from test + + +-- lib.go -- +package p +func f(x *int) *int { return x } + +-- main.go -- +package main +func main() {} + +-- p/p_test.go -- +package p +import "testing" +func Test(t *testing.T) {println("TEST")} diff --git a/src/cmd/go/testdata/script/build_cache_trimpath.txt b/src/cmd/go/testdata/script/build_cache_trimpath.txt new file mode 100644 index 0000000..9a4b9d7 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_trimpath.txt @@ -0,0 +1,47 @@ +[short] skip +env GO111MODULE=on + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +cd $WORK +go build -o a.out + +# Varying -trimpath should cause a rebuild. +go build -x -o a.out -trimpath +stderr '(compile|gccgo)( |\.exe)' +stderr 'link( |\.exe)' + +# Two distinct versions of the same module with identical content should +# still be cached separately. +# Verifies golang.org/issue/35412. +go get -d example.com/stack@v1.0.0 +go run -trimpath printstack.go +stdout '^example.com/stack@v1.0.0/stack.go$' +go get -d example.com/stack@v1.0.1 +go run -trimpath printstack.go +stdout '^example.com/stack@v1.0.1/stack.go$' + +-- $WORK/hello.go -- +package main +func main() { println("hello") } + +-- $WORK/printstack.go -- +// +build ignore + +package main + +import ( + "fmt" + + "example.com/stack" +) + +func main() { + fmt.Println(stack.TopFile()) +} +-- $WORK/go.mod -- +module m + +go 1.14 diff --git a/src/cmd/go/testdata/script/build_cd_gopath_different.txt b/src/cmd/go/testdata/script/build_cd_gopath_different.txt new file mode 100644 index 0000000..a7a4bf4 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cd_gopath_different.txt @@ -0,0 +1,73 @@ +[gccgo] skip 'gccgo does not support -ldflags -X' +env GO111MODULE=off +go build run_go.go + +# Apply identity function to GOPATH +exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH IDENTITY build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked +exec $WORK/tmp/a.exe +stderr 'linkXworked' +rm $WORK/tmp/a.exe + +[!windows] stop 'rest of the tests only apply to Windows' + +# Replace '\' with '/' in GOPATH +exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH REPLACE_SLASH build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked +exec $WORK/tmp/a.exe +stderr 'linkXworked' +rm $WORK/tmp/a.exe + +# Apply identity function to GOPATH +exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH UPPER build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked +exec $WORK/tmp/a.exe +stderr 'linkXworked' +rm $WORK/tmp/a.exe + +# Apply identity function to GOPATH +exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH LOWER build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked +exec $WORK/tmp/a.exe +stderr 'linkXworked' +rm $WORK/tmp/a.exe + +-- run_go.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "strings" +) + +func main() { + dir := os.Args[1] + gopath := os.Args[2] + switch os.Args[3] { + case "IDENTITY": + case "REPLACE_SLASH": gopath = strings.ReplaceAll(gopath, `\`, `/`) + case "UPPER": gopath = strings.ToUpper(gopath) + case "LOWER": gopath = strings.ToLower(gopath) + default: fmt.Fprintln(os.Stderr, "bad op"); os.Exit(1) + } + cmd := exec.Command("go", os.Args[4:]...) + cmd.Dir = dir + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +-- my.pkg/main/main.go -- +package main + +import "my.pkg" + +func main() { + println(pkg.Text) +} +-- my.pkg/pkg.go -- +package pkg + +var Text = "unset" diff --git a/src/cmd/go/testdata/script/build_cgo_consistent_results.txt b/src/cmd/go/testdata/script/build_cgo_consistent_results.txt new file mode 100644 index 0000000..88a24de --- /dev/null +++ b/src/cmd/go/testdata/script/build_cgo_consistent_results.txt @@ -0,0 +1,23 @@ +[short] skip +[!cgo] skip + +[solaris] skip "skipping on Solaris; see golang.org/issue/13247" +[illumos] skip "skipping on Solaris; see golang.org/issue/13247" + +go build -o $WORK/exe1$GOEXE cgotest +go build -x -o $WORK/exe2$GOEXE cgotest + +# TODO(matloob): skip if stderr does not contain '-fdebug-prefix-map=\$WORK' + +cmp $WORK/exe1$GOEXE $WORK/exe2$GOEXE + +-- go.mod -- +module cgotest + +go 1.16 +-- m.go -- +package cgotest + +import "C" + +var _ C.int diff --git a/src/cmd/go/testdata/script/build_darwin_cc_arch.txt b/src/cmd/go/testdata/script/build_darwin_cc_arch.txt new file mode 100644 index 0000000..2b81b4c --- /dev/null +++ b/src/cmd/go/testdata/script/build_darwin_cc_arch.txt @@ -0,0 +1,24 @@ +# Test that we pass -arch flag to C compiler on Darwin (issue 43692). + +[!darwin] skip +[!cgo] skip + +# clear CC, in case user sets it +env CC= + +env CGO_ENABLED=1 + +env GOARCH=amd64 +go build -n -x c.go +stderr 'clang.*-arch x86_64' + +env GOARCH=arm64 +go build -n -x c.go +stderr 'clang.*-arch arm64' + +-- c.go -- +package main + +import "C" + +func main() {} diff --git a/src/cmd/go/testdata/script/build_dash_n_cgo.txt b/src/cmd/go/testdata/script/build_dash_n_cgo.txt new file mode 100644 index 0000000..3f49ef6 --- /dev/null +++ b/src/cmd/go/testdata/script/build_dash_n_cgo.txt @@ -0,0 +1,18 @@ +# Tests golang.org/issue/14944 + +[!cgo] skip + +go build -n foo.go +! stderr 'os.Stat .* no such file or directory' # there shouldn't be a stat of the archive file + +-- foo.go -- +package main + +/* +#include <limits.h> +*/ +import "C" + +func main() { + println(C.INT_MAX) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_dash_o_dev_null.txt b/src/cmd/go/testdata/script/build_dash_o_dev_null.txt new file mode 100644 index 0000000..e415fc2 --- /dev/null +++ b/src/cmd/go/testdata/script/build_dash_o_dev_null.txt @@ -0,0 +1,13 @@ +# Issue #25579 + +[short] skip + +go build -o $devnull hello.go +! exists 'hello'$GOEXE + +-- hello.go -- +package main + +func main() { + println("hello, world") +} diff --git a/src/cmd/go/testdata/script/build_dash_x.txt b/src/cmd/go/testdata/script/build_dash_x.txt new file mode 100644 index 0000000..6fd5bbe --- /dev/null +++ b/src/cmd/go/testdata/script/build_dash_x.txt @@ -0,0 +1,49 @@ +[short] skip +[!cgo] skip + +[!exec:/usr/bin/env] skip +[!exec:bash] skip +[!exec:cat] skip + +mkdir $WORK/tmp/cache +env GOCACHE=$WORK/tmp/cache + +# Before building our test main.go, ensure that an up-to-date copy of +# runtime/cgo is present in the cache. If it isn't, the 'go build' step below +# will fail with "can't open import". See golang.org/issue/29004. +# +# (The fix in golang.org/issue/29004 didn't completely fix the underlying issue: +# cmd/go/internal/load adds a bunch of implicit dependencies +# based on various heuristics, and, due to a bug described in +# https://golang.org/issue/31544#issuecomment-490607180, +# those implicit dependencies are not added early enough during +# loading to properly affect the import graph.) +go build runtime/cgo + +go build -x -o main main.go +cp stderr commands.txt +exec cat header.txt commands.txt +cp stdout test.sh + +exec ./main +cmp stderr hello.txt +rm ./main + +exec /usr/bin/env bash -x test.sh +exec ./main +cmp stderr hello.txt + +grep '^WORK=(.*)\n' commands.txt + +-- main.go -- +package main + +import "C" + +func main() { + print("hello\n") +} +-- header.txt -- +set -e +-- hello.txt -- +hello diff --git a/src/cmd/go/testdata/script/build_exe.txt b/src/cmd/go/testdata/script/build_exe.txt new file mode 100644 index 0000000..a994d17 --- /dev/null +++ b/src/cmd/go/testdata/script/build_exe.txt @@ -0,0 +1,25 @@ +# go build with -o and -buildmode=exe should report an error on a non-main package. + +! go build -buildmode=exe -o out$GOEXE ./not_main +stderr '-buildmode=exe requires exactly one main package' +! exists out$GOEXE +! go build -buildmode=exe -o out$GOEXE ./main_one ./main_two +stderr '-buildmode=exe requires exactly one main package' +! exists out$GOEXE + +-- go.mod -- +module m + +go 1.16 +-- not_main/not_main.go -- +package not_main + +func F() {} +-- main_one/main_one.go -- +package main + +func main() {} +-- main_two/main_two.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/build_gcflags.txt b/src/cmd/go/testdata/script/build_gcflags.txt new file mode 100644 index 0000000..b472374 --- /dev/null +++ b/src/cmd/go/testdata/script/build_gcflags.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +# Test that the user can override default code generation flags. + +[gccgo] skip # gccgo does not use -gcflags +[!cgo] skip +[!linux] skip # test only works if c-archive implies -shared +[short] skip + +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. +go build -x -n -buildmode=c-archive -gcflags=all=-shared=false ./override.go +stderr '^.*/compile (.* )?-shared (.* )?-shared=false' + +-- override.go -- +package main + +import "C" + +//export GoFunc +func GoFunc() {} + +func main() {} diff --git a/src/cmd/go/testdata/script/build_gopath_order.txt b/src/cmd/go/testdata/script/build_gopath_order.txt new file mode 100644 index 0000000..caf2502 --- /dev/null +++ b/src/cmd/go/testdata/script/build_gopath_order.txt @@ -0,0 +1,36 @@ +# golang.org/issue/14176#issuecomment-179895769 +# golang.org/issue/14192 +# -I arguments to compiler could end up not in GOPATH order, +# leading to unexpected import resolution in the compiler. + +env GO111MODULE=off +env GOPATH=$WORK/p1${:}$WORK/p2 +mkdir $WORK/p1/src/foo $WORK/p2/src/baz +mkdir $WORK/p2/pkg/${GOOS}_${GOARCH} $WORK/p1/src/bar +cp foo.go $WORK/p1/src/foo/foo.go +cp baz.go $WORK/p2/src/baz/baz.go +cp foo.a $WORK/p2/pkg/${GOOS}_${GOARCH}/foo.a +cp bar.go $WORK/p1/src/bar/bar.go + +go install -x bar + +# add in baz.a to the mix +mkdir $WORK/p1/pkg/${GOOS}_${GOARCH} +cp baz.a $WORK/p1/pkg/${GOOS}_${GOARCH}/baz.a +env GOPATH=$WORK/p1${:}$WORK/p2 +go install -x bar +env GOPATH=$WORK/p2${:}$WORK/p1 +go install -x bar + +-- foo.go -- +package foo +-- baz.go -- +package baz +-- foo.a -- +bad +-- baz.a -- +bad +-- bar.go -- +package bar +import _ "baz" +import _ "foo" diff --git a/src/cmd/go/testdata/script/build_i.txt b/src/cmd/go/testdata/script/build_i.txt new file mode 100644 index 0000000..0e7ebed --- /dev/null +++ b/src/cmd/go/testdata/script/build_i.txt @@ -0,0 +1,41 @@ +env GO111MODULE=off + +# Test that 'go build -i' installs dependencies of the requested package. + +[short] skip + +# Since we are checking installation of dependencies, use a clean cache +# to ensure that multiple runs of the test do not interfere. +env GOCACHE=$WORK/cache + +# The initial 'go build -i' for bar should install its dependency foo. + +go build -v -i x/y/bar +stderr 'x/y/foo' # should be rebuilt +go build -v -i x/y/bar +! stderr 'x/y/foo' # should already be installed + +# After modifying the source files, both packages should be rebuild. + +cp x/y/foo/foo.go.next x/y/foo/foo.go +cp x/y/bar/bar.go.next x/y/bar/bar.go + +go build -v -i x/y/bar +stderr 'x/y/foo' # should be rebuilt +go build -v -i x/y/bar +! stderr 'x/y/foo' # should already be installed + +-- x/y/foo/foo.go -- +package foo +func F() {} +-- x/y/bar/bar.go -- +package bar +import "x/y/foo" +func F() { foo.F() } +-- x/y/foo/foo.go.next -- +package foo +func F() { F() } +-- x/y/bar/bar.go.next -- +package main +import "x/y/foo" +func main() { foo.F() } diff --git a/src/cmd/go/testdata/script/build_i_deprecate.txt b/src/cmd/go/testdata/script/build_i_deprecate.txt new file mode 100644 index 0000000..71356e5 --- /dev/null +++ b/src/cmd/go/testdata/script/build_i_deprecate.txt @@ -0,0 +1,24 @@ +# Check that deprecation warnings are printed when the -i flag is used. +# TODO(golang.org/issue/41696): remove the -i flag after Go 1.16, and this test. + +go build -n -i +stderr '^go build: -i flag is deprecated$' + +go install -n -i +stderr '^go install: -i flag is deprecated$' + +go test -n -i +stderr '^go test: -i flag is deprecated$' + + +# 'go clean -i' should not print a deprecation warning. +# It will continue working. +go clean -i . +! stderr . + +-- go.mod -- +module m + +go 1.16 +-- m.go -- +package m diff --git a/src/cmd/go/testdata/script/build_import_comment.txt b/src/cmd/go/testdata/script/build_import_comment.txt new file mode 100644 index 0000000..b500340 --- /dev/null +++ b/src/cmd/go/testdata/script/build_import_comment.txt @@ -0,0 +1,68 @@ +# Test in GOPATH mode first. +env GO111MODULE=off +cd m + +# Import comment matches +go build -n works.go + +# Import comment mismatch +! go build -n wrongplace.go +stderr 'wrongplace expects import "my/x"' + +# Import comment syntax error +! go build -n bad.go +stderr 'cannot parse import comment' + +# Import comment conflict +! go build -n conflict.go +stderr 'found import comments' + + +# Test in module mode. +# We ignore import comments, so these commands should succeed. +env GO111MODULE=on + +# Import comment matches +go build -n works.go + +# Import comment mismatch +go build -n wrongplace.go + +# Import comment syntax error +go build -n bad.go + +# Import comment conflict +go build -n conflict.go + +-- m/go.mod -- +module m + +go 1.16 +-- m/bad.go -- +package p + +import "m/bad" +-- m/conflict.go -- +package p + +import "m/conflict" +-- m/works.go -- +package p + +import _ "m/works/x" +-- m/wrongplace.go -- +package p + +import "m/wrongplace" +-- m/bad/bad.go -- +package bad // import +-- m/conflict/a.go -- +package conflict // import "a" +-- m/conflict/b.go -- +package conflict /* import "b" */ +-- m/works/x/x.go -- +package x // import "m/works/x" +-- m/works/x/x1.go -- +package x // important! not an import comment +-- m/wrongplace/x.go -- +package x // import "my/x" diff --git a/src/cmd/go/testdata/script/build_import_cycle.txt b/src/cmd/go/testdata/script/build_import_cycle.txt new file mode 100644 index 0000000..16e4e87 --- /dev/null +++ b/src/cmd/go/testdata/script/build_import_cycle.txt @@ -0,0 +1,13 @@ +# mod_import_cycle covers this error in module mode. +env GO111MODULE=off + +! go build selfimport +stderr -count=1 'import cycle not allowed' + +go list -e -f '{{.Error}}' selfimport # Don't hang forever +stdout -count=1 'import cycle not allowed' + +-- selfimport/selfimport.go -- +package selfimport + +import "selfimport" diff --git a/src/cmd/go/testdata/script/build_internal.txt b/src/cmd/go/testdata/script/build_internal.txt new file mode 100644 index 0000000..25aa18c --- /dev/null +++ b/src/cmd/go/testdata/script/build_internal.txt @@ -0,0 +1,63 @@ +# Test internal package errors are handled +cd testinternal3 +go list . +stdout 'testinternal3' + +# Test internal cache +cd ../testinternal4 +! go build testinternal4/p +stderr 'internal' + +# Test internal packages outside GOROOT are respected +cd ../testinternal2 +! go build -v . +stderr 'p\.go:3:8: use of internal package .*internal/w not allowed' + +[gccgo] skip # gccgo does not have GOROOT +cd ../testinternal +! go build -v . +stderr 'p\.go:3:8: use of internal package net/http/internal not allowed' + +-- testinternal/go.mod -- +module testinternal + +go 1.16 +-- testinternal/p.go -- +package p + +import _ "net/http/internal" +-- testinternal2/go.mod -- +module testinternal2 + +go 1.16 +-- testinternal2/p.go -- +package p + +import _ "./x/y/z/internal/w" +-- testinternal2/x/y/z/internal/w/w.go -- +package w +-- testinternal3/go.mod -- +module testinternal3 + +go 1.16 +-- testinternal3/t.go -- +package t + +import _ "internal/does-not-exist" +-- testinternal4/go.mod -- +module testinternal4 + +go 1.16 +-- testinternal4/p/p.go -- +package p + +import ( + _ "testinternal4/q/internal/x" + _ "testinternal4/q/j" +) +-- testinternal4/q/internal/x/x.go -- +package x +-- testinternal4/q/j/j.go -- +package j + +import _ "testinternal4/q/internal/x" diff --git a/src/cmd/go/testdata/script/build_issue6480.txt b/src/cmd/go/testdata/script/build_issue6480.txt new file mode 100644 index 0000000..cf1e9ea --- /dev/null +++ b/src/cmd/go/testdata/script/build_issue6480.txt @@ -0,0 +1,128 @@ +# "go test -c -test.bench=XXX errors" should not hang. +# "go test -c" should also produce reproducible binaries. +# "go test -c" should also appear to write a new binary every time, +# even if it's really just updating the mtime on an existing up-to-date binary. + +[gccgo] skip +[short] skip + +# Install some commands to compare mtimes +env GOBIN=$WORK/tmp/bin +go install m/now m/mtime m/before + +# Initial builds +go test -c -test.bench=XXX errors +go test -c -o errors2.test errors +cmp errors.test$GOEXE errors2.test # // errors2.test has no exeSuffix because -o above doesn't have it + +# Check errors.test mtime is updated +exec $GOBIN/now +cp stdout start_time.txt +go test -x -c -test.bench=XXX errors +! stderr '[\\/]link|gccgo' # make sure up-to-date test binary is not relinked +exec $GOBIN/mtime errors.test$GOEXE +cp stdout errors1_mod_time.txt +exec $GOBIN/before start_time.txt errors1_mod_time.txt +rm start_time.txt errors1_mod_time.txt + +# Check errors2.test mtime is updated +exec $GOBIN/now +cp stdout start_time.txt +go test -x -c -o errors2.test errors +! stderr '[\\/]link|gccgo' # make sure up-to-date test binary is not relinked +exec $GOBIN/mtime errors2.test +cp stdout errors2_mod_time.txt +exec $GOBIN/before start_time.txt errors2_mod_time.txt + +-- go.mod -- +module m + +go 1.16 +-- now/now.go -- +// Writes time.Now() to a file +package main + +import ( + "encoding/json" + "fmt" + "os" + "time" +) + +func main() { + if err := json.NewEncoder(os.Stdout).Encode(time.Now()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- mtime/mtime.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" +) + +func main() { + info, err := os.Stat(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.NewEncoder(os.Stdout).Encode(info.ModTime()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- before/before.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" + "time" +) + +func truncateLike(t, p time.Time) time.Time { + nano := p.UnixNano() + d := 1 * time.Nanosecond + for nano%int64(d) == 0 && d < 1*time.Second { + d *= 10 + } + for nano%int64(d) == 0 && d < 2*time.Second { + d *= 2 + } + return t.Truncate(d) +} + +func main() { + var t1 time.Time + b1, err := os.ReadFile(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b1, &t1); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + var t2 time.Time + b2, err := os.ReadFile(os.Args[2]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b2, &t2); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + t1 = truncateLike(t1, t2) + if !t1.Before(t2) { + fmt.Fprintf(os.Stderr, "time in %v (%v) is not before time in %v (%v)", os.Args[1], t1, os.Args[2], t2) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt b/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt new file mode 100644 index 0000000..f1de1e4 --- /dev/null +++ b/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt @@ -0,0 +1,22 @@ +[gccgo] skip 'gccgo does not support -ldflags -X' + +go build -o linkx$GOEXE -ldflags -X=my.pkg.Text=linkXworked my.pkg/main +exec ./linkx$GOEXE +stderr '^linkXworked$' + +-- go.mod -- +module my.pkg + +go 1.16 +-- main/main.go -- +package main + +import "my.pkg" + +func main() { + println(pkg.Text) +} +-- pkg.go -- +package pkg + +var Text = "unset" diff --git a/src/cmd/go/testdata/script/build_multi_main.txt b/src/cmd/go/testdata/script/build_multi_main.txt new file mode 100644 index 0000000..8afd8b8 --- /dev/null +++ b/src/cmd/go/testdata/script/build_multi_main.txt @@ -0,0 +1,43 @@ +# Verify build -o can output multiple executables to a directory. + +mkdir $WORK/bin +go build -o $WORK/bin ./cmd/c1 ./cmd/c2 +! stderr 'multiple packages' + +! go build -o $WORK/bin ./pkg1 ./pkg1 +stderr 'no main packages' + +! go build ./cmd/c1 +stderr 'already exists and is a directory' + +# Verify build -o output correctly local packages +mkdir $WORK/local +go build -o $WORK/local ./exec.go +exists $WORK/local/exec$GOEXE + +-- go.mod -- +module exmod + +-- cmd/c1/main.go -- +package main + +func main() {} + +-- cmd/c2/main.go -- +package main + +func main() {} + +-- pkg1/pkg1.go -- +package pkg1 + +-- pkg2/pkg2.go -- +package pkg2 + +-- exec.go -- +package main + +func main() {} + +-- c1$GOEXE/keep.txt -- +Create c1 directory. diff --git a/src/cmd/go/testdata/script/build_n_cgo.txt b/src/cmd/go/testdata/script/build_n_cgo.txt new file mode 100644 index 0000000..7aa77ae --- /dev/null +++ b/src/cmd/go/testdata/script/build_n_cgo.txt @@ -0,0 +1,17 @@ +[!cgo] skip + +# Test that nothing is prepended to $WORK path prefix. +# See issue golang.org/issue/37012. +go build -n +! stderr '[/\\]\$WORK' + +-- go.mod -- +module m + +go 1.16 +-- main.go -- +package main + +import "C" + +var _ C.int diff --git a/src/cmd/go/testdata/script/build_no_go.txt b/src/cmd/go/testdata/script/build_no_go.txt new file mode 100644 index 0000000..b61d752 --- /dev/null +++ b/src/cmd/go/testdata/script/build_no_go.txt @@ -0,0 +1,41 @@ +! go build ./empty/test +stderr 'no non-test Go files in ' + +! go build ./empty/xtest +stderr 'no non-test Go files in ' + +! go build ./empty/testxtest +stderr 'no non-test Go files in ' + +! go build ./exclude +stderr 'build constraints exclude all Go files in ' + +! go build ./exclude/ignore +stderr 'no Go files in ' + +! go build ./exclude/empty +stderr 'no Go files in ' + +-- go.mod -- +module m + +go 1.16 +-- empty/test/test_test.go -- +package p +-- empty/testxtest/test_test.go -- +package p +-- empty/testxtest/xtest_test.go -- +package p_test +-- empty/xtest/xtest_test.go -- +package p_test +-- exclude/empty/x.txt -- +-- exclude/ignore/_x.go -- +package x +-- exclude/x.go -- +// +build linux,!linux + +package x +-- exclude/x_linux.go -- +// +build windows + +package x diff --git a/src/cmd/go/testdata/script/build_nocache.txt b/src/cmd/go/testdata/script/build_nocache.txt new file mode 100644 index 0000000..1059cad --- /dev/null +++ b/src/cmd/go/testdata/script/build_nocache.txt @@ -0,0 +1,40 @@ +env GO111MODULE=off + +# As of Go 1.12, the module cache is required. + +# If none of the variables we use to locate GOCACHE are set, the cache is off +# and we cannot build. +env GOCACHE= +env XDG_CACHE_HOME= +env HOME= +[plan9] env home= +[windows] env LocalAppData= +! go build -o triv triv.go +stderr 'build cache is required, but could not be located: GOCACHE is not defined and .*' + +# If GOCACHE is set but is not an absolute path, and we cannot build. +env GOCACHE=test +! go build -o triv triv.go +stderr 'build cache is required, but could not be located: GOCACHE is not an absolute path' + +# An explicit GOCACHE=off also disables builds. +env GOCACHE=off +! go build -o triv triv.go +stderr 'build cache is disabled by GOCACHE=off' + +# If GOCACHE is set to an unwritable directory, we should diagnose it as such. +[windows] stop # Does not support unwritable directories. +[root] skip # Can write to unwritable directories. + +mkdir $WORK/unwritable/home +chmod 0555 $WORK/unwritable/home +[!plan9] env HOME=$WORK/unwritable/home +[plan9] env home=$WORK/unwritable/home + +env GOCACHE=$WORK/unwritable/home +! go build -o triv triv.go +stderr 'failed to initialize build cache.* permission denied' + +-- triv.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/build_output.txt b/src/cmd/go/testdata/script/build_output.txt new file mode 100644 index 0000000..1e82950 --- /dev/null +++ b/src/cmd/go/testdata/script/build_output.txt @@ -0,0 +1,117 @@ +[gccgo] skip 'gccgo has no standard packages' +[short] skip + +[!windows] env NONEXE='.exe' +[windows] env NONEXE='' + +env GOBIN=$WORK/tmp/bin +go install m/isarchive & + +go build x.go +exists -exec x$GOEXE +rm x$GOEXE +! exists x$NONEXE + +go build -o myprog x.go +! exists x +! exists x.exe +exists -exec myprog +! exists myprogr.exe + +! exists bin +go build -o bin/x x.go +exists -exec bin/x +rm bin + +! exists bin +go build -o bin/ x.go +exists -exec bin/x$GOEXE +rm bin + +[windows] ! exists bin +[windows] go build -o bin\x x.go +[windows] exists -exec bin\x +[windows] rm bin + +[windows] ! exists bin +[windows] go build -o bin\ x.go +[windows] exists -exec bin\x.exe +[windows] rm bin + +! exists bin +mkdir bin +go build -o bin x.go +exists -exec bin/x$GOEXE +rm bin + +go build p.go +! exists p +! exists p.a +! exists p.o +! exists p.exe + +wait # for isarchive + +go build -o p.a p.go +exists p.a +exec $GOBIN/isarchive p.a + +go build cmd/gofmt +exists -exec gofmt$GOEXE +rm gofmt$GOEXE +! exists gofmt$NONEXE + +go build -o mygofmt cmd/gofmt +exists -exec mygofmt +! exists mygofmt.exe +! exists gofmt +! exists gofmt.exe + +go build sync/atomic +! exists atomic +! exists atomic.exe + +go build -o myatomic.a sync/atomic +exists myatomic.a +exec $GOBIN/isarchive myatomic.a +! exists atomic +! exists atomic.a +! exists atomic.exe + +! go build -o whatever cmd/gofmt sync/atomic +stderr 'multiple packages' + +-- go.mod -- +module m + +go 1.16 +-- x.go -- +package main + +func main() {} +-- p.go -- +package p +-- isarchive/isarchive.go -- +package main + +import ( + "bytes" + "fmt" + "io" + "os" +) + +func main() { + f, err := os.Open(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + buf := make([]byte, 100) + io.ReadFull(f, buf) + f.Close() + if !bytes.HasPrefix(buf, []byte("!<arch>\n")) { + fmt.Fprintf(os.Stderr, "file %s exists but is not an archive\n", os.Args[1]) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/build_overlay.txt b/src/cmd/go/testdata/script/build_overlay.txt new file mode 100644 index 0000000..b11cd96 --- /dev/null +++ b/src/cmd/go/testdata/script/build_overlay.txt @@ -0,0 +1,308 @@ +[short] skip + +# Test building in overlays. +# TODO(#39958): add a test case where the destination file in the replace map +# isn't a go file. Either completely exclude that case in fs.IsDirWithGoFiles +# if the compiler doesn't allow it, or test that it works all the way. +# TODO(#39958): add a test that both gc and gccgo assembly files can include .h +# files. + +# The main package (m) is contained in an overlay. It imports m/dir2 which has one +# file in an overlay and one file outside the overlay, which in turn imports m/dir, +# which only has source files in the overlay. + +cd m + +! go build . +go build -overlay overlay.json -o main$GOEXE . +exec ./main$goexe +stdout '^hello$' + +go build -overlay overlay.json -o print_abspath$GOEXE ./printpath +exec ./print_abspath$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go + +go build -overlay overlay.json -o print_trimpath$GOEXE -trimpath ./printpath +exec ./print_trimpath$GOEXE +stdout ^m[/\\]printpath[/\\]main.go + +go build -overlay overlay.json -o print_trimpath_two_files$GOEXE printpath/main.go printpath/other.go +exec ./print_trimpath_two_files$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]other.go + +go build -overlay overlay.json -o main_cgo_replace$GOEXE ./cgo_hello_replace +exec ./main_cgo_replace$GOEXE +stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_cgo_quote$GOEXE ./cgo_hello_quote +exec ./main_cgo_quote$GOEXE +stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_cgo_angle$GOEXE ./cgo_hello_angle +exec ./main_cgo_angle$GOEXE +stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_call_asm$GOEXE ./call_asm +exec ./main_call_asm$GOEXE +! stdout . + +# Change the contents of a file in the overlay and ensure that makes the target stale +go install -overlay overlay.json ./test_cache +go list -overlay overlay.json -f '{{.Stale}}' ./test_cache +stdout '^false$' +cp overlay/test_cache_different.go overlay/test_cache.go +go list -overlay overlay.json -f '{{.Stale}}' ./test_cache +stdout '^true$' + +go list -compiled -overlay overlay.json -f '{{range .CompiledGoFiles}}{{. | printf "%s\n"}}{{end}}' ./cgo_hello_replace +cp stdout compiled_cgo_sources.txt +go run ../print_line_comments.go compiled_cgo_sources.txt +stdout $GOPATH[/\\]src[/\\]m[/\\]cgo_hello_replace[/\\]cgo_hello_replace.go +! stdout $GOPATH[/\\]src[/\\]m[/\\]overlay[/\\]hello.c + +# Run same tests but with gccgo. +env GO111MODULE=off +[!exec:gccgo] stop + +! go build -compiler=gccgo . +go build -compiler=gccgo -overlay overlay.json -o main_gccgo$GOEXE . +exec ./main_gccgo$goexe +stdout '^hello$' + +go build -compiler=gccgo -overlay overlay.json -o print_abspath_gccgo$GOEXE ./printpath +exec ./print_abspath_gccgo$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go + +go build -compiler=gccgo -overlay overlay.json -o print_trimpath_gccgo$GOEXE -trimpath ./printpath +exec ./print_trimpath_gccgo$GOEXE +stdout ^\.[/\\]printpath[/\\]main.go + + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_replace_gccgo$GOEXE ./cgo_hello_replace +exec ./main_cgo_replace_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_quote_gccgo$GOEXE ./cgo_hello_quote +exec ./main_cgo_quote_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_angle_gccgo$GOEXE ./cgo_hello_angle +exec ./main_cgo_angle_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_call_asm_gccgo$GOEXE ./call_asm +exec ./main_call_asm_gccgo$GOEXE +! stdout . + + +-- m/go.mod -- +// TODO(matloob): how do overlays work with go.mod (especially if mod=readonly) +module m + +go 1.16 + +-- m/dir2/h.go -- +package dir2 + +func PrintMessage() { + printMessage() +} +-- m/dir/foo.txt -- +The build action code currently expects the package directory +to exist, so it can run the compiler in that directory. +TODO(matloob): Remove this requirement. +-- m/printpath/about.txt -- +the actual code is in the overlay +-- m/overlay.json -- +{ + "Replace": { + "f.go": "overlay/f.go", + "dir/g.go": "overlay/dir_g.go", + "dir2/i.go": "overlay/dir2_i.go", + "printpath/main.go": "overlay/printpath.go", + "printpath/other.go": "overlay2/printpath2.go", + "call_asm/asm_gc.s": "overlay/asm_gc.s", + "call_asm/asm_gccgo.s": "overlay/asm_gccgo.s", + "test_cache/main.go": "overlay/test_cache.go", + "cgo_hello_replace/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_replace/hello.c": "overlay/hello.c", + "cgo_hello_quote/cgo_hello.go": "overlay/cgo_hello_quote.go", + "cgo_hello_quote/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_angle/cgo_hello.go": "overlay/cgo_hello_angle.go", + "cgo_hello_angle/cgo_header.h": "overlay/cgo_head.h" + } +} +-- m/cgo_hello_replace/cgo_hello_replace.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/cgo_hello_replace/cgo_header.h -- + // Test that this header is replaced with one that has the proper declaration. +void say_goodbye(); + +-- m/cgo_hello_replace/hello.c -- +#include <stdio.h> + +void say_goodbye() { puts("goodbye cgo\n"); fflush(stdout); } + +-- m/overlay/f.go -- +package main + +import "m/dir2" + +func main() { + dir2.PrintMessage() +} +-- m/call_asm/main.go -- +package main + +func foo() // There will be a "missing function body" error if the assembly file isn't found. + +func main() { + foo() +} +-- m/overlay/dir_g.go -- +package dir + +import "fmt" + +func PrintMessage() { + fmt.Println("hello") +} +-- m/overlay/printpath.go -- +package main + +import ( + "fmt" + "path/filepath" + "runtime" +) + +func main() { + _, file, _, _ := runtime.Caller(0) + + // Since https://golang.org/cl/214286, the runtime's debug paths are + // slash-separated regardless of platform, so normalize them to system file + // paths. + fmt.Println(filepath.FromSlash(file)) +} +-- m/overlay2/printpath2.go -- +package main + +import ( + "fmt" + "path/filepath" + "runtime" +) + +func init() { + _, file, _, _ := runtime.Caller(0) + fmt.Println(filepath.FromSlash(file)) +} +-- m/overlay/dir2_i.go -- +package dir2 + +import "m/dir" + +func printMessage() { + dir.PrintMessage() +} +-- m/overlay/cgo_hello_quote.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_hello_angle.go -- +package main + +// #include <cgo_header.h> +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_head.h -- +void say_hello(); +-- m/overlay/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/overlay/asm_gc.s -- +// +build !gccgo + +TEXT ·foo(SB),0,$0 + RET + +-- m/overlay/asm_gccgo.s -- +// +build gccgo + +.globl main.foo +.text +main.foo: + ret + +-- m/overlay/test_cache.go -- +package foo + +import "fmt" + +func bar() { + fmt.Println("something") +} +-- m/overlay/test_cache_different.go -- +package foo + +import "fmt" + +func bar() { + fmt.Println("different") +} +-- m/cgo_hello_quote/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/cgo_hello_angle/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } + +-- print_line_comments.go -- +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "strings" +) + +func main() { + compiledGoFilesArg := os.Args[1] + b, err := ioutil.ReadFile(compiledGoFilesArg) + if err != nil { + log.Fatal(err) + } + compiledGoFiles := strings.Split(strings.TrimSpace(string(b)), "\n") + for _, f := range compiledGoFiles { + b, err := ioutil.ReadFile(f) + if err != nil { + log.Fatal(err) + } + for _, line := range strings.Split(string(b), "\n") { + if strings.HasPrefix(line, "#line") || strings.HasPrefix(line, "//line") { + fmt.Println(line) + } + } + } +} diff --git a/src/cmd/go/testdata/script/build_package_not_stale_trailing_slash.txt b/src/cmd/go/testdata/script/build_package_not_stale_trailing_slash.txt new file mode 100644 index 0000000..38a151e --- /dev/null +++ b/src/cmd/go/testdata/script/build_package_not_stale_trailing_slash.txt @@ -0,0 +1,13 @@ +# Tests Issue #12690 + +[gccgo] skip 'gccgo does not have GOROOT' + +! stale runtime +! stale os +! stale io + +env GOROOT=$GOROOT'/' + +! stale runtime +! stale os +! stale io
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt b/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt new file mode 100644 index 0000000..6a600cf --- /dev/null +++ b/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt @@ -0,0 +1,36 @@ +# Tests issue #18778 +[short] skip + +cd pkgs + +env GO111MODULE=off +go build ./... +! stdout . +go test ./... +stdout '^ok' +go list ./... +stdout 'pkgs$' +stdout 'pkgs/a' + +-- pkgs/go.mod -- +module pkgs + +go 1.16 +-- pkgs/a.go -- +package x +-- pkgs/a_test.go -- +package x_test + +import "testing" + +func TestX(t *testing.T) { +} +-- pkgs/a/a.go -- +package a +-- pkgs/a/a_test.go -- +package a_test + +import "testing" + +func TestA(t *testing.T) { +} diff --git a/src/cmd/go/testdata/script/build_plugin_non_main.txt b/src/cmd/go/testdata/script/build_plugin_non_main.txt new file mode 100644 index 0000000..e0bbbef --- /dev/null +++ b/src/cmd/go/testdata/script/build_plugin_non_main.txt @@ -0,0 +1,13 @@ +# Plugins are not supported on all platforms. +[!buildmode:plugin] skip + +go build -n testdep +! go build -buildmode=plugin testdep +stderr '-buildmode=plugin requires exactly one main package' + +-- go.mod -- +module testdep + +go 1.16 +-- testdep.go -- +package p diff --git a/src/cmd/go/testdata/script/build_relative_pkgdir.txt b/src/cmd/go/testdata/script/build_relative_pkgdir.txt new file mode 100644 index 0000000..0716bcd --- /dev/null +++ b/src/cmd/go/testdata/script/build_relative_pkgdir.txt @@ -0,0 +1,9 @@ +env GO111MODULE=off + +# Regression test for golang.org/issue/21309: accept relative -pkgdir argument. + +[short] skip + +mkdir $WORK/gocache +env GOCACHE=$WORK/gocache +go build -i -pkgdir=. runtime diff --git a/src/cmd/go/testdata/script/build_relative_tmpdir.txt b/src/cmd/go/testdata/script/build_relative_tmpdir.txt new file mode 100644 index 0000000..3e98a67 --- /dev/null +++ b/src/cmd/go/testdata/script/build_relative_tmpdir.txt @@ -0,0 +1,18 @@ +env GO111MODULE=off + +# If GOTMPDIR is relative, 'go build' should derive an absolute $WORK directory. +cd $WORK +mkdir tmp +env GOTMPDIR=tmp +go build -work a +stderr 'WORK=\$WORK' # the test script itself converts the absolute directory back to $WORK + +# Similarly if TMP/TMPDIR is relative. +env GOTMPDIR= +env TMP=tmp # Windows +env TMPDIR=tmp # Unix +go build -work a +stderr 'WORK=\$WORK' + +-- a/a.go -- +package a diff --git a/src/cmd/go/testdata/script/build_runtime_gcflags.txt b/src/cmd/go/testdata/script/build_runtime_gcflags.txt new file mode 100644 index 0000000..da1b65f --- /dev/null +++ b/src/cmd/go/testdata/script/build_runtime_gcflags.txt @@ -0,0 +1,11 @@ +env GO111MODULE=off +[short] skip # rebuilds all of std + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Verify the standard library (specifically runtime/internal/atomic) can be +# built with -gcflags when -n is given. See golang.org/issue/29346. +go build -n -gcflags=all='-l' std +stderr 'compile.* -l .* runtime/internal/atomic' diff --git a/src/cmd/go/testdata/script/build_tag_goexperiment.txt b/src/cmd/go/testdata/script/build_tag_goexperiment.txt new file mode 100644 index 0000000..26ad029 --- /dev/null +++ b/src/cmd/go/testdata/script/build_tag_goexperiment.txt @@ -0,0 +1,104 @@ +# compile_ext will fail if the buildtags that are enabled (or not enabled) for the +# framepointer and fieldtrack experiments are not consistent with the value of +# GOEXPSTRING (which comes from objabi.Expstring()). + +[short] skip +go run m + +-- expt_main.go -- +package main + +import ( + "os" + "strings" +) + +func main() { + fp() + ft() +} + +func hasExpEntry(s string) bool { + // script_test.go defines GOEXPSTRING to be the value of + // objabi.Expstring(), which gives the enabled experiments baked into the + // toolchain. + g := os.Getenv("GOEXPSTRING") + for _, f := range strings.Split(g, ",") { + if f == s { + return true + } + } + return false +} + +-- fp_off.go -- +// +build !goexperiment.framepointer + +package main + +import ( + "fmt" + "os" +) + +func fp() { + if hasExpEntry("framepointer") { + fmt.Println("in !framepointer build, but objabi.Expstring() has 'framepointer'") + os.Exit(1) + } +} + +-- fp_on.go -- +// +build goexperiment.framepointer + +package main + +import ( + "fmt" + "os" +) + +func fp() { + if !hasExpEntry("framepointer") { + fmt.Println("in framepointer build, but objabi.Expstring() does not have 'framepointer', is", os.Getenv("GOEXPSTRING")) + os.Exit(1) + } +} + +-- ft_off.go -- +// +build !goexperiment.fieldtrack + +package main + +import ( + "fmt" + "os" +) + +func ft() { + if hasExpEntry("fieldtrack") { + fmt.Println("in !fieldtrack build, but objabi.Expstring() has 'fieldtrack'") + os.Exit(1) + } +} + +-- ft_on.go -- +// +build goexperiment.fieldtrack + +package main + +import ( + "fmt" + "os" +) + +func ft() { + if !hasExpEntry("fieldtrack") { + fmt.Println("in fieldtrack build, but objabi.Expstring() does not have 'fieldtrack', is", os.Getenv("GOEXPSTRING")) + os.Exit(1) + } +} + +-- go.mod -- +module m +go 1.14 diff --git a/src/cmd/go/testdata/script/build_tags_no_comma.txt b/src/cmd/go/testdata/script/build_tags_no_comma.txt new file mode 100644 index 0000000..f3eb282 --- /dev/null +++ b/src/cmd/go/testdata/script/build_tags_no_comma.txt @@ -0,0 +1,4 @@ +[gccgo] skip 'gccgo has no standard packages' +go build -tags 'tag1 tag2' math +! go build -tags 'tag1,tag2 tag3' math +stderr 'space-separated list contains comma'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_test_only.txt b/src/cmd/go/testdata/script/build_test_only.txt new file mode 100644 index 0000000..8693a80 --- /dev/null +++ b/src/cmd/go/testdata/script/build_test_only.txt @@ -0,0 +1,19 @@ +# Named explicitly, test-only packages should be reported as +# unbuildable/uninstallable, even if there is a wildcard also matching. +! go build m/testonly m/testonly... +stderr 'no non-test Go files in' +! go install ./testonly +stderr 'no non-test Go files in' + +# Named through a wildcard, the test-only packages should be silently ignored. +go build m/testonly... +go install ./testonly... + +-- go.mod -- +module m + +go 1.16 +-- testonly/t_test.go -- +package testonly +-- testonly2/t.go -- +package testonly2 diff --git a/src/cmd/go/testdata/script/build_trimpath.txt b/src/cmd/go/testdata/script/build_trimpath.txt new file mode 100644 index 0000000..2c3bee8 --- /dev/null +++ b/src/cmd/go/testdata/script/build_trimpath.txt @@ -0,0 +1,162 @@ +[short] skip + +# If GOROOT_FINAL is set, 'go build -trimpath' bakes that into the resulting +# binary instead of GOROOT. Explicitly unset it here. +env GOROOT_FINAL= + +# Set up two identical directories that can be used as GOPATH. +env GO111MODULE=on +mkdir $WORK/a/src/paths $WORK/b/src/paths +cp paths.go $WORK/a/src/paths +cp paths.go $WORK/b/src/paths +cp overlay.json $WORK/a/src/paths +cp overlay.json $WORK/b/src/paths +cp go.mod $WORK/a/src/paths/ +cp go.mod $WORK/b/src/paths/ + + +# A binary built without -trimpath should contain the module root dir +# and GOROOT for debugging and stack traces. +cd $WORK/a/src/paths +go build -o $WORK/paths-dbg.exe . +exec $WORK/paths-dbg.exe $WORK/paths-dbg.exe +stdout 'binary contains module root: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain the current workspace +# or GOROOT. +go build -trimpath -o $WORK/paths-a.exe . +exec $WORK/paths-a.exe $WORK/paths-a.exe +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' + +# A binary from an external module built with -trimpath should not contain +# the current workspace or GOROOT. +go get -trimpath rsc.io/fortune +exec $WORK/paths-a.exe $GOPATH/bin/fortune$GOEXE +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' +go mod edit -droprequire rsc.io/fortune + +# Two binaries built from identical packages in different directories +# should be identical. +cd $WORK/b/src/paths +go build -trimpath -o $WORK/paths-b.exe +cmp -q $WORK/paths-a.exe $WORK/paths-b.exe + + +# Same sequence of tests but with overlays. +# A binary built without -trimpath should contain the module root dir +# and GOROOT for debugging and stack traces. +cd $WORK/a/src/paths +go build -overlay overlay.json -o $WORK/paths-dbg.exe ./overlaydir +exec $WORK/paths-dbg.exe $WORK/paths-dbg.exe +stdout 'binary contains module root: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain the current workspace +# or GOROOT. +go build -overlay overlay.json -trimpath -o $WORK/paths-a.exe ./overlaydir +exec $WORK/paths-a.exe $WORK/paths-a.exe +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different directories +# should be identical. +cd $WORK/b/src/paths +go build -overlay overlay.json -trimpath -o $WORK/paths-b.exe ./overlaydir +cmp -q $WORK/paths-a.exe $WORK/paths-b.exe + + +# Same sequence of tests but in GOPATH mode. +# A binary built without -trimpath should contain GOPATH and GOROOT. +env GO111MODULE=off +cd $WORK +env GOPATH=$WORK/a +go build -o paths-dbg.exe paths +exec ./paths-dbg.exe paths-dbg.exe +stdout 'binary contains GOPATH: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain GOPATH or GOROOT. +go build -trimpath -o paths-a.exe paths +exec ./paths-a.exe paths-a.exe +stdout 'binary contains GOPATH: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different GOPATH roots +# should be identical. +env GOPATH=$WORK/b +go build -trimpath -o paths-b.exe paths +cmp -q paths-a.exe paths-b.exe + + +# Same sequence of tests but with gccgo. +# gccgo does not support builds in module mode. +[!exec:gccgo] stop +env GOPATH=$WORK/a + +# A binary built with gccgo without -trimpath should contain the current +# GOPATH and GOROOT. +go build -compiler=gccgo -o paths-dbg.exe paths +exec ./paths-dbg.exe paths-dbg.exe +stdout 'binary contains GOPATH: true' +stdout 'binary contains GOROOT: false' # gccgo doesn't load std from GOROOT. + +# A binary built with gccgo with -trimpath should not contain GOPATH or GOROOT. +go build -compiler=gccgo -trimpath -o paths-a.exe paths +exec ./paths-a.exe paths-a.exe +stdout 'binary contains GOPATH: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different directories +# should be identical. +env GOPATH=$WORK/b +go build -compiler=gccgo -trimpath -o paths-b.exe paths +cmp -q paths-a.exe paths-b.exe + +-- paths.go -- +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + exe := os.Args[1] + data, err := ioutil.ReadFile(exe) + if err != nil { + log.Fatal(err) + } + + if os.Getenv("GO111MODULE") == "on" { + out, err := exec.Command("go", "env", "GOMOD").Output() + if err != nil { + log.Fatal(err) + } + modRoot := filepath.Dir(strings.TrimSpace(string(out))) + check(data, "module root", modRoot) + } else { + check(data, "GOPATH", os.Getenv("GOPATH")) + } + check(data, "GOROOT", os.Getenv("GOROOT")) +} + +func check(data []byte, desc, dir string) { + containsDir := bytes.Contains(data, []byte(dir)) + containsSlashDir := bytes.Contains(data, []byte(filepath.ToSlash(dir))) + fmt.Printf("binary contains %s: %v\n", desc, containsDir || containsSlashDir) +} +-- overlay.json -- +{ "Replace": { "overlaydir/paths.go": "paths.go" } } +-- go.mod -- +module paths + +go 1.14 diff --git a/src/cmd/go/testdata/script/build_trimpath_cgo.txt b/src/cmd/go/testdata/script/build_trimpath_cgo.txt new file mode 100644 index 0000000..3187b4d --- /dev/null +++ b/src/cmd/go/testdata/script/build_trimpath_cgo.txt @@ -0,0 +1,184 @@ +# This test builds a cgo binary and verifies the source directory path +# does not appear in the binary, either literally or in compressed DWARF. +# TODO(golang.org/issue/36072): ideally we should build a binary from identical +# sources in different directories and verify the binary and all intermediate +# files are identical. + +[short] skip +[!cgo] skip + +# Check that the source path appears when -trimpath is not used. +go build -o hello.exe . +grep -q gopath[/\\]src hello.exe +go run ./list-dwarf hello.exe +stdout gopath[/\\]src + +# Check that the source path does not appear when -trimpath is used. +[aix] stop # can't inspect XCOFF binaries +go build -trimpath -o hello.exe . +! grep -q gopath[/\\]src hello.exe +go run ./list-dwarf hello.exe +! stdout gopath/src + + +# Do the above, with the cgo (but not .c) sources in an overlay +# Check that the source path appears when -trimpath is not used. +mkdir $WORK/overlay +cp hello.go $WORK/overlay/hello.go +mkdir hello_overlay +cp hello.c hello_overlay/hello.c +go build -overlay overlay.json -o hello_overlay.exe ./hello_overlay +grep -q gopath[/\\]src hello_overlay.exe +! grep -q $WORK[/\\]overlay hello_overlay.exe +go run ./list-dwarf hello_overlay.exe +stdout gopath[/\\]src +! stdout $WORK[/\\]overlay + +# Check that the source path does not appear when -trimpath is used. +go build -overlay overlay.json -trimpath -o hello_overlay.exe ./hello_overlay +! grep -q gopath[/\\]src hello_overlay.exe +! grep -q $WORK[/\\]overlay hello_overlay.exe +go run ./list-dwarf hello_overlay.exe +! stdout gopath/src +! stdout $WORK[/\\]overlay + +-- go.mod -- +module m + +go 1.14 +-- overlay.json -- +{ + "Replace": { + "hello_overlay/hello.go": "../../overlay/hello.go" + } +} +-- hello.c -- +#include <stdio.h> + +void say_hello() { puts("Hello, world!\n"); } + +-- hello.go -- +package main + +// void say_hello(); +import "C" + +func main() { + C.say_hello() +} + +-- list-dwarf/list-dwarf.go -- +package main + +import ( + "debug/dwarf" + "fmt" + "io" + "log" + "os" + "sort" +) + +func main() { + files, err := run(os.Args[1]) + if err != nil { + log.Fatal(err) + } + for _, file := range files { + fmt.Println(file) + } +} + +func run(exePath string) ([]string, error) { + dwarfData, err := readDWARF(exePath) + if err != nil { + return nil, err + } + + dwarfReader := dwarfData.Reader() + files := make(map[string]bool) + for { + e, err := dwarfReader.Next() + if err != nil { + return nil, err + } + if e == nil { + break + } + lr, err := dwarfData.LineReader(e) + if err != nil { + return nil, err + } + if lr == nil { + continue + } + + var le dwarf.LineEntry + for { + if err := lr.Next(&le); err != nil { + if err == io.EOF { + break + } + return nil, err + } + files[le.File.Name] = true + } + } + + sortedFiles := make([]string, 0, len(files)) + for file := range files { + sortedFiles = append(sortedFiles, file) + } + sort.Strings(sortedFiles) + return sortedFiles, nil +} +-- list-dwarf/read_darwin.go -- +package main + +import ( + "debug/dwarf" + "debug/macho" +) + +func readDWARF(exePath string) (*dwarf.Data, error) { + machoFile, err := macho.Open(exePath) + if err != nil { + return nil, err + } + defer machoFile.Close() + return machoFile.DWARF() +} +-- list-dwarf/read_elf.go -- +// +build android dragonfly freebsd illumos linux netbsd openbsd solaris + +package main + +import ( + "debug/dwarf" + "debug/elf" +) + +func readDWARF(exePath string) (*dwarf.Data, error) { + elfFile, err := elf.Open(exePath) + if err != nil { + return nil, err + } + defer elfFile.Close() + return elfFile.DWARF() +} +-- list-dwarf/read_windows.go -- +package main + +import ( + "debug/dwarf" + "debug/pe" +) + +func readDWARF(exePath string) (*dwarf.Data, error) { + peFile, err := pe.Open(exePath) + if err != nil { + return nil, err + } + defer peFile.Close() + return peFile.DWARF() +} diff --git a/src/cmd/go/testdata/script/build_unsupported_goos.txt b/src/cmd/go/testdata/script/build_unsupported_goos.txt new file mode 100644 index 0000000..d61e420 --- /dev/null +++ b/src/cmd/go/testdata/script/build_unsupported_goos.txt @@ -0,0 +1,6 @@ +[gccgo] skip # gccgo assumes cross-compilation is always possible + +env GOOS=windwos + +! go build -n exclude +stderr 'unsupported GOOS/GOARCH pair'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_vendor.txt b/src/cmd/go/testdata/script/build_vendor.txt new file mode 100644 index 0000000..f430ff2 --- /dev/null +++ b/src/cmd/go/testdata/script/build_vendor.txt @@ -0,0 +1,42 @@ +# Build +env GO111MODULE=off +go build vend/x +! stdout . +! stderr . + +-- vend/dir1/dir1.go -- +package dir1 +-- vend/subdir/bad.go -- +package subdir + +import _ "r" +-- vend/subdir/good.go -- +package subdir + +import _ "p" +-- vend/vendor/p/p.go -- +package p +-- vend/vendor/q/q.go -- +package q +-- vend/vendor/vend/dir1/dir2/dir2.go -- +package dir2 +-- vend/x/invalid/invalid.go -- +package invalid + +import "vend/x/invalid/vendor/foo" +-- vend/x/vendor/p/p/p.go -- +package p + +import _ "notfound" +-- vend/x/vendor/p/p.go -- +package p +-- vend/x/vendor/r/r.go -- +package r +-- vend/x/x.go -- +package x + +import _ "p" +import _ "q" +import _ "r" +import _ "vend/dir1" // not vendored +import _ "vend/dir1/dir2" // vendored diff --git a/src/cmd/go/testdata/script/cache_unix.txt b/src/cmd/go/testdata/script/cache_unix.txt new file mode 100644 index 0000000..0e07ba6 --- /dev/null +++ b/src/cmd/go/testdata/script/cache_unix.txt @@ -0,0 +1,36 @@ +env GO111MODULE=off + +# Integration test for cache directory calculation (cmd/go/internal/cache). + +[windows] skip +[darwin] skip +[plan9] skip + +mkdir $WORK/gocache +mkdir $WORK/xdg +mkdir $WORK/home + +# Set GOCACHE, XDG_CACHE_HOME, and HOME. +env GOCACHE=$WORK/gocache +env XDG_CACHE_HOME=$WORK/xdg +env HOME=$WORK/home + +# With all three set, we should prefer GOCACHE. +go env GOCACHE +stdout '\$WORK/gocache$' + +# Without GOCACHE, we should prefer XDG_CACHE_HOME over HOME. +env GOCACHE= +go env GOCACHE +stdout '\$WORK/xdg/go-build$$' + +# With only HOME set, we should use $HOME/.cache. +env XDG_CACHE_HOME= +go env GOCACHE +stdout '\$WORK/home/.cache/go-build$' + +# With no guidance from the environment, we must disable the cache, but that +# should not cause commands that do not write to the cache to fail. +env HOME= +go env GOCACHE +stdout 'off' diff --git a/src/cmd/go/testdata/script/cache_vet.txt b/src/cmd/go/testdata/script/cache_vet.txt new file mode 100644 index 0000000..928024e --- /dev/null +++ b/src/cmd/go/testdata/script/cache_vet.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +[short] skip +[GODEBUG:gocacheverify=1] skip +[gccgo] skip # gccgo has no standard packages + +# Start with a clean build cache: +# test failures may be masked if the cache has just the right entries already. +env GOCACHE=$WORK/cache + +# Run 'go vet os/user' once to warm up the cache. +go vet os/user + +# Check that second vet reuses cgo-derived inputs. +# The first command could be build instead of vet, +# except that if the cache is empty and there's a net.a +# in GOROOT/pkg, the build will not bother to regenerate +# and cache the cgo outputs, whereas vet always will. + +go vet -x os/user +! stderr '^(clang|gcc)' # should not have run compiler +! stderr '[\\/]cgo ' # should not have run cgo diff --git a/src/cmd/go/testdata/script/cgo_asm_error.txt b/src/cmd/go/testdata/script/cgo_asm_error.txt new file mode 100644 index 0000000..7aaa713 --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_asm_error.txt @@ -0,0 +1,25 @@ +[!cgo] skip + +# Test that cgo package can't contain a go assembly file. + +# Ensure the build fails and reports that the package has a Go assembly file. +! go build cgoasm +stderr 'package using cgo has Go assembly file' + +-- go.mod -- +module cgoasm + +go 1.16 +-- p.go -- +package p + +/* +// hi +*/ +import "C" + +func F() {} +-- p.s -- +TEXT asm(SB),$0 + RET + diff --git a/src/cmd/go/testdata/script/cgo_bad_directives.txt b/src/cmd/go/testdata/script/cgo_bad_directives.txt new file mode 100644 index 0000000..6bf3beb --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_bad_directives.txt @@ -0,0 +1,129 @@ +[!cgo] skip +[short] skip + +cp x.go.txt x.go + +# Only allow //go:cgo_ldflag .* in cgo-generated code +[gc] cp x_gc.go.txt x.go +[gc] ! go build x +[gc] stderr '//go:cgo_ldflag .* only allowed in cgo-generated code' + +# Ignore _* files +rm x.go +! go build . +stderr 'no Go files' +cp cgo_yy.go.txt _cgo_yy.go +! go build . +stderr 'no Go files' #_* files are ignored... + +[gc] ! go build _cgo_yy.go # ... but if forced, the comment is rejected +# Actually, today there is a separate issue that _ files named +# on the command line are ignored. Once that is fixed, +# we want to see the cgo_ldflag error. +[gc] stderr '//go:cgo_ldflag only allowed in cgo-generated code|no Go files' + +rm _cgo_yy.go + +# Reject #cgo CFLAGS: -fplugin=foo.so +cp x.go.txt x.go +cp y_fplugin.go.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -fplugin=foo.so' + +# Reject #cgo CFLAGS: -lbar -fplugin=foo.so +cp y_lbar_fplugin.go.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -fplugin=foo.so' + +# Reject #cgo pkg-config: -foo +cp y_pkgconfig_dash_foo.txt y.go +! go build x +stderr 'invalid pkg-config package name: -foo' + +# Reject #cgo pkg-config: @foo +cp y_pkgconfig_at_foo.txt y.go +! go build x +stderr 'invalid pkg-config package name: @foo' + +# Reject #cgo CFLAGS: @foo +cp y_cflags_at_foo.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: @foo' + +# Reject #cgo CFLAGS: -D +cp y_cflags_dash_d.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -D without argument' + +# Note that -I @foo is allowed because we rewrite it into -I /path/to/src/@foo +# before the check is applied. There's no such rewrite for -D. + +# Reject #cgo CFLAGS: -D @foo +cp y_cflags_dash_d_space_at_foo.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -D @foo' + +# Reject #cgo CFLAGS -D@foo +cp y_cflags_dash_d_at_foo.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -D@foo' + +# Check for CFLAGS in commands +env CGO_CFLAGS=-D@foo +cp y_no_cflags.txt y.go +go build -n x +stderr '-D@foo' + +-- go.mod -- +module x + +go 1.16 +-- x_gc.go.txt -- +package x + +//go:cgo_ldflag "-fplugin=foo.so" + +import "C" +-- cgo_yy.go.txt -- +package x + +//go:cgo_ldflag "-fplugin=foo.so" + +import "C" +-- x.go.txt -- +package x +-- y_fplugin.go.txt -- +package x +// #cgo CFLAGS: -fplugin=foo.so +import "C" +-- y_lbar_fplugin.go.txt -- +package x +// #cgo CFLAGS: -Ibar -fplugin=foo.so +import "C" +-- y_pkgconfig_dash_foo.txt -- +package x +// #cgo pkg-config: -foo +import "C" +-- y_pkgconfig_at_foo.txt -- +package x +// #cgo pkg-config: @foo +import "C" +-- y_cflags_at_foo.txt -- +package x +// #cgo CFLAGS: @foo +import "C" +-- y_cflags_dash_d.txt -- +package x +// #cgo CFLAGS: -D +import "C" +-- y_cflags_dash_d_space_at_foo.txt -- +package x +// #cgo CFLAGS: -D @foo +import "C" +-- y_cflags_dash_d_at_foo.txt -- +package x +// #cgo CFLAGS: -D@foo +import "C" +-- y_no_cflags.txt -- +package x +import "C" diff --git a/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt b/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt new file mode 100644 index 0000000..bd4777c --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt @@ -0,0 +1,15 @@ +[!cgo] skip +[!race] skip + +go list -race -deps foo +stdout syscall + +-- go.mod -- +module foo + +go 1.16 +-- foo.go -- +package foo + +// #include <stdio.h> +import "C" diff --git a/src/cmd/go/testdata/script/cgo_flag_contains_space.txt b/src/cmd/go/testdata/script/cgo_flag_contains_space.txt new file mode 100644 index 0000000..a3372bb --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_flag_contains_space.txt @@ -0,0 +1,16 @@ +[short] skip +[!cgo] skip + +env GOCACHE=$WORK/gocache # Looking for compile flags, so need a clean cache. +go build -x -n main.go +stderr '"-I[^"]+c flags"' # find quoted c flags +! stderr '"-I[^"]+c flags".*"-I[^"]+c flags"' # don't find too many quoted c flags per line +stderr '"-L[^"]+ld flags"' # find quoted ld flags +! stderr '"-L[^"]+c flags".*"-L[^"]+c flags"' # don't find too many quoted ld flags per line + +-- main.go -- +package main +// #cgo CFLAGS: -I"c flags" +// #cgo LDFLAGS: -L"ld flags" +import "C" +func main() {} diff --git a/src/cmd/go/testdata/script/cgo_path.txt b/src/cmd/go/testdata/script/cgo_path.txt new file mode 100644 index 0000000..be9609e --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_path.txt @@ -0,0 +1,43 @@ +[!cgo] skip + +# Set CC explicitly to something that requires a PATH lookup. +# Normally, the default is gcc or clang, but if CC was set during make.bash, +# that becomes the default. +[exec:clang] env CC=clang +[exec:gcc] env CC=gcc +[!exec:clang] [!exec:gcc] skip 'Unknown C compiler' + +env GOCACHE=$WORK/gocache # Looking for compile flags, so need a clean cache. +[!windows] env PATH=.:$PATH +[!windows] chmod 0755 p/gcc p/clang +[!windows] exists -exec p/gcc p/clang +[windows] exists -exec p/gcc.bat p/clang.bat +! exists p/bug.txt +! go build -x +stderr '^cgo: exec (clang|gcc): (clang|gcc) resolves to executable relative to current directory \(.[/\\](clang|gcc)(.bat)?\)$' +! exists p/bug.txt + +-- go.mod -- +module m + +-- m.go -- +package m + +import _ "m/p" + +-- p/p.go -- +package p + +// #define X 1 +import "C" + +-- p/gcc -- +#!/bin/sh +echo ran gcc >bug.txt +-- p/clang -- +#!/bin/sh +echo ran clang >bug.txt +-- p/gcc.bat -- +echo ran gcc >bug.txt +-- p/clang.bat -- +echo ran clang >bug.txt diff --git a/src/cmd/go/testdata/script/cgo_path_space.txt b/src/cmd/go/testdata/script/cgo_path_space.txt new file mode 100644 index 0000000..654295d --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_path_space.txt @@ -0,0 +1,56 @@ +# Check that if the PATH directory containing the C compiler has a space, +# we can still use that compiler with cgo. +# Verifies #43808. +[!cgo] skip + +# Set CC explicitly to something that requires a PATH lookup. +# Normally, the default is gcc or clang, but if CC was set during make.bash, +# that becomes the default. +[exec:clang] env CC=clang +[exec:gcc] env CC=gcc +[!exec:clang] [!exec:gcc] skip 'Unknown C compiler' + +[!windows] chmod 0755 $WORK/'program files'/clang +[!windows] chmod 0755 $WORK/'program files'/gcc +[!windows] exists -exec $WORK/'program files'/clang +[!windows] exists -exec $WORK/'program files'/gcc +[!windows] env PATH=$WORK/'program files':$PATH +[windows] exists -exec $WORK/'program files'/gcc.bat +[windows] exists -exec $WORK/'program files'/clang.bat +[windows] env PATH=$WORK\'program files';%PATH% + +! exists $WORK/log.txt +? go build -x +exists $WORK/log.txt +rm $WORK/log.txt + +# TODO(#41400, #43078): when CC is set explicitly, it should be allowed to +# contain spaces separating arguments, and it should be possible to quote +# arguments with spaces (including the path), as in CGO_CFLAGS and other +# variables. For now, this doesn't work. +[!windows] env CC=$WORK/'program files'/gcc +[windows] env CC=$WORK\'program files'\gcc.bat +! go build -x +! exists $WORK/log.txt + +-- go.mod -- +module m + +-- m.go -- +package m + +// #define X 1 +import "C" + +-- $WORK/program files/gcc -- +#!/bin/sh + +echo ok >$WORK/log.txt +-- $WORK/program files/clang -- +#!/bin/sh + +echo ok >$WORK/log.txt +-- $WORK/program files/gcc.bat -- +echo ok >%WORK%\log.txt +-- $WORK/program files/clang.bat -- +echo ok >%WORK%\log.txt diff --git a/src/cmd/go/testdata/script/cgo_syso_issue29253.txt b/src/cmd/go/testdata/script/cgo_syso_issue29253.txt new file mode 100644 index 0000000..4fb5cca --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_syso_issue29253.txt @@ -0,0 +1,31 @@ +env GO111MODULE=off +[short] skip + +# This test tests that we can link in-package syso files that provides symbols +# for cgo. See issue 29253. +[!cgo] stop +[!gc] stop +cc -c -o pkg/o.syso ext.c +go build main.go + +-- ext.c -- +// +build ignore + +int f() { return 42; } +-- pkg/pkg.go -- +package pkg + +// extern int f(void); +import "C" + +func init() { + if v := C.f(); v != 42 { + panic(v) + } +} +-- main.go -- +package main + +import _ "pkg" + +func main() {} diff --git a/src/cmd/go/testdata/script/clean_binary.txt b/src/cmd/go/testdata/script/clean_binary.txt new file mode 100644 index 0000000..7335f8a --- /dev/null +++ b/src/cmd/go/testdata/script/clean_binary.txt @@ -0,0 +1,78 @@ +# Build something to create the executable, including several cases +[short] skip + +# --------------------- clean executables ------------------------- + +# case1: test file-named executable 'main' +env GO111MODULE=on + +! exists main$GOEXE +go build main.go +exists -exec main$GOEXE +go clean +! exists main$GOEXE + +# case2: test module-named executable 'a.b.c' +! exists a.b.c$GOEXE +go build +exists -exec a.b.c$GOEXE +go clean +! exists a.b.c$GOEXE + +# case3: directory-named executable 'src' +env GO111MODULE=off + +! exists src$GOEXE +go build +exists -exec src$GOEXE +go clean +! exists src$GOEXE + +# --------------------- clean test files ------------------------- + +# case1: test file-named test file +env GO111MODULE=on + +! exists main.test$GOEXE +go test -c main_test.go +exists -exec main.test$GOEXE +go clean +! exists main.test$GOEXE + +# case2: test module-named test file +! exists a.b.c.test$GOEXE +go test -c +exists -exec a.b.c.test$GOEXE +go clean +! exists a.b.c.test$GOEXE + +# case3: test directory-based test file +env GO111MODULE=off + +! exists src.test$GOEXE +go test -c +exists -exec src.test$GOEXE +go clean +! exists src.test$GOEXE + +-- main.go -- +package main + +import "fmt" + +func main() { + fmt.Println("hello!") +} + +-- main_test.go -- +package main + +import "testing" + +func TestSomething(t *testing.T) { +} + +-- go.mod -- +module example.com/a.b.c/v2 + +go 1.12
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/clean_cache_n.txt b/src/cmd/go/testdata/script/clean_cache_n.txt new file mode 100644 index 0000000..4497b36 --- /dev/null +++ b/src/cmd/go/testdata/script/clean_cache_n.txt @@ -0,0 +1,25 @@ +# We're testing cache behavior, so start with a clean GOCACHE. +env GOCACHE=$WORK/cache + +# Build something so that the cache gets populates +go build main.go + +# Check that cache contains directories before running +exists $GOCACHE/00 + +# Run go clean -cache -n and ensure that directories weren't deleted +go clean -cache -n +exists $GOCACHE/00 + +# Re-run go clean cache without the -n flag go ensure that directories were properly removed +go clean -cache +! exists $GOCACHE/00 + +-- main.go -- +package main + +import "fmt" + +func main() { + fmt.Println("hello!") +} diff --git a/src/cmd/go/testdata/script/clean_testcache.txt b/src/cmd/go/testdata/script/clean_testcache.txt new file mode 100644 index 0000000..b3f32fe --- /dev/null +++ b/src/cmd/go/testdata/script/clean_testcache.txt @@ -0,0 +1,26 @@ +env GO111MODULE=off +[short] skip + +# go clean -testcache +# should work (see golang.org/issue/29757). +cd x +go test x_test.go +go clean -testcache +go test x_test.go +! stdout 'cached' + +# golang.org/issue/29100: 'go clean -testcache' should succeed +# if the cache directory doesn't exist at all. +# It should not write a testexpire.txt file, since there are no +# test results that need to be invalidated in the first place. +env GOCACHE=$WORK/nonexistent +go clean -testcache +! exists $WORK/nonexistent + +-- x/x_test.go -- +package x_test +import ( + "testing" +) +func TestMain(t *testing.T) { +} diff --git a/src/cmd/go/testdata/script/cmd_import_error.txt b/src/cmd/go/testdata/script/cmd_import_error.txt new file mode 100644 index 0000000..dea76f4 --- /dev/null +++ b/src/cmd/go/testdata/script/cmd_import_error.txt @@ -0,0 +1,16 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/31031: +# Importing or loading a non-existent package in cmd/ should print +# a clear error in module mode. + +! go list cmd/unknown +stderr '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' + +go list -f '{{range .DepsErrors}}{{.Err}}{{end}}' x.go +stdout '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' + +-- x.go -- +package x + +import _ "cmd/unknown" diff --git a/src/cmd/go/testdata/script/cover_asm.txt b/src/cmd/go/testdata/script/cover_asm.txt new file mode 100644 index 0000000..57f76d6 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_asm.txt @@ -0,0 +1,33 @@ +[short] skip +[gccgo] skip # gccgo has no cover tool + +# Test cover for a package that has an assembly function. + +go test -outputdir=$WORK -coverprofile=cover.out coverasm +go tool cover -func=$WORK/cover.out +stdout '\tg\t*100.0%' # Check g is 100% covered. +! stdout '\tf\t*[0-9]' # Check for no coverage on the assembly function + +-- go.mod -- +module coverasm + +go 1.16 +-- p.go -- +package p + +func f() + +func g() { + println("g") +} +-- p.s -- +// empty asm file, +// so go test doesn't complain about declaration of f in p.go. +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) { + g() +} diff --git a/src/cmd/go/testdata/script/cover_atomic_pkgall.txt b/src/cmd/go/testdata/script/cover_atomic_pkgall.txt new file mode 100644 index 0000000..c3bc67d --- /dev/null +++ b/src/cmd/go/testdata/script/cover_atomic_pkgall.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +[short] skip + +go test -coverpkg=all -covermode=atomic x +stdout ok[\s\S]+?coverage + +[!race] stop + +go test -coverpkg=all -race x +stdout ok[\s\S]+?coverage + +-- x/x.go -- +package x + +import _ "sync/atomic" + +func F() {} + +-- x/x_test.go -- +package x + +import "testing" + +func TestF(t *testing.T) { F() } diff --git a/src/cmd/go/testdata/script/cover_blank_func_decl.txt b/src/cmd/go/testdata/script/cover_blank_func_decl.txt new file mode 100644 index 0000000..e7d5250 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_blank_func_decl.txt @@ -0,0 +1,35 @@ +[short] skip +go test -cover coverblank +stdout 'coverage: 100.0% of statements' + + +-- go.mod -- +module coverblank + +go 1.16 +-- a.go -- +package coverblank + +func _() { + println("unreachable") +} + +type X int + +func (x X) Print() { + println(x) +} + +func (x X) _() { + println("unreachable") +} + +-- a_test.go -- +package coverblank + +import "testing" + +func TestX(t *testing.T) { + var x X + x.Print() +} diff --git a/src/cmd/go/testdata/script/cover_cgo.txt b/src/cmd/go/testdata/script/cover_cgo.txt new file mode 100644 index 0000000..9cf78f7 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_cgo.txt @@ -0,0 +1,42 @@ +[short] skip +[!cgo] skip +[gccgo] skip # gccgo has no cover tool + +# Test coverage on cgo code. + +go test -short -cover cgocover +stdout 'coverage:.*[1-9][0-9.]+%' +! stderr '[^0-9]0\.0%' + +-- go.mod -- +module cgocover + +go 1.16 +-- p.go -- +package p + +/* +void +f(void) +{ +} +*/ +import "C" + +var b bool + +func F() { + if b { + for { + } + } + C.f() +} +-- p_test.go -- +package p + +import "testing" + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_cgo_extra_file.txt b/src/cmd/go/testdata/script/cover_cgo_extra_file.txt new file mode 100644 index 0000000..c53b979 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_cgo_extra_file.txt @@ -0,0 +1,48 @@ +[short] skip +[!cgo] skip +[gccgo] skip # gccgo has no cover tool + +# Test coverage on cgo code. This test case includes an +# extra empty non-cgo file in the package being checked. + +go test -short -cover cgocover4 +stdout 'coverage:.*[1-9][0-9.]+%' +! stderr '[^0-9]0\.0%' + +-- go.mod -- +module cgocover4 + +go 1.16 +-- notcgo.go -- +package p +-- p.go -- +package p + +/* +void +f(void) +{ +} +*/ +import "C" + +var b bool + +func F() { + if b { + for { + } + } + C.f() +} +-- x_test.go -- +package p_test + +import ( + . "cgocover4" + "testing" +) + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_cgo_extra_test.txt b/src/cmd/go/testdata/script/cover_cgo_extra_test.txt new file mode 100644 index 0000000..b501ab0 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_cgo_extra_test.txt @@ -0,0 +1,49 @@ +[short] skip +[!cgo] skip +[gccgo] skip # gccgo has no cover tool + +# Test coverage on cgo code. This test case has an external +# test that tests the code and an in-package test file with +# no test cases. + +go test -short -cover cgocover3 +stdout 'coverage:.*[1-9][0-9.]+%' +! stderr '[^0-9]0\.0%' + +-- go.mod -- +module cgocover3 + +go 1.16 +-- p.go -- +package p + +/* +void +f(void) +{ +} +*/ +import "C" + +var b bool + +func F() { + if b { + for { + } + } + C.f() +} +-- p_test.go -- +package p +-- x_test.go -- +package p_test + +import ( + . "cgocover3" + "testing" +) + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_cgo_xtest.txt b/src/cmd/go/testdata/script/cover_cgo_xtest.txt new file mode 100644 index 0000000..79cc08c --- /dev/null +++ b/src/cmd/go/testdata/script/cover_cgo_xtest.txt @@ -0,0 +1,45 @@ +[short] skip +[!cgo] skip +[gccgo] skip # gccgo has no cover tool + +# Test cgo coverage with an external test. + +go test -short -cover cgocover2 +stdout 'coverage:.*[1-9][0-9.]+%' +! stderr '[^0-9]0\.0%' + +-- go.mod -- +module cgocover2 + +go 1.16 +-- p.go -- +package p + +/* +void +f(void) +{ +} +*/ +import "C" + +var b bool + +func F() { + if b { + for { + } + } + C.f() +} +-- x_test.go -- +package p_test + +import ( + . "cgocover2" + "testing" +) + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_dash_c.txt b/src/cmd/go/testdata/script/cover_dash_c.txt new file mode 100644 index 0000000..8950f8d --- /dev/null +++ b/src/cmd/go/testdata/script/cover_dash_c.txt @@ -0,0 +1,31 @@ +[short] skip +[gccgo] skip + +# Test for issue 24588 + +go test -c -o $WORK/coverdep -coverprofile=$WORK/no/such/dir/cover.out coverdep +exists -exec $WORK/coverdep + +-- go.mod -- +module coverdep + +go 1.16 +-- p.go -- +package p + +import _ "coverdep/p1" + +func F() { +} +-- p1/p1.go -- +package p1 + +import _ "errors" +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_dep_loop.txt b/src/cmd/go/testdata/script/cover_dep_loop.txt new file mode 100644 index 0000000..36ea6e0 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_dep_loop.txt @@ -0,0 +1,36 @@ +[short] skip +[gccgo] skip + +# coverdep2/p1's xtest imports coverdep2/p2 which imports coverdep2/p1. +# Make sure that coverage on coverdep2/p2 recompiles coverdep2/p2. + +go test -short -cover coverdep2/p1 +stdout 'coverage: 100.0% of statements' # expect 100.0% coverage + +-- go.mod -- +module coverdep2 + +go 1.16 +-- p1/p.go -- +package p1 + +func F() int { return 1 } +-- p1/p_test.go -- +package p1_test + +import ( + "coverdep2/p2" + "testing" +) + +func Test(t *testing.T) { + p2.F() +} +-- p2/p2.go -- +package p2 + +import "coverdep2/p1" + +func F() { + p1.F() +} diff --git a/src/cmd/go/testdata/script/cover_dot_import.txt b/src/cmd/go/testdata/script/cover_dot_import.txt new file mode 100644 index 0000000..d492e42 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_dot_import.txt @@ -0,0 +1,29 @@ +[short] skip +[gccgo] skip # gccgo has no cover tool + +go test -coverpkg=coverdot/a,coverdot/b coverdot/b +! stderr '[^0-9]0\.0%' +! stdout '[^0-9]0\.0%' + +-- go.mod -- +module coverdot + +go 1.16 +-- a/a.go -- +package a + +func F() {} +-- b/b.go -- +package b + +import . "coverdot/a" + +func G() { F() } +-- b/b_test.go -- +package b + +import "testing" + +func TestG(t *testing.T) { + G() +} diff --git a/src/cmd/go/testdata/script/cover_error.txt b/src/cmd/go/testdata/script/cover_error.txt new file mode 100644 index 0000000..583a664 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_error.txt @@ -0,0 +1,74 @@ +[short] skip +[gccgo] skip + +# Test line numbers in cover errors. + +# Get errors from a go test into stderr.txt +! go test coverbad +stderr 'p\.go:4' # look for error at coverbad/p.go:4 +[cgo] stderr 'p1\.go:6' # look for error at coverbad/p.go:6 +! stderr $WORK # make sure temporary directory isn't in error + +cp stderr $WORK/stderr.txt + +# Clean out character positions from stderr.txt +# It's OK that stderr2 drops the character position in the error, +# because of the //line directive (see golang.org/issue/22662). +go run clean_charpos.go $WORK/stderr.txt & + +# Get errors from coverage into stderr2.txt +! go test -cover coverbad +cp stderr $WORK/stderr2.txt + +wait # for go run above + +cmp $WORK/stderr.txt $WORK/stderr2.txt + +-- go.mod -- +module coverbad + +go 1.16 +-- p.go -- +package p + +func f() { + g() +} +-- p1.go -- +package p + +import "C" + +func h() { + j() +} +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) {} +-- clean_charpos.go -- +// +build ignore + +package main + +import ( + "log" + "os" + "strings" +) + +func main() { + log.SetFlags(0) + b, err := os.ReadFile(os.Args[1]) + if err != nil { + log.Fatal(err) + } + s := strings.ReplaceAll(string(b), "p.go:4:2:", "p.go:4:") + s = strings.ReplaceAll(s, "p1.go:6:2:", "p1.go:6:") + os.WriteFile(os.Args[1], []byte(s), 0644) + if err != nil { + log.Fatal(err) + } +} diff --git a/src/cmd/go/testdata/script/cover_import_main_loop.txt b/src/cmd/go/testdata/script/cover_import_main_loop.txt new file mode 100644 index 0000000..eb6de67 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_import_main_loop.txt @@ -0,0 +1,26 @@ +[gccgo] skip # gccgo has no cover tool + +! go test -n importmain/test +stderr 'not an importable package' # check that import main was detected +! go test -n -cover importmain/test +stderr 'not an importable package' # check that import main was detected + +-- go.mod -- +module importmain + +go 1.16 +-- ismain/main.go -- +package main + +import _ "importmain/test" + +func main() {} +-- test/test.go -- +package test +-- test/test_test.go -- +package test_test + +import "testing" +import _ "importmain/ismain" + +func TestCase(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/cover_mod_empty.txt b/src/cmd/go/testdata/script/cover_mod_empty.txt new file mode 100644 index 0000000..3c45243 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_mod_empty.txt @@ -0,0 +1,9 @@ +go tool cover -func=cover.out +stdout total.*statements.*0.0% + +go mod init golang.org/issue/33855 + +go tool cover -func=cover.out +stdout total.*statements.*0.0% + +-- cover.out -- diff --git a/src/cmd/go/testdata/script/cover_modes.txt b/src/cmd/go/testdata/script/cover_modes.txt new file mode 100644 index 0000000..f8a399d --- /dev/null +++ b/src/cmd/go/testdata/script/cover_modes.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +# Coverage analysis should use 'set' mode by default, +# and should merge coverage profiles correctly. + +[short] skip +[gccgo] skip # gccgo has no cover tool + +go test -short -cover encoding/binary errors -coverprofile=$WORK/cover.out +! stderr '[^0-9]0\.0%' +! stdout '[^0-9]0\.0%' + +grep -count=1 '^mode: set$' $WORK/cover.out +grep 'errors\.go' $WORK/cover.out +grep 'binary\.go' $WORK/cover.out + +[!race] stop + +go test -short -race -cover encoding/binary errors -coverprofile=$WORK/cover.out +! stderr '[^0-9]0\.0%' +! stdout '[^0-9]0\.0%' + +grep -count=1 '^mode: atomic$' $WORK/cover.out +grep 'errors\.go' $WORK/cover.out +grep 'binary\.go' $WORK/cover.out diff --git a/src/cmd/go/testdata/script/cover_pattern.txt b/src/cmd/go/testdata/script/cover_pattern.txt new file mode 100644 index 0000000..ec0850c --- /dev/null +++ b/src/cmd/go/testdata/script/cover_pattern.txt @@ -0,0 +1,41 @@ +[gccgo] skip + +# If coverpkg=m/sleepy... expands by package loading +# (as opposed to pattern matching on deps) +# then it will try to load sleepybad, which does not compile, +# and the test command will fail. +! go list m/sleepy... +go test -c -n -coverprofile=$TMPDIR/cover.out -coverpkg=m/sleepy... -run=^$ m/sleepy1 + +-- go.mod -- +module m + +go 1.16 +-- sleepy1/p_test.go -- +package p + +import ( + "testing" + "time" +) + +func Test1(t *testing.T) { + time.Sleep(200 * time.Millisecond) +} +-- sleepy2/p_test.go -- +package p + +import ( + "testing" + "time" +) + +func Test1(t *testing.T) { + time.Sleep(200 * time.Millisecond) +} +-- sleepybad/p.go -- +package p + +import ^ + +var _ = io.DoesNotExist diff --git a/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt b/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt new file mode 100644 index 0000000..f21cd8b --- /dev/null +++ b/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt @@ -0,0 +1,46 @@ +# This test checks that multiple main packages can be tested +# with -coverpkg=all without duplicate symbol errors. +# Verifies golang.org/issue/30374, golang.org/issue/34114. + +[short] skip +cd $GOPATH/src/example.com/cov + +env GO111MODULE=on +go test -coverpkg=all ./... + +env GO111MODULE=off +go test -coverpkg=all ./... + +-- $GOPATH/src/example.com/cov/go.mod -- +module example.com/cov + +-- $GOPATH/src/example.com/cov/mainonly/mainonly.go -- +package main + +func main() {} + +-- $GOPATH/src/example.com/cov/mainwithtest/mainwithtest.go -- +package main + +func main() {} + +func Foo() {} + +-- $GOPATH/src/example.com/cov/mainwithtest/mainwithtest_test.go -- +package main + +import "testing" + +func TestFoo(t *testing.T) { + Foo() +} + +-- $GOPATH/src/example.com/cov/xtest/x.go -- +package x + +-- $GOPATH/src/example.com/cov/xtest/x_test.go -- +package x_test + +import "testing" + +func TestX(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/cover_pkgall_runtime.txt b/src/cmd/go/testdata/script/cover_pkgall_runtime.txt new file mode 100644 index 0000000..9927c30 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_pkgall_runtime.txt @@ -0,0 +1,23 @@ +env GO111MODULE=off + +# Issue 23882 + +[short] skip + +go test -coverpkg=all x +stdout ok[\s\S]+?coverage + +[!race] stop + +go test -coverpkg=all -race x +stdout ok[\s\S]+?coverage + +-- x/x.go -- +package x +import _ "runtime" +func F() {} + +-- x/x_test.go -- +package x +import "testing" +func TestF(t *testing.T) { F() } diff --git a/src/cmd/go/testdata/script/cover_runs.txt b/src/cmd/go/testdata/script/cover_runs.txt new file mode 100644 index 0000000..38a7bb7 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_runs.txt @@ -0,0 +1,13 @@ +[gccgo] skip 'gccgo has no cover tool' +[short] skip + +go test -short -coverpkg=strings strings regexp +! stdout '[^0-9]0\.0%' +stdout 'strings.*coverage:.*[1-9][0-9.]+%' +stdout 'regexp.*coverage:.*[1-9][0-9.]+%' + +go test -short -cover strings math regexp +! stdout '[^0-9]0\.0%' +stdout 'strings.*coverage:.*[1-9][0-9.]+%' +stdout 'math.*coverage:.*[1-9][0-9.]+%' +stdout 'regexp.*coverage:.*[1-9][0-9.]+%'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/cover_statements.txt b/src/cmd/go/testdata/script/cover_statements.txt new file mode 100644 index 0000000..4f3c9ca --- /dev/null +++ b/src/cmd/go/testdata/script/cover_statements.txt @@ -0,0 +1,61 @@ +[short] skip +go test -cover ./pkg1 ./pkg2 ./pkg3 ./pkg4 +stdout 'pkg1 \[no test files\]' +stdout 'pkg2 \S+ coverage: 0.0% of statements \[no tests to run\]' +stdout 'pkg3 \S+ coverage: 100.0% of statements' +stdout 'pkg4 \S+ coverage: \[no statements\]' + +-- go.mod -- +module m + +go 1.16 +-- pkg1/a.go -- +package pkg1 + +import "fmt" + +func F() { + fmt.Println("pkg1") +} +-- pkg2/a.go -- +package pkg2 + +import "fmt" + +func F() { + fmt.Println("pkg2") +} +-- pkg2/a_test.go -- +package pkg2 +-- pkg3/a.go -- +package pkg3 + +import "fmt" + +func F() { + fmt.Println("pkg3") +} +-- pkg3/a_test.go -- +package pkg3 + +import "testing" + +func TestF(t *testing.T) { + F() +} +-- pkg4/a.go -- +package pkg4 + +type T struct { + X bool +} +-- pkg4/a_test.go -- +package pkg4 + +import ( + "testing" +) + +func TestT(t *testing.T) { + _ = T{} +} diff --git a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt new file mode 100644 index 0000000..433af9a --- /dev/null +++ b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt @@ -0,0 +1,28 @@ +[short] skip +[gccgo] skip # gccgo has no cover tool + +go test -short -cover -covermode=atomic -coverpkg=coverdep/p1 coverdep + +-- go.mod -- +module coverdep + +go 1.16 +-- p.go -- +package p + +import _ "coverdep/p1" + +func F() { +} +-- p1/p1.go -- +package p1 + +import _ "errors" +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cpu_profile_twice.txt b/src/cmd/go/testdata/script/cpu_profile_twice.txt new file mode 100644 index 0000000..38d6439 --- /dev/null +++ b/src/cmd/go/testdata/script/cpu_profile_twice.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +# Issue 23150 + +[short] skip + +go test -o=$WORK/x.test -cpuprofile=$WORK/cpu_profile_twice.out x +rm $WORK/cpu_profile_twice.out + +go test -o=$WORK/x.test -cpuprofile=$WORK/cpu_profile_twice.out x +exists $WORK/cpu_profile_twice.out + + +-- x/x_test.go -- +package x_test +import ( + "testing" + "time" +) +func TestSleep(t *testing.T) { + time.Sleep(10 * time.Millisecond) +} diff --git a/src/cmd/go/testdata/script/devnull.txt b/src/cmd/go/testdata/script/devnull.txt new file mode 100644 index 0000000..ccb866a --- /dev/null +++ b/src/cmd/go/testdata/script/devnull.txt @@ -0,0 +1,26 @@ +env GO111MODULE=off + +# Issue 28035: go test -c -o NUL should work. +# Issue 28549: go test -c -o /dev/null should not overwrite /dev/null when run as root. +cd x +cmp $devnull $WORK/empty.txt +go test -o=$devnull -c +! exists x.test$GOEXE +cmp $devnull $WORK/empty.txt + +# Issue 12407: go build -o /dev/null should succeed. +cd .. +go build -o $devnull y +cmp $devnull $WORK/empty.txt + +-- x/x_test.go -- +package x_test +import ( + "testing" +) +func TestNUL(t *testing.T) { +} +-- y/y.go -- +package y +func main() {} +-- $WORK/empty.txt -- diff --git a/src/cmd/go/testdata/script/doc.txt b/src/cmd/go/testdata/script/doc.txt new file mode 100644 index 0000000..3ff1aab --- /dev/null +++ b/src/cmd/go/testdata/script/doc.txt @@ -0,0 +1,75 @@ +# go doc --help +! go doc --help +stderr 'go doc' +stderr 'go doc <pkg>' +stderr 'go doc <sym>\[\.<methodOrField>\]' +stderr 'go doc \[<pkg>\.\]<sym>\[\.<methodOrField>\]' +stderr 'go doc \[<pkg>\.\]\[<sym>\.\]<methodOrField>' +stderr 'go doc <pkg> <sym>\[\.<methodOrField>\]' + +# go help doc +go help doc +stdout 'go doc' +stdout 'go doc <pkg>' +stdout 'go doc <sym>\[\.<methodOrField>\]' +stdout 'go doc \[<pkg>\.\]<sym>\[\.<methodOrField>\]' +stdout 'go doc \[<pkg>\.\]\[<sym>\.\]<methodOrField>' +stdout 'go doc <pkg> <sym>\[\.<methodOrField>\]' + +# go doc <pkg> +go doc p/v2 +stdout . + +# go doc <pkg> <sym> +go doc p/v2 Symbol +stdout . + +# go doc <pkg> <sym> <method> +! go doc p/v2 Symbol Method +stderr . + +# go doc <pkg>.<sym> +go doc p/v2.Symbol +stdout . + +# go doc <pkg>.<sym>.<method> +go doc p/v2.Symbol.Method +stdout . + +# go doc <sym> +go doc Symbol +stdout . + +# go doc <sym> <method> +! go doc Symbol Method +stderr . + +# go doc <sym>.<method> +go doc Symbol.Method +stdout . + +# go doc <pkg>.<method> +go doc p/v2.Method +stdout . + +# go doc <pkg> <method> +go doc p/v2 Method +stdout . + +# go doc <method> +go doc Method +stdout . + +-- go.mod -- +module p/v2 + +go 1.13 + +-- p.go -- +package p + +type Symbol struct{} + +func (Symbol) Method() error { + return nil +} diff --git a/src/cmd/go/testdata/script/embed.txt b/src/cmd/go/testdata/script/embed.txt new file mode 100644 index 0000000..6ad42e9 --- /dev/null +++ b/src/cmd/go/testdata/script/embed.txt @@ -0,0 +1,109 @@ +# go list shows patterns and files +go list -f '{{.EmbedPatterns}}' +stdout '\[x\*t\*t\]' +go list -f '{{.EmbedFiles}}' +stdout '\[x.txt\]' +go list -test -f '{{.TestEmbedPatterns}}' +stdout '\[y\*t\*t\]' +go list -test -f '{{.TestEmbedFiles}}' +stdout '\[y.txt\]' +go list -test -f '{{.XTestEmbedPatterns}}' +stdout '\[z\*t\*t\]' +go list -test -f '{{.XTestEmbedFiles}}' +stdout '\[z.txt\]' + +# build embeds x.txt +go build -x +stderr 'x.txt' + +# build uses cache correctly +go build -x +! stderr 'x.txt' +cp x.txt2 x.txt +go build -x +stderr 'x.txt' + +# build rejects invalid names +cp x.go2 x.go +go build -x +cp x.txt .git +! go build -x +stderr '^x.go:5:12: pattern [*]t: cannot embed file [.]git: invalid name [.]git$' +rm .git + +# build rejects symlinks +[symlink] symlink x.tzt -> x.txt +[symlink] ! go build -x +[symlink] stderr 'pattern [*]t: cannot embed irregular file x.tzt' +[symlink] rm x.tzt + +# build rejects empty directories +mkdir t +! go build -x +stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$' + +# build ignores symlinks and invalid names in directories +cp x.txt t/.git +! go build -x +stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$' +go list -e -f '{{.Incomplete}}' +stdout 'true' +[symlink] symlink t/x.link -> ../x.txt +[symlink] ! go build -x +[symlink] stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$' + +cp x.txt t/x.txt +go build -x + +# build reports errors with positions in imported packages +rm t/x.txt +! go build m/use +stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$' + +-- x.go -- +package p + +import "embed" + +//go:embed x*t*t +var X embed.FS + +-- x_test.go -- +package p + +import "embed" + +//go:embed y*t*t +var Y string + +-- x_x_test.go -- +package p_test + +import "embed" + +//go:embed z*t*t +var Z string + +-- x.go2 -- +package p + +import "embed" + +//go:embed *t +var X embed.FS + +-- x.txt -- +hello + +-- y.txt -- +-- z.txt -- +-- x.txt2 -- +not hello + +-- use/use.go -- +package use + +import _ "m" +-- go.mod -- +module m + diff --git a/src/cmd/go/testdata/script/embed_fmt.txt b/src/cmd/go/testdata/script/embed_fmt.txt new file mode 100644 index 0000000..8a16afe --- /dev/null +++ b/src/cmd/go/testdata/script/embed_fmt.txt @@ -0,0 +1,22 @@ +# go fmt ignores file not found +go fmt xnofmt.go +cmp xnofmt.go xfmt.ref +! go build xnofmt.go +stderr 'xnofmt.go:5:12: pattern missing.txt: no matching files found' + +-- xnofmt.go -- +package p + +import "embed" + +//go:embed missing.txt +var X embed.FS +-- xfmt.ref -- +package p + +import "embed" + +//go:embed missing.txt +var X embed.FS +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/env_write.txt b/src/cmd/go/testdata/script/env_write.txt new file mode 100644 index 0000000..bda1e57 --- /dev/null +++ b/src/cmd/go/testdata/script/env_write.txt @@ -0,0 +1,175 @@ +env GO111MODULE=off + +# go env should default to the right places +env AppData=$HOME/windowsappdata +env home=$HOME/plan9home +go env GOENV +[aix] stdout $HOME/.config/go/env +[darwin] stdout $HOME'/Library/Application Support/go/env' +[freebsd] stdout $HOME/.config/go/env +[linux] stdout $HOME/.config/go/env +[netbsd] stdout $HOME/.config/go/env +[openbsd] stdout $HOME/.config/go/env +[plan9] stdout $HOME/plan9home/lib/go/env +[windows] stdout $HOME\\windowsappdata\\go\\env + +# Now override it to something writable. +env GOENV=$WORK/envdir/go/env +go env GOENV +stdout envdir[\\/]go[\\/]env + +# go env shows all variables +go env +stdout GOARCH= +stdout GOOS= +stdout GOROOT= + +# go env ignores invalid flag in GOFLAGS environment variable +env GOFLAGS='=true' +go env + +# checking errors +! go env -w +stderr 'go env -w: no KEY=VALUE arguments given' +! go env -u +stderr 'go env -u: no arguments given' + +# go env -w changes default setting +env root= +[windows] env root=c: +env GOPATH= +go env -w GOPATH=$root/non-exist/gopath +! stderr .+ +grep GOPATH=$root/non-exist/gopath $WORK/envdir/go/env +go env GOPATH +stdout /non-exist/gopath + +# go env -w does not override OS environment, and warns about that +env GOPATH=$root/other +go env -w GOPATH=$root/non-exist/gopath2 +stderr 'warning: go env -w GOPATH=... does not override conflicting OS environment variable' +go env GOPATH +stdout $root/other + +# but go env -w does do the update, and unsetting the env var exposes the change +env GOPATH= +go env GOPATH +stdout $root/non-exist/gopath2 + +# unsetting with go env -u does not warn about OS environment overrides, +# nor does it warn about variables that haven't been set by go env -w. +env GOPATH=$root/other +go env -u GOPATH +! stderr .+ +go env -u GOPATH +! stderr .+ + +# go env -w rejects unknown or bad variables +! go env -w GODEBUG=gctrace=1 +stderr 'unknown go command variable GODEBUG' +! go env -w GOEXE=.bat +stderr 'GOEXE cannot be modified' +! go env -w GOVERSION=customversion +stderr 'GOVERSION cannot be modified' +! go env -w GOENV=/env +stderr 'GOENV can only be set using the OS environment' + +# go env -w can set multiple variables +env CC= +go env CC +! stdout ^xyc$ +go env -w GOOS=$GOOS CC=xyc +grep CC=xyc $GOENV +# file is maintained in sorted order +grep 'CC=xyc\nGOOS=' $GOENV +go env CC +stdout ^xyc$ + +# go env -u unsets effect of go env -w. +go env -u CC +go env CC +! stdout ^xyc$ + +# go env -w rejects double-set variables +! go env -w GOOS=$GOOS GOOS=$GOOS +stderr 'multiple values for key: GOOS' + +# go env -w rejects missing variables +! go env -w GOOS +stderr 'arguments must be KEY=VALUE: invalid argument: GOOS' + +# go env -w rejects invalid GO111MODULE values, as otherwise cmd/go would break +! go env -w GO111MODULE=badvalue +stderr 'invalid GO111MODULE value "badvalue"' + +# go env -w rejects invalid GOPATH values +! go env -w GOPATH=~/go +stderr 'GOPATH entry cannot start with shell metacharacter' + +! go env -w GOPATH=./go +stderr 'GOPATH entry is relative; must be absolute path' + +# go env -w rejects invalid GOTMPDIR values +! go env -w GOTMPDIR=x +stderr 'go env -w: GOTMPDIR must be an absolute path' + +# go env -w should accept absolute GOTMPDIR value +# and should not create it +[windows] go env -w GOTMPDIR=$WORK\x\y\z +[!windows] go env -w GOTMPDIR=$WORK/x/y/z +! exists $WORK/x/y/z +# we should be able to clear an env +go env -u GOTMPDIR +go env GOTMPDIR +stdout ^$ + +[windows] go env -w GOTMPDIR=$WORK\x\y\z +[!windows] go env -w GOTMPDIR=$WORK/x/y/z +go env -w GOTMPDIR= +go env GOTMPDIR +stdout ^$ + +# go env -w rejects relative CC values +[!windows] go env -w CC=/usr/bin/clang +go env -w CC=clang +[!windows] ! go env -w CC=./clang +[!windows] ! go env -w CC=bin/clang +[!windows] stderr 'go env -w: CC entry is relative; must be absolute path' + +[windows] go env -w CC=$WORK\bin\clang +[windows] ! go env -w CC=.\clang +[windows] ! go env -w CC=bin\clang +[windows] stderr 'go env -w: CC entry is relative; must be absolute path' + +# go env -w rejects relative CXX values +[!windows] go env -w CC=/usr/bin/cpp +go env -w CXX=cpp +[!windows] ! go env -w CXX=./cpp +[!windows] ! go env -w CXX=bin/cpp +[!windows] stderr 'go env -w: CXX entry is relative; must be absolute path' + +[windows] go env -w CXX=$WORK\bin\cpp +[windows] ! go env -w CXX=.\cpp +[windows] ! go env -w CXX=bin\cpp +[windows] stderr 'go env -w: CXX entry is relative; must be absolute path' + +# go env -w/-u checks validity of GOOS/ARCH combinations +env GOOS= +env GOARCH= +# check -w doesn't allow invalid GOOS +! go env -w GOOS=linuxx +stderr 'unsupported GOOS/GOARCH pair linuxx' +# check -w doesn't allow invalid GOARCH +! go env -w GOARCH=amd644 +stderr 'unsupported GOOS/GOARCH.*/amd644$' +# check -w doesn't allow invalid GOOS with valid GOARCH +! go env -w GOOS=linuxx GOARCH=amd64 +stderr 'unsupported GOOS/GOARCH pair linuxx' +# check a valid GOOS and GOARCH values but an incompatible combinations +! go env -w GOOS=android GOARCH=s390x +stderr 'unsupported GOOS/GOARCH pair android/s390x' +# check that -u considers explicit envs +go env -w GOOS=linux GOARCH=mips +env GOOS=windows +! go env -u GOOS +stderr 'unsupported GOOS/GOARCH.*windows/mips$' diff --git a/src/cmd/go/testdata/script/fileline.txt b/src/cmd/go/testdata/script/fileline.txt new file mode 100644 index 0000000..5cb35f0 --- /dev/null +++ b/src/cmd/go/testdata/script/fileline.txt @@ -0,0 +1,8 @@ +env GO111MODULE=off + +# look for short, relative file:line in error message +! go run ../../gopath/x/y/z/err.go +stderr ^..[\\/]x[\\/]y[\\/]z[\\/]err.go: + +-- ../x/y/z/err.go -- +package main; import "bar" diff --git a/src/cmd/go/testdata/script/fmt_load_errors.txt b/src/cmd/go/testdata/script/fmt_load_errors.txt new file mode 100644 index 0000000..297ec0f --- /dev/null +++ b/src/cmd/go/testdata/script/fmt_load_errors.txt @@ -0,0 +1,19 @@ +env GO111MODULE=off + +! go fmt does-not-exist + +go fmt -n exclude +stdout 'exclude[/\\]x\.go' +stdout 'exclude[/\\]x_linux\.go' + +-- exclude/empty/x.txt -- +-- exclude/ignore/_x.go -- +package x +-- exclude/x.go -- +// +build linux,!linux + +package x +-- exclude/x_linux.go -- +// +build windows + +package x diff --git a/src/cmd/go/testdata/script/gccgo_link_c.txt b/src/cmd/go/testdata/script/gccgo_link_c.txt new file mode 100644 index 0000000..422adea --- /dev/null +++ b/src/cmd/go/testdata/script/gccgo_link_c.txt @@ -0,0 +1,16 @@ +# Issue #7573 +# cmd/cgo: undefined reference when linking a C-library using gccgo + +[!cgo] skip +[!gccgo] skip + +go build -r -compiler gccgo cgoref +stderr 'gccgo.*\-L [^ ]*alibpath \-lalib' # make sure that Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage + +-- cgoref/cgoref.go -- +package main +// #cgo LDFLAGS: -L alibpath -lalib +// void f(void) {} +import "C" + +func main() { C.f() }
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/gccgo_m.txt b/src/cmd/go/testdata/script/gccgo_m.txt new file mode 100644 index 0000000..b63ba46 --- /dev/null +++ b/src/cmd/go/testdata/script/gccgo_m.txt @@ -0,0 +1,19 @@ +# It's absurd, but builds with -compiler=gccgo used to fail to build module m. +# golang.org/issue/34358 + +env GO111MODULE=off + +[short] skip + +cd m +go build +exists m$GOEXE +rm m$GOEXE +[exec:gccgo] go build -compiler=gccgo +[exec:gccgo] exists m$GOEXE + +-- m/go.mod -- +module m +-- m/main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/gccgo_mangle.txt b/src/cmd/go/testdata/script/gccgo_mangle.txt new file mode 100644 index 0000000..7a09a80 --- /dev/null +++ b/src/cmd/go/testdata/script/gccgo_mangle.txt @@ -0,0 +1,15 @@ +# Issue 33871. + +cd m/a.0 +go build + +-- m/go.mod -- +module m +-- m/a.0/a.go -- +package a + +type T int + +func (t T) M() int { + return int(t) +} diff --git a/src/cmd/go/testdata/script/gcflags_patterns.txt b/src/cmd/go/testdata/script/gcflags_patterns.txt new file mode 100644 index 0000000..f23cece --- /dev/null +++ b/src/cmd/go/testdata/script/gcflags_patterns.txt @@ -0,0 +1,92 @@ +env GO111MODULE=off + +[!gc] skip 'using -gcflags and -ldflags' +[short] skip + +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. + +# -gcflags=-e applies to named packages, not dependencies +go build -n -v -gcflags=-e z1 z2 +stderr 'compile.* -e.* -p z1' +stderr 'compile.* -e.* -p z2' +stderr 'compile.* -p y' +! stderr 'compile.* -e.* -p [^z]' + +# -gcflags can specify package=flags, and can be repeated; last match wins +go build -n -v -gcflags=-e -gcflags=z1=-N z1 z2 +stderr 'compile.* -N.* -p z1' +! stderr 'compile.* -e.* -p z1' +! stderr 'compile.* -N.* -p z2' +stderr 'compile.* -e.* -p z2' +stderr 'compile.* -p y' +! stderr 'compile.* -e.* -p [^z]' +! stderr 'compile.* -N.* -p [^z]' + +# -gcflags can have arbitrary spaces around the flags +go build -n -v -gcflags=' z1 = -e ' z1 +stderr 'compile.* -e.* -p z1' + +# -gcflags='all=-e' should apply to all packages, even with go test +go test -c -n -gcflags='all=-e' z1 +stderr 'compile.* -e.* -p z3 ' + +# this particular -gcflags argument made the compiler crash +! go build -gcflags=-d=ssa/ z1 +stderr 'PhaseOptions usage' + +# -ldflags for implicit test package applies to test binary +go test -c -n -gcflags=-N -ldflags=-X=x.y=z z1 +stderr 'compile.* -N .*z_test.go' +stderr 'link.* -X=x.y=z' + +# -ldflags for explicit test package applies to test binary +go test -c -n -gcflags=z1=-N -ldflags=z1=-X=x.y=z z1 +stderr 'compile.* -N .*z_test.go' +stderr 'link.* -X=x.y=z' + +# -ldflags applies to link of command +go build -n -ldflags=-X=math.pi=3 my/cmd/prog +stderr 'link.* -X=math.pi=3' + +# -ldflags applies to link of command even with strange directory name +go build -n -ldflags=-X=math.pi=3 my/cmd/prog/ +stderr 'link.* -X=math.pi=3' + +# -ldflags applies to current directory +cd my/cmd/prog +go build -n -ldflags=-X=math.pi=3 +stderr 'link.* -X=math.pi=3' + +# -ldflags applies to current directory even if GOPATH is funny +[windows] cd $WORK/GoPath/src/my/cmd/prog +[darwin] cd $WORK/GoPath/src/my/cmd/prog +go build -n -ldflags=-X=math.pi=3 +stderr 'link.* -X=math.pi=3' + +# cgo.a should not be a dependency of internally-linked go package +go build -ldflags='-linkmode=external -linkmode=internal' -n prog.go +! stderr 'packagefile .*runtime/cgo.a' + +-- z1/z.go -- +package z1 +import _ "y" +import _ "z2" + +-- z1/z_test.go -- +package z1_test +import "testing" +import _ "z3" +func Test(t *testing.T) {} + +-- z2/z.go -- +package z2 + +-- z3/z.go -- +package z3 + +-- y/y.go -- +package y + +-- my/cmd/prog/prog.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/generate.txt b/src/cmd/go/testdata/script/generate.txt new file mode 100644 index 0000000..c3c563e --- /dev/null +++ b/src/cmd/go/testdata/script/generate.txt @@ -0,0 +1,91 @@ +[short] skip + +# Install an echo command because Windows doesn't have it. +env GOBIN=$WORK/tmp/bin +go install echo.go +env PATH=$GOBIN${:}$PATH + +# Test go generate handles a simple command +go generate ./generate/simple.go +stdout 'Success' + +# Test go generate handles a command alias +go generate './generate/alias.go' +stdout 'Now is the time for all good men' + +# Test go generate's variable substitution +go generate './generate/substitution.go' +stdout $GOARCH' substitution.go:7 pabc xyzp/substitution.go/123' + +# Test go generate's run flag +go generate -run y.s './generate/flag.go' +stdout 'yes' # flag.go should select yes +! stdout 'no' # flag.go should not select no + +# Test go generate provides the right "$GOPACKAGE" name in an x_test +go generate './generate/env_test.go' +stdout 'main_test' + +-- echo.go -- +package main + +import ( + "fmt" + "os" + "strings" +) + +func main() { + fmt.Println(strings.Join(os.Args[1:], " ")) + fmt.Println() +} +-- generate/simple.go -- +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Simple test for go generate. + +// We include a build tag that go generate should ignore. + +// +build ignore + +//go:generate echo Success + +package p +-- generate/alias.go -- +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that go generate handles command aliases. + +//go:generate -command run echo Now is the time +//go:generate run for all good men + +package p +-- generate/substitution.go -- +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test go generate variable substitution. + +//go:generate echo $GOARCH $GOFILE:$GOLINE ${GOPACKAGE}abc xyz$GOPACKAGE/$GOFILE/123 + +package p +-- generate/flag.go -- +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test -run flag + +//go:generate echo oh yes my man +//go:generate echo no, no, a thousand times no + +package p +-- generate/env_test.go -- +package main_test + +//go:generate echo $GOPACKAGE
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/generate_bad_imports.txt b/src/cmd/go/testdata/script/generate_bad_imports.txt new file mode 100644 index 0000000..4d31573 --- /dev/null +++ b/src/cmd/go/testdata/script/generate_bad_imports.txt @@ -0,0 +1,15 @@ +[windows] skip # skip because windows has no echo command + +go generate gencycle +stdout 'hello world' # check go generate gencycle ran the generator + +-- go.mod -- +module gencycle + +go 1.16 +-- gencycle.go -- +//go:generate echo hello world + +package gencycle + +import _ "gencycle" diff --git a/src/cmd/go/testdata/script/generate_env.txt b/src/cmd/go/testdata/script/generate_env.txt new file mode 100644 index 0000000..2df1663 --- /dev/null +++ b/src/cmd/go/testdata/script/generate_env.txt @@ -0,0 +1,32 @@ +# Install an env command because Windows and plan9 don't have it. +env GOBIN=$WORK/tmp/bin +go install env.go +[plan9] env path=$GOBIN${:}$path +[!plan9] env PATH=$GOBIN${:}$PATH + +# Test generators have access to the environment +go generate ./printenv.go +stdout '^GOARCH='$GOARCH +stdout '^GOOS='$GOOS +stdout '^GOFILE=' +stdout '^GOLINE=' +stdout '^GOPACKAGE=' +stdout '^DOLLAR=' + +-- env.go -- +package main + +import ( + "fmt" + "os" +) + +func main() { + for _, v := range os.Environ() { + fmt.Println(v) + } +} +-- printenv.go -- +package main + +//go:generate env
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/generate_invalid.txt b/src/cmd/go/testdata/script/generate_invalid.txt new file mode 100644 index 0000000..e18e62c --- /dev/null +++ b/src/cmd/go/testdata/script/generate_invalid.txt @@ -0,0 +1,203 @@ +[short] skip + +# Install an echo command because Windows doesn't have it. +env GOBIN=$WORK/tmp/bin +go install echo.go +env PATH=$GOBIN${:}$PATH + +# Test go generate for directory with no go files +go generate ./nogo +! stdout 'Fail' + +# Test go generate for package where all .go files are excluded by build +# constraints +go generate -v ./excluded +! stdout 'Fail' +! stderr 'go' # -v shouldn't list any files + +# Test go generate for "package" with no package clause in any file +go generate ./nopkg +stdout 'Success a' +! stdout 'Fail' + +# Test go generate for package with inconsistent package clauses +# $GOPACKAGE should depend on each file's package clause +go generate ./inconsistent +stdout 'Success a' +stdout 'Success b' +stdout -count=2 'Success c' +! stdout 'Fail' + +# Test go generate for syntax errors before and after package clauses +go generate ./syntax +stdout 'Success a' +stdout 'Success b' +! stdout 'Fail' + +# Test go generate for files importing non-existent packages +go generate ./importerr +stdout 'Success a' +stdout 'Success b' +stdout 'Success c' + +-- echo.go -- +package main + +import ( + "fmt" + "os" + "strings" +) + +func main() { + fmt.Println(strings.Join(os.Args[1:], " ")) + fmt.Println() +} + +-- go.mod -- +module m + +go 1.16 +-- nogo/foo.txt -- +Text file in a directory without go files. +Go generate should ignore this directory. +//go:generate echo Fail nogo + +-- excluded/a.go -- +// Include a build tag that go generate should exclude. +// Go generate should ignore this file. + +// +build a + +//go:generate echo Fail a + +package excluded + +-- excluded/b.go -- +// Include a build tag that go generate should exclude. +// Go generate should ignore this file. + +//go:generate echo Fail b + +// +build b + +package excluded + + +-- nopkg/a.go -- +// Go file with package clause after comment. +// Go generate should process this file. + +/* Pre-comment */ package nopkg +//go:generate echo Success a + +-- nopkg/b.go -- +// Go file with commented package clause. +// Go generate should ignore this file. + +//package nopkg + +//go:generate echo Fail b + +-- nopkg/c.go -- +// Go file with package clause inside multiline comment. +// Go generate should ignore this file. + +/* +package nopkg +*/ + +//go:generate echo Fail c + +-- nopkg/d.go -- +// Go file with package clause inside raw string literal. +// Go generate should ignore this file. + +const foo = ` +package nopkg +` +//go:generate echo Fail d + +-- nopkg/e.go -- +// Go file without package clause. +// Go generate should ignore this file. + +//go:generate echo Fail e + +-- inconsistent/a.go -- +// Valid go file with inconsistent package name. +// Go generate should process this file with GOPACKAGE=a + +package a +//go:generate echo Success $GOPACKAGE + +-- inconsistent/b.go -- +// Valid go file with inconsistent package name. +// Go generate should process this file with GOPACKAGE=b + +//go:generate echo Success $GOPACKAGE +package b + +-- inconsistent/c.go -- +// Go file with two package clauses. +// Go generate should process this file with GOPACKAGE=c + +//go:generate echo Success $GOPACKAGE +package c +// Invalid package clause, should be ignored: +package cinvalid +//go:generate echo Success $GOPACKAGE + +-- inconsistent/d.go -- +// Go file with invalid package name. +// Go generate should ignore this file. + +package +d+ +//go:generate echo Fail $GOPACKAGE + +-- syntax/a.go -- +// Go file with syntax error after package clause. +// Go generate should process this file. + +package syntax +123 +//go:generate echo Success a + +-- syntax/b.go -- +// Go file with syntax error after package clause. +// Go generate should process this file. + +package syntax; 123 +//go:generate echo Success b + +-- syntax/c.go -- +// Go file with syntax error before package clause. +// Go generate should ignore this file. + +foo +package syntax +//go:generate echo Fail c + +-- importerr/a.go -- +// Go file which imports non-existing package. +// Go generate should process this file. + +package importerr +//go:generate echo Success a +import "foo" + +-- importerr/b.go -- +// Go file which imports non-existing package. +// Go generate should process this file. + +//go:generate echo Success b +package importerr +import "bar" + +-- importerr/c.go -- +// Go file which imports non-existing package. +// Go generate should process this file. + +package importerr +import "moo" +//go:generate echo Success c diff --git a/src/cmd/go/testdata/script/get_404_meta.txt b/src/cmd/go/testdata/script/get_404_meta.txt new file mode 100644 index 0000000..b71cc7f --- /dev/null +++ b/src/cmd/go/testdata/script/get_404_meta.txt @@ -0,0 +1,11 @@ +# golang.org/issue/13037: 'go get' was not parsing <meta> tags in 404 served over HTTPS. + +[!net] skip +[!exec:git] skip + +env GO111MODULE=off +go get -d -insecure bazil.org/fuse/fs/fstestutil + +env GO111MODULE=on +env GOPROXY=direct +go get -d -insecure bazil.org/fuse/fs/fstestutil diff --git a/src/cmd/go/testdata/script/get_brace.txt b/src/cmd/go/testdata/script/get_brace.txt new file mode 100644 index 0000000..3449a0c --- /dev/null +++ b/src/cmd/go/testdata/script/get_brace.txt @@ -0,0 +1,51 @@ +env GO111MODULE=off + +[!exec:git] skip + +# Set up some empty repositories. +cd $WORK/_origin/foo +exec git init +exec git config user.name 'Nameless Gopher' +exec git config user.email 'nobody@golang.org' +exec git commit --allow-empty -m 'create master branch' + +cd $WORK +cd '_origin/{confusing}' +exec git init +exec git config user.name 'Nameless Gopher' +exec git config user.email 'nobody@golang.org' +exec git commit --allow-empty -m 'create master branch' + +# Clone the empty repositories into GOPATH. +# This tells the Go command where to find them: it takes the place of a user's meta-tag redirector. +mkdir $GOPATH/src/example.com +cd $GOPATH/src/example.com +exec git clone $WORK/_origin/foo +exec git clone $WORK/_origin/{confusing} + +# Commit contents to the repositories. +cd $WORK/_origin/foo +exec git add main.go +exec git commit -m 'add main' + +cd $WORK +cd '_origin/{confusing}' +exec git add confusing.go +exec git commit -m 'just try to delete this!' + +# 'go get' should refuse to download or update the confusingly-named repo. +cd $GOPATH/src/example.com/foo +! go get -u 'example.com/{confusing}' +stderr 'invalid char' +! go get -u example.com/foo +stderr 'invalid import path' +! exists example.com/{confusing} + +-- $WORK/_origin/foo/main.go -- +package main +import _ "example.com/{confusing}" + +func main() {} + +-- $WORK/_origin/{confusing}/confusing.go -- +package confusing diff --git a/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt b/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt new file mode 100644 index 0000000..cda25e1 --- /dev/null +++ b/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt @@ -0,0 +1,6 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get -u rsc.io/pdf/... +exists $GOPATH/bin/pdfpasswd$GOEXE diff --git a/src/cmd/go/testdata/script/get_dash_t.txt b/src/cmd/go/testdata/script/get_dash_t.txt new file mode 100644 index 0000000..baac916 --- /dev/null +++ b/src/cmd/go/testdata/script/get_dash_t.txt @@ -0,0 +1,9 @@ +# Tests issue 8181 + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get -v -t github.com/rsc/go-get-issue-8181/a github.com/rsc/go-get-issue-8181/b +go list ... +stdout 'x/build/gerrit' diff --git a/src/cmd/go/testdata/script/get_domain_root.txt b/src/cmd/go/testdata/script/get_domain_root.txt new file mode 100644 index 0000000..9187848 --- /dev/null +++ b/src/cmd/go/testdata/script/get_domain_root.txt @@ -0,0 +1,20 @@ +# Tests issue #9357 +# go get foo.io (not foo.io/subdir) was not working consistently. + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# go-get-issue-9357.appspot.com is running +# the code at github.com/rsc/go-get-issue-9357, +# a trivial Go on App Engine app that serves a +# <meta> tag for the domain root. +go get -d go-get-issue-9357.appspot.com +go get go-get-issue-9357.appspot.com +go get -u go-get-issue-9357.appspot.com + +rm $GOPATH/src/go-get-issue-9357.appspot.com +go get go-get-issue-9357.appspot.com + +rm $GOPATH/src/go-get-issue-9357.appspot.com +go get -u go-get-issue-9357.appspot.com diff --git a/src/cmd/go/testdata/script/get_dot_slash_download.txt b/src/cmd/go/testdata/script/get_dot_slash_download.txt new file mode 100644 index 0000000..dbaf46c --- /dev/null +++ b/src/cmd/go/testdata/script/get_dot_slash_download.txt @@ -0,0 +1,10 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# Tests Issues #9797 and #19769 + +mkdir $WORK/tmp/src/rsc.io +env GOPATH=$WORK/tmp +cd $WORK/tmp/src/rsc.io +go get ./pprof_mac_fix diff --git a/src/cmd/go/testdata/script/get_dotfiles.txt b/src/cmd/go/testdata/script/get_dotfiles.txt new file mode 100644 index 0000000..6757f9d --- /dev/null +++ b/src/cmd/go/testdata/script/get_dotfiles.txt @@ -0,0 +1,64 @@ +env GO111MODULE=off +[short] skip + +[!exec:git] skip + +# Set up a benign repository and a repository with a dotfile name. +cd $WORK/_origin/foo +exec git init +exec git config user.name 'Nameless Gopher' +exec git config user.email 'nobody@golang.org' +exec git commit --allow-empty -m 'create master branch' + +cd $WORK/_origin/.hidden +exec git init +exec git config user.name 'Nameless Gopher' +exec git config user.email 'nobody@golang.org' +exec git commit --allow-empty -m 'create master branch' + +# Clone the empty repositories into GOPATH. +# This tells the Go command where to find them: it takes the place of a user's meta-tag redirector. +mkdir $GOPATH/src/example.com +cd $GOPATH/src/example.com +exec git clone $WORK/_origin/foo +exec git clone $WORK/_origin/.hidden + +# Add a benign commit. +cd $WORK/_origin/foo +cp _ok/main.go main.go +exec git add main.go +exec git commit -m 'add ok' + +# 'go get' should install the benign commit. +cd $GOPATH +go get -u example.com/foo + +# Now sneak in an import of a dotfile path. +cd $WORK/_origin/.hidden +exec git add hidden.go +exec git commit -m 'nothing to see here, move along' + +cd $WORK/_origin/foo +cp _sneaky/main.go main.go +exec git add main.go +exec git commit -m 'fix typo (heh heh heh)' + +# 'go get -u' should refuse to download or update the dotfile-named repo. +cd $GOPATH/src/example.com/foo +! go get -u example.com/foo +stderr 'leading dot' +! exists example.com/.hidden/hidden.go + +-- $WORK/_origin/foo/_ok/main.go -- +package main + +func main() {} + +-- $WORK/_origin/foo/_sneaky/main.go -- +package main +import _ "example.com/.hidden" + +func main() {} + +-- $WORK/_origin/.hidden/hidden.go -- +package hidden diff --git a/src/cmd/go/testdata/script/get_go_file.txt b/src/cmd/go/testdata/script/get_go_file.txt new file mode 100644 index 0000000..bed8720 --- /dev/null +++ b/src/cmd/go/testdata/script/get_go_file.txt @@ -0,0 +1,60 @@ +# Tests Issue #38478 +# Tests that go get in GOPATH mode returns a specific error if the argument +# ends with '.go', and either has no slash or refers to an existing file. + +env GO111MODULE=off + +# argument doesn't have .go suffix +go get -d test + +# argument has .go suffix, is a file and exists +! go get -d test.go +stderr 'go get test.go: arguments must be package or module paths' + +# argument has .go suffix, doesn't exist and has no slashes +! go get -d test_missing.go +stderr 'go get test_missing.go: arguments must be package or module paths' + +# argument has .go suffix, is a file and exists in sub-directory +! go get -d test/test.go +stderr 'go get: test/test.go exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, doesn't exist and has slashes +! go get -d test/test_missing.go +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, is a symlink and exists +[symlink] symlink test_sym.go -> test.go +[symlink] ! go get -d test_sym.go +[symlink] stderr 'go get test_sym.go: arguments must be package or module paths' +[symlink] rm test_sym.go + +# argument has .go suffix, is a symlink and exists in sub-directory +[symlink] symlink test/test_sym.go -> test.go +[symlink] ! go get -d test/test_sym.go +[symlink] stderr 'go get: test/test_sym.go exists as a file, but ''go get'' requires package arguments' +[symlink] rm test_sym.go + +# argument has .go suffix, is a directory and exists +mkdir test_dir.go +! go get -d test_dir.go +stderr 'go get test_dir.go: arguments must be package or module paths' +rm test_dir.go + +# argument has .go suffix, is a directory and exists in sub-directory +mkdir test/test_dir.go +! go get -d test/test_dir.go +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' +rm test/test_dir.go + + +-- test.go -- +package main +func main() {println("test")} + + +-- test/test.go -- +package main +func main() {println("test")} diff --git a/src/cmd/go/testdata/script/get_goroot.txt b/src/cmd/go/testdata/script/get_goroot.txt new file mode 100644 index 0000000..929435a --- /dev/null +++ b/src/cmd/go/testdata/script/get_goroot.txt @@ -0,0 +1,53 @@ +[!net] skip +env GO111MODULE=off + +# Issue 4186. go get cannot be used to download packages to $GOROOT. +# Test that without GOPATH set, go get should fail. + +# Fails because GOROOT=GOPATH +env GOPATH=$WORK/tmp +env GOROOT=$WORK/tmp +! go get -d github.com/golang/example/hello +stderr 'warning: GOPATH set to GOROOT' +stderr '\$GOPATH must not be set to \$GOROOT' + +# Fails because GOROOT=GOPATH after cleaning. +env GOPATH=$WORK/tmp/ +env GOROOT=$WORK/tmp +! go get -d github.com/golang/example/hello +stderr 'warning: GOPATH set to GOROOT' +stderr '\$GOPATH must not be set to \$GOROOT' + +env GOPATH=$WORK/tmp +env GOROOT=$WORK/tmp/ +! go get -d github.com/golang/example/hello +stderr 'warning: GOPATH set to GOROOT' +stderr '\$GOPATH must not be set to \$GOROOT' + +# Make a home directory +mkdir $WORK/home/go + +# Fails because GOROOT=$HOME/go so default GOPATH unset. +[windows] env USERPROFILE=$WORK/home +[plan9] env home=$WORK/home +[!windows] [!plan9] env HOME=$WORK/home +env GOPATH= +env GOROOT=$WORK/home/go +! go get -d github.com/golang/example/hello +stderr '\$GOPATH not set' + +[windows] env USERPROFILE=$WORK/home/ +[plan9] env home=$WORK/home/ +[!windows] [!plan9] env HOME=$WORK/home/ +env GOPATH= +env GOROOT=$WORK/home/go +! go get -d github.com/golang/example/hello +stderr '\$GOPATH not set' + +[windows] env USERPROFILE=$WORK/home +[plan9] env home=$WORK/home +[!windows] [!plan9] env HOME=$WORK/home +env GOPATH= +env GOROOT=$WORK/home/go/ +! go get -d github.com/golang/example/hello +stderr '\$GOPATH not set' diff --git a/src/cmd/go/testdata/script/get_insecure.txt b/src/cmd/go/testdata/script/get_insecure.txt new file mode 100644 index 0000000..36ad2c0 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure.txt @@ -0,0 +1,51 @@ +# TODO(matloob): Split this test into two? It's one of the slowest tests we have. + +[!net] skip +[!exec:git] skip + +env PATH=$WORK/tmp/bin${:}$PATH +go build -o $WORK/tmp/bin/ssh ssh.go + +# GOPATH: Set up +env GO111MODULE=off + +# GOPATH: Try go get -d of HTTP-only repo (should fail). +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try again with -insecure (should succeed). +go get -d -insecure insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try updating without -insecure (should fail). +! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + +# Modules: Set up +env GOPATH=$WORK/m/gp +mkdir $WORK/m +cp module_file $WORK/m/go.mod +cd $WORK/m +env GO111MODULE=on +env GOPROXY='' + +# Modules: Try go get -d of HTTP-only repo (should fail). +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# Modules: Try again with -insecure (should succeed). +go get -d -insecure insecure.go-get-issue-15410.appspot.com/pkg/p + +# Modules: Try updating without -insecure (should fail). +! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + +go list -m ... +stdout 'insecure.go-get-issue' + +-- ssh.go -- +// stub out uses of ssh by go get +package main + +import "os" + +func main() { + os.Exit(1) +} +-- module_file -- +module m
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/get_insecure_custom_domain.txt b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt new file mode 100644 index 0000000..a4a6fd4 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt @@ -0,0 +1,6 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p +go get -d -insecure insecure.go-get-issue-15410.appspot.com/pkg/p diff --git a/src/cmd/go/testdata/script/get_insecure_deprecated.txt b/src/cmd/go/testdata/script/get_insecure_deprecated.txt new file mode 100644 index 0000000..7f5f5c7 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_deprecated.txt @@ -0,0 +1,21 @@ +# GOPATH: Set up +env GO111MODULE=off + +# GOPATH: Fetch without insecure, no warning +! go get test +! stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details' + +# GOPATH: Fetch with insecure, should warn +! go get -insecure test +stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details' + +# Modules: Set up +env GO111MODULE=on + +# Modules: Fetch without insecure, no warning +! go get test +! stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details' + +# Modules: Fetch with insecure, should warn +! go get -insecure test +stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details' diff --git a/src/cmd/go/testdata/script/get_insecure_env.txt b/src/cmd/go/testdata/script/get_insecure_env.txt new file mode 100644 index 0000000..8d88427 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_env.txt @@ -0,0 +1,29 @@ +[!net] skip +[!exec:git] skip + +# GOPATH: Set up +env GO111MODULE=off + +# GOPATH: Try go get -d of HTTP-only repo (should fail). +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try again with invalid GOINSECURE (should fail). +env GOINSECURE=insecure.go-get-issue-15410.appspot.com/pkg/q +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try with correct GOINSECURE (should succeed). +env GOINSECURE=insecure.go-get-issue-15410.appspot.com/pkg/p +go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try updating without GOINSECURE (should fail). +env GOINSECURE= +! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try updating with GOINSECURE glob (should succeed). +env GOINSECURE=*.go-get-*.appspot.com +go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try updating with GOINSECURE base URL (should succeed). +env GOINSECURE=insecure.go-get-issue-15410.appspot.com +go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + diff --git a/src/cmd/go/testdata/script/get_insecure_redirect.txt b/src/cmd/go/testdata/script/get_insecure_redirect.txt new file mode 100644 index 0000000..0478d1f --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_redirect.txt @@ -0,0 +1,12 @@ +# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure. +# golang.org/issue/34049: 'go get' would panic in case of an insecure redirect in GOPATH mode + +[!net] skip +[!exec:git] skip + +env GO111MODULE=off + +! go get -d vcs-test.golang.org/insecure/go/insecure +stderr 'redirected .* to insecure URL' + +go get -d -insecure vcs-test.golang.org/insecure/go/insecure diff --git a/src/cmd/go/testdata/script/get_insecure_update.txt b/src/cmd/go/testdata/script/get_insecure_update.txt new file mode 100644 index 0000000..4511c98 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_update.txt @@ -0,0 +1,12 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# Clone the repo via HTTP manually. +exec git clone -q http://github.com/golang/example github.com/golang/example + +# Update without -insecure should fail. +# Update with -insecure should succeed. +# We need -f to ignore import comments. +! go get -d -u -f github.com/golang/example/hello +go get -d -u -f -insecure github.com/golang/example/hello diff --git a/src/cmd/go/testdata/script/get_internal_wildcard.txt b/src/cmd/go/testdata/script/get_internal_wildcard.txt new file mode 100644 index 0000000..ff20d4b --- /dev/null +++ b/src/cmd/go/testdata/script/get_internal_wildcard.txt @@ -0,0 +1,6 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# This used to fail with errors about internal packages +go get github.com/rsc/go-get-issue-11960/... diff --git a/src/cmd/go/testdata/script/get_issue11307.txt b/src/cmd/go/testdata/script/get_issue11307.txt new file mode 100644 index 0000000..9d6b7dd --- /dev/null +++ b/src/cmd/go/testdata/script/get_issue11307.txt @@ -0,0 +1,9 @@ +# go get -u was not working except in checkout directory + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +env GOPATH=$WORK/tmp/gopath +go get github.com/rsc/go-get-issue-11307 +go get -u github.com/rsc/go-get-issue-11307 # was failing diff --git a/src/cmd/go/testdata/script/get_legacy.txt b/src/cmd/go/testdata/script/get_legacy.txt new file mode 100644 index 0000000..938d428 --- /dev/null +++ b/src/cmd/go/testdata/script/get_legacy.txt @@ -0,0 +1,58 @@ +# This test was converted from a test in vendor_test.go (which no longer exists). +# That seems to imply that it's about vendoring semantics, but the test doesn't +# use 'go -mod=vendor' (and none of the fetched repos have vendor folders). +# The test still seems to be useful as a test of direct-mode go get. + +[short] skip +[!exec:git] skip +env GO111MODULE=off + +env GOPATH=$WORK/tmp/d1 +go get vcs-test.golang.org/git/modlegacy1-old.git/p1 +go list -f '{{.Deps}}' vcs-test.golang.org/git/modlegacy1-old.git/p1 +stdout 'new.git/p2' # old/p1 should depend on new/p2 +! stdout new.git/v2/p2 # old/p1 should NOT depend on new/v2/p2 +go build vcs-test.golang.org/git/modlegacy1-old.git/p1 vcs-test.golang.org/git/modlegacy1-new.git/p1 +! stdout . + +env GOPATH=$WORK/tmp/d2 + +rm $GOPATH +go get github.com/rsc/vgotest5 +go get github.com/rsc/vgotest4 +go get github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/rsc/vgotest4 +go get github.com/rsc/vgotest5 +go get github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/rsc/vgotest4 github.com/rsc/vgotest5 +go get github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/rsc/vgotest5 github.com/rsc/vgotest4 +go get github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/myitcv/vgo_example_compat +go get github.com/rsc/vgotest5 github.com/rsc/vgotest4 + +rm $GOPATH +go get github.com/myitcv/vgo_example_compat github.com/rsc/vgotest4 github.com/rsc/vgotest5 + +rm $GOPATH +go get github.com/myitcv/vgo_example_compat github.com/rsc/vgotest5 github.com/rsc/vgotest4 + +rm $GOPATH +go get github.com/rsc/vgotest4 github.com/myitcv/vgo_example_compat github.com/rsc/vgotest5 + +rm $GOPATH +go get github.com/rsc/vgotest4 github.com/rsc/vgotest5 github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/rsc/vgotest5 github.com/myitcv/vgo_example_compat github.com/rsc/vgotest4 + +rm $GOPATH +go get github.com/rsc/vgotest5 github.com/rsc/vgotest4 github.com/myitcv/vgo_example_compat diff --git a/src/cmd/go/testdata/script/get_non_pkg.txt b/src/cmd/go/testdata/script/get_non_pkg.txt new file mode 100644 index 0000000..a878530 --- /dev/null +++ b/src/cmd/go/testdata/script/get_non_pkg.txt @@ -0,0 +1,14 @@ +[!net] skip +[!exec:git] skip + +env GOBIN=$WORK/tmp/gobin +env GO111MODULE=off + +! go get -d golang.org/x/tools +stderr 'golang.org/x/tools: no Go files' + +! go get -d -u golang.org/x/tools +stderr 'golang.org/x/tools: no Go files' + +! go get -d golang.org/x/tools +stderr 'golang.org/x/tools: no Go files'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/get_race.txt b/src/cmd/go/testdata/script/get_race.txt new file mode 100644 index 0000000..16a560a --- /dev/null +++ b/src/cmd/go/testdata/script/get_race.txt @@ -0,0 +1,8 @@ +# Tests issue #20502 + +[!net] skip +[!exec:git] skip +[!race] skip +env GO111MODULE=off + +go get -race github.com/rsc/go-get-issue-9224-cmd diff --git a/src/cmd/go/testdata/script/get_test_only.txt b/src/cmd/go/testdata/script/get_test_only.txt new file mode 100644 index 0000000..a3f38dd --- /dev/null +++ b/src/cmd/go/testdata/script/get_test_only.txt @@ -0,0 +1,6 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get golang.org/x/tour/content... +go get -t golang.org/x/tour/content... diff --git a/src/cmd/go/testdata/script/get_tilde.txt b/src/cmd/go/testdata/script/get_tilde.txt new file mode 100644 index 0000000..e520957 --- /dev/null +++ b/src/cmd/go/testdata/script/get_tilde.txt @@ -0,0 +1,24 @@ +env GO111MODULE=off +[short] skip + +# Paths containing windows short names should be rejected before attempting to fetch. +! go get example.com/longna~1.dir/thing +stderr 'trailing tilde and digits' +! go get example.com/longna~1/thing +stderr 'trailing tilde and digits' +! go get example.com/~9999999/thing +stderr 'trailing tilde and digits' + +# A path containing an element that is just a tilde, or a tilde followed by non-digits, +# should attempt to resolve. +! go get example.com/~glenda/notfound +! stderr 'trailing tilde and digits' +stderr 'unrecognized import path' + +! go get example.com/~glenda2/notfound +! stderr 'trailing tilde and digits' +stderr 'unrecognized import path' + +! go get example.com/~/notfound +! stderr 'trailing tilde and digits' +stderr 'unrecognized import path' diff --git a/src/cmd/go/testdata/script/get_update.txt b/src/cmd/go/testdata/script/get_update.txt new file mode 100644 index 0000000..9afce6a --- /dev/null +++ b/src/cmd/go/testdata/script/get_update.txt @@ -0,0 +1,25 @@ +# Tests Issue #9224 +# The recursive updating was trying to walk to +# former dependencies, not current ones. + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# Rewind +go get github.com/rsc/go-get-issue-9224-cmd +cd $GOPATH/src/github.com/rsc/go-get-issue-9224-lib +exec git reset --hard HEAD~ +cd $GOPATH/src + +# Run get +go get -u 'github.com/rsc/go-get-issue-9224-cmd' + +# (Again with -d -u) Rewind +go get github.com/rsc/go-get-issue-9224-cmd +cd $GOPATH/src/github.com/rsc/go-get-issue-9224-lib +exec git reset --hard HEAD~ +cd $GOPATH/src + +# (Again with -d -u) Run get +go get -d -u 'github.com/rsc/go-get-issue-9224-cmd' diff --git a/src/cmd/go/testdata/script/get_update_all.txt b/src/cmd/go/testdata/script/get_update_all.txt new file mode 100644 index 0000000..2b75849 --- /dev/null +++ b/src/cmd/go/testdata/script/get_update_all.txt @@ -0,0 +1,9 @@ +# Issue 14444: go get -u .../ duplicate loads errors +# Check that go get update -u ... does not try to load duplicates + +[!net] skip + +env GO111MODULE=off + +go get -u -n .../ +! stderr 'duplicate loads of' # make sure old packages are removed from cache diff --git a/src/cmd/go/testdata/script/get_update_unknown_protocol.txt b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt new file mode 100644 index 0000000..b00adea --- /dev/null +++ b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt @@ -0,0 +1,14 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# Clone the repo via HTTPS manually. +exec git clone -q https://github.com/golang/example github.com/golang/example + +# Configure the repo to use a protocol unknown to cmd/go +# that still actually works. +cd github.com/golang/example +exec git remote set-url origin xyz://github.com/golang/example +exec git config --local url.https://github.com/.insteadOf xyz://github.com/ + +go get -d -u -f github.com/golang/example/hello diff --git a/src/cmd/go/testdata/script/get_update_wildcard.txt b/src/cmd/go/testdata/script/get_update_wildcard.txt new file mode 100644 index 0000000..4e66004 --- /dev/null +++ b/src/cmd/go/testdata/script/get_update_wildcard.txt @@ -0,0 +1,16 @@ +# Issue 14450: go get -u .../ tried to import not downloaded package + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get github.com/tmwh/go-get-issue-14450/a +! go get -u .../ +stderr 'cannot find package.*d-dependency/e' + +# Even though get -u failed, the source for others should be downloaded. +exists github.com/tmwh/go-get-issue-14450/b +exists github.com/tmwh/go-get-issue-14450-b-dependency/c +exists github.com/tmwh/go-get-issue-14450-b-dependency/d + +! exists github.com/tmwh/go-get-issue-14450-c-dependency/e diff --git a/src/cmd/go/testdata/script/get_vcs_error_message.txt b/src/cmd/go/testdata/script/get_vcs_error_message.txt new file mode 100644 index 0000000..8dc84fc --- /dev/null +++ b/src/cmd/go/testdata/script/get_vcs_error_message.txt @@ -0,0 +1,9 @@ +# Test that the Version Control error message includes the correct directory +env GO111MODULE=off +! go get -u foo +stderr gopath(\\\\|/)src(\\\\|/)foo + +-- foo/foo.go -- +package foo +-- math/math.go -- +package math diff --git a/src/cmd/go/testdata/script/get_vendor.txt b/src/cmd/go/testdata/script/get_vendor.txt new file mode 100644 index 0000000..4ebb8a2 --- /dev/null +++ b/src/cmd/go/testdata/script/get_vendor.txt @@ -0,0 +1,95 @@ +[short] skip +env GO111MODULE=off + +cd $GOPATH/src/v +go run m.go +go test +go list -f '{{.Imports}}' +stdout 'v/vendor/vendor.org/p' +go list -f '{{.TestImports}}' +stdout 'v/vendor/vendor.org/p' +go get -d +go get -t -d + +[!net] stop +[!exec:git] stop + +cd $GOPATH/src + +# Update +go get 'github.com/rsc/go-get-issue-11864' +go get -u 'github.com/rsc/go-get-issue-11864' +exists github.com/rsc/go-get-issue-11864/vendor + +# get -u +rm $GOPATH +mkdir $GOPATH/src +go get -u 'github.com/rsc/go-get-issue-11864' +exists github.com/rsc/go-get-issue-11864/vendor + +# get -t -u +rm $GOPATH +mkdir $GOPATH/src +go get -t -u 'github.com/rsc/go-get-issue-11864/...' +exists github.com/rsc/go-get-issue-11864/vendor + +# Submodules +rm $GOPATH +mkdir $GOPATH/src +go get -d 'github.com/rsc/go-get-issue-12612' +go get -u -d 'github.com/rsc/go-get-issue-12612' +exists github.com/rsc/go-get-issue-12612/vendor/golang.org/x/crypto/.git + +# Bad vendor (bad/imp) +rm $GOPATH +mkdir $GOPATH/src +! go get -t -u 'github.com/rsc/go-get-issue-18219/bad/imp' +stderr 'must be imported as' +! exists github.com/rsc/go-get-issue-11864/vendor + +# Bad vendor (bad/imp2) +rm $GOPATH +mkdir $GOPATH/src +! go get -t -u 'github.com/rsc/go-get-issue-18219/bad/imp2' +stderr 'must be imported as' +! exists github.com/rsc/go-get-issue-11864/vendor + +# Bad vendor (bad/imp3) +rm $GOPATH +mkdir $GOPATH/src +! go get -t -u 'github.com/rsc/go-get-issue-18219/bad/imp3' +stderr 'must be imported as' +! exists github.com/rsc/go-get-issue-11864/vendor + +# Bad vendor (bad/...) +rm $GOPATH +mkdir $GOPATH/src +! go get -t -u 'github.com/rsc/go-get-issue-18219/bad/...' +stderr 'must be imported as' +! exists github.com/rsc/go-get-issue-11864/vendor + +-- v/m.go -- +package main + +import ( + "fmt" + "vendor.org/p" +) + +func main() { + fmt.Println(p.C) +} +-- v/m_test.go -- +package main +import ( + "fmt" + "testing" + "vendor.org/p" +) + +func TestNothing(t *testing.T) { + fmt.Println(p.C) +} +-- v/vendor/vendor.org/p/p.go -- +package p +const C = 1 diff --git a/src/cmd/go/testdata/script/get_with_git_trace.txt b/src/cmd/go/testdata/script/get_with_git_trace.txt new file mode 100644 index 0000000..98854c7 --- /dev/null +++ b/src/cmd/go/testdata/script/get_with_git_trace.txt @@ -0,0 +1,9 @@ +env GO111MODULE=off + +env GIT_TRACE=1 + +[!net] skip +[!exec:git] skip + +# go get should be success when GIT_TRACE set +go get golang.org/x/text diff --git a/src/cmd/go/testdata/script/goflags.txt b/src/cmd/go/testdata/script/goflags.txt new file mode 100644 index 0000000..686d113 --- /dev/null +++ b/src/cmd/go/testdata/script/goflags.txt @@ -0,0 +1,59 @@ +env GO111MODULE=off + +# GOFLAGS sets flags for commands + +env GOFLAGS='-e -f={{.Dir}} --test.benchtime=1s -count=10' +go list asdfasdfasdf # succeeds because of -e +go list runtime +stdout '[\\/]runtime$' + +env GOFLAGS=-race OLDGOARCH=$GOARCH OLDGOOS=$GOOS GOARCH=386 GOOS=linux +! go list runtime +stderr 'race is only supported on' + +env GOARCH=$OLDGOARCH GOOS=$OLDGOOS + +# go env succeeds even though -f={{.Dir}} is inappropriate +go env + +# bad flags are diagnosed +env GOFLAGS=-typoflag +! go list runtime +stderr 'unknown flag -typoflag' + +env GOFLAGS=- +! go list runtime +stderr '^go: parsing \$GOFLAGS: non-flag "-"' + +env GOFLAGS=-- +! go list runtime +stderr '^go: parsing \$GOFLAGS: non-flag "--"' + +env GOFLAGS=---oops +! go list runtime +stderr '^go: parsing \$GOFLAGS: non-flag "---oops"' + +env GOFLAGS=-=noname +! go list runtime +stderr '^go: parsing \$GOFLAGS: non-flag "-=noname"' + +env GOFLAGS=-f +! go list runtime +stderr '^go: flag needs an argument: -f \(from (\$GOFLAGS|%GOFLAGS%)\)$' + +env GOFLAGS=-e=asdf +! go list runtime +stderr '^go: invalid boolean value \"asdf\" for flag -e \(from (\$GOFLAGS|%GOFLAGS%)\)' + +# except in go bug (untested) and go env +go env +stdout GOFLAGS + +# Flags listed in GOFLAGS should be safe to duplicate on the command line. +env GOFLAGS=-tags=magic +go list -tags=magic +go test -tags=magic -c -o $devnull +go vet -tags=magic + +-- foo_test.go -- +package foo diff --git a/src/cmd/go/testdata/script/gopath_install.txt b/src/cmd/go/testdata/script/gopath_install.txt new file mode 100644 index 0000000..4b42fc5 --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_install.txt @@ -0,0 +1,53 @@ +# Regression test for 'go install' locations in GOPATH mode. +env GO111MODULE=off +[short] skip + +# Without $GOBIN set, binaries should be installed into the GOPATH bin directory. +env GOBIN= +rm $GOPATH/bin/go-cmd-test$GOEXE +go install go-cmd-test +exists $GOPATH/bin/go-cmd-test$GOEXE + +# With $GOBIN set, binaries should be installed to $GOBIN. +env GOBIN=$WORK/bin1 +mkdir -p $GOBIN +go install go-cmd-test +exists $GOBIN/go-cmd-test$GOEXE + +# Issue 11065: installing to the current directory should create an executable. +cd go-cmd-test +env GOBIN=$PWD +go install +exists ./go-cmd-test$GOEXE +cd .. + +# Without $GOBIN set, installing a program outside $GOPATH should fail +# (there is nowhere to install it). +env GOPATH= # reset to default ($HOME/go, which does not exist) +env GOBIN= +! go install go-cmd-test/helloworld.go +stderr '^go install: no install location for \.go files listed on command line \(GOBIN not set\)$' + +# With $GOBIN set, should install there. +env GOBIN=$WORK/bin1 +go install go-cmd-test/helloworld.go +exists $GOBIN/helloworld$GOEXE + +# We can't assume that we can write to GOROOT, because it may not be writable. +# However, we can check its install location using 'go list'. +# cmd/fix should be installed to GOROOT/pkg, not GOPATH/bin. +env GOPATH=$PWD +go list -f '{{.Target}}' cmd/fix +stdout $GOROOT'[/\\]pkg[/\\]tool[/\\]'$GOOS'_'$GOARCH'[/\\]fix'$GOEXE'$' + +# GOBIN should not affect toolchain install locations. +env GOBIN=$WORK/bin1 +go list -f '{{.Target}}' cmd/fix +stdout $GOROOT'[/\\]pkg[/\\]tool[/\\]'$GOOS'_'$GOARCH'[/\\]fix'$GOEXE'$' + +-- go-cmd-test/helloworld.go -- +package main + +func main() { + println("hello world") +} diff --git a/src/cmd/go/testdata/script/gopath_local.txt b/src/cmd/go/testdata/script/gopath_local.txt new file mode 100644 index 0000000..7ee1f83 --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_local.txt @@ -0,0 +1,117 @@ +env GO111MODULE=off # Relative imports only work in GOPATH mode. + +[short] skip + +# Imports should be resolved relative to the source file. +go build testdata/local/easy.go +exec ./easy$GOEXE +stdout '^easysub\.Hello' + +# Ignored files should be able to import the package built from +# non-ignored files in the same directory. +go build -o easysub$GOEXE testdata/local/easysub/main.go +exec ./easysub$GOEXE +stdout '^easysub\.Hello' + +# Files in relative-imported packages should be able to +# use relative imports themselves. +go build testdata/local/hard.go +exec ./hard$GOEXE +stdout '^sub\.Hello' + +# Explicit source files listed on the command line should not install without +# GOBIN set, since individual source files aren't part of the containing GOPATH. +! go install testdata/local/easy.go +stderr '^go install: no install location for \.go files listed on command line \(GOBIN not set\)$' + +[windows] stop # Windows does not allow the ridiculous directory name we're about to use. + +env BAD_DIR_NAME='#$%:, &()*;<=>?\^{}' + +mkdir -p testdata/$BAD_DIR_NAME/easysub +mkdir -p testdata/$BAD_DIR_NAME/sub/sub + +cp testdata/local/easy.go testdata/$BAD_DIR_NAME/easy.go +cp testdata/local/easysub/easysub.go testdata/$BAD_DIR_NAME/easysub/easysub.go +cp testdata/local/easysub/main.go testdata/$BAD_DIR_NAME/easysub/main.go +cp testdata/local/hard.go testdata/$BAD_DIR_NAME/hard.go +cp testdata/local/sub/sub.go testdata/$BAD_DIR_NAME/sub/sub.go +cp testdata/local/sub/sub/subsub.go testdata/$BAD_DIR_NAME/sub/sub/subsub.go + +# Imports should be resolved relative to the source file. +go build testdata/$BAD_DIR_NAME/easy.go +exec ./easy$GOEXE +stdout '^easysub\.Hello' + +# Ignored files should be able to import the package built from +# non-ignored files in the same directory. +go build -o easysub$GOEXE testdata/$BAD_DIR_NAME/easysub/main.go +exec ./easysub$GOEXE +stdout '^easysub\.Hello' + +# Files in relative-imported packages should be able to +# use relative imports themselves. +go build testdata/$BAD_DIR_NAME/hard.go +exec ./hard$GOEXE +stdout '^sub\.Hello' + +# Explicit source files listed on the command line should not install without +# GOBIN set, since individual source files aren't part of the containing GOPATH. +! go install testdata/$BAD_DIR_NAME/easy.go +stderr '^go install: no install location for \.go files listed on command line \(GOBIN not set\)$' + +-- testdata/local/easy.go -- +package main + +import "./easysub" + +func main() { + easysub.Hello() +} +-- testdata/local/easysub/easysub.go -- +package easysub + +import "fmt" + +func Hello() { + fmt.Println("easysub.Hello") +} +-- testdata/local/easysub/main.go -- +// +build ignore + +package main + +import "." + +func main() { + easysub.Hello() +} +-- testdata/local/hard.go -- +package main + +import "./sub" + +func main() { + sub.Hello() +} +-- testdata/local/sub/sub.go -- +package sub + +import ( + "fmt" + + subsub "./sub" +) + +func Hello() { + fmt.Println("sub.Hello") + subsub.Hello() +} +-- testdata/local/sub/sub/subsub.go -- +package subsub + +import "fmt" + +func Hello() { + fmt.Println("subsub.Hello") +} diff --git a/src/cmd/go/testdata/script/gopath_moved_repo.txt b/src/cmd/go/testdata/script/gopath_moved_repo.txt new file mode 100644 index 0000000..99d80bf --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_moved_repo.txt @@ -0,0 +1,67 @@ +env GO111MODULE=off + +# Test that 'go get -u' reports packages whose VCS configurations do not +# match their import paths. + +[!net] skip +[short] skip + +# We need to execute a custom Go program to break the config files. +# +# git will ask for a username and password when we run 'go get -d -f -u', +# so we also need to set GIT_ASKPASS. Conveniently, a single binary can +# perform both tasks! + +go build -o replace.exe replace +env GIT_ASKPASS=$PWD/replace.exe + + +# Test that 'go get -u' reports moved git packages. + +[exec:git] go get -d rsc.io/pdf +[exec:git] go get -d -u rsc.io/pdf +[exec:git] exec ./replace.exe pdf rsc.io/pdf/.git/config + +[exec:git] ! go get -d -u rsc.io/pdf +[exec:git] stderr 'is a custom import path for' +[exec:git] ! go get -d -f -u rsc.io/pdf +[exec:git] stderr 'validating server certificate|[nN]ot [fF]ound' + + +# Test that 'go get -u' reports moved Mercurial packages. + +[exec:hg] go get -d vcs-test.golang.org/go/custom-hg-hello +[exec:hg] go get -d -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] exec ./replace.exe custom-hg-hello vcs-test.golang.org/go/custom-hg-hello/.hg/hgrc + +[exec:hg] ! go get -d -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] stderr 'is a custom import path for' +[exec:hg] ! go get -d -f -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] stderr 'validating server certificate|[nN]ot [fF]ound' + + +-- replace/replace.go -- +package main + +import ( + "bytes" + "log" + "os" +) + +func main() { + if len(os.Args) < 3 { + return + } + + base := []byte(os.Args[1]) + path := os.Args[2] + data, err := os.ReadFile(path) + if err != nil { + log.Fatal(err) + } + err = os.WriteFile(path, bytes.ReplaceAll(data, base, append(base, "XXX"...)), 0644) + if err != nil { + log.Fatal(err) + } +} diff --git a/src/cmd/go/testdata/script/gopath_paths.txt b/src/cmd/go/testdata/script/gopath_paths.txt new file mode 100644 index 0000000..04265b1 --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_paths.txt @@ -0,0 +1,43 @@ +# Regression test for GOPATH validation in GOPATH mode. +env GO111MODULE=off + +env ORIG_GOPATH=$GOPATH + +# The literal path '.' in GOPATH should be rejected. +env GOPATH=. +! go build go-cmd-test/helloworld.go +stderr 'GOPATH entry is relative' + +# It should still be rejected if the requested package can be +# found using another entry. +env GOPATH=${:}$ORIG_GOPATH${:}. +! go build go-cmd-test +stderr 'GOPATH entry is relative' + +# GOPATH cannot be a relative subdirectory of the working directory. +env ORIG_GOPATH +stdout 'ORIG_GOPATH='$WORK[/\\]gopath +cd $WORK +env GOPATH=gopath +! go build gopath/src/go-cmd-test/helloworld.go +stderr 'GOPATH entry is relative' + +# Blank paths in GOPATH should be rejected as relative (issue 21928). +env GOPATH=' '${:}$ORIG_GOPATH +! go build go-cmd-test +stderr 'GOPATH entry is relative' + +[short] stop + +# Empty paths in GOPATH should be ignored (issue 21928). +env GOPATH=${:}$ORIG_GOPATH +env GOPATH +go install go-cmd-test +exists $ORIG_GOPATH/bin/go-cmd-test$GOEXE + +-- go-cmd-test/helloworld.go -- +package main + +func main() { + println("hello world") +} diff --git a/src/cmd/go/testdata/script/gopath_std_vendor.txt b/src/cmd/go/testdata/script/gopath_std_vendor.txt new file mode 100644 index 0000000..a0a41a5 --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_std_vendor.txt @@ -0,0 +1,44 @@ +env GO111MODULE=off + +[!gc] skip + +go list -f '{{.Dir}}' vendor/golang.org/x/net/http2/hpack +stdout $GOPATH[/\\]src[/\\]vendor + +# A package importing 'net/http' should resolve its dependencies +# to the package 'vendor/golang.org/x/net/http2/hpack' within GOROOT. +cd importnethttp +go list -deps -f '{{.ImportPath}} {{.Dir}}' +stdout ^vendor/golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack +! stdout $GOPATH[/\\]src[/\\]vendor + +# In the presence of $GOPATH/src/vendor/golang.org/x/net/http2/hpack, +# a package in GOPATH importing 'golang.org/x/net/http2/hpack' should +# resolve its dependencies in GOPATH/src. +cd ../issue16333 +go build . + +go list -deps -f '{{.ImportPath}} {{.Dir}}' . +stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack +! stdout $GOROOT[/\\]src[/\\]vendor + +go list -test -deps -f '{{.ImportPath}} {{.Dir}}' . +stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack +! stdout $GOROOT[/\\]src[/\\]vendor + +-- issue16333/issue16333.go -- +package vendoring17 + +import _ "golang.org/x/net/http2/hpack" +-- issue16333/issue16333_test.go -- +package vendoring17 + +import _ "testing" +import _ "golang.org/x/net/http2/hpack" +-- importnethttp/http.go -- +package importnethttp + +import _ "net/http" +-- $GOPATH/src/vendor/golang.org/x/net/http2/hpack/hpack.go -- +package hpack diff --git a/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt b/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt new file mode 100644 index 0000000..22e6048 --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt @@ -0,0 +1,25 @@ +[!net] skip +env GO111MODULE=off + +# Issue 17119: Test more duplicate load errors. +! go build dupload +! stderr 'duplicate load|internal error' +stderr 'dupload/vendor/p must be imported as p' + +-- dupload/dupload.go -- +package main + +import ( + _ "dupload/p2" + _ "p" +) + +func main() {} +-- dupload/p/p.go -- +package p +-- dupload/p2/p2.go -- +package p2 + +import _ "dupload/vendor/p" +-- dupload/vendor/p/p.go -- +package p diff --git a/src/cmd/go/testdata/script/goroot_executable.txt b/src/cmd/go/testdata/script/goroot_executable.txt new file mode 100644 index 0000000..fdbcde0 --- /dev/null +++ b/src/cmd/go/testdata/script/goroot_executable.txt @@ -0,0 +1,111 @@ +[gccgo] skip + +mkdir $WORK/new/bin + +# In this test, we are specifically checking the logic for deriving +# the value of GOROOT from runtime.GOROOT. +# GOROOT_FINAL changes the default behavior of runtime.GOROOT, +# and will thus cause the test to fail if it is set when our +# new cmd/go is built. +env GOROOT_FINAL= + +go build -o $WORK/new/bin/go$GOEXE cmd/go & +go build -o $WORK/bin/check$GOEXE check.go & +wait + +env TESTGOROOT=$GOROOT +env GOROOT= + +# Relocated Executable +# cp $TESTGOROOT/bin/go$GOEXE $WORK/new/bin/go$GOEXE +exec $WORK/bin/check$GOEXE $WORK/new/bin/go$GOEXE $TESTGOROOT + +# Relocated Tree: +# If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT, +# so it should find the new tree. +mkdir $WORK/new/pkg/tool +exec $WORK/bin/check$GOEXE $WORK/new/bin/go$GOEXE $WORK/new + +[!symlink] stop 'The rest of the test cases require symlinks' + +# Symlinked Executable: +# With a symlink into go tree, we should still find the go tree. +mkdir $WORK/other/bin +symlink $WORK/other/bin/go$GOEXE -> $WORK/new/bin/go$GOEXE +exec $WORK/bin/check$GOEXE $WORK/new/bin/go$GOEXE $WORK/new + +rm $WORK/new/pkg + +# Runtime GOROOT: +# Binaries built in the new tree should report the +# new tree when they call runtime.GOROOT. +symlink $WORK/new/src -> $TESTGOROOT/src +symlink $WORK/new/pkg -> $TESTGOROOT/pkg +exec $WORK/new/bin/go$GOEXE run check_runtime_goroot.go $WORK/new + +-- check.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + exe := os.Args[1] + want := os.Args[2] + cmd := exec.Command(exe, "env", "GOROOT") + out, err := cmd.CombinedOutput() + if err != nil { + fmt.Fprintf(os.Stderr, "%s env GOROOT: %v, %s\n", exe, err, out) + os.Exit(1) + } + goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out))) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + want, err = filepath.EvalSymlinks(want) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if !strings.EqualFold(goroot, want) { + fmt.Fprintf(os.Stderr, "go env GOROOT:\nhave %s\nwant %s\n", goroot, want) + os.Exit(1) + } + fmt.Fprintf(os.Stderr, "go env GOROOT: %s\n", goroot) + +} +-- check_runtime_goroot.go -- +package main + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "strings" +) + +func main() { + goroot, err := filepath.EvalSymlinks(runtime.GOROOT()) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + want, err := filepath.EvalSymlinks(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if !strings.EqualFold(goroot, want) { + fmt.Fprintf(os.Stderr, "go env GOROOT:\nhave %s\nwant %s\n", goroot, want) + os.Exit(1) + } + fmt.Fprintf(os.Stderr, "go env GOROOT: %s\n", goroot) + +} diff --git a/src/cmd/go/testdata/script/govcs.txt b/src/cmd/go/testdata/script/govcs.txt new file mode 100644 index 0000000..4180d7d --- /dev/null +++ b/src/cmd/go/testdata/script/govcs.txt @@ -0,0 +1,174 @@ +env GO111MODULE=on +env proxy=$GOPROXY +env GOPROXY=direct + +# GOVCS stops go get +env GOVCS='*:none' +! go get github.com/google/go-cmp +stderr '^go get: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' +env GOPRIVATE='github.com/google' +! go get github.com/google/go-cmp +stderr '^go get: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$' + +# public pattern works +env GOPRIVATE='github.com/google' +env GOVCS='public:all,private:none' +! go get github.com/google/go-cmp +stderr '^go get: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$' + +# private pattern works +env GOPRIVATE='hubgit.com/google' +env GOVCS='private:all,public:none' +! go get github.com/google/go-cmp +stderr '^go get: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' + +# other patterns work (for more patterns, see TestGOVCS) +env GOPRIVATE= +env GOVCS='github.com:svn|hg' +! go get github.com/google/go-cmp +stderr '^go get: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' +env GOVCS='github.com/google/go-cmp/inner:git,github.com:svn|hg' +! go get github.com/google/go-cmp +stderr '^go get: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' + +# bad patterns are reported (for more bad patterns, see TestGOVCSErrors) +env GOVCS='git' +! go get github.com/google/go-cmp +stderr '^go get github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"$' + +env GOVCS=github.com:hg,github.com:git +! go get github.com/google/go-cmp +stderr '^go get github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"$' + +# bad GOVCS patterns do not stop commands that do not need to check VCS +go list +env GOPROXY=$proxy +go get -d rsc.io/quote # ok because used proxy +env GOPROXY=direct + +# svn is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.svn/hello +stderr '^go get rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn; see ''go help vcs''$' + +# fossil is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.fossil/hello +stderr '^go get rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil; see ''go help vcs''$' + +# bzr is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.bzr/hello +stderr '^go get rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr; see ''go help vcs''$' + +# git is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:git] [!short] go get rsc.io/sampler + +# hg is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:hg] [!short] go get vcs-test.golang.org/go/custom-hg-hello + +# git can be disallowed +env GOVCS=public:hg +! go get rsc.io/nonexist.git/hello +stderr '^go get rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git; see ''go help vcs''$' + +# hg can be disallowed +env GOVCS=public:git +! go get rsc.io/nonexist.hg/hello +stderr '^go get rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg; see ''go help vcs''$' + +# Repeat in GOPATH mode. Error texts slightly different. + +env GO111MODULE=off + +# GOVCS stops go get +env GOVCS='*:none' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' +env GOPRIVATE='github.com/google' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$' + +# public pattern works +env GOPRIVATE='github.com/google' +env GOVCS='public:all,private:none' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$' + +# private pattern works +env GOPRIVATE='hubgit.com/google' +env GOVCS='private:all,public:none' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' + +# other patterns work (for more patterns, see TestGOVCS) +env GOPRIVATE= +env GOVCS='github.com:svn|hg' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' +env GOVCS='github.com/google/go-cmp/inner:git,github.com:svn|hg' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' + +# bad patterns are reported (for more bad patterns, see TestGOVCSErrors) +env GOVCS='git' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"$' + +env GOVCS=github.com:hg,github.com:git +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"$' + +# bad GOVCS patterns do not stop commands that do not need to check VCS +go list + +# svn is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.svn/hello +stderr '^package rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn; see ''go help vcs''$' + +# fossil is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.fossil/hello +stderr '^package rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil; see ''go help vcs''$' + +# bzr is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.bzr/hello +stderr '^package rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr; see ''go help vcs''$' + +# git is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:git] [!short] go get rsc.io/sampler + +# hg is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:hg] [!short] go get vcs-test.golang.org/go/custom-hg-hello + +# git can be disallowed +env GOVCS=public:hg +! go get rsc.io/nonexist.git/hello +stderr '^package rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git; see ''go help vcs''$' + +# hg can be disallowed +env GOVCS=public:git +! go get rsc.io/nonexist.hg/hello +stderr '^package rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg; see ''go help vcs''$' + +-- go.mod -- +module m + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/script/help.txt b/src/cmd/go/testdata/script/help.txt new file mode 100644 index 0000000..26a0194 --- /dev/null +++ b/src/cmd/go/testdata/script/help.txt @@ -0,0 +1,51 @@ +env GO111MODULE=off + +# go help shows overview. +go help +stdout 'Go is a tool' +stdout 'bug.*start a bug report' + +# go help bug shows usage for bug +go help bug +stdout 'usage: go bug' +stdout 'bug report' + +# go bug help is an error (bug takes no arguments) +! go bug help +stderr 'bug takes no arguments' + +# go help mod shows mod subcommands +go help mod +stdout 'go mod <command>' +stdout tidy + +# go help mod tidy explains tidy +go help mod tidy +stdout 'usage: go mod tidy' + +# go mod help tidy does too +go mod help tidy +stdout 'usage: go mod tidy' + +# go mod --help doesn't print help but at least suggests it. +! go mod --help +stderr 'Run ''go help mod'' for usage.' + +# Earlier versions of Go printed the same as 'go -h' here. +# Also make sure we print the short help line. +! go vet -h +stderr 'usage: go vet .*' +stderr 'Run ''go help vet'' for details.' +stderr 'Run ''go tool vet help'' for a full list of flags and analyzers.' +stderr 'Run ''go tool vet -help'' for an overview.' + +# Earlier versions of Go printed a large document here, instead of these two +# lines. +! go test -h +stderr 'usage: go test' +stderr 'Run ''go help test'' and ''go help testflag'' for details.' + +# go help get shows usage for get +go help get +stdout 'usage: go get' +stdout 'get when using GOPATH' diff --git a/src/cmd/go/testdata/script/import_cycle.txt b/src/cmd/go/testdata/script/import_cycle.txt new file mode 100644 index 0000000..901f43c --- /dev/null +++ b/src/cmd/go/testdata/script/import_cycle.txt @@ -0,0 +1,12 @@ +env GO111MODULE=off + +! go build selfimport +stderr -count=1 'import cycle not allowed' + +# 'go list' shouldn't hang forever. +go list -e -json selfimport + +-- $GOPATH/src/selfimport/selfimport.go -- +package selfimport + +import "selfimport" diff --git a/src/cmd/go/testdata/script/import_ignore.txt b/src/cmd/go/testdata/script/import_ignore.txt new file mode 100644 index 0000000..83a39a0 --- /dev/null +++ b/src/cmd/go/testdata/script/import_ignore.txt @@ -0,0 +1,11 @@ +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +-- go.mod -- +module m.test + +go 1.16 +-- .ignore.go -- +package p +import _ "golang.org/x/mod/modfile"
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/import_main.txt b/src/cmd/go/testdata/script/import_main.txt new file mode 100644 index 0000000..bc2cc4d --- /dev/null +++ b/src/cmd/go/testdata/script/import_main.txt @@ -0,0 +1,114 @@ +env GO111MODULE=off + +# Test that you cannot import a main package. +# See golang.org/issue/4210 and golang.org/issue/17475. + +[short] skip +cd $WORK + +# Importing package main from that package main's test should work. +go build x +go test -c x + +# Importing package main from another package should fail. +! go build p1 +stderr 'import "x" is a program, not an importable package' + +# ... even in that package's test. +go build p2 +! go test -c p2 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package's test is an xtest. +go build p3 +! go test p3 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package is a package main +go build p4 +! go test -c p4 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package is a package main using an xtest. +go build p5 +! go test -c p5 +stderr 'import "x" is a program, not an importable package' + +-- x/main.go -- +package main + +var X int + +func main() {} +-- x/main_test.go -- +package main_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p1/p.go -- +package p1 + +import xmain "x" + +var _ = xmain.X +-- p2/p.go -- +package p2 +-- p2/p_test.go -- +package p2 + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p3/p.go -- +package p +-- p3/p_test.go -- +package p_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p4/p.go -- +package main + +func main() {} +-- p4/p_test.go -- +package main + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p5/p.go -- +package main +func main() {} +-- p5/p_test.go -- +package main_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/install_cgo_excluded.txt b/src/cmd/go/testdata/script/install_cgo_excluded.txt new file mode 100644 index 0000000..5a2b460 --- /dev/null +++ b/src/cmd/go/testdata/script/install_cgo_excluded.txt @@ -0,0 +1,15 @@ +env CGO_ENABLED=0 + +! go install cgotest +stderr 'build constraints exclude all Go files' + +-- go.mod -- +module cgotest + +go 1.16 +-- m.go -- +package cgotest + +import "C" + +var _ C.int diff --git a/src/cmd/go/testdata/script/install_cleans_build.txt b/src/cmd/go/testdata/script/install_cleans_build.txt new file mode 100644 index 0000000..dc85eb8 --- /dev/null +++ b/src/cmd/go/testdata/script/install_cleans_build.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off +[short] skip + +# 'go install' with no arguments should clean up after go build +cd mycmd +go build +exists mycmd$GOEXE +go install +! exists mycmd$GOEXE + +# 'go install mycmd' does not clean up, even in the mycmd directory +go build +exists mycmd$GOEXE +go install mycmd +exists mycmd$GOEXE + +# 'go install mycmd' should not clean up in an unrelated current directory either +cd .. +cp mycmd/mycmd$GOEXE mycmd$GOEXE +go install mycmd +exists mycmd$GOEXE + +-- mycmd/main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/install_cmd_gobin.txt b/src/cmd/go/testdata/script/install_cmd_gobin.txt new file mode 100644 index 0000000..38fd66c --- /dev/null +++ b/src/cmd/go/testdata/script/install_cmd_gobin.txt @@ -0,0 +1,10 @@ +# Check that commands in cmd are install to $GOROOT/bin, not $GOBIN. +# Verifies golang.org/issue/32674. +env GOBIN=gobin +mkdir gobin +go list -f '{{.Target}}' cmd/go +stdout $GOROOT[/\\]bin[/\\]go$GOEXE + +# Check that tools are installed to $GOTOOLDIR, not $GOBIN. +go list -f '{{.Target}}' cmd/compile +stdout $GOROOT[/\\]pkg[/\\]tool[/\\]${GOOS}_${GOARCH}[/\\]compile$GOEXE diff --git a/src/cmd/go/testdata/script/install_cross_gobin.txt b/src/cmd/go/testdata/script/install_cross_gobin.txt new file mode 100644 index 0000000..33d48fc --- /dev/null +++ b/src/cmd/go/testdata/script/install_cross_gobin.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off +[short] skip # rebuilds std for alternate architecture + +cd mycmd +go build mycmd + +# cross-compile install with implicit GOBIN=$GOPATH/bin can make subdirectory +env GOARCH=386 +[386] env GOARCH=amd64 +env GOOS=linux +go install mycmd +exists $GOPATH/bin/linux_$GOARCH/mycmd + +# cross-compile install with explicit GOBIN cannot make subdirectory +env GOBIN=$WORK/bin +! go install mycmd +! exists $GOBIN/linux_$GOARCH + +# The install directory for a cross-compiled standard command should include GOARCH. +go list -f '{{.Target}}' cmd/pack +stdout ${GOROOT}[/\\]pkg[/\\]tool[/\\]${GOOS}_${GOARCH}[/\\]pack$ + +-- mycmd/x.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/install_msan_and_race_require_cgo.txt b/src/cmd/go/testdata/script/install_msan_and_race_require_cgo.txt new file mode 100644 index 0000000..7985cd2 --- /dev/null +++ b/src/cmd/go/testdata/script/install_msan_and_race_require_cgo.txt @@ -0,0 +1,18 @@ +# Tests Issue #21895 + +[!msan] [!race] skip 'skipping because both msan and the race detector are not supported' + +env CGO_ENABLED=0 + +[race] ! go install -race triv.go +[race] stderr '-race requires cgo' +[race] ! stderr '-msan' + +[msan] ! go install -msan triv.go +[msan] stderr '-msan requires cgo' +[msan] ! stderr '-race' + +-- triv.go -- +package main + +func main() {}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/install_rebuild_gopath.txt b/src/cmd/go/testdata/script/install_rebuild_gopath.txt new file mode 100644 index 0000000..14a6c86 --- /dev/null +++ b/src/cmd/go/testdata/script/install_rebuild_gopath.txt @@ -0,0 +1,30 @@ +env GO111MODULE=off + +# GOPATH with p1 in d1, p2 in d2 +env GOPATH=$WORK/d1${:}$WORK/d2 + +# build & install p1 +go install -i p1 +! stale p1 p2 + +# modify p2 - p1 should appear stale +cp $WORK/p2x.go $WORK/d2/src/p2/p2.go +stale p1 p2 + +# build & install p1 again +go install -i p1 +! stale p1 p2 + +-- $WORK/d1/src/p1/p1.go -- +package p1 +import "p2" +func F() { p2.F() } + +-- $WORK/d2/src/p2/p2.go -- +package p2 +func F() {} + +-- $WORK/p2x.go -- +package p2 +func F() {} +func G() {} diff --git a/src/cmd/go/testdata/script/install_rebuild_removed.txt b/src/cmd/go/testdata/script/install_rebuild_removed.txt new file mode 100644 index 0000000..5db3778 --- /dev/null +++ b/src/cmd/go/testdata/script/install_rebuild_removed.txt @@ -0,0 +1,44 @@ +env GO111MODULE=off + +# go command should detect package staleness as source file set changes +go install mypkg +! stale mypkg + +# z.go was not compiled; removing it should NOT make mypkg stale +rm mypkg/z.go +! stale mypkg + +# y.go was compiled; removing it should make mypkg stale +rm mypkg/y.go +stale mypkg + +# go command should detect executable staleness too +go install mycmd +! stale mycmd +rm mycmd/z.go +! stale mycmd +rm mycmd/y.go +stale mycmd + +-- mypkg/x.go -- +package mypkg + +-- mypkg/y.go -- +package mypkg + +-- mypkg/z.go -- +// +build missingtag + +package mypkg + +-- mycmd/x.go -- +package main +func main() {} + +-- mycmd/y.go -- +package main + +-- mycmd/z.go -- +// +build missingtag + +package main diff --git a/src/cmd/go/testdata/script/install_relative_gobin_fail.txt b/src/cmd/go/testdata/script/install_relative_gobin_fail.txt new file mode 100644 index 0000000..aa14524 --- /dev/null +++ b/src/cmd/go/testdata/script/install_relative_gobin_fail.txt @@ -0,0 +1,12 @@ +env GOBIN=. +! go install +stderr 'cannot install, GOBIN must be an absolute path' + +-- go.mod -- +module triv + +go 1.16 +-- triv.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/install_shadow_gopath.txt b/src/cmd/go/testdata/script/install_shadow_gopath.txt new file mode 100644 index 0000000..2039d9e --- /dev/null +++ b/src/cmd/go/testdata/script/install_shadow_gopath.txt @@ -0,0 +1,20 @@ +# Tests Issue #3562 +# go get foo.io (not foo.io/subdir) was not working consistently. + +[!net] skip + +env GO111MODULE=off +env GOPATH=$WORK/gopath1${:}$WORK/gopath2 + +mkdir $WORK/gopath1/src/test +mkdir $WORK/gopath2/src/test +cp main.go $WORK/gopath2/src/test/main.go +cd $WORK/gopath2/src/test + +! go install +stderr 'no install location for.*gopath2.src.test: hidden by .*gopath1.src.test' + +-- main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/issue36000.txt b/src/cmd/go/testdata/script/issue36000.txt new file mode 100644 index 0000000..4173275 --- /dev/null +++ b/src/cmd/go/testdata/script/issue36000.txt @@ -0,0 +1,6 @@ +# Tests golang.org/issue/36000 + +[!cgo] skip + +# go env with CGO flags should not make NUL file +go env CGO_CFLAGS diff --git a/src/cmd/go/testdata/script/ldflag.txt b/src/cmd/go/testdata/script/ldflag.txt new file mode 100644 index 0000000..6ceb33b --- /dev/null +++ b/src/cmd/go/testdata/script/ldflag.txt @@ -0,0 +1,44 @@ +# Issue #42565 + +[!cgo] skip + +# We can't build package bad, which uses #cgo LDFLAGS. +cd bad +! go build +stderr no-such-warning + +# We can build package ok with the same flags in CGO_LDFLAGS. +env CGO_LDFLAGS=-Wno-such-warning -Wno-unknown-warning-option +cd ../ok +go build + +# Build a main program that actually uses LDFLAGS. +cd .. +go build -ldflags=-v + +# Because we passed -v the Go linker should print the external linker +# command which should include the flag we passed in CGO_LDFLAGS. +stderr no-such-warning + +-- go.mod -- +module ldflag + +-- bad/bad.go -- +package bad + +// #cgo LDFLAGS: -Wno-such-warning -Wno-unknown-warning +import "C" + +func F() {} +-- ok/ok.go -- +package ok + +import "C" + +func F() {} +-- main.go -- +package main + +import _ "ldflag/ok" + +func main() {} diff --git a/src/cmd/go/testdata/script/link_matching_actionid.txt b/src/cmd/go/testdata/script/link_matching_actionid.txt new file mode 100644 index 0000000..b8d423d --- /dev/null +++ b/src/cmd/go/testdata/script/link_matching_actionid.txt @@ -0,0 +1,38 @@ +# Checks that an identical binary is built with -trimpath from the same +# source files, with GOROOT in two different locations. +# Verifies golang.org/issue/38989 + +[short] skip +[!symlink] skip + +# Symlink the compiler to a local path +env GOROOT=$WORK/goroot1 +symlink $GOROOT -> $TESTGO_GOROOT + +# Set up fresh GOCACHE +env GOCACHE=$WORK/gocache1 +mkdir $GOCACHE + +# Build a simple binary +go build -o binary1 -trimpath -x main.go + +# Now repeat the same process with the compiler at a different local path +env GOROOT=$WORK/goroot2 +symlink $GOROOT -> $TESTGO_GOROOT + +env GOCACHE=$WORK/gocache2 +mkdir $GOCACHE + +go build -o binary2 -trimpath -x main.go + +# Check that the binaries match exactly +go tool buildid binary1 +cp stdout buildid1 +go tool buildid binary2 +cp stdout buildid2 +cmp buildid1 buildid2 + + +-- main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/link_syso_issue33139.txt b/src/cmd/go/testdata/script/link_syso_issue33139.txt new file mode 100644 index 0000000..8a8cb4a --- /dev/null +++ b/src/cmd/go/testdata/script/link_syso_issue33139.txt @@ -0,0 +1,43 @@ +# Test that we can use the external linker with a host syso file that is +# embedded in a package, that is referenced by a Go assembly function. +# See issue 33139. +[!gc] skip +[!cgo] skip + +# External linking is not supported on linux/ppc64. +# See: https://github.com/golang/go/issues/8912 +[linux] [ppc64] skip + +cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c +go build -ldflags='-linkmode=external' ./cmd/main.go + +-- go.mod -- +module m + +go 1.16 +-- syso/objTest.s -- +#include "textflag.h" + +TEXT ·ObjTest(SB), NOSPLIT, $0 + // We do not actually execute this function in the test above, thus + // there is no stack frame setup here. + // We only care about Go build and/or link errors when referencing + // the objTestImpl symbol in the syso file. + JMP objTestImpl(SB) + +-- syso/pkg.go -- +package syso + +func ObjTest() + +-- syso/src/objTestImpl.c -- +void objTestImpl() { /* Empty */ } + +-- cmd/main.go -- +package main + +import "m/syso" + +func main() { + syso.ObjTest() +} diff --git a/src/cmd/go/testdata/script/linkname.txt b/src/cmd/go/testdata/script/linkname.txt new file mode 100644 index 0000000..1133659 --- /dev/null +++ b/src/cmd/go/testdata/script/linkname.txt @@ -0,0 +1,9 @@ +env GO111MODULE=off + +# check for linker name in error message about linker crash +[!gc] skip +! go build -ldflags=-crash_for_testing x.go +stderr [\\/]tool[\\/].*[\\/]link + +-- x.go -- +package main; func main() {} diff --git a/src/cmd/go/testdata/script/list_ambiguous_path.txt b/src/cmd/go/testdata/script/list_ambiguous_path.txt new file mode 100644 index 0000000..82dde45 --- /dev/null +++ b/src/cmd/go/testdata/script/list_ambiguous_path.txt @@ -0,0 +1,38 @@ +# Ensures that we can correctly list package patterns ending in '.go'. +# See golang.org/issue/34653. + +# A single pattern for a package ending in '.go'. +go list ./foo.go +stdout '^test/foo.go$' + +# Multiple patterns for packages including one ending in '.go'. +go list ./bar ./foo.go +stdout '^test/bar$' +stdout '^test/foo.go$' + +# A single pattern for a Go file. +go list ./a.go +stdout '^command-line-arguments$' + +# A single typo-ed pattern for a Go file. This should +# treat the wrong pattern as if it were a package. +! go list ./foo.go/b.go +stderr '^stat .*[/\\]foo\.go[/\\]b\.go: directory not found$' + +# Multiple patterns for Go files with a typo. This should +# treat the wrong pattern as if it were a nonexistent file. +! go list ./foo.go/a.go ./foo.go/b.go +[plan9] stderr 'stat ./foo.go/b.go: ''./foo.go/b.go'' does not exist' +[windows] stderr './foo.go/b.go: The system cannot find the file specified' +[!plan9] [!windows] stderr './foo.go/b.go: no such file or directory' + +-- a.go -- +package main +-- bar/a.go -- +package bar +-- foo.go/a.go -- +package foo.go +-- go.mod -- +module "test" + +go 1.13 diff --git a/src/cmd/go/testdata/script/list_bad_import.txt b/src/cmd/go/testdata/script/list_bad_import.txt new file mode 100644 index 0000000..dbec350 --- /dev/null +++ b/src/cmd/go/testdata/script/list_bad_import.txt @@ -0,0 +1,72 @@ +env GO111MODULE=off +[short] skip + +# This test matches mod_list_bad_import, but in GOPATH mode. +# Please keep them in sync. + +env GO111MODULE=off +cd example.com + +# Without -e, listing an otherwise-valid package with an unsatisfied direct import should fail. +# BUG: Today it succeeds. +go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}} {{range .DepsErrors}}bad dep: {{.Err}}{{end}}' example.com/direct +! stdout ^error +stdout 'incomplete' +stdout 'bad dep: .*example.com[/\\]notfound' + +# Listing with -deps should also fail. +! go list -deps example.com/direct +stderr example.com[/\\]notfound + +# But -e -deps should succeed. +go list -e -deps example.com/direct +stdout example.com/notfound + + +# Listing an otherwise-valid package that imports some *other* package with an +# unsatisfied import should also fail. +# BUG: Today, it succeeds. +go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}} {{range .DepsErrors}}bad dep: {{.Err}}{{end}}' example.com/indirect +! stdout ^error +stdout incomplete +stdout 'bad dep: .*example.com[/\\]notfound' + +# Again, -deps should fail. +! go list -deps example.com/indirect +stderr example.com[/\\]notfound + +# But -deps -e should succeed. +go list -e -deps example.com/indirect +stdout example.com/notfound + + +# Listing the missing dependency directly should fail outright... +! go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound +stderr 'no Go files in .*example.com[/\\]notfound' +! stdout error +! stdout incomplete + +# ...but listing with -e should succeed. +go list -e -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound +stdout error +stdout incomplete + + +# The pattern "all" should match only packages that actually exist, +# ignoring those whose existence is merely implied by imports. +go list -e -f '{{.ImportPath}}' all +stdout example.com/direct +stdout example.com/indirect +! stdout example.com/notfound + + +-- example.com/direct/direct.go -- +package direct +import _ "example.com/notfound" + +-- example.com/indirect/indirect.go -- +package indirect +import _ "example.com/direct" + +-- example.com/notfound/README -- +This directory intentionally left blank. diff --git a/src/cmd/go/testdata/script/list_case_collision.txt b/src/cmd/go/testdata/script/list_case_collision.txt new file mode 100644 index 0000000..181a202 --- /dev/null +++ b/src/cmd/go/testdata/script/list_case_collision.txt @@ -0,0 +1,41 @@ +# Tests golang.org/issue/4773 + +go list -json example/a +stdout 'case-insensitive import collision' + +! go build example/a +stderr 'case-insensitive import collision' + +# List files explicitly on command line, to encounter case-checking +# logic even on case-insensitive filesystems. +cp b/file.go b/FILE.go # no-op on case-insensitive filesystems +! go list b/file.go b/FILE.go +stderr 'case-insensitive file name collision' + +mkdir a/Pkg # no-op on case-insensitive filesystems +cp a/pkg/pkg.go a/Pkg/pkg.go # no-op on case-insensitive filesystems +! go list example/a/pkg example/a/Pkg + +# Test that the path reported with an indirect import is correct. +cp b/file.go b/FILE.go +[case-sensitive] ! go build example/c +[case-sensitive] stderr '^package example/c\n\timports example/b: case-insensitive file name collision: "FILE.go" and "file.go"$' + +-- go.mod -- +module example + +go 1.16 +-- a/a.go -- +package p +import ( + _ "example/a/pkg" + _ "example/a/Pkg" +) +-- a/pkg/pkg.go -- +package pkg +-- b/file.go -- +package b +-- c/c.go -- +package c + +import _ "example/b" diff --git a/src/cmd/go/testdata/script/list_compiled_imports.txt b/src/cmd/go/testdata/script/list_compiled_imports.txt new file mode 100644 index 0000000..7780b07 --- /dev/null +++ b/src/cmd/go/testdata/script/list_compiled_imports.txt @@ -0,0 +1,31 @@ +env GO111MODULE=off + +[!cgo] skip + +# go list should report import "C" +cd x +go list -f '{{.Imports}}' +! stdout runtime/cgo +! stdout unsafe +! stdout syscall +stdout C +stdout unicode +stdout unicode/utf16 + +# go list -compiled should report imports in compiled files as well, +# adding "runtime/cgo", "unsafe", and "syscall" but not dropping "C". +go list -compiled -f '{{.Imports}}' +stdout runtime/cgo +stdout unsafe +stdout syscall +stdout C +stdout unicode +stdout unicode/utf16 + +-- x/x.go -- +package x +import "C" +import "unicode" // does not use unsafe, syscall, runtime/cgo, unicode/utf16 +-- x/x1.go -- +package x +import "unicode/utf16" // does not use unsafe, syscall, runtime/cgo, unicode diff --git a/src/cmd/go/testdata/script/list_constraints.txt b/src/cmd/go/testdata/script/list_constraints.txt new file mode 100644 index 0000000..7115c36 --- /dev/null +++ b/src/cmd/go/testdata/script/list_constraints.txt @@ -0,0 +1,86 @@ +# Check that files and their imports are not included in 'go list' output +# when they are excluded by build constraints. + +# Linux and cgo files should be included when building in that configuration. +env GOOS=linux +env GOARCH=amd64 +env CGO_ENABLED=1 +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^cgotag.go empty.go suffix_linux.go tag.go $' +go list -f '{{range .CgoFiles}}{{.}} {{end}}' +stdout '^cgoimport.go $' +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^C cgoimport cgotag suffix tag $' + +# Disabling cgo should exclude cgo files and their imports. +env CGO_ENABLED=0 +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout 'empty.go suffix_linux.go tag.go' +go list -f '{{range .CgoFiles}}{{.}} {{end}}' +! stdout . +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^suffix tag $' + +# Changing OS should exclude linux sources. +env GOOS=darwin +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^empty.go $' +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^$' + +# Enabling a tag should include files that require it. +go list -tags=extra -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^empty.go extra.go $' +go list -tags=extra -f '{{range .Imports}}{{.}} {{end}}' +stdout '^extra $' + +# Packages that require a tag should not be listed unless the tag is on. +! go list ./tagonly +go list -tags=extra ./tagonly +stdout m/tagonly + +-- go.mod -- +module m + +go 1.13 + +-- empty.go -- +package p + +-- extra.go -- +// +build extra + +package p + +import _ "extra" + +-- suffix_linux.go -- +package p + +import _ "suffix" + +-- tag.go -- +// +build linux + +package p + +import _ "tag" + +-- cgotag.go -- +// +build cgo + +package p + +import _ "cgotag" + +-- cgoimport.go -- +package p + +import "C" + +import _ "cgoimport" + +-- tagonly/tagonly.go -- +// +build extra + +package tagonly diff --git a/src/cmd/go/testdata/script/list_dedup_packages.txt b/src/cmd/go/testdata/script/list_dedup_packages.txt new file mode 100644 index 0000000..30c68dd --- /dev/null +++ b/src/cmd/go/testdata/script/list_dedup_packages.txt @@ -0,0 +1,31 @@ +# Setup +env GO111MODULE=off +mkdir $WORK/tmp/testdata/src/xtestonly +cp f.go $WORK/tmp/testdata/src/xtestonly/f.go +cp f_test.go $WORK/tmp/testdata/src/xtestonly/f_test.go +env GOPATH=$WORK/tmp/testdata +cd $WORK + +# Check output of go list to ensure no duplicates +go list xtestonly ./tmp/testdata/src/xtestonly/... +cmp stdout $WORK/gopath/src/wantstdout + +-- wantstdout -- +xtestonly +-- f.go -- +package xtestonly + +func F() int { return 42 } +-- f_test.go -- +package xtestonly_test + +import ( + "testing" + "xtestonly" +) + +func TestF(t *testing.T) { + if x := xtestonly.F(); x != 42 { + t.Errorf("f.F() = %d, want 42", x) + } +} diff --git a/src/cmd/go/testdata/script/list_err_cycle.txt b/src/cmd/go/testdata/script/list_err_cycle.txt new file mode 100644 index 0000000..44b82a6 --- /dev/null +++ b/src/cmd/go/testdata/script/list_err_cycle.txt @@ -0,0 +1,15 @@ +# Check that we don't get infinite recursion when loading a package with +# an import cycle and another error. Verifies #25830. +! go list +stderr 'found packages a \(a.go\) and b \(b.go\)' + +-- go.mod -- +module errcycle + +go 1.16 +-- a.go -- +package a + +import _ "errcycle" +-- b.go -- +package b
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/list_err_stack.txt b/src/cmd/go/testdata/script/list_err_stack.txt new file mode 100644 index 0000000..a7be9fd --- /dev/null +++ b/src/cmd/go/testdata/script/list_err_stack.txt @@ -0,0 +1,27 @@ + +# golang.org/issue/40544: regression in error stacks for parse errors + +env GO111MODULE=off +cd sandbox/foo +go list -e -json . +stdout '"sandbox/foo"' +stdout '"sandbox/bar"' +stdout '"Pos": "..(/|\\\\)bar(/|\\\\)bar.go:1:1"' +stdout '"Err": "expected ''package'', found ackage"' + +env GO111MODULE=on +go list -e -json . +stdout '"sandbox/foo"' +stdout '"sandbox/bar"' +stdout '"Pos": "..(/|\\\\)bar(/|\\\\)bar.go:1:1"' +stdout '"Err": "expected ''package'', found ackage"' + +-- sandbox/go.mod -- +module sandbox + +-- sandbox/foo/foo.go -- +package pkg + +import "sandbox/bar" +-- sandbox/bar/bar.go -- +ackage bar
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/list_find.txt b/src/cmd/go/testdata/script/list_find.txt new file mode 100644 index 0000000..d450fc9 --- /dev/null +++ b/src/cmd/go/testdata/script/list_find.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +# go list -find should not report imports + +go list -f {{.Incomplete}} x/y/z... # should probably exit non-zero but never has +stdout true +go list -find -f '{{.Incomplete}} {{.Imports}}' x/y/z... +stdout '^false \[\]' + +# go list -find -compiled should use cached sources the second time it's run. +# It might not find the same cached sources as "go build", but the sources +# should be identical. "go build" derives action IDs (which are used as cache +# keys) from dependencies' action IDs. "go list -find" won't know what the +# dependencies are, so it's can't construct the same action IDs. +[short] skip +go list -find -compiled net +go list -find -compiled -x net +! stderr 'cgo' + +-- x/y/z/z.go -- +package z +import "does/not/exist" diff --git a/src/cmd/go/testdata/script/list_gofile_in_goroot.txt b/src/cmd/go/testdata/script/list_gofile_in_goroot.txt new file mode 100644 index 0000000..6e48d7b --- /dev/null +++ b/src/cmd/go/testdata/script/list_gofile_in_goroot.txt @@ -0,0 +1,76 @@ +# Return an error if the user tries to list a go source file directly in $GOROOT/src. +# Tests golang.org/issue/36587 + +env GOROOT=$WORK/goroot +env GOPATH=$WORK/gopath + +go env GOROOT +stdout $WORK[/\\]goroot + +# switch to GOROOT/src +cd $GOROOT/src + +# In module mode, 'go list ./...' should not treat .go files in GOROOT/src as an +# importable package, since that directory has no valid import path. +env GO111MODULE=on +go list ... +stdout -count=1 '^.+$' +stdout '^fmt$' +! stdout foo + +go list ./... +stdout -count=1 '^.+$' +stdout '^fmt$' +! stdout foo + +go list std +stdout -count=1 '^.+$' +stdout '^fmt$' + +! go list . +stderr '^GOROOT/src is not an importable package$' + +# In GOPATH mode, 'go list ./...' should synthesize a legacy GOPATH-mode path — +# not a standard-library or empty path — for the errant package. +env GO111MODULE=off +go list ./... +stdout -count=2 '^.+$' # Both 'fmt' and GOROOT/src should be listed. +stdout '^fmt$' +[!windows] stdout ^_$WORK/goroot/src$ +[windows] stdout goroot/src$ # On windows the ":" in the volume name is mangled + +go list ... +! stdout goroot/src + +go list std +! stdout goroot/src + +go list . +[!windows] stdout ^_$WORK/goroot/src$ +[windows] stdout goroot/src$ + +# switch to GOPATH/src +cd $GOPATH/src + +# GO111MODULE=off,GOPATH +env GO111MODULE=off +go list ./... +[!windows] stdout ^_$WORK/gopath/src$ +[windows] stdout gopath/src$ + +go list all +! stdout gopath/src + +-- $WORK/goroot/src/go.mod -- +module std + +go 1.14 +-- $WORK/goroot/src/foo.go -- +package foo +-- $WORK/goroot/src/fmt/fmt.go -- +package fmt +-- $WORK/goroot/src/cmd/README -- +This directory must exist in order for the 'cmd' pattern to have something to +match against. +-- $GOPATH/src/foo.go -- +package foo diff --git a/src/cmd/go/testdata/script/list_importmap.txt b/src/cmd/go/testdata/script/list_importmap.txt new file mode 100644 index 0000000..f424b98 --- /dev/null +++ b/src/cmd/go/testdata/script/list_importmap.txt @@ -0,0 +1,27 @@ +env GO111MODULE=off + +# gccgo does not have standard packages. +[gccgo] skip + +# fmt should have no rewritten imports. +# The import from a/b should map c/d to a's vendor directory. +go list -f '{{.ImportPath}}: {{.ImportMap}}' fmt a/b +stdout 'fmt: map\[\]' +stdout 'a/b: map\[c/d:a/vendor/c/d\]' + +# flag [fmt.test] should import fmt [fmt.test] as fmt +# fmt.test should import testing [fmt.test] as testing +# fmt.test should not import a modified os +go list -deps -test -f '{{.ImportPath}} MAP: {{.ImportMap}}{{"\n"}}{{.ImportPath}} IMPORT: {{.Imports}}' fmt +stdout '^flag \[fmt\.test\] MAP: map\[fmt:fmt \[fmt\.test\]\]' +stdout '^fmt\.test MAP: map\[(.* )?testing:testing \[fmt\.test\]' +! stdout '^fmt\.test MAP: map\[(.* )?os:' +stdout '^fmt\.test IMPORT: \[fmt \[fmt\.test\] fmt_test \[fmt\.test\] os reflect testing \[fmt\.test\] testing/internal/testdeps \[fmt\.test\]\]' + + +-- a/b/b.go -- +package b + +import _ "c/d" +-- a/vendor/c/d/d.go -- +package d diff --git a/src/cmd/go/testdata/script/list_linkshared.txt b/src/cmd/go/testdata/script/list_linkshared.txt new file mode 100644 index 0000000..baae1e2 --- /dev/null +++ b/src/cmd/go/testdata/script/list_linkshared.txt @@ -0,0 +1,16 @@ +env GO111MODULE=on + +# golang.org/issue/35759: 'go list -linkshared' +# panicked if invoked on a test-only package. + +[!buildmode:shared] skip + +go list -f '{{.ImportPath}}: {{.Target}} {{.Shlib}}' -linkshared . +stdout '^example.com: $' + +-- go.mod -- +module example.com + +go 1.14 +-- x.go -- +package x diff --git a/src/cmd/go/testdata/script/list_load_err.txt b/src/cmd/go/testdata/script/list_load_err.txt new file mode 100644 index 0000000..b3b7271 --- /dev/null +++ b/src/cmd/go/testdata/script/list_load_err.txt @@ -0,0 +1,79 @@ +# go list -e -deps should list imports from any file it can read, even if +# other files in the same package cause go/build.Import to return an error. +# Verfifies golang.org/issue/38568 + + +go list -e -deps ./scan +stdout m/want + + +go list -e -deps ./multi +stdout m/want + + +go list -e -deps ./constraint +stdout m/want + + +[cgo] go list -e -test -deps ./cgotest +[cgo] stdout m/want + + +[cgo] go list -e -deps ./cgoflag +[cgo] stdout m/want + +-- go.mod -- +module m + +go 1.14 + +-- want/want.go -- +package want + +-- scan/scan.go -- +// scan error +ʕ◔ϖ◔ʔ + +-- scan/good.go -- +package scan + +import _ "m/want" + +-- multi/a.go -- +package a + +-- multi/b.go -- +package b + +import _ "m/want" + +-- constraint/constraint.go -- +// +build !!nope + +package constraint + +-- constraint/good.go -- +package constraint + +import _ "m/want" + +-- cgotest/cgo_test.go -- +package cgo_test + +// cgo is not allowed in tests. +// See golang.org/issue/18647 + +import "C" +import ( + "testing" + _ "m/want" +) + +func Test(t *testing.T) {} + +-- cgoflag/cgoflag.go -- +package cgoflag + +// #cgo ʕ◔ϖ◔ʔ: + +import _ "m/want" diff --git a/src/cmd/go/testdata/script/list_overlay.txt b/src/cmd/go/testdata/script/list_overlay.txt new file mode 100644 index 0000000..1153975 --- /dev/null +++ b/src/cmd/go/testdata/script/list_overlay.txt @@ -0,0 +1,63 @@ +# Test listing with overlays + +# Overlay in an existing directory +go list -overlay overlay.json -f '{{.GoFiles}}' . +stdout '^\[f.go\]$' + +# Overlays in a non-existing directory +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir +stdout '^\[g.go\]$' + +# Overlays in an existing directory with already existing files +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir2 +stdout '^\[h.go i.go\]$' + +# Overlay that removes a file from a directory +! go list ./dir3 # contains a file without a package statement +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir3 # overlay removes that file + +# Walking through an overlay +go list -overlay overlay.json ./... +cmp stdout want-list.txt + +# TODO(#39958): assembly files, C files, files that require cgo preprocessing + +-- want-list.txt -- +m +m/dir +m/dir2 +m/dir3 +-- go.mod -- +// TODO(#39958): Support and test overlays including go.mod itself (especially if mod=readonly) +module m + +go 1.16 + +-- dir2/h.go -- +package dir2 + +-- dir3/good.go -- +package dir3 +-- dir3/bad.go -- +// no package statement +-- overlay.json -- +{ + "Replace": { + "f.go": "overlay/f_go", + "dir/g.go": "overlay/dir_g_go", + "dir2/i.go": "overlay/dir2_i_go", + "dir3/bad.go": "" + } +} +-- overlay/f_go -- +package m + +func f() { +} +-- overlay/dir_g_go -- +package m + +func g() { +} +-- overlay/dir2_i_go -- +package dir2 diff --git a/src/cmd/go/testdata/script/list_parse_err.txt b/src/cmd/go/testdata/script/list_parse_err.txt new file mode 100644 index 0000000..3c53458 --- /dev/null +++ b/src/cmd/go/testdata/script/list_parse_err.txt @@ -0,0 +1,45 @@ +# 'go list' without -e should fail and print errors on stderr. +! go list ./p +stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$' +! go list -f '{{range .Imports}}{{.}} {{end}}' ./p +stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$' +! go list -test ./t +stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ' +! go list -test -f '{{range .Imports}}{{.}} {{end}}' ./t +stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ' + +# 'go list -e' should report imports, even if some files have parse errors +# before the import block. +go list -e -f '{{range .Imports}}{{.}} {{end}}' ./p +stdout '^fmt ' + +# 'go list' should report the position of the error if there's only one. +go list -e -f '{{.Error.Pos}} => {{.Error.Err}}' ./p +stdout 'b.go:[0-9:]+ => expected ''package'', found ''EOF''' + +# 'go test' should report the position of the error if there's only one. +go list -e -test -f '{{if .Error}}{{.Error.Pos}} => {{.Error.Err}}{{end}}' ./t +stdout 't_test.go:[0-9:]+ => expected declaration, found ʕ' + +-- go.mod -- +module m + +go 1.13 + +-- p/a.go -- +package a + +import "fmt" + +-- p/b.go -- +// no package statement + +-- t/t_test.go -- +package t + +import "testing" + +func Test(t *testing.T) {} + +// scan error +ʕ◔ϖ◔ʔ diff --git a/src/cmd/go/testdata/script/list_permissions.txt b/src/cmd/go/testdata/script/list_permissions.txt new file mode 100644 index 0000000..f65896c --- /dev/null +++ b/src/cmd/go/testdata/script/list_permissions.txt @@ -0,0 +1,84 @@ +env GO111MODULE=on + +# Establish baseline behavior, before mucking with file permissions. + +go list ./noread/... +stdout '^example.com/noread$' + +go list example.com/noread/... +stdout '^example.com/noread$' + +go list ./empty/... +stderr 'matched no packages' + +[root] stop # Root typically ignores file permissions. + +# Make the directory ./noread unreadable, and verify that 'go list' reports an +# explicit error for a pattern that should match it (rather than treating it as +# equivalent to an empty directory). + +[windows] skip # Does not have Unix-style directory permissions. +[plan9] skip # Might not have Unix-style directory permissions. + +chmod 000 noread + +# Check explicit paths. + +! go list ./noread +! stdout '^example.com/noread$' +! stderr 'matched no packages' + +! go list example.com/noread +! stdout '^example.com/noread$' +! stderr 'matched no packages' + +# Check filesystem-relative patterns. + +! go list ./... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern ./...: ' + +! go list ./noread/... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern ./noread/...: ' + + +# Check module-prefix patterns. + +! go list example.com/... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern example.com/...: ' + +! go list example.com/noread/... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern example.com/noread/...: ' + + +[short] stop + +# Check global patterns, which should still +# fail due to errors in the local module. + +! go list all +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern all: ' + +! go list ... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern ...: ' + + +-- go.mod -- +module example.com +go 1.15 +-- noread/noread.go -- +// Package noread exists, but will be made unreadable. +package noread +-- empty/README.txt -- +This directory intentionally left empty. diff --git a/src/cmd/go/testdata/script/list_shadow.txt b/src/cmd/go/testdata/script/list_shadow.txt new file mode 100644 index 0000000..7b24d93 --- /dev/null +++ b/src/cmd/go/testdata/script/list_shadow.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off +env GOPATH=$WORK/gopath/src/shadow/root1${:}$WORK/gopath/src/shadow/root2 + +# The math in root1 is not "math" because the standard math is. +go list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./shadow/root1/src/math +stdout '^\(.*(\\|/)src(\\|/)shadow(\\|/)root1(\\|/)src(\\|/)math\) \('$GOROOT'(\\|/)?src(\\|/)math\)$' + +# The foo in root1 is "foo". +go list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./shadow/root1/src/foo +stdout '^\(foo\) \(\)$' + +# The foo in root2 is not "foo" because the foo in root1 got there first. +go list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./shadow/root2/src/foo +stdout '^\(.*gopath(\\|/)src(\\|/)shadow(\\|/)root2(\\|/)src(\\|/)foo\) \('$WORK'(\\|/)?gopath(\\|/)src(\\|/)shadow(\\|/)root1(\\|/)src(\\|/)foo\)$' + +# The error for go install should mention the conflicting directory. +! go install -n ./shadow/root2/src/foo +stderr 'go install: no install location for '$WORK'(\\|/)?gopath(\\|/)src(\\|/)shadow(\\|/)root2(\\|/)src(\\|/)foo: hidden by '$WORK'(\\|/)?gopath(\\|/)src(\\|/)shadow(\\|/)root1(\\|/)src(\\|/)foo' + +-- shadow/root1/src/foo/foo.go -- +package foo +-- shadow/root1/src/math/math.go -- +package math +-- shadow/root2/src/foo/foo.go -- +package foo
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/list_split_main.txt b/src/cmd/go/testdata/script/list_split_main.txt new file mode 100644 index 0000000..74e7d5d --- /dev/null +++ b/src/cmd/go/testdata/script/list_split_main.txt @@ -0,0 +1,25 @@ +# This test checks that a "main" package with an external test package +# is recompiled only once. +# Verifies golang.org/issue/34321. + +env GO111MODULE=off + +go list -e -test -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' pkg +cmp stdout want + +-- $GOPATH/src/pkg/pkg.go -- +package main + +func main() {} + +-- $GOPATH/src/pkg/pkg_test.go -- +package main + +import "testing" + +func Test(t *testing.T) {} + +-- want -- +pkg +pkg [pkg.test] +pkg.test diff --git a/src/cmd/go/testdata/script/list_std.txt b/src/cmd/go/testdata/script/list_std.txt new file mode 100644 index 0000000..6ab1bd1 --- /dev/null +++ b/src/cmd/go/testdata/script/list_std.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +[!gc] skip +[short] skip + +# Listing GOROOT should only find standard packages. +cd $GOROOT/src +go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' ./... +! stdout . + +# Standard packages should include cmd, but not cmd/vendor. +go list ./... +stdout cmd/compile +! stdout vendor/golang.org +! stdout cmd/vendor + +# In GOPATH mode, packages vendored into GOROOT should be reported as standard. +go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' std cmd +stdout golang.org/x/net/http2/hpack +stdout cmd/vendor/golang\.org/x/arch/x86/x86asm + +# However, vendored packages should not match wildcard patterns beginning with cmd. +go list cmd/... +stdout cmd/compile +! stdout cmd/vendor diff --git a/src/cmd/go/testdata/script/list_symlink.txt b/src/cmd/go/testdata/script/list_symlink.txt new file mode 100644 index 0000000..f74ca86 --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink.txt @@ -0,0 +1,12 @@ +[!symlink] skip +env GO111MODULE=off + +mkdir $WORK/tmp/src +symlink $WORK/tmp/src/dir1 -> $WORK/tmp +cp p.go $WORK/tmp/src/dir1/p.go +env GOPATH=$WORK/tmp +go list -f '{{.Root}}' dir1 +stdout '^'$WORK/tmp'$' + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/script/list_symlink_internal.txt b/src/cmd/go/testdata/script/list_symlink_internal.txt new file mode 100644 index 0000000..f756a56 --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink_internal.txt @@ -0,0 +1,27 @@ +[!symlink] skip +env GO111MODULE=off + +mkdir $WORK/tmp/gopath/src/dir1/internal/v +cp p.go $WORK/tmp/gopath/src/dir1/p.go +cp v.go $WORK/tmp/gopath/src/dir1/internal/v/v.go +symlink $WORK/tmp/symdir1 -> $WORK/tmp/gopath/src/dir1 +env GOPATH=$WORK/tmp/gopath +cd $WORK/tmp/symdir1 +go list -f '{{.Root}}' . +stdout '^'$WORK/tmp/gopath'$' + +# All of these should succeed, not die in internal-handling code. +go run p.go & +go build & +go install & + +wait + +-- p.go -- +package main + +import _ `dir1/internal/v` + +func main() {} +-- v.go -- +package v diff --git a/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt b/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt new file mode 100644 index 0000000..8e63a5a --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt @@ -0,0 +1,28 @@ +[!symlink] skip +env GO111MODULE=off + +mkdir $WORK/tmp/gopath/src/dir1/vendor/v +cp p.go $WORK/tmp/gopath/src/dir1/p.go +cp v.go $WORK/tmp/gopath/src/dir1/vendor/v/v.go +symlink $WORK/tmp/symdir1 -> $WORK/tmp/gopath/src/dir1 +env GOPATH=$WORK/tmp/gopath +cd $WORK/tmp/symdir1 + +go list -f '{{.Root}}' . +stdout '^'$WORK/tmp/gopath'$' + +# All of these should succeed, not die in vendor-handling code. +go run p.go & +go build & +go install & + +wait + +-- p.go -- +package main + +import _ `v` + +func main () {} +-- v.go -- +package v diff --git a/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt b/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt new file mode 100644 index 0000000..19f2138 --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt @@ -0,0 +1,21 @@ +[!symlink] skip +env GO111MODULE=off + +mkdir $WORK/tmp/gopath/src/x/y/_vendor/src/x +symlink $WORK/tmp/gopath/src/x/y/_vendor/src/x/y -> ../../.. +mkdir $WORK/tmp/gopath/src/x/y/_vendor/src/x/y/w +cp w.go $WORK/tmp/gopath/src/x/y/w/w.go +symlink $WORK/tmp/gopath/src/x/y/w/vendor -> ../_vendor/src +mkdir $WORK/tmp/gopath/src/x/y/_vendor/src/x/y/z +cp z.go $WORK/tmp/gopath/src/x/y/z/z.go + +env GOPATH=$WORK/tmp/gopath/src/x/y/_vendor${:}$WORK/tmp/gopath +cd $WORK/tmp/gopath/src +go list ./... + +-- w.go -- +package w + +import "x/y/z" +-- z.go -- +package z diff --git a/src/cmd/go/testdata/script/list_test_e.txt b/src/cmd/go/testdata/script/list_test_e.txt new file mode 100644 index 0000000..263892b --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_e.txt @@ -0,0 +1,11 @@ +env GO111MODULE=off + +# issue 25980: crash in go list -e -test +go list -e -test -deps -f '{{.Error}}' p +stdout '^p[/\\]d_test.go:2:8: cannot find package "d" in any of:' + +-- p/d.go -- +package d +-- p/d_test.go -- +package d_test +import _ "d" diff --git a/src/cmd/go/testdata/script/list_test_err.txt b/src/cmd/go/testdata/script/list_test_err.txt new file mode 100644 index 0000000..c6f1ecf --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_err.txt @@ -0,0 +1,129 @@ +env GO111MODULE=off + +# issue 28491: errors in test source files should not prevent +# "go list -test" from returning useful information. + +# go list prints information for package, internal test, +# external test, but not testmain package when there is a +# syntax error in test sources. +! go list -test -deps syntaxerr +stdout pkgdep +stdout testdep_a +stdout testdep_b +stdout ^syntaxerr$ +stdout '^syntaxerr \[syntaxerr.test\]' +stdout '^syntaxerr_test \[syntaxerr.test\]' +! stdout '^syntaxerr\.test' +stderr 'expected declaration' + +# go list -e prints information for all test packages. +# The syntax error is shown in the package error field. +go list -e -test -deps -f '{{.ImportPath}} {{.Error | printf "%q"}}' syntaxerr +stdout 'pkgdep <nil>' +stdout 'testdep_a <nil>' +stdout 'testdep_b <nil>' +stdout 'syntaxerr <nil>' +stdout 'syntaxerr \[syntaxerr.test\] <nil>' +stdout 'syntaxerr_test \[syntaxerr.test\] <nil>' +stdout 'syntaxerr\.test "[^"]*expected declaration' +! stderr 'expected declaration' + +[short] stop + +# go list prints partial information with test naming error +! go list -test -deps nameerr +stdout pkgdep +stdout testdep_a +stdout testdep_b +stderr 'wrong signature for TestBad' + +go list -e -test -deps -f '{{.ImportPath}} {{.Error | printf "%q"}}' nameerr +stdout 'pkgdep <nil>' +stdout 'testdep_a <nil>' +stdout 'testdep_b <nil>' +stdout 'nameerr\.test "[^"]*wrong signature for TestBad' +! stderr 'wrong signature for TestBad' + +# go list prints partial information with error if test has cyclic import +! go list -test -deps cycleerr +stdout cycleerr +stderr 'import cycle not allowed in test' + +go list -e -test -deps -f '{{.ImportPath}} {{.Error | printf "%q"}}' cycleerr +stdout 'cycleerr <nil>' +stdout 'testdep_a <nil>' +stdout 'testdep_cycle <nil>' +stdout 'cycleerr \[cycleerr.test\] "[^"]*import cycle not allowed in test' +! stderr 'import cycle not allowed in test' + +-- syntaxerr/syntaxerr.go -- +package syntaxerr + +import _ "pkgdep" + +-- syntaxerr/syntaxerr_ie_test.go -- +package syntaxerr + +!!!syntax error + +-- syntaxerr/syntaxerr_xe_test.go -- +package syntaxerr_test + +!!!syntax error + +-- syntaxerr/syntaxerr_i_test.go -- +package syntaxerr + +import _ "testdep_a" + +-- syntaxerr/syntaxerr_x_test.go -- +package syntaxerr + +import _ "testdep_b" + +-- nameerr/nameerr.go -- +package nameerr + +import _ "pkgdep" + +-- nameerr/nameerr_i_test.go -- +package nameerr + +import ( + _ "testdep_a" + "testing" +) + +func TestBad(t *testing.B) {} + +-- nameerr/nameerr_x_test.go -- +package nameerr_test + +import ( + _ "testdep_b" + "testing" +) + +func TestBad(t *testing.B) {} + +-- cycleerr/cycleerr_test.go -- +package cycleerr + +import ( + _ "testdep_a" + _ "testdep_cycle" +) + +-- pkgdep/pkgdep.go -- +package pkgdep + +-- testdep_a/testdep_a.go -- +package testdep_a + +-- testdep_b/testdep_b.go -- +package testdep_b + +-- testdep_cycle/testdep_cycle.go -- +package testdep_cycle + +import _ "cycleerr" diff --git a/src/cmd/go/testdata/script/list_test_imports.txt b/src/cmd/go/testdata/script/list_test_imports.txt new file mode 100644 index 0000000..0342eba --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_imports.txt @@ -0,0 +1,21 @@ +env GO111MODULE=off + +# issue 26880: list with tests has wrong variant in imports +go list -test -f '{{.ImportPath}}:{{with .Imports}} {{join . ", "}}{{end}}' a b +cmp stdout imports.txt + +-- a/a.go -- +package a; import _ "b" +-- b/b.go -- +package b +-- b/b_test.go -- +package b +-- b/b_x_test.go -- +package b_test; import _ "a" + +-- imports.txt -- +a: b +b: +b.test: b [b.test], b_test [b.test], os, reflect, testing, testing/internal/testdeps +b [b.test]: +b_test [b.test]: a [b.test] diff --git a/src/cmd/go/testdata/script/list_test_non_go_files.txt b/src/cmd/go/testdata/script/list_test_non_go_files.txt new file mode 100644 index 0000000..6b2b633 --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_non_go_files.txt @@ -0,0 +1,13 @@ +env GO111MODULE=off + +# issue 29899: handling files with non-Go extension +go list -e -test -json -- c.c x.go +stdout '"Err": "named files must be .go files: c.c"' + +! go list -test -json -- c.c x.go +stderr '^named files must be \.go files: c\.c$' + +-- x.go -- +package main +-- c.c -- +package c diff --git a/src/cmd/go/testdata/script/list_test_simple.txt b/src/cmd/go/testdata/script/list_test_simple.txt new file mode 100644 index 0000000..954897c --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_simple.txt @@ -0,0 +1,67 @@ +[short] skip + +# Test +go test -list=Test +stdout TestSimple + +# Benchmark +go test -list=Benchmark +stdout BenchmarkSimple + +# Examples +go test -list=Example +stdout ExampleSimple +stdout ExampleWithEmptyOutput + +-- go.mod -- +module m + +go 1.16 +-- bench_test.go -- +package testlist + +import ( + "fmt" + "testing" +) + +func BenchmarkSimplefunc(b *testing.B) { + b.StopTimer() + b.StartTimer() + for i := 0; i < b.N; i++ { + _ = fmt.Sprint("Test for bench") + } +} +-- example_test.go -- +package testlist + +import ( + "fmt" +) + +func ExampleSimple() { + fmt.Println("Test with Output.") + + // Output: Test with Output. +} + +func ExampleWithEmptyOutput() { + fmt.Println("") + + // Output: +} + +func ExampleNoOutput() { + _ = fmt.Sprint("Test with no output") +} +-- test_test.go -- +package testlist + +import ( + "fmt" + "testing" +) + +func TestSimple(t *testing.T) { + _ = fmt.Sprint("Test simple") +} diff --git a/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt b/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt new file mode 100644 index 0000000..02b1088 --- /dev/null +++ b/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt @@ -0,0 +1,17 @@ +# Test that wildcards don't look in useless directories. + +# First make sure that badpkg fails the list of '...'. +! go list ./... +stderr badpkg + +# Check that the list of './goodpkg...' succeeds. That implies badpkg was skipped. +go list ./goodpkg... + +-- go.mod -- +module m + +go 1.16 +-- goodpkg/x.go -- +package goodpkg +-- badpkg/x.go -- +pkg badpkg diff --git a/src/cmd/go/testdata/script/load_test_pkg_err.txt b/src/cmd/go/testdata/script/load_test_pkg_err.txt new file mode 100644 index 0000000..d088ee4 --- /dev/null +++ b/src/cmd/go/testdata/script/load_test_pkg_err.txt @@ -0,0 +1,30 @@ +# Tests issue 37971. Check that tests are still loaded even when the package has an error. + +go list -e -test d +cmp stdout want_stdout + +go list -e -test -deps d +stdout golang.org/fake/d + +-- want_stdout -- +d +d.test +d_test [d.test] +-- go.mod -- +module d + +go 1.16 +-- d.go -- +package d + +import "net/http" + +const d = http.MethodGet +func Get() string { return d; } +-- d2.go -- +-- d_test.go -- +package d_test + +import "testing" +import "golang.org/fake/d" +func TestD(t *testing.T) { d.Get(); } diff --git a/src/cmd/go/testdata/script/mod_all.txt b/src/cmd/go/testdata/script/mod_all.txt new file mode 100644 index 0000000..aac6629 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_all.txt @@ -0,0 +1,444 @@ +# This test illustrates the relationship between the 'all' pattern and +# the dependencies of the main module. + +# The package import graph used in this test looks like: +# +# main --------- a --------- b +# | | +# | a_test ---- c +# | | +# | c_test ---- d +# | +# main_test ---- t --------- u +# | +# t_test ---- w +# | +# w_test ---- x +# +# main/testonly_test ---- q --------- r +# | +# q_test ---- s +# +# And the module dependency graph looks like: +# +# main --- a.1 ---- b.1 +# \ \ \ +# \ \ c.1 -- d.1 +# \ \ +# \ t.1 ---- u.1 +# \ \ +# \ w.1 -- x.1 +# \ +# q.1 ---- r.1 +# \ +# s.1 + +env PKGFMT='{{if .Module}}{{.ImportPath}}{{end}}' +env MODFMT='{{.Path}}' + + +# 'go list -deps' lists packages and tests in the main module, +# along with their transitive dependencies. + +go list -f $PKGFMT -deps ./... +stdout -count=4 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly' + + +# 'go list -deps -test' lists transitive imports of tests and non-tests in the +# main module. + +go list -f $PKGFMT -deps -test ./... +stdout -count=13 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' + + +# 'go list all' lists the fixpoint of iterating 'go list -deps -test' starting +# with the packages in the main module, then reducing to only the non-test +# variants of those packages. + +go list -f $PKGFMT all +stdout -count=13 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/d$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/x$' + + +# 'go list -test all' is equivalent to 'go list -test $(go list all)' +# and both should include tests for every package in 'all'. + +go list -test -f $PKGFMT example.com/a example.com/b example.com/c example.com/d example.com/main example.com/main/testonly example.com/q example.com/r example.com/s example.com/t example.com/u example.com/w example.com/x +cp stdout list-test-explicit.txt + +go list -test -f $PKGFMT all +cmp stdout list-test-explicit.txt +stdout -count=36 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/d$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/x$' +stdout '^example.com/a.test$' +stdout '^example.com/a_test \[example.com/a.test\]$' +stdout '^example.com/b.test$' +stdout '^example.com/b_test \[example.com/b.test\]$' +stdout '^example.com/c.test$' +stdout '^example.com/c_test \[example.com/c.test\]$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q.test$' +stdout '^example.com/q_test \[example.com/q.test\]$' +stdout '^example.com/r.test$' +stdout '^example.com/r_test \[example.com/r.test\]$' +stdout '^example.com/s.test$' +stdout '^example.com/s_test \[example.com/s.test\]$' +stdout '^example.com/t.test$' +stdout '^example.com/t_test \[example.com/t.test\]$' +stdout '^example.com/u.test$' +stdout '^example.com/u_test \[example.com/u.test\]$' +stdout '^example.com/w.test$' +stdout '^example.com/w_test \[example.com/w.test\]$' + + +# 'go list -m all' covers the packages in 'go list -test -deps all'. + +go list -m -f $MODFMT all +stdout -count=12 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/d$' +stdout '^example.com/main$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/x$' + + +# 'go mod vendor' copies in only the packages transitively imported by the main +# module, and omits their tests. As a result, the 'all' and '...' patterns +# report fewer packages when using '-mod=vendor'. + +go mod vendor + +go list -f $PKGFMT -mod=vendor all +stdout -count=8 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' + +go list -test -f $PKGFMT -mod=vendor all +stdout -count=13 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' + +rm vendor + +# Convert all modules to go 1.16 to enable lazy loading. +go mod edit -go=1.16 a/go.mod +go mod edit -go=1.16 b/go.mod +go mod edit -go=1.16 c/go.mod +go mod edit -go=1.16 d/go.mod +go mod edit -go=1.16 q/go.mod +go mod edit -go=1.16 r/go.mod +go mod edit -go=1.16 s/go.mod +go mod edit -go=1.16 t/go.mod +go mod edit -go=1.16 u/go.mod +go mod edit -go=1.16 w/go.mod +go mod edit -go=1.16 x/go.mod +go mod edit -go=1.16 + +# With lazy loading, 'go list all' with neither -mod=vendor nor -test should +# match -mod=vendor without -test in 1.15. + +go list -f $PKGFMT all +stdout -count=8 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' + +# 'go list -test all' should expand that to include the test variants of the +# packages in 'all', but not the dependencies of outside tests. + +go list -test -f $PKGFMT all +stdout -count=25 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/a.test$' +stdout '^example.com/a_test \[example.com/a.test\]$' +stdout '^example.com/b.test$' +stdout '^example.com/b_test \[example.com/b.test\]$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q.test$' +stdout '^example.com/q_test \[example.com/q.test\]$' +stdout '^example.com/r.test$' +stdout '^example.com/r_test \[example.com/r.test\]$' +stdout '^example.com/t.test$' +stdout '^example.com/t_test \[example.com/t.test\]$' +stdout '^example.com/u.test$' +stdout '^example.com/u_test \[example.com/u.test\]$' + +# 'go list -test -deps all' should include the dependencies of those tests, +# but not the tests of the dependencies of outside tests. + +go list -test -deps -f $PKGFMT all +stdout -count=28 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/a.test$' +stdout '^example.com/a_test \[example.com/a.test\]$' +stdout '^example.com/b.test$' +stdout '^example.com/b_test \[example.com/b.test\]$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q.test$' +stdout '^example.com/q_test \[example.com/q.test\]$' +stdout '^example.com/r.test$' +stdout '^example.com/r_test \[example.com/r.test\]$' +stdout '^example.com/t.test$' +stdout '^example.com/t_test \[example.com/t.test\]$' +stdout '^example.com/u.test$' +stdout '^example.com/u_test \[example.com/u.test\]$' + + +# TODO(#36460): +# 'go list -m all' should exactly cover the packages in 'go list -test all'. + +-- go.mod -- +module example.com/main + +go 1.15 + +require ( + example.com/a v0.1.0 + example.com/b v0.1.0 + example.com/q v0.1.0 + example.com/t v0.1.0 +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b + example.com/c v0.1.0 => ./c + example.com/d v0.1.0 => ./d + example.com/q v0.1.0 => ./q + example.com/r v0.1.0 => ./r + example.com/s v0.1.0 => ./s + example.com/t v0.1.0 => ./t + example.com/u v0.1.0 => ./u + example.com/w v0.1.0 => ./w + example.com/x v0.1.0 => ./x +) +-- main.go -- +package main + +import _ "example.com/a" + +func main() {} +-- main_test.go -- +package main_test + +import _ "example.com/t" +-- testonly/testonly_test.go -- +package testonly_test + +import _ "example.com/q" +-- a/go.mod -- +module example.com/a + +go 1.15 + +require ( + example.com/b v0.1.0 + example.com/c v0.1.0 +) +-- a/a.go -- +package a + +import _ "example.com/b" +-- a/a_test.go -- +package a_test + +import _ "example.com/c" +-- b/go.mod -- +module example.com/b + +go 1.15 +-- b/b.go -- +package b +-- b/b_test.go -- +package b_test +-- c/go.mod -- +module example.com/c + +go 1.15 + +require example.com/d v0.1.0 +-- c/c.go -- +package c +-- c/c_test.go -- +package c_test + +import _ "example.com/d" +-- d/go.mod -- +module example.com/d + +go 1.15 +-- d/d.go -- +package d +-- q/go.mod -- +module example.com/q + +go 1.15 + +require ( + example.com/r v0.1.0 + example.com/s v0.1.0 +) +-- q/q.go -- +package q +import _ "example.com/r" +-- q/q_test.go -- +package q_test +import _ "example.com/s" +-- r/go.mod -- +module example.com/r + +go 1.15 +-- r/r.go -- +package r +-- r/r_test.go -- +package r_test +-- s/go.mod -- +module example.com/s + +go 1.15 +-- s/s.go -- +package s +-- s/s_test.go -- +package s_test +-- t/go.mod -- +module example.com/t + +go 1.15 + +require ( + example.com/u v0.1.0 + example.com/w v0.1.0 +) +-- t/t.go -- +package t + +import _ "example.com/u" +-- t/t_test.go -- +package t_test + +import _ "example.com/w" +-- u/go.mod -- +module example.com/u + +go 1.15 +-- u/u.go -- +package u +-- u/u_test.go -- +package u_test +-- w/go.mod -- +module example.com/w + +go 1.15 + +require example.com/x v0.1.0 +-- w/w.go -- +package w +-- w/w_test.go -- +package w_test + +import _ "example.com/x" +-- x/go.mod -- +module example.com/x + +go 1.15 +-- x/x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_alt_goroot.txt b/src/cmd/go/testdata/script/mod_alt_goroot.txt new file mode 100644 index 0000000..32f94c5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_alt_goroot.txt @@ -0,0 +1,20 @@ +env GO111MODULE=on + +# If the working directory is a different GOROOT, then the 'std' module should be +# treated as an ordinary module (with an ordinary module prefix). +# It should not override packages in GOROOT, but should not fail the command. +# See golang.org/issue/30756. +go list -e -deps -f '{{.ImportPath}} {{.Dir}}' ./bytes +stdout ^std/bytes.*$PWD[/\\]bytes +stdout '^bytes/modified' + +-- go.mod -- +module std + +go 1.12 +-- bytes/bytes.go -- +package bytes + +import _"bytes/modified" +-- bytes/modified/modified.go -- +package modified diff --git a/src/cmd/go/testdata/script/mod_ambiguous_import.txt b/src/cmd/go/testdata/script/mod_ambiguous_import.txt new file mode 100644 index 0000000..feaf5d2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_ambiguous_import.txt @@ -0,0 +1,48 @@ +env GO111MODULE=on + +cd $WORK + +# An import provided by two different modules should be flagged as an error. +! go build ./importx +stderr '^importx[/\\]importx.go:2:8: ambiguous import: found package example.com/a/x in multiple modules:\n\texample.com/a v0.1.0 \('$WORK'[/\\]a[/\\]x\)\n\texample.com/a/x v0.1.0 \('$WORK'[/\\]ax\)$' + +# However, it should not be an error if that import is unused. +go build ./importy + +# An import provided by both the main module and the vendor directory +# should be flagged as an error only when -mod=vendor is set. +mkdir vendor/example.com/m/importy +cp $WORK/importy/importy.go vendor/example.com/m/importy/importy.go +go build example.com/m/importy +! go build -mod=vendor example.com/m/importy +stderr '^ambiguous import: found package example.com/m/importy in multiple directories:\n\t'$WORK'[/\\]importy\n\t'$WORK'[/\\]vendor[/\\]example.com[/\\]m[/\\]importy$' + +-- $WORK/go.mod -- +module example.com/m +go 1.13 +require ( + example.com/a v0.1.0 + example.com/a/x v0.1.0 +) +replace ( + example.com/a v0.1.0 => ./a + example.com/a/x v0.1.0 => ./ax +) +-- $WORK/importx/importx.go -- +package importx +import _ "example.com/a/x" +-- $WORK/importy/importy.go -- +package importy +import _ "example.com/a/y" +-- $WORK/a/go.mod -- +module example.com/a +go 1.14 +-- $WORK/a/x/x.go -- +package x +-- $WORK/a/y/y.go -- +package y +-- $WORK/ax/go.mod -- +module example.com/a/x +go 1.14 +-- $WORK/ax/x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_auth.txt b/src/cmd/go/testdata/script/mod_auth.txt new file mode 100644 index 0000000..d8ea586 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_auth.txt @@ -0,0 +1,35 @@ +[!net] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off +env GOVCS='*:off' + +# Without credentials, downloading a module from a path that requires HTTPS +# basic auth should fail. +env NETRC=$WORK/empty +! go mod tidy +stderr '^\tserver response: ACCESS DENIED, buddy$' +stderr '^\tserver response: File\? What file\?$' + +# With credentials from a netrc file, it should succeed. +env NETRC=$WORK/netrc +go mod tidy +go list all +stdout vcs-test.golang.org/auth/or401 +stdout vcs-test.golang.org/auth/or404 + +-- go.mod -- +module private.example.com +-- main.go -- +package useprivate + +import ( + _ "vcs-test.golang.org/auth/or401" + _ "vcs-test.golang.org/auth/or404" +) +-- $WORK/empty -- +-- $WORK/netrc -- +machine vcs-test.golang.org + login aladdin + password opensesame diff --git a/src/cmd/go/testdata/script/mod_bad_domain.txt b/src/cmd/go/testdata/script/mod_bad_domain.txt new file mode 100644 index 0000000..7a270d0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_bad_domain.txt @@ -0,0 +1,47 @@ +env GO111MODULE=on + +# explicit get should report errors about bad names +! go get appengine +stderr '^go get: malformed module path "appengine": missing dot in first path element$' +! go get x/y.z +stderr 'malformed module path "x/y.z": missing dot in first path element' + + +# 'go list -m' should report errors about module names, never GOROOT. +! go list -m -versions appengine +stderr 'malformed module path "appengine": missing dot in first path element' +! go list -m -versions x/y.z +stderr 'malformed module path "x/y.z": missing dot in first path element' + + +# build should report all unsatisfied imports, +# but should be more definitive about non-module import paths +! go build ./useappengine +stderr '^useappengine[/\\]x.go:2:8: cannot find package$' +! go build ./usenonexistent +stderr '^usenonexistent[/\\]x.go:2:8: no required module provides package nonexistent.rsc.io; to add it:\n\tgo get nonexistent.rsc.io$' + + +# 'get -d' should be similarly definitive + +go get -d ./useappengine # TODO(#41315): This should fail. + # stderr '^useappengine[/\\]x.go:2:8: cannot find package$' + +! go get -d ./usenonexistent +stderr '^x/usenonexistent imports\n\tnonexistent.rsc.io: cannot find module providing package nonexistent.rsc.io$' + + +# go mod vendor and go mod tidy should ignore appengine imports. +rm usenonexistent/x.go +go mod tidy +go mod vendor + +-- go.mod -- +module x + +-- useappengine/x.go -- +package useappengine +import _ "appengine" // package does not exist +-- usenonexistent/x.go -- +package usenonexistent +import _ "nonexistent.rsc.io" // domain does not exist diff --git a/src/cmd/go/testdata/script/mod_bad_filenames.txt b/src/cmd/go/testdata/script/mod_bad_filenames.txt new file mode 100644 index 0000000..eb556f4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_bad_filenames.txt @@ -0,0 +1,11 @@ +env GO111MODULE=on + +! go get rsc.io/badfile1 rsc.io/badfile2 rsc.io/badfile3 rsc.io/badfile4 rsc.io/badfile5 +! stderr 'unzip.*badfile1' +stderr 'unzip.*badfile2[\\/]@v[\\/]v1.0.0.zip:.*malformed file path "☺.go": invalid char ''☺''' +stderr 'unzip.*badfile3[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile3@v1.0.0[\\/]x\?y.go: malformed file path "x\?y.go": invalid char ''\?''' +stderr 'unzip.*badfile4[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile4@v1.0.0[\\/]x[\\/]y.go: case-insensitive file name collision: "x/Y.go" and "x/y.go"' +stderr 'unzip.*badfile5[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile5@v1.0.0[\\/]x[\\/]Y[\\/]zz[\\/]ww.go: case-insensitive file name collision: "x/y" and "x/Y"' + +-- go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_build_info_err.txt b/src/cmd/go/testdata/script/mod_build_info_err.txt new file mode 100644 index 0000000..cee055e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_build_info_err.txt @@ -0,0 +1,33 @@ +# This test verifies that line numbers are included in module import errors. +# Verifies golang.org/issue/34393. + +go list -e -mod=mod -deps -f '{{with .Error}}{{.Pos}}: {{.Err}}{{end}}' ./main +stdout '^bad[/\\]bad.go:3:8: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + +# TODO(#26909): This should include an import stack. +# (Today it includes only a file and line.) +! go build ./main +stderr '^bad[/\\]bad.go:3:8: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + +# TODO(#41688): This should include a file and line, and report the reason for the error.. +# (Today it includes only an import stack.) +! go get -d ./main +stderr '^m/main imports\n\tm/bad imports\n\t🐧.example.com/string: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + + +-- go.mod -- +module m + +go 1.13 + +-- main/main.go -- +package main + +import _ "m/bad" + +func main() {} + +-- bad/bad.go -- +package bad + +import _ "🐧.example.com/string" diff --git a/src/cmd/go/testdata/script/mod_build_tags.txt b/src/cmd/go/testdata/script/mod_build_tags.txt new file mode 100644 index 0000000..ae1d605 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_build_tags.txt @@ -0,0 +1,33 @@ +# Test that build tags are used. +# golang.org/issue/24053. + +env GO111MODULE=on + +cd x +! go list -f {{.GoFiles}} +stderr 'build constraints exclude all Go files' + +go list -f {{.GoFiles}} -tags tag1 +stdout '\[x.go\]' + +go list -f {{.GoFiles}} -tags tag2 +stdout '\[y\.go\]' + +go list -f {{.GoFiles}} -tags 'tag1 tag2' +stdout '\[x\.go y\.go\]' + +go list -f {{.GoFiles}} -tags tag1,tag2 # commas allowed as of Go 1.13 +stdout '\[x\.go y\.go\]' + +-- x/go.mod -- +module x + +-- x/x.go -- +// +build tag1 + +package y + +-- x/y.go -- +// +build tag2 + +package y diff --git a/src/cmd/go/testdata/script/mod_build_versioned.txt b/src/cmd/go/testdata/script/mod_build_versioned.txt new file mode 100644 index 0000000..d1d74de --- /dev/null +++ b/src/cmd/go/testdata/script/mod_build_versioned.txt @@ -0,0 +1,17 @@ +env GO111MODULE=on +[short] skip + +go get -d rsc.io/fortune/v2 + +# The default executable name shouldn't be v2$GOEXE +go build rsc.io/fortune/v2 +! exists v2$GOEXE +exists fortune$GOEXE + +# The default test binary name shouldn't be v2.test$GOEXE +go test -c rsc.io/fortune/v2 +! exists v2.test$GOEXE +exists fortune.test$GOEXE + +-- go.mod -- +module scratch diff --git a/src/cmd/go/testdata/script/mod_cache_rw.txt b/src/cmd/go/testdata/script/mod_cache_rw.txt new file mode 100644 index 0000000..a541076 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_cache_rw.txt @@ -0,0 +1,49 @@ +# Regression test for golang.org/issue/31481. + +env GO111MODULE=on + +# golang.org/issue/31481: an explicit flag should make directories in the module +# cache writable in order to work around the historical inability of 'rm -rf' to +# forcibly remove files in unwritable directories. +go get -modcacherw -d rsc.io/quote@v1.5.2 +cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go + +# After adding an extraneous file, 'go mod verify' should fail. +! go mod verify + +# However, files within those directories should still be read-only to avoid +# accidental mutations. +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + +# If all 'go' commands ran with the flag, the system's 'rm' binary +# should be able to remove the module cache if the '-rf' flags are set. +[!windows] [exec:rm] exec rm -rf $GOPATH/pkg/mod +[!windows] [!exec:rm] go clean -modcache +[windows] [exec:cmd.exe] exec cmd.exe /c rmdir /s /q $GOPATH\pkg\mod +[windows] [!exec:cmd.exe] go clean -modcache +! exists $GOPATH/pkg/mod + +# The directories in the module cache should by default be unwritable, +# so that tests and tools will not accidentally add extraneous files to them. +# Windows does not respect FILE_ATTRIBUTE_READONLY on directories, according +# to MSDN, so there we disable testing whether the directory itself is +# unwritable. +go get -d rsc.io/quote@latest +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod +[!windows] [!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go +! exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go + + +# Repeat part of the test with 'go mod download' instead of 'go get' to verify +# -modcacherw is supported on 'go mod' subcommands. +go clean -modcache +go mod download -modcacherw rsc.io/quote +cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go +! go mod verify +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + + +-- $WORK/extraneous.txt -- +module oops +-- go.mod -- +module golang.org/issue/31481 diff --git a/src/cmd/go/testdata/script/mod_case.txt b/src/cmd/go/testdata/script/mod_case.txt new file mode 100644 index 0000000..4a46986 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_case.txt @@ -0,0 +1,25 @@ +env GO111MODULE=on + +go get -d +go list -m all +stdout '^rsc.io/quote v1.5.2' +stdout '^rsc.io/QUOTE v1.5.2' + +go list -f 'DIR {{.Dir}} DEPS {{.Deps}}' rsc.io/QUOTE/QUOTE +stdout 'DEPS.*rsc.io/quote' +stdout 'DIR.*!q!u!o!t!e' + +go get -d rsc.io/QUOTE@v1.5.3-PRE +go list -m all +stdout '^rsc.io/QUOTE v1.5.3-PRE' + +go list -f '{{.Dir}}' rsc.io/QUOTE/QUOTE +stdout '!q!u!o!t!e@v1.5.3-!p!r!e' + +-- go.mod -- +module x + +-- use.go -- +package use + +import _ "rsc.io/QUOTE/QUOTE" diff --git a/src/cmd/go/testdata/script/mod_case_cgo.txt b/src/cmd/go/testdata/script/mod_case_cgo.txt new file mode 100644 index 0000000..f3d6aaa --- /dev/null +++ b/src/cmd/go/testdata/script/mod_case_cgo.txt @@ -0,0 +1,11 @@ +[!cgo] skip + +env GO111MODULE=on + +go get -d rsc.io/CGO +[short] stop + +go build rsc.io/CGO + +-- go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_clean_cache.txt b/src/cmd/go/testdata/script/mod_clean_cache.txt new file mode 100644 index 0000000..01fbc38 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_clean_cache.txt @@ -0,0 +1,58 @@ +env GO111MODULE=on + +# 'mod download' should download the module to the cache. +go mod download rsc.io/quote@v1.5.0 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip + +# '-n' should print commands but not actually execute them. +go clean -modcache -n +stdout '^rm -rf .*pkg.mod$' +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip + +# 'go clean -modcache' should actually delete the files. +go clean -modcache +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip + +# 'go clean -r -modcache' should clean only the dependencies that are within the +# main module. +# BUG(golang.org/issue/28680): Today, it cleans across module boundaries. +cd r +exists ./test.out +exists ../replaced/test.out +go clean -r -modcache +! exists ./test.out +! exists ../replaced/test.out # BUG: should still exist + +# 'go clean -modcache' should not download anything before cleaning. +go mod edit -require rsc.io/quote@v1.99999999.0-not-a-real-version +go clean -modcache +! stderr 'finding rsc.io' +go mod edit -droprequire rsc.io/quote + +-- go.mod -- +module m +-- m.go -- +package m + +-- r/go.mod -- +module example.com/r +require example.com/r/replaced v0.0.0 +replace example.com/r/replaced => ../replaced +-- r/r.go -- +package r +import _ "example.com/r/replaced" +-- r/test.out -- +DELETE ME + +-- replaced/go.mod -- +module example.com/r/replaced +-- replaced/replaced.go -- +package replaced +-- replaced/test.out -- +DO NOT DELETE diff --git a/src/cmd/go/testdata/script/mod_concurrent.txt b/src/cmd/go/testdata/script/mod_concurrent.txt new file mode 100644 index 0000000..8c21525 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_concurrent.txt @@ -0,0 +1,32 @@ +env GO111MODULE=on + +# Concurrent builds should succeed, even if they need to download modules. +go get -d ./x ./y +go build ./x & +go build ./y +wait + +# Concurrent builds should update go.sum to the union of the hashes for the +# modules they read. +cmp go.sum go.sum.want + +-- go.mod -- +module golang.org/issue/26794 + +require ( + golang.org/x/text v0.3.0 + rsc.io/sampler v1.0.0 +) +-- x/x.go -- +package x + +import _ "golang.org/x/text/language" +-- y/y.go -- +package y + +import _ "rsc.io/sampler" +-- go.sum.want -- +golang.org/x/text v0.3.0 h1:ivTorhoiROmZ1mcs15mO2czVF0uy0tnezXpBVNzgrmA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/sampler v1.0.0 h1:SRJnjyQ07sAtq6G4RcfJEmz8JxqLyj3PoGXG2VhbDWo= +rsc.io/sampler v1.0.0/go.mod h1:cqxpM3ZVz9VtirqxZPmrWzkQ+UkiNiGtkrN+B+i8kx8= diff --git a/src/cmd/go/testdata/script/mod_convert_dep.txt b/src/cmd/go/testdata/script/mod_convert_dep.txt new file mode 100644 index 0000000..875a836 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_dep.txt @@ -0,0 +1,30 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found Gopkg.lock in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +# In Plan 9, directories are automatically created in /n. +# For example, /n/Gopkg.lock always exists, but it's a directory. +# Test that we ignore directories when trying to find alternate config files. +cd $WORK/gopkgdir/x +! go list . +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! stderr 'Gopkg.lock' + +-- $WORK/test/Gopkg.lock -- +-- $WORK/test/x/x.go -- +package x // import "m/x" +-- $WORK/gopkgdir/Gopkg.lock/README.txt -- +../Gopkg.lock is a directory, not a file. +-- $WORK/gopkgdir/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_git.txt b/src/cmd/go/testdata/script/mod_convert_git.txt new file mode 100644 index 0000000..6ff1eb5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_git.txt @@ -0,0 +1,40 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found .git/config in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +# We should not suggest creating a go.mod file in $GOROOT, even though there may be a .git/config there. +cd $GOROOT +! go list . +! stderr 'go mod init' + +# We should also not suggest creating a go.mod file in $GOROOT if its own +# .git/config has been stripped away and we find one in a parent directory. +# (https://golang.org/issue/34191) +env GOROOT=$WORK/parent/goroot +cd $GOROOT +! go list . +! stderr 'go mod init' + +cd $GOROOT/doc +! go list . +! stderr 'go mod init' + +-- $WORK/test/.git/config -- +-- $WORK/test/x/x.go -- +package x // import "m/x" +-- $WORK/parent/.git/config -- +-- $WORK/parent/goroot/README -- +This directory isn't really a GOROOT, but let's pretend that it is. +-- $WORK/parent/goroot/doc/README -- +This is a subdirectory of our fake GOROOT. diff --git a/src/cmd/go/testdata/script/mod_convert_glide.txt b/src/cmd/go/testdata/script/mod_convert_glide.txt new file mode 100644 index 0000000..9f1fff5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_glide.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found glide.lock in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/glide.lock -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_glockfile.txt b/src/cmd/go/testdata/script/mod_convert_glockfile.txt new file mode 100644 index 0000000..6aa0794 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_glockfile.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found GLOCKFILE in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/GLOCKFILE -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_godeps.txt b/src/cmd/go/testdata/script/mod_convert_godeps.txt new file mode 100644 index 0000000..da7b6c1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_godeps.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found Godeps/Godeps.json in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/Godeps/Godeps.json -- +{} +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_tsv.txt b/src/cmd/go/testdata/script/mod_convert_tsv.txt new file mode 100644 index 0000000..6015ac8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_tsv.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found dependencies.tsv in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/dependencies.tsv -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt b/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt new file mode 100644 index 0000000..ddb0c08 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt @@ -0,0 +1,27 @@ +env GO111MODULE=on + +[!net] skip +[!exec:git] skip + +# secure fetch should report insecure warning +cd $WORK/test +go mod init +stderr 'redirected .* to insecure URL' + +# insecure fetch should not +env GOINSECURE=*.golang.org +rm go.mod +go mod init +! stderr 'redirected .* to insecure URL' + +# insecure fetch invalid path should report insecure warning +env GOINSECURE=foo.golang.org +rm go.mod +go mod init +stderr 'redirected .* to insecure URL' + +-- $WORK/test/dependencies.tsv -- +vcs-test.golang.org/insecure/go/insecure git 6fecd21f7c0c 2019-09-04T18:39:48Z + +-- $WORK/test/x.go -- +package x // import "m" diff --git a/src/cmd/go/testdata/script/mod_convert_vendor_conf.txt b/src/cmd/go/testdata/script/mod_convert_vendor_conf.txt new file mode 100644 index 0000000..57ec419 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_vendor_conf.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found vendor.conf in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/vendor.conf -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_vendor_json.txt b/src/cmd/go/testdata/script/mod_convert_vendor_json.txt new file mode 100644 index 0000000..df6db36 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_vendor_json.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found vendor/vendor.json in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m +stdout '^m$' + +-- $WORK/test/vendor/vendor.json -- +{} +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_vendor_manifest.txt b/src/cmd/go/testdata/script/mod_convert_vendor_manifest.txt new file mode 100644 index 0000000..8b6a141 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_vendor_manifest.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found vendor/manifest in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m +stdout '^m$' + +-- $WORK/test/vendor/manifest -- +{} +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_vendor_yml.txt b/src/cmd/go/testdata/script/mod_convert_vendor_yml.txt new file mode 100644 index 0000000..4ed140a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_vendor_yml.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found vendor.yml in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/vendor.yml -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_dir.txt b/src/cmd/go/testdata/script/mod_dir.txt new file mode 100644 index 0000000..05548f6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_dir.txt @@ -0,0 +1,20 @@ +# The directory named go.mod should be ignored + +env GO111MODULE=on + +cd $WORK/sub + +go list . +stdout 'x/sub' + +mkdir go.mod +exists go.mod + +go list . +stdout 'x/sub' + +-- $WORK/go.mod -- +module x + +-- $WORK/sub/x.go -- +package x
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/mod_doc.txt b/src/cmd/go/testdata/script/mod_doc.txt new file mode 100644 index 0000000..595ad67 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_doc.txt @@ -0,0 +1,89 @@ +# go doc should find module documentation + +env GO111MODULE=on +env GOFLAGS=-mod=mod +[short] skip + +# Check when module x is inside GOPATH/src. +go doc y +stdout 'Package y is.*alphabet' +stdout 'import "x/y"' +go doc x/y +stdout 'Package y is.*alphabet' +! go doc quote.Hello +stderr 'doc: symbol quote is not a type' # because quote is not in local cache +go list rsc.io/quote # now it is +go doc quote.Hello +stdout 'Hello returns a greeting' +go doc quote +stdout 'Package quote collects pithy sayings.' + +# Double-check when module x is outside GOPATH/src. +env GOPATH=$WORK/emptygopath +go doc x/y +stdout 'Package y is.*alphabet' +go doc y +stdout 'Package y is.*alphabet' + +# Triple-check when module x is outside GOPATH/src, +# but other packages with same import paths are in GOPATH/src. +# Since go doc is running in module mode here, packages in active module +# should be preferred over packages in GOPATH. See golang.org/issue/28992. +env GOPATH=$WORK/gopath2 +go doc x/y +! stdout 'Package y is.*GOPATH' +stdout 'Package y is.*alphabet' +go doc rsc.io/quote +! stdout 'Package quote is located in a GOPATH workspace.' +stdout 'Package quote collects pithy sayings.' + +# Check that a sensible error message is printed when a package is not found. +env GOPROXY=off +! go doc example.com/hello +stderr '^doc: cannot find module providing package example.com/hello: module lookup disabled by GOPROXY=off$' + +# When in a module with a vendor directory, doc should use the vendored copies +# of the packages. 'std' and 'cmd' are convenient examples of such modules. +# +# When in those modules, the "// import" comment should refer to the same import +# path used in source code, not to the absolute path relative to GOROOT. + +cd $GOROOT/src +env GOFLAGS= +go doc cryptobyte +stdout '// import "golang.org/x/crypto/cryptobyte"' + +cd $GOROOT/src/cmd/go +go doc modfile +stdout '// import "golang.org/x/mod/modfile"' + +# When outside of the 'std' module, its vendored packages +# remain accessible using the 'vendor/' prefix, but report +# the correct "// import" comment as used within std. +cd $GOPATH +go doc vendor/golang.org/x/crypto/cryptobyte +stdout '// import "vendor/golang.org/x/crypto/cryptobyte"' + +go doc cmd/vendor/golang.org/x/mod/modfile +stdout '// import "cmd/vendor/golang.org/x/mod/modfile"' + +-- go.mod -- +module x +require rsc.io/quote v1.5.2 + +-- y/y.go -- +// Package y is the next to last package of the alphabet. +package y + +-- x.go -- +package x + +-- $WORK/gopath2/src/x/y/y.go -- +// Package y is located in a GOPATH workspace. +package y +-- $WORK/gopath2/src/rsc.io/quote/quote.go -- +// Package quote is located in a GOPATH workspace. +package quote + +// Hello is located in a GOPATH workspace. +func Hello() string { return "" } diff --git a/src/cmd/go/testdata/script/mod_domain_root.txt b/src/cmd/go/testdata/script/mod_domain_root.txt new file mode 100644 index 0000000..14745b5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_domain_root.txt @@ -0,0 +1,12 @@ +# Module paths that are domain roots should resolve. +# (example.com not example.com/something) + +env GO111MODULE=on +go get -d + +-- go.mod -- +module x + +-- x.go -- +package x +import _ "example.com" diff --git a/src/cmd/go/testdata/script/mod_dot.txt b/src/cmd/go/testdata/script/mod_dot.txt new file mode 100644 index 0000000..ca8d5c6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_dot.txt @@ -0,0 +1,131 @@ +env GO111MODULE=on + +# golang.org/issue/32917 and golang.org/issue/28459: 'go build' and 'go test' +# in an empty directory should refer to the path '.' and should not attempt +# to resolve an external module. +cd dir +! go get +stderr '^go get: no package in current directory$' +! go get . +stderr '^go get \.: no package in current directory$' +! go get ./subdir +stderr '^go get: \.[/\\]subdir \('$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir\) is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src[/\\]dir$' +! go list +! stderr 'cannot find module providing package' +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$' + +cd subdir +! go list +! stderr 'cannot find module providing package' +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$' +cd .. + +# golang.org/issue/30590: if a package is found in the filesystem +# but is not in the main module, the error message should not say +# "cannot find module providing package", and we shouldn't try +# to find a module providing the package. +! go list ./othermodule +! stderr 'cannot find module providing package' +stderr '^main module \(example\.com\) does not contain package example.com/othermodule$' + +# golang.org/issue/27122: 'go build' of a nonexistent directory should produce +# a helpful "no Go files" error message, not a generic "unknown import path". +! go list ./subdir +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$' + +# golang.org/issue/29280: 'go list -e' for a nonexistent directory should +# report a nonexistent package with an error. +go list -e -json ./subdir +stdout '"Incomplete": true' + +# golang.org/issue/28155: 'go list ./testdata' should not synthesize underscores. +go list ./testdata +stdout '^example.com/testdata' + +# golang.org/issue/32921: vendor directories should only be accepted as directories +# if the directory would actually be used to load the package. +! go list ./vendor/nonexist +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]nonexist$' + +! go list ./vendor/pkg +stderr '^without -mod=vendor, directory '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]pkg has no package path$' + +! go list -mod=vendor ./vendor/nonexist +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]nonexist$' + +! go list -mod=vendor ./vendor/unlisted +stderr '^directory '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]unlisted is not a package listed in vendor/modules.txt$' + +go list -mod=vendor ./vendor/pkg +stdout '^pkg$' + +# Packages within GOROOT should resolve as in any other module, +# except that -mod=vendor is implied by default. +cd $GOROOT/src +! go list . +stderr '^no Go files in '$GOROOT'[/\\]src$' + +! go list ./builtin +stderr '^"builtin" is a pseudo-package, not an importable package$' + +! go list ./debug +! stderr 'cannot find module providing package' +stderr '^no Go files in '$GOROOT'[/\\]src[/\\]debug$' + +! go list ./golang.org/x/tools/cmd/goimports +! stderr 'cannot find module providing package' +stderr '^stat '$GOROOT'[/\\]src[/\\]golang.org[/\\]x[/\\]tools[/\\]cmd[/\\]goimports: directory not found' + +go list ./vendor/golang.org/x/net/http2/hpack +stdout '^golang.org/x/net/http2/hpack$' + +# golang.org/issue/30756: packages in other GOROOTs should not get the special +# prefixless treatment of GOROOT itself. +cd $WORK/othergoroot/src +! go list . +stderr '^no Go files in '$WORK'[/\\]othergoroot[/\\]src$' + +go list ./builtin +stdout '^std/builtin$' # Only the "std" in actual $GOROOT is special, and only its "builtin" is special. + +! go list ./bytes +! stderr 'cannot find module providing package' +stderr '^no Go files in '$WORK'[/\\]othergoroot[/\\]src[/\\]bytes$' + +! go list ./vendor/golang.org/x/net/http2/hpack +stderr '^without -mod=vendor, directory '$WORK'[/\\]othergoroot[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack has no package path$' + +-- dir/go.mod -- +module example.com +go 1.13 +-- dir/subdir/README -- +There are no Go source files in this directory. +-- dir/othermodule/go.mod -- +module example.com/othermodule +go 1.13 +-- dir/othermodule/om.go -- +package othermodule +-- dir/testdata/td.go -- +package testdata +-- dir/vendor/modules.txt -- +# pkg v0.0.0 +pkg +-- dir/vendor/nonexist/README -- +There are no Go source files here either. +-- dir/vendor/pkg/pkg.go -- +package pkg +-- dir/vendor/unlisted/unlisted.go -- +package unlisted +-- emptyroot/go.mod -- +module example.com/emptyroot +-- emptyroot/pkg/pkg.go -- +package pkg +-- $WORK/othergoroot/src/go.mod -- +module std +go 1.13 +-- $WORK/othergoroot/src/builtin/builtin.go -- +package builtin +-- $WORK/othergoroot/src/bytes/README -- +There are no Go source files in this directory. +-- $WORK/othergoroot/src/vendor/golang.org/x/net/http2/hpack -- +package hpack diff --git a/src/cmd/go/testdata/script/mod_download.txt b/src/cmd/go/testdata/script/mod_download.txt new file mode 100644 index 0000000..c2b72b2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download.txt @@ -0,0 +1,170 @@ +env GO111MODULE=on + +# download with version should print nothing. +# It should not load retractions from the .mod file from the latest version. +go mod download rsc.io/quote@v1.5.0 +! stdout . +! stderr . +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod + +# download of an invalid path should report the error +[short] skip +! go mod download this.domain.is.invalid/somemodule@v1.0.0 +stderr 'this.domain.is.invalid' +! go mod download -json this.domain.is.invalid/somemodule@v1.0.0 +stdout '"Error": ".*this.domain.is.invalid.*"' + +# download -json with version should print JSON +go mod download -json 'rsc.io/quote@<=v1.5.0' +stdout '^\t"Path": "rsc.io/quote"' +stdout '^\t"Version": "v1.5.0"' +stdout '^\t"Info": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.0.info"' +stdout '^\t"GoMod": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.0.mod"' +stdout '^\t"Zip": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.0.zip"' +stdout '^\t"Sum": "h1:6fJa6E\+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE="' # hash of testdata/mod version, not real version! +stdout '^\t"GoModSum": "h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe\+TKr0="' +! stdout '"Error"' + +# download queries above should not have added to go.mod. +go list -m all +! stdout rsc.io + +# download query should have downloaded go.mod for the highest release version +# in order to find retractions when resolving the query '@<=v1.5.0'. +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# add to go.mod so we can test non-query downloads +go mod edit -require rsc.io/quote@v1.5.3-pre1 +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip + +# module loading will page in the info and mod files +go list -m -mod=mod all +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip + +# download will fetch and unpack the zip file +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 + +# download repopulates deleted files and directories independently. +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +rm -r $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 +go mod download +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 + +# download reports the locations of downloaded files +go mod download -json +stdout '^\t"Path": "rsc.io/quote"' +stdout '^\t"Version": "v1.5.3-pre1"' +stdout '^\t"Info": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.info"' +stdout '^\t"GoMod": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.mod"' +stdout '^\t"Zip": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.zip"' +stdout '^\t"Dir": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)rsc.io(\\\\|/)quote@v1.5.3-pre1"' + +# download will follow replacements +go mod edit -require rsc.io/quote@v1.5.1 -replace rsc.io/quote@v1.5.1=rsc.io/quote@v1.5.2 +go mod download +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# download will not follow replacements for explicit module queries +go mod download -json rsc.io/quote@v1.5.1 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip + +# download reports errors encountered when locating modules +! go mod download bad/path +stderr '^go mod download: module bad/path: not a known dependency$' +! go mod download bad/path@latest +stderr '^go mod download: bad/path@latest: malformed module path "bad/path": missing dot in first path element$' +! go mod download rsc.io/quote@v1.999.999 +stderr '^go mod download: rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$' +! go mod download -json bad/path +stdout '^\t"Error": "module bad/path: not a known dependency"' + +# download main module produces a warning or error +go mod download m +stderr '^go mod download: skipping argument m that resolves to the main module\n' +! go mod download m@latest +stderr '^go mod download: m@latest: malformed module path "m": missing dot in first path element$' + +# download without arguments updates go.mod and go.sum after loading the +# build list, but does not save sums for downloaded zips. +cd update +cp go.mod.orig go.mod +! exists go.sum +go mod download +cmp go.mod.update go.mod +cmp go.sum.update go.sum +cp go.mod.orig go.mod +rm go.sum + +# download with arguments (even "all") does update go.mod and go.sum. +go mod download rsc.io/sampler +cmp go.mod.update go.mod +grep '^rsc.io/sampler v1.3.0 ' go.sum +cp go.mod.orig go.mod +rm go.sum + +go mod download all +cmp go.mod.update go.mod +grep '^rsc.io/sampler v1.3.0 ' go.sum +cd .. + +# allow go mod download without go.mod +env GO111MODULE=auto +rm go.mod +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.2.1.zip +go mod download rsc.io/quote@v1.2.1 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.2.1.zip + +# download -x with version should print +# the underlying commands such as contacting GOPROXY. +go mod download -x rsc.io/quote@v1.0.0 +! stdout . +stderr 'get '$GOPROXY + +-- go.mod -- +module m + +-- update/go.mod.orig -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.2.1 // older version than in build list +) +-- update/go.mod.update -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // older version than in build list +) +-- update/go.sum.update -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_download_concurrent_read.txt b/src/cmd/go/testdata/script/mod_download_concurrent_read.txt new file mode 100644 index 0000000..231babd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_concurrent_read.txt @@ -0,0 +1,110 @@ +# This test simulates a process watching for changes and reading files in +# module cache as a module is extracted. +# +# Before Go 1.16, we extracted each module zip to a temporary directory with +# a random name, then renamed that into place with os.Rename. On Windows, +# this failed with ERROR_ACCESS_DENIED when another process (usually an +# anti-virus scanner) opened files in the temporary directory. This test +# simulates that behavior, verifying golang.org/issue/36568. +# +# Since 1.16, we extract to the final directory, but we create a .partial file +# so that if we crash, other processes know the directory is incomplete. + +[!windows] skip +[short] skip + +go run downloader.go + +-- go.mod -- +module example.com/m + +go 1.14 + +-- downloader.go -- +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" +) + +func main() { + if err := run(); err != nil { + log.Fatal(err) + } +} + +// run repeatedly downloads a module while opening files in the module cache +// in a background goroutine. +// +// run uses a different temporary module cache in each iteration so that we +// don't need to clean the cache or synchronize closing files after each +// iteration. +func run() (err error) { + tmpDir, err := os.MkdirTemp("", "") + if err != nil { + return err + } + defer func() { + if rmErr := os.RemoveAll(tmpDir); err == nil && rmErr != nil { + err = rmErr + } + }() + for i := 0; i < 10; i++ { + gopath := filepath.Join(tmpDir, fmt.Sprintf("gopath%d", i)) + var err error + done := make(chan struct{}) + go func() { + err = download(gopath) + close(done) + }() + readCache(gopath, done) + if err != nil { + return err + } + } + return nil +} + +// download downloads a module into the given cache using 'go mod download'. +func download(gopath string) error { + cmd := exec.Command("go", "mod", "download", "-modcacherw", "rsc.io/quote@v1.5.2") + cmd.Stderr = os.Stderr + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + return cmd.Run() +} + +// readCache repeatedly globs for go.mod files in the given cache, then opens +// those files for reading. When the done chan is closed, readCache closes +// files and returns. +func readCache(gopath string, done <-chan struct{}) { + files := make(map[string]*os.File) + defer func() { + for _, f := range files { + f.Close() + } + }() + + pattern := filepath.Join(gopath, "pkg/mod/rsc.io/quote@v1.5.2*/go.mod") + for { + select { + case <-done: + return + default: + } + + names, _ := filepath.Glob(pattern) + for _, name := range names { + if files[name] != nil { + continue + } + f, _ := os.Open(name) + if f != nil { + files[name] = f + } + } + } +} diff --git a/src/cmd/go/testdata/script/mod_download_hash.txt b/src/cmd/go/testdata/script/mod_download_hash.txt new file mode 100644 index 0000000..5a42c4b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_hash.txt @@ -0,0 +1,24 @@ +env GO111MODULE=on + +# Testing mod download with non semantic versions; turn off proxy. +[!net] skip +[!exec:git] skip +env GOPROXY=direct +env GOSUMDB=off + +go mod download rsc.io/quote@a91498bed0a73d4bb9c1fb2597925f7883bc40a7 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.zip + +go mod download rsc.io/quote@master +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.zip + + +-- go.mod -- +module m + +-- m.go -- +package m diff --git a/src/cmd/go/testdata/script/mod_download_json.txt b/src/cmd/go/testdata/script/mod_download_json.txt new file mode 100644 index 0000000..9555adf --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_json.txt @@ -0,0 +1,9 @@ +env GO111MODULE=on +env GOSUMDB=$sumdb' '$proxy/sumdb-wrong + +# download -json with version should print JSON on sumdb failure +! go mod download -json 'rsc.io/quote@<=v1.5.0' +stdout '"Error": ".*verifying (module|go.mod)' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_download_partial.txt b/src/cmd/go/testdata/script/mod_download_partial.txt new file mode 100644 index 0000000..0aab60d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_partial.txt @@ -0,0 +1,68 @@ +# Download modules and populate go.sum. +go get -d -modcacherw +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + +# 'go mod verify' should fail if we delete a file. +go mod verify +rm $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod +! go mod verify + +# Create a .partial file to simulate an failure extracting the zip file. +cp empty $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.partial + +# 'go mod verify' should not fail, since the module hasn't been completely +# ingested into the cache. +go mod verify + +# 'go list' should not load packages from the directory. +# NOTE: the message "directory $dir outside available modules" is reported +# for directories not in the main module, active modules in the module cache, +# or local replacements. In this case, the directory is in the right place, +# but it's incomplete, so 'go list' acts as if it's not an active module. +! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +stderr 'outside available modules' + +# 'go list -m' should not print the directory. +go list -m -f '{{.Dir}}' rsc.io/quote +! stdout . + +# 'go mod download' should re-extract the module and remove the .partial file. +go mod download -modcacherw rsc.io/quote +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.partial +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + +# 'go list' should succeed. +go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +stdout '^rsc.io/quote$' + +# 'go list -m' should print the directory. +go list -m -f '{{.Dir}}' rsc.io/quote +stdout 'pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2' + +# go mod verify should fail if we delete a file. +go mod verify +rm $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod +! go mod verify + +# 'go mod download' should not leave behind a directory or a .partial file +# if there is an error extracting the zip file. +rm $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +cp empty $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip +! go mod download +stderr 'not a valid zip file' +! exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.partial + +-- go.mod -- +module m + +go 1.14 + +require rsc.io/quote v1.5.2 + +-- use.go -- +package use + +import _ "rsc.io/quote" + +-- empty -- diff --git a/src/cmd/go/testdata/script/mod_download_replace_file.txt b/src/cmd/go/testdata/script/mod_download_replace_file.txt new file mode 100644 index 0000000..f6ab4fe --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_replace_file.txt @@ -0,0 +1,16 @@ +# This test checks that 'go mod download' produces no output for +# the main module (when specified implicitly) and for a module replaced +# with a file path. +# Verifies golang.org/issue/35505. +go mod download -json all +cmp stdout no-output + +-- go.mod -- +module example.com/a + +require example.com/b v1.0.0 + +replace example.com/b => ./local/b +-- local/b/go.mod -- +module example.com/b +-- no-output -- diff --git a/src/cmd/go/testdata/script/mod_e.txt b/src/cmd/go/testdata/script/mod_e.txt new file mode 100644 index 0000000..3a0d18d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_e.txt @@ -0,0 +1,89 @@ +cp go.mod go.mod.orig + + +# If a dependency cannot be resolved, 'go mod tidy' fails with an error message +# explaining the problem and does not update the go.mod file. +# TODO(bcmills): Ideally, with less redundancy than these error messages! + +! go mod tidy + +stderr '^example.com/untidy imports\n\texample.net/directnotfound: cannot find module providing package example.net/directnotfound: module example.net/directnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy imports\n\texample.net/m imports\n\texample.net/indirectnotfound: cannot find module providing package example.net/indirectnotfound: module example.net/indirectnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy tested by\n\texample.com/untidy.test imports\n\texample.net/directtestnotfound: cannot find module providing package example.net/directtestnotfound: module example.net/directtestnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy imports\n\texample.net/m tested by\n\texample.net/m.test imports\n\texample.net/indirecttestnotfound: cannot find module providing package example.net/indirecttestnotfound: module example.net/indirecttestnotfound: reading http://.*: 404 Not Found$' + +cmp go.mod.orig go.mod + + +# If a dependency cannot be resolved, 'go mod vendor' fails with an error message +# explaining the problem, does not update the go.mod file, and does not create +# the vendor directory. + +! go mod vendor + +stderr '^example.com/untidy imports\n\texample.net/directnotfound: cannot find module providing package example.net/directnotfound: module example.net/directnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy imports\n\texample.net/m imports\n\texample.net/indirectnotfound: cannot find module providing package example.net/indirectnotfound: module example.net/indirectnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy tested by\n\texample.com/untidy.test imports\n\texample.net/directtestnotfound: cannot find module providing package example.net/directtestnotfound: module example.net/directtestnotfound: reading http://.*: 404 Not Found$' + +! stderr 'indirecttestnotfound' # Vendor prunes test dependencies. + +cmp go.mod.orig go.mod +! exists vendor + + +# 'go mod tidy' still logs the errors, but succeeds and updates go.mod. + +go mod tidy -e +stderr -count=4 'cannot find module providing package' +cmp go.mod.final go.mod + + +# 'go mod vendor -e' still logs the errors, but succeeds and updates go.mod. + +cp go.mod.orig go.mod +go mod vendor -e +stderr -count=3 'cannot find module providing package' +cmp go.mod.final go.mod +exists vendor/modules.txt +exists vendor/example.net/m/m.go + + +-- go.mod -- +module example.com/untidy +go 1.16 +replace example.net/m v0.1.0 => ./m +-- go.mod.final -- +module example.com/untidy + +go 1.16 + +replace example.net/m v0.1.0 => ./m + +require example.net/m v0.1.0 +-- untidy.go -- +package untidy + +import ( + _ "example.net/m" + _ "example.net/directnotfound" +) +-- untidy_test.go -- +package untidy_test + +import _ "example.net/directtestnotfound" +-- m/go.mod -- +module example.net/m +go 1.16 +-- m/m.go -- +package m + +import _ "example.net/indirectnotfound" +-- m/m_test.go -- +package m_test + +import _ "example.net/indirecttestnotfound" diff --git a/src/cmd/go/testdata/script/mod_edit.txt b/src/cmd/go/testdata/script/mod_edit.txt new file mode 100644 index 0000000..9da6930 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_edit.txt @@ -0,0 +1,303 @@ +env GO111MODULE=on + +# Test that go mod edits and related mod flags work. +# Also test that they can use a dummy name that isn't resolvable. golang.org/issue/24100 + +# go mod init +! go mod init +stderr 'cannot determine module path' +! exists go.mod + +go mod init x.x/y/z +stderr 'creating new go.mod: module x.x/y/z' +cmpenv go.mod $WORK/go.mod.init + +! go mod init +cmpenv go.mod $WORK/go.mod.init + +# go mod edits +go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -exclude=x.1@v2.0.0+incompatible -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0 +cmpenv go.mod $WORK/go.mod.edit1 +go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropexclude=x.1@v2.0.0+incompatible -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0] +cmpenv go.mod $WORK/go.mod.edit2 + +# -exclude and -retract reject invalid versions. +! go mod edit -exclude=example.com/m@bad +stderr '^go mod: -exclude=example.com/m@bad: version "bad" invalid: must be of the form v1.2.3$' +! go mod edit -retract=bad +stderr '^go mod: -retract=bad: version "bad" invalid: must be of the form v1.2.3$' + +! go mod edit -exclude=example.com/m@v2.0.0 +stderr '^go mod: -exclude=example.com/m@v2\.0\.0: version "v2\.0\.0" invalid: should be v2\.0\.0\+incompatible \(or module example\.com/m/v2\)$' + +! go mod edit -exclude=example.com/m/v2@v1.0.0 +stderr '^go mod: -exclude=example.com/m/v2@v1\.0\.0: version "v1\.0\.0" invalid: should be v2, not v1$' + +! go mod edit -exclude=gopkg.in/example.v1@v2.0.0 +stderr '^go mod: -exclude=gopkg\.in/example\.v1@v2\.0\.0: version "v2\.0\.0" invalid: should be v1, not v2$' + +cmpenv go.mod $WORK/go.mod.edit2 + +# go mod edit -json +go mod edit -json +cmpenv stdout $WORK/go.mod.json + +# go mod edit -json (retractions with rationales) +go mod edit -json $WORK/go.mod.retractrationale +cmp stdout $WORK/go.mod.retractrationale.json + +# go mod edit -json (empty mod file) +go mod edit -json $WORK/go.mod.empty +cmp stdout $WORK/go.mod.empty.json + +# go mod edit -replace +go mod edit -replace=x.1@v1.3.0=y.1/v2@v2.3.5 -replace=x.1@v1.4.0=y.1/v2@v2.3.5 +cmpenv go.mod $WORK/go.mod.edit3 +go mod edit -replace=x.1=y.1/v2@v2.3.6 +cmpenv go.mod $WORK/go.mod.edit4 +go mod edit -dropreplace=x.1 +cmpenv go.mod $WORK/go.mod.edit5 + +# go mod edit -fmt +cp $WORK/go.mod.badfmt go.mod +go mod edit -fmt -print # -print should avoid writing file +cmpenv stdout $WORK/go.mod.goodfmt +cmp go.mod $WORK/go.mod.badfmt +go mod edit -fmt # without -print, should write file (and nothing to stdout) +! stdout . +cmpenv go.mod $WORK/go.mod.goodfmt + +# go mod edit -module +cd $WORK/m +go mod init a.a/b/c +go mod edit -module x.x/y/z +cmpenv go.mod go.mod.edit + +# golang.org/issue/30513: don't require go-gettable module paths. +cd $WORK/local +go mod init foo +go mod edit -module local-only -require=other-local@v1.0.0 -replace other-local@v1.0.0=./other +cmpenv go.mod go.mod.edit + +-- x.go -- +package x + +-- w/w.go -- +package w + +-- $WORK/go.mod.init -- +module x.x/y/z + +go $goversion +-- $WORK/go.mod.edit1 -- +module x.x/y/z + +go $goversion + +require x.1 v1.0.0 + +exclude ( + x.1 v1.2.0 + x.1 v1.2.1 + x.1 v2.0.0+incompatible +) + +replace ( + x.1 v1.3.0 => y.1 v1.4.0 + x.1 v1.4.0 => ../z +) + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] + [v1.1.0, v1.2.0] + v1.0.0 +) +-- $WORK/go.mod.edit2 -- +module x.x/y/z + +go $goversion + +exclude x.1 v1.2.0 + +replace x.1 v1.4.0 => ../z + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + +require x.3 v1.99.0 +-- $WORK/go.mod.json -- +{ + "Module": { + "Path": "x.x/y/z" + }, + "Go": "$goversion", + "Require": [ + { + "Path": "x.3", + "Version": "v1.99.0" + } + ], + "Exclude": [ + { + "Path": "x.1", + "Version": "v1.2.0" + } + ], + "Replace": [ + { + "Old": { + "Path": "x.1", + "Version": "v1.4.0" + }, + "New": { + "Path": "../z" + } + } + ], + "Retract": [ + { + "Low": "v1.6.0", + "High": "v1.6.0" + }, + { + "Low": "v1.3.0", + "High": "v1.4.0" + } + ] +} +-- $WORK/go.mod.edit3 -- +module x.x/y/z + +go $goversion + +exclude x.1 v1.2.0 + +replace ( + x.1 v1.3.0 => y.1/v2 v2.3.5 + x.1 v1.4.0 => y.1/v2 v2.3.5 +) + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + +require x.3 v1.99.0 +-- $WORK/go.mod.edit4 -- +module x.x/y/z + +go $goversion + +exclude x.1 v1.2.0 + +replace x.1 => y.1/v2 v2.3.6 + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + +require x.3 v1.99.0 +-- $WORK/go.mod.edit5 -- +module x.x/y/z + +go $goversion + +exclude x.1 v1.2.0 + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + +require x.3 v1.99.0 +-- $WORK/local/go.mod.edit -- +module local-only + +go $goversion + +require other-local v1.0.0 + +replace other-local v1.0.0 => ./other +-- $WORK/go.mod.badfmt -- +module x.x/y/z + +go 1.10 + +exclude x.1 v1.2.0 + +replace x.1 => y.1/v2 v2.3.6 + +require x.3 v1.99.0 + +retract [ "v1.8.1" , "v1.8.2" ] +-- $WORK/go.mod.goodfmt -- +module x.x/y/z + +go 1.10 + +exclude x.1 v1.2.0 + +replace x.1 => y.1/v2 v2.3.6 + +require x.3 v1.99.0 + +retract [v1.8.1, v1.8.2] +-- $WORK/m/go.mod.edit -- +module x.x/y/z + +go $goversion +-- $WORK/go.mod.retractrationale -- +module x.x/y/z + +go 1.15 + +// a +retract v1.0.0 + +// b +retract ( + v1.0.1 + v1.0.2 // c +) +-- $WORK/go.mod.retractrationale.json -- +{ + "Module": { + "Path": "x.x/y/z" + }, + "Go": "1.15", + "Require": null, + "Exclude": null, + "Replace": null, + "Retract": [ + { + "Low": "v1.0.0", + "High": "v1.0.0", + "Rationale": "a" + }, + { + "Low": "v1.0.1", + "High": "v1.0.1", + "Rationale": "b" + }, + { + "Low": "v1.0.2", + "High": "v1.0.2", + "Rationale": "c" + } + ] +} +-- $WORK/go.mod.empty -- +-- $WORK/go.mod.empty.json -- +{ + "Module": { + "Path": "" + }, + "Require": null, + "Exclude": null, + "Replace": null, + "Retract": null +} diff --git a/src/cmd/go/testdata/script/mod_edit_go.txt b/src/cmd/go/testdata/script/mod_edit_go.txt new file mode 100644 index 0000000..38321d0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_edit_go.txt @@ -0,0 +1,23 @@ +# Test support for go mod -edit to set language version. + +env GO111MODULE=on +! go build +stderr 'type aliases only supported as of' +go mod edit -go=1.9 +grep 'go 1.9' go.mod +go build + +# Reverting the version should force a rebuild and error instead of using +# the cached 1.9 build. (https://golang.org/issue/37804) +go mod edit -go=1.8 +! go build +stderr 'type aliases only supported as of' + + +-- go.mod -- +module m +go 1.8 + +-- alias.go -- +package alias +type T = int diff --git a/src/cmd/go/testdata/script/mod_empty_err.txt b/src/cmd/go/testdata/script/mod_empty_err.txt new file mode 100644 index 0000000..982e6b2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_empty_err.txt @@ -0,0 +1,36 @@ +# This test checks error messages for non-existant packages in module mode. +# Veries golang.org/issue/35414 +env GO111MODULE=on +cd $WORK + +go list -e -f {{.Error}} . +stdout 'no Go files in \$WORK' + +go list -e -f {{.Error}} ./empty +stdout 'no Go files in \$WORK[/\\]empty' + +go list -e -f {{.Error}} ./exclude +stdout 'build constraints exclude all Go files in \$WORK[/\\]exclude' + +go list -e -f {{.Error}} ./missing +stdout 'stat '$WORK'[/\\]missing: directory not found' + +# use 'go build -n' because 'go list' reports no error. +! go build -n ./testonly +stderr 'example.com/m/testonly: no non-test Go files in \$WORK[/\\]testonly' + +-- $WORK/go.mod -- +module example.com/m + +go 1.14 + +-- $WORK/empty/empty.txt -- +-- $WORK/exclude/exclude.go -- +// +build exclude + +package exclude +-- $WORK/testonly/testonly_test.go -- +package testonly_test +-- $WORK/excluded-stdout -- +package ./excluded: cannot find package "." in: + $WORK/excluded diff --git a/src/cmd/go/testdata/script/mod_enabled.txt b/src/cmd/go/testdata/script/mod_enabled.txt new file mode 100644 index 0000000..39f1ece --- /dev/null +++ b/src/cmd/go/testdata/script/mod_enabled.txt @@ -0,0 +1,93 @@ +# GO111MODULE=auto should trigger any time a go.mod exists in a parent directory. +env GO111MODULE=auto + +cd $GOPATH/src/x/y/z +go env GOMOD +stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod +go list -m -f {{.GoMod}} +stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod + +cd $GOPATH/src/x/y/z/w +go env GOMOD +stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod + +cd $GOPATH/src/x/y +go env GOMOD +! stdout . + +cd $GOPATH/foo +go env GOMOD +stdout foo[/\\]go.mod +go list -m -f {{.GoMod}} +stdout foo[/\\]go.mod + +cd $GOPATH/foo/bar/baz +go env GOMOD +stdout foo[/\\]go.mod + +# GO111MODULE unset should be equivalent to on. +env GO111MODULE= + +cd $GOPATH/src/x/y/z +go env GOMOD +stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod + +cd $GOPATH/src/x/y +go env GOMOD +stdout 'NUL|/dev/null' + +# GO111MODULE=on should trigger everywhere +env GO111MODULE=on + +cd $GOPATH/src/x/y/z +go env GOMOD +stdout z[/\\]go.mod + +cd $GOPATH/src/x/y/z/w +go env GOMOD +stdout z[/\\]go.mod + +cd $GOPATH/src/x/y +go env GOMOD +stdout 'NUL|/dev/null' +go list -m +stdout '^command-line-arguments$' + +cd $GOPATH/foo +go env GOMOD +stdout foo[/\\]go.mod + +cd $GOPATH/foo/bar/baz +go env GOMOD +stdout foo[/\\]go.mod + +# GO111MODULE=off should trigger nowhere +env GO111MODULE=off + +cd $GOPATH/src/x/y/z +go env GOMOD +! stdout .+ + +cd $GOPATH/foo +go env GOMOD +! stdout .+ + +cd $GOPATH/foo/bar/baz +go env GOMOD +! stdout .+ + +# GO111MODULE=auto should ignore and warn about /tmp/go.mod +env GO111MODULE=auto +cp $GOPATH/src/x/y/z/go.mod $WORK/tmp/go.mod +mkdir $WORK/tmp/mydir +cd $WORK/tmp/mydir +go env GOMOD +! stdout .+ +stderr '^go: warning: ignoring go.mod in system temp root ' + +-- $GOPATH/src/x/y/z/go.mod -- +module x/y/z +-- $GOPATH/src/x/y/z/w/w.txt -- +-- $GOPATH/foo/go.mod -- +module example.com/mod +-- $GOPATH/foo/bar/baz/quux.txt -- diff --git a/src/cmd/go/testdata/script/mod_file_proxy.txt b/src/cmd/go/testdata/script/mod_file_proxy.txt new file mode 100644 index 0000000..38d9fd2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_file_proxy.txt @@ -0,0 +1,36 @@ +[short] skip + +# Allow (cached) downloads for -mod=readonly. +env GO111MODULE=on +env GOPATH=$WORK/gopath1 +cd $WORK/x +go mod edit -fmt +go list -mod=readonly +env GOPROXY=file:///nonexist +go list +grep v1.5.1 $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/list + +# Use download cache as file:/// proxy. +env GOPATH=$WORK/gopath2 +[windows] env GOPROXY=file:///C:/nonexist +[!windows] env GOPROXY=file:///nonexist +! go list +[windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download +[!windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download +go list +grep v1.5.1 $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/list + +-- $WORK/x/go.mod -- +module x +go 1.13 +require rsc.io/quote v1.5.1 +-- $WORK/x/x.go -- +package x +import _ "rsc.io/quote" +-- $WORK/x/go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.1 h1:ZE3OgnVGrhXtFkGw90HwW992ZRqcdli/33DLqEYsoxA= +rsc.io/quote v1.5.1/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_find.txt b/src/cmd/go/testdata/script/mod_find.txt new file mode 100644 index 0000000..1e01973 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_find.txt @@ -0,0 +1,104 @@ +env GO111MODULE=on + +# Derive module path from import comment. +cd $WORK/x +exists x.go +go mod init +stderr 'module x' + +# Import comment works even with CRLF line endings. +rm go.mod +addcrlf x.go +go mod init +stderr 'module x' + +# Derive module path from location inside GOPATH. +# 'go mod init' should succeed if modules are not explicitly disabled. +cd $GOPATH/src/example.com/x/y +go mod init +stderr 'module example.com/x/y$' +rm go.mod + +# go mod init rejects a zero-length go.mod file +cp $devnull go.mod # can't use touch to create it because Windows +! go mod init +stderr 'go.mod already exists' + +# Module path from Godeps/Godeps.json overrides GOPATH. +cd $GOPATH/src/example.com/x/y/z +go mod init +stderr 'unexpected.com/z' +rm go.mod + +# Empty directory outside GOPATH fails. +mkdir $WORK/empty +cd $WORK/empty +! go mod init +stderr 'cannot determine module path for source directory' +rm go.mod + +# Empty directory inside GOPATH/src uses location inside GOPATH. +mkdir $GOPATH/src/empty +cd $GOPATH/src/empty +go mod init +stderr 'empty' +rm go.mod + +# In Plan 9, directories are automatically created in /n. +# For example, /n/go.mod always exist, but it's a directory. +# Test that we ignore directories when trying to find go.mod. +cd $WORK/gomoddir +! go list . +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +[!symlink] stop + +# gplink1/src/empty where gopathlink -> GOPATH +symlink $WORK/gopathlink -> gopath +cd $WORK/gopathlink/src/empty +go mod init +rm go.mod + +# GOPATH/src/link where link -> out of GOPATH +symlink $GOPATH/src/link -> $WORK/empty +cd $WORK/empty +! go mod init +cd $GOPATH/src/link +go mod init +stderr link +rm go.mod + +# GOPATH/src/empty where GOPATH itself is a symlink +env GOPATH=$WORK/gopathlink +cd $GOPATH/src/empty +go mod init +rm go.mod +cd $WORK/gopath/src/empty +go mod init +rm go.mod + +# GOPATH/src/link where GOPATH and link are both symlinks +cd $GOPATH/src/link +go mod init +stderr link +rm go.mod + +# Too hard: doesn't match unevaluated nor completely evaluated. (Only partially evaluated.) +# Whether this works depends on which OS we are running on. +# cd $WORK/gopath/src/link +# ! go mod init + +-- $WORK/x/x.go -- +package x // import "x" + +-- $GOPATH/src/example.com/x/y/y.go -- +package y +-- $GOPATH/src/example.com/x/y/z/z.go -- +package z +-- $GOPATH/src/example.com/x/y/z/Godeps/Godeps.json -- +{"ImportPath": "unexpected.com/z"} + +-- $WORK/gomoddir/go.mod/README.txt -- +../go.mod is a directory, not a file. +-- $WORK/gomoddir/p.go -- +package p diff --git a/src/cmd/go/testdata/script/mod_fs_patterns.txt b/src/cmd/go/testdata/script/mod_fs_patterns.txt new file mode 100644 index 0000000..a20fefd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_fs_patterns.txt @@ -0,0 +1,97 @@ +env GO111MODULE=on + +# File system pattern searches should skip sub-modules and vendor directories. +cd x + +# all packages +go list all +stdout ^m$ +stdout ^m/vendor$ +! stdout vendor/ +stdout ^m/y$ +! stdout ^m/y/z + +# path pattern +go list m/... +stdout ^m$ +stdout ^m/vendor$ +! stdout vendor/ +stdout ^m/y$ +! stdout ^m/y/z + +# directory pattern +go list ./... +stdout ^m$ +stdout ^m/vendor$ +! stdout vendor/ +stdout ^m/y$ +! stdout ^m/y/z + +# non-existent directory should not prompt lookups +! go build -mod=readonly example.com/nonexist +stderr 'import lookup disabled' + +! go build -mod=readonly ./nonexist +! stderr 'import lookup disabled' +stderr '^stat '$GOPATH'[/\\]src[/\\]x[/\\]nonexist: directory not found' + +! go build -mod=readonly ./go.mod +! stderr 'import lookup disabled' +stderr 'main module \(m\) does not contain package m/go.mod' + + +# File system paths and patterns should allow the '@' character. +cd ../@at +go list $PWD +stdout '^at$' +go list $PWD/... +stdout '^at$' + +# The '@' character is not allowed in directory paths that are part of +# a package path. +cd ../badat/bad@ +! go list . +stderr 'directory . outside available modules' +! go list $PWD +stderr 'directory . outside available modules' +! go list $PWD/... +stderr 'directory . outside available modules' + +-- x/go.mod -- +module m + +-- x/x.go -- +package x + +-- x/vendor/v/v.go -- +package v +import _ "golang.org/x/crypto" + +-- x/vendor/v.go -- +package main + +-- x/y/y.go -- +package y + +-- x/y/z/go.mod -- +syntax error! + +-- x/y/z/z.go -- +package z + +-- x/y/z/w/w.go -- +package w + +-- @at/go.mod -- +module at + +go 1.14 +-- @at/at.go -- +package at + +-- badat/go.mod -- +module badat + +go 1.14 +-- badat/bad@/bad.go -- +package bad diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt new file mode 100644 index 0000000..daed03b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt @@ -0,0 +1,107 @@ +go mod tidy +cp go.mod go.mod.orig + +# If there is no sensible *package* meaning for 'm/p', it should refer +# to *module* m/p. + +go get -d m/p # @latest +go list -m all +stdout '^m/p v0.3.0 ' +! stdout '^m ' + +cp go.mod.orig go.mod + +go get -d m/p@v0.1.0 +go list -m all +stdout '^m/p v0.1.0 ' +! stdout '^m ' + +# When feasible, the argument 'm/p' in 'go get m/p' refers to *package* m/p, +# which is in module m. +# +# (It only refers to *module* m/p if there is no such package at the +# requested version.) + +go get -d m/p@v0.2.0 +go list -m all +stdout '^m v0.2.0 ' +stdout '^m/p v0.1.0 ' # unchanged from the previous case + +# Repeating the above with module m/p already in the module graph does not +# change its meaning. + +go get -d m/p@v0.2.0 +go list -m all +stdout '^m v0.2.0 ' +stdout '^m/p v0.1.0 ' + +-- go.mod -- +module example.com + +go 1.16 + +replace ( + m v0.1.0 => ./m01 + m v0.2.0 => ./m02 + m v0.3.0 => ./m03 + m/p v0.1.0 => ./mp01 + m/p v0.2.0 => ./mp02 + m/p v0.3.0 => ./mp03 +) +-- m01/go.mod -- +module m + +go 1.16 +-- m01/README.txt -- +Module m at v0.1.0 does not yet contain package p. + +-- m02/go.mod -- +module m + +go 1.16 + +require m/p v0.1.0 +-- m02/p/p.go -- +// Package p is present in module m, but not module m/p. +package p + +-- m03/go.mod -- +module m + +go 1.16 + +require m/p v0.1.0 +-- m03/README.txt -- +Module m at v0.3.0 no longer contains package p. + +-- mv2/go.mod -- +module m/v2 + +go 1.16 +-- mv2/README.txt -- +This module is m/v2. It doesn't actually need to exist, +but it explains how module m could plausibly exist +and still contain package p at 'latest' even when module +m/p also exists. + +-- mp01/go.mod -- +module m/p + +go 1.16 +-- mp01/README.txt -- +This module is m/p. +Package m/p does not exist in this module. +-- mp02/go.mod -- +module m/p + +go 1.16 +-- mp02/README.txt -- +This module is m/p. +Package m/p does not exist in this module. +-- mp03/go.mod -- +module m/p + +go 1.16 +-- mp03/README.txt -- +This module is m/p. +Package m/p does not exist in this module. diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt new file mode 100644 index 0000000..33605f5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt @@ -0,0 +1,60 @@ +go list -m all +stdout '^example.net/m v0.1.0 ' +! stdout '^example.net/m/p ' +cp go.mod go.mod.orig + +# Upgrading example.net/m/p without also upgrading example.net/m +# causes the import of package example.net/m/p to be ambiguous. +# +# TODO(#27899): Should we automatically upgrade example.net/m to v0.2.0 +# to resolve the conflict? +! go get -d example.net/m/p@v1.0.0 +stderr '^example.net/m/p: ambiguous import: found package example.net/m/p in multiple modules:\n\texample.net/m v0.1.0 \(.*[/\\]m1[/\\]p\)\n\texample.net/m/p v1.0.0 \(.*[/\\]p0\)\n\z' +cmp go.mod go.mod.orig + +# Upgrading both modules simultaneously resolves the ambiguous upgrade. +# Note that this command line mixes a module path (example.net/m) +# and a package path (example.net/m/p) in the same command. +go get -d example.net/m@v0.2.0 example.net/m/p@v1.0.0 + +go list -m all +stdout '^example.net/m v0.2.0 ' +stdout '^example.net/m/p v1.0.0 ' + +-- go.mod -- +module example.net/importer + +go 1.16 + +require ( + example.net/m v0.1.0 +) + +replace ( + example.net/m v0.1.0 => ./m1 + example.net/m v0.2.0 => ./m2 + example.net/m/p v1.0.0 => ./p0 +) +-- importer.go -- +package importer +import _ "example.net/m/p" +-- m1/go.mod -- +module example.net/m + +go 1.16 +-- m1/p/p.go -- +package p +-- m2/go.mod -- +module example.net/m + +go 1.16 +-- m2/README.txt -- +Package p has been moved to module …/m/p. +Module …/m/p does not require any version of module …/m. + +-- p0/go.mod -- +module example.net/m/p + +go 1.16 +-- p0/p.go -- +package p diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt new file mode 100644 index 0000000..0e7f93b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt @@ -0,0 +1,87 @@ +# Both example.net/ambiguous v0.1.0 and example.net/ambiguous/pkg v0.1.0 exist. +# 'go mod tidy' would arbitrarily choose the one with the longer path, +# but 'go mod tidy' also arbitrarily chooses the latest version. + +cp go.mod go.mod.orig + + +# From a clean slate, 'go get' currently does the same thing as 'go mod tidy': +# it resolves the package from the module with the longest matching prefix. + +go get -d example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +# From an initial state that already depends on the shorter path, +# the same 'go get' command should (somewhat arbitrarily) keep the +# existing path, since it is a valid interpretation of the command. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get -d example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous v0.1.0$' +! stdout '^example.net/ambiguous/nested ' + + +# The user should be able to make the command unambiguous by explicitly +# upgrading the conflicting module... + +go get -d example.net/ambiguous@v0.2.0 example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +stdout '^example.net/ambiguous v0.2.0$' + + +# ...or by explicitly NOT adding the conflicting module. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get -d example.net/ambiguous/nested/pkg@v0.1.0 example.net/ambiguous/nested@none +go list -m all +! stdout '^example.net/ambiguous/nested ' +stdout '^example.net/ambiguous v0.1.0$' + + +# The user should also be able to fix it by *downgrading* the conflicting module +# away. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get -d example.net/ambiguous@none example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +# In contrast, if we do the same thing tacking a wildcard pattern ('/...') on +# the end of the package path, we get different behaviors depending on the +# initial state, and no error. (This seems to contradict the “same meaning +# regardless of the initial state” point above, but maybe that's ok?) + +cp go.mod.orig go.mod + +go get -d example.net/ambiguous/nested/pkg/...@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get -d example.net/ambiguous/nested/pkg/...@v0.1.0 +go list -m all +! stdout '^example.net/ambiguous/nested ' +stdout '^example.net/ambiguous v0.1.0$' + + +-- go.mod -- +module test + +go 1.16 diff --git a/src/cmd/go/testdata/script/mod_get_changes.txt b/src/cmd/go/testdata/script/mod_get_changes.txt new file mode 100644 index 0000000..3287b2a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_changes.txt @@ -0,0 +1,70 @@ +# When adding a requirement, 'go get' prints a message for the requirement +# and for changed explicit dependencies. 'go get' does not print messages +# for changed indirect dependencies. +go list -m all +! stdout golang.org/x/text +go get -d rsc.io/quote@v1.5.2 +stderr '^go get: added rsc.io/quote v1.5.2$' +stderr '^go get: upgraded rsc.io/sampler v1.0.0 => v1.3.0$' +! stderr '^go get.*golang.org/x/text' +go list -m all +stdout golang.org/x/text +cmp go.mod go.mod.upgrade + +# When removing a requirement, 'go get' prints a message for the requiremnent +# and for changed explicit dependencies. 'go get' does not print messages +# for changed indirect dependencies. +go get -d rsc.io/sampler@none +stderr '^go get: downgraded rsc.io/quote v1.5.2 => v1.3.0$' +stderr '^go get: removed rsc.io/sampler v1.3.0$' +! stderr '^go get.*golang.org/x/text' +cmp go.mod go.mod.downgrade + +# When removing or downgrading a requirement, 'go get' also prints a message +# for explicit dependencies removed as a consequence. +cp go.mod.usequote go.mod +go get -d rsc.io/quote@v1.5.1 +stderr '^go get: downgraded rsc.io/quote v1.5.2 => v1.5.1$' +stderr '^go get: removed usequote v0.0.0$' + +-- go.mod -- +module m + +go 1.16 + +require rsc.io/sampler v1.0.0 +-- go.sum -- +rsc.io/sampler v1.0.0 h1:SRJnjyQ07sAtq6G4RcfJEmz8JxqLyj3PoGXG2VhbDWo= +rsc.io/sampler v1.0.0/go.mod h1:cqxpM3ZVz9VtirqxZPmrWzkQ+UkiNiGtkrN+B+i8kx8= +-- go.mod.upgrade -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/sampler v1.3.0 +) +-- go.mod.downgrade -- +module m + +go 1.16 + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect + rsc.io/quote v1.3.0 // indirect +) +-- go.mod.usequote -- +module m + +go 1.16 + +require usequote v0.0.0 + +replace usequote => ./usequote +-- usequote/go.mod -- +module usequote + +go 1.16 + +require rsc.io/quote v1.5.2 diff --git a/src/cmd/go/testdata/script/mod_get_cmd.txt b/src/cmd/go/testdata/script/mod_get_cmd.txt new file mode 100644 index 0000000..d31cee1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_cmd.txt @@ -0,0 +1,20 @@ +env GO111MODULE=on +[short] skip + +# Test that when 'go get' is run from $GOBIN, it does not delete binaries +# after it installs them. Verifies golang.org/issue/32766. + +go get example.com/tools/cmd/hello + +# 'go get' should not delete the command when run from $GOPATH/bin +cd $GOPATH/bin +exists hello$GOEXE +go get example.com/tools/cmd/hello +exists hello$GOEXE + +# 'go get' should not delete the command when run from a different $GOBIN +mkdir $WORK/bin +cd $WORK/bin +env GOBIN=$WORK/bin +go get example.com/tools/cmd/hello +exists hello$GOEXE diff --git a/src/cmd/go/testdata/script/mod_get_commit.txt b/src/cmd/go/testdata/script/mod_get_commit.txt new file mode 100644 index 0000000..4649491 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_commit.txt @@ -0,0 +1,51 @@ +env GO111MODULE=on +[short] skip + +# @commit should resolve + +# golang.org/x/text/language@commit should resolve. +# Because of -d, the compiler should not run. +go get -d -x golang.org/x/text/language@14c0d48 +! stderr 'compile|cp|gccgo .*language\.a$' + +# go get should skip build with no Go files in root +go get -d golang.org/x/text@14c0d48 + +# dropping -d, we should see a build. +[short] skip + +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. + +go get -x golang.org/x/text/language@14c0d48 +stderr 'compile|cp|gccgo .*language\.a$' + +# BUG: after the build, the package should not be stale, as 'go install' would +# not do anything further. +go list -f '{{.Stale}}' golang.org/x/text/language +stdout ^true + +# install after get should not run the compiler again. +go install -x golang.org/x/text/language +! stderr 'compile|cp|gccgo .*language\.a$' + +# even with -d, we should see an error for unknown packages. +! go get -d -x golang.org/x/text/foo@14c0d48 + +# get pseudo-version should record that version +go get -d rsc.io/quote@v0.0.0-20180214005840-23179ee8a569 +grep 'rsc.io/quote v0.0.0-20180214005840-23179ee8a569' go.mod + +# but as commit should record as v1.5.1 +go get -d rsc.io/quote@23179ee8 +grep 'rsc.io/quote v1.5.1' go.mod + +# go mod edit -require does not interpret commits +go mod edit -require rsc.io/quote@23179ee +grep 'rsc.io/quote 23179ee' go.mod + +# but other commands fix them +go mod graph +grep 'rsc.io/quote v1.5.1' go.mod + +-- go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_get_direct.txt b/src/cmd/go/testdata/script/mod_get_direct.txt new file mode 100644 index 0000000..42ccbcd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_direct.txt @@ -0,0 +1,20 @@ +# Regression test for golang.org/issue/34092: with an empty module cache, +# 'GOPROXY=direct go get golang.org/x/tools/gopls@master' did not correctly +# resolve the pseudo-version for its dependency on golang.org/x/tools. + +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +go list -m cloud.google.com/go@master +! stdout 'v0.0.0-' + +-- go.mod -- +module example.com + +go 1.14 +-- go.sum -- diff --git a/src/cmd/go/testdata/script/mod_get_downgrade.txt b/src/cmd/go/testdata/script/mod_get_downgrade.txt new file mode 100644 index 0000000..a954c10 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downgrade.txt @@ -0,0 +1,56 @@ +env GO111MODULE=on +[short] skip + +# downgrade sampler should downgrade quote +cp go.mod.orig go.mod +go get -d rsc.io/sampler@v1.0.0 +go list -m all +stdout 'rsc.io/quote v1.4.0' +stdout 'rsc.io/sampler v1.0.0' + +# downgrade sampler away should downgrade quote further +go get -d rsc.io/sampler@none +go list -m all +stdout 'rsc.io/quote v1.3.0' + +# downgrade should report inconsistencies and not change go.mod +go get -d rsc.io/quote@v1.5.1 +go list -m all +stdout 'rsc.io/quote v1.5.1' +stdout 'rsc.io/sampler v1.3.0' + +! go get -d rsc.io/sampler@v1.0.0 rsc.io/quote@v1.5.2 golang.org/x/text@none +stderr '^go get: rsc.io/quote@v1.5.2 requires rsc.io/sampler@v1.3.0, not rsc.io/sampler@v1.0.0$' +stderr '^go get: rsc.io/quote@v1.5.2 requires golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c, not golang.org/x/text@none$' + +go list -m all +stdout 'rsc.io/quote v1.5.1' +stdout 'rsc.io/sampler v1.3.0' + +# go get -u args should limit upgrades +cp go.mod.empty go.mod +go get -d -u rsc.io/quote@v1.4.0 rsc.io/sampler@v1.0.0 +go list -m all +stdout 'rsc.io/quote v1.4.0' +stdout 'rsc.io/sampler v1.0.0' +! stdout golang.org/x/text + +# downgrading away quote should also downgrade away latemigrate/v2, +# since there are no older versions. v2.0.0 is incompatible. +cp go.mod.orig go.mod +go list -m -versions example.com/latemigrate/v2 +stdout v2.0.0 # proxy may serve incompatible versions +go get -d rsc.io/quote@none +go list -m all +! stdout 'example.com/latemigrate/v2' + +-- go.mod.orig -- +module x +require ( + rsc.io/quote v1.5.1 + example.com/latemigrate/v2 v2.0.1 +) +-- go.mod.empty -- +module x +-- x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt b/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt new file mode 100644 index 0000000..5b768fa --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt @@ -0,0 +1,43 @@ +cp go.mod go.mod.orig + +# getting a specific version of a module along with a pattern +# not yet present in that module should report the version mismatch +# rather than a "matched no packages" warning. + +! go get -d example.net/pkgadded@v1.1.0 example.net/pkgadded/subpkg/... +stderr '^go get: example.net/pkgadded@v1.1.0 conflicts with example.net/pkgadded/subpkg/...@upgrade \(v1.2.0\)$' +! stderr 'matched no packages' +cmp go.mod.orig go.mod + + +# A wildcard pattern should match the pattern with that path. + +go get -d example.net/pkgadded/...@v1.0.0 +go list -m all +stdout '^example.net/pkgadded v1.0.0' +cp go.mod.orig go.mod + + +# If we need to resolve a transitive dependency of a package, +# and another argument constrains away the version that provides that +# package, then 'go get' should fail with a useful error message. + +! go get -d example.net/pkgadded@v1.0.0 . +stderr '^example.com/m imports\n\texample.net/pkgadded/subpkg: cannot find module providing package example.net/pkgadded/subpkg$' +! stderr 'example.net/pkgadded v1\.2\.0' +cmp go.mod.orig go.mod + +go get -d example.net/pkgadded@v1.0.0 +! go list -deps -mod=readonly . +stderr '^m.go:3:8: cannot find module providing package example\.net/pkgadded/subpkg: ' + +-- go.mod -- +module example.com/m + +go 1.16 + +require example.net/pkgadded v1.2.0 +-- m.go -- +package m + +import _ "example.net/pkgadded/subpkg" diff --git a/src/cmd/go/testdata/script/mod_get_errors.txt b/src/cmd/go/testdata/script/mod_get_errors.txt new file mode 100644 index 0000000..5c37058 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_errors.txt @@ -0,0 +1,69 @@ +cp go.mod go.mod.orig + + +# Both 'go get' and 'go get -d' should fail, without updating go.mod, +# if the transitive dependencies of the requested package (by default, +# the package in the current directory) cannot be resolved. + +! go get +stderr '^example.com/m imports\n\texample.com/badimport imports\n\texample.net/oops: cannot find module providing package example.net/oops$' +cmp go.mod.orig go.mod + +! go get -d +stderr '^example.com/m imports\n\texample.com/badimport imports\n\texample.net/oops: cannot find module providing package example.net/oops$' +cmp go.mod.orig go.mod + +cd importsyntax + + +# If 'go get' fails due to a compile error (such as a syntax error), +# it should not update the go.mod file. + +! go get +stderr '^..[/\\]badimport[/\\]syntaxerror[/\\]syntaxerror.go:1:1: expected ''package'', found pack$' # TODO: An import stack would be nice. +cmp ../go.mod.orig ../go.mod + + +# A syntax error in a dependency prevents the compiler from needing that +# dependency's imports, so 'go get -d' should not report an error when those +# imports cannot be resolved: it has all of the dependencies that the compiler +# needs, and the user did not request to run the compiler. + +go get -d +cmp ../go.mod.syntax-d ../go.mod + + +-- go.mod -- +module example.com/m + +go 1.16 + +replace example.com/badimport v0.1.0 => ./badimport +-- go.mod.syntax-d -- +module example.com/m + +go 1.16 + +replace example.com/badimport v0.1.0 => ./badimport + +require example.com/badimport v0.1.0 +-- m.go -- +package m + +import _ "example.com/badimport" +-- importsyntax/importsyntax.go -- +package importsyntax + +import _ "example.com/badimport/syntaxerror" +-- badimport/go.mod -- +module example.com/badimport + +go 1.16 +-- badimport/badimport.go -- +package badimport + +import "example.net/oops" +-- badimport/syntaxerror/syntaxerror.go -- +pack-age syntaxerror // sic + +import "example.net/oops" diff --git a/src/cmd/go/testdata/script/mod_get_extra.txt b/src/cmd/go/testdata/script/mod_get_extra.txt new file mode 100644 index 0000000..7efa24e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_extra.txt @@ -0,0 +1,69 @@ +cp go.mod go.mod.orig + +# The -u flag should not (even temporarily) upgrade modules whose versions are +# determined by explicit queries to any version other than the explicit one. +# Otherwise, 'go get -u' could introduce spurious dependencies. + +go get -d -u example.net/a@v0.1.0 example.net/b@v0.1.0 +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' +! stdout '^example.net/c ' + + +# TODO(bcmills): This property does not yet hold for modules added for +# missing packages when the newly-added module matches a wildcard. + +cp go.mod.orig go.mod + +go get -d -u example.net/a@v0.1.0 example.net/b/...@v0.1.0 +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' +stdout '^example.net/c ' # BUG, but a minor and rare one + + +-- go.mod -- +module example + +go 1.15 + +replace ( + example.net/a v0.1.0 => ./a1 + example.net/b v0.1.0 => ./b1 + example.net/b v0.2.0 => ./b2 + example.net/c v0.1.0 => ./c1 + example.net/c v0.2.0 => ./c1 +) + +-- a1/go.mod -- +module example.net/a + +go 1.15 + +// example.net/a needs a dependency on example.net/b, but lacks a requirement +// on it (perhaps due to a missed file in a VCS commit). +-- a1/a.go -- +package a +import _ "example.net/b" + +-- b1/go.mod -- +module example.net/b + +go 1.15 +-- b1/b.go -- +package b + +-- b2/go.mod -- +module example.net/b + +go 1.15 + +require example.net/c v0.1.0 +-- b2/b.go -- +package b + +-- c1/go.mod -- +module example.net/c + +go 1.15 diff --git a/src/cmd/go/testdata/script/mod_get_fallback.txt b/src/cmd/go/testdata/script/mod_get_fallback.txt new file mode 100644 index 0000000..9733fa3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_fallback.txt @@ -0,0 +1,10 @@ +env GO111MODULE=on + +[!net] skip + +env GOPROXY=https://proxy.golang.org,direct +env GOSUMDB=off + +go get -x -v -d golang.org/x/tools/cmd/goimports +stderr '# get https://proxy.golang.org/golang.org/x/tools/@v/list' +! stderr '# get https://golang.org' diff --git a/src/cmd/go/testdata/script/mod_get_fossil.txt b/src/cmd/go/testdata/script/mod_get_fossil.txt new file mode 100644 index 0000000..baad544 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_fossil.txt @@ -0,0 +1,29 @@ +[!net] skip +[!exec:fossil] skip + +# Regression test for 'go get' to ensure repositories +# provided by fossil v2.12 and up are able to be fetched +# and parsed correctly. +# Verifies golang.org/issue/42323. + + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# 'go get' for the fossil repo will fail if fossil +# is unable to determine your fossil user. Easiest +# way to set it for use by 'go get' is specifying +# a any non-empty $USER; the value doesn't otherwise matter. +env USER=fossiluser +env FOSSIL_HOME=$WORK/home + +# Attempting to get the latest version of a fossil repo. +go get vcs-test.golang.org/fossil/hello.fossil +! stderr 'unexpected response from fossil info' +grep 'vcs-test.golang.org/fossil/hello.fossil' go.mod +exists $GOPATH/bin/hello.fossil$GOEXE + +-- go.mod -- +module x +-- $WORK/home/.fossil -- diff --git a/src/cmd/go/testdata/script/mod_get_go_file.txt b/src/cmd/go/testdata/script/mod_get_go_file.txt new file mode 100644 index 0000000..0c7b5dc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_go_file.txt @@ -0,0 +1,68 @@ +# Tests Issue #38478 +# Tests that go get in GOMOD mode returns a specific error if the argument +# ends with '.go', has no version, and either has no slash or refers to an +# existing file. + +env GO111MODULE=on + +# argument doesn't have .go suffix and has no version +! go get test +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix and has version +! go get test.go@v1.0.0 +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, is a file and exists +! go get test.go +stderr 'go get test.go: arguments must be package or module paths' + +# argument has .go suffix, doesn't exist and has no slashes +! go get test_missing.go +stderr 'arguments must be package or module paths' + +# argument has .go suffix, is a file and exists in sub-directory +! go get test/test.go +stderr 'go get: test/test.go exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, doesn't exist and has slashes +! go get test/test_missing.go +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, is a symlink and exists +[symlink] symlink test_sym.go -> test.go +[symlink] ! go get test_sym.go +[symlink] stderr 'go get test_sym.go: arguments must be package or module paths' +[symlink] rm test_sym.go + +# argument has .go suffix, is a symlink and exists in sub-directory +[symlink] symlink test/test_sym.go -> test.go +[symlink] ! go get test/test_sym.go +[symlink] stderr 'go get: test/test_sym.go exists as a file, but ''go get'' requires package arguments' +[symlink] rm test_sym.go + +# argument has .go suffix, is a directory and exists +mkdir test_dir.go +! go get test_dir.go +stderr 'go get test_dir.go: arguments must be package or module paths' +rm test_dir.go + +# argument has .go suffix, is a directory and exists in sub-directory +mkdir test/test_dir.go +! go get test/test_dir.go +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' +rm test/test_dir.go + + +-- test.go -- +package main +func main() {println("test")} + + +-- test/test.go -- +package main +func main() {println("test")} diff --git a/src/cmd/go/testdata/script/mod_get_hash.txt b/src/cmd/go/testdata/script/mod_get_hash.txt new file mode 100644 index 0000000..3bb3ee7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_hash.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off +[!net] skip +[!exec:git] skip + +# fetch commit hash reachable from refs/heads/* and refs/tags/* is OK +go list -m golang.org/x/time@8be79e1e0910c292df4e79c241bb7e8f7e725959 # on master branch + +# fetch other commit hash, even with a non-standard ref, is not OK +! go list -m golang.org/x/time@334d83c35137ac2b376c1dc3e4c7733791855a3a # refs/changes/24/41624/3 +stderr 'unknown revision' +! go list -m golang.org/x/time@v0.0.0-20170424233410-334d83c35137 +stderr 'unknown revision' +! go list -m golang.org/x/time@334d83c35137 +stderr 'unknown revision' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_get_incompatible.txt b/src/cmd/go/testdata/script/mod_get_incompatible.txt new file mode 100644 index 0000000..8000ee6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_incompatible.txt @@ -0,0 +1,26 @@ +env GO111MODULE=on + +go get -d x +go list -m all +stdout 'rsc.io/breaker v2.0.0\+incompatible' + +cp go.mod2 go.mod +go get -d rsc.io/breaker@7307b30 +go list -m all +stdout 'rsc.io/breaker v2.0.0\+incompatible' + +go get -d rsc.io/breaker@v2.0.0 +go list -m all +stdout 'rsc.io/breaker v2.0.0\+incompatible' + +-- go.mod -- +module x + +-- go.mod2 -- +module x +require rsc.io/breaker v1.0.0 + +-- x.go -- +package x +import "rsc.io/breaker" +var _ = breaker.XX diff --git a/src/cmd/go/testdata/script/mod_get_indirect.txt b/src/cmd/go/testdata/script/mod_get_indirect.txt new file mode 100644 index 0000000..e1cc1ab --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_indirect.txt @@ -0,0 +1,59 @@ +env GO111MODULE=on +[short] skip + +# get -u should not upgrade anything, since the package +# in the current directory doesn't import anything. +go get -u +go list -m all +stdout 'quote v1.5.1$' +grep 'rsc.io/quote v1.5.1$' go.mod + +# get -u should find quote v1.5.2 once there is a use. +cp $WORK/tmp/usequote.go x.go +go get -u +go list -m all +stdout 'quote v1.5.2$' +grep 'rsc.io/quote v1.5.2$' go.mod + +# it should also update x/text later than requested by v1.5.2 +go list -m -f '{{.Path}} {{.Version}}{{if .Indirect}} // indirect{{end}}' all +stdout '^golang.org/x/text [v0-9a-f\.-]+ // indirect' +grep 'golang.org/x/text [v0-9a-f\.-]+ // indirect' go.mod + +# importing an empty module root as a package does not remove indirect tag. +cp $WORK/tmp/usetext.go x.go +go list -e +grep 'golang.org/x/text v0.3.0 // indirect$' go.mod + +# indirect tag should be removed upon seeing direct import. +cp $WORK/tmp/uselang.go x.go +go get -d +grep 'rsc.io/quote v1.5.2$' go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+$' go.mod + +# indirect tag should be added by go mod tidy +cp $WORK/tmp/usequote.go x.go +go mod tidy +grep 'rsc.io/quote v1.5.2$' go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+ // indirect' go.mod + +# requirement should be dropped entirely if not needed +cp $WORK/tmp/uselang.go x.go +go mod tidy +! grep rsc.io/quote go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+$' go.mod + +-- go.mod -- +module x +require rsc.io/quote v1.5.1 +-- x.go -- +package x +-- $WORK/tmp/usetext.go -- +package x +import _ "golang.org/x/text" +-- $WORK/tmp/uselang.go -- +package x +import _ "golang.org/x/text/language" +-- $WORK/tmp/usequote.go -- +package x +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt b/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt new file mode 100644 index 0000000..3755f17 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt @@ -0,0 +1,34 @@ +# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure. + +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +! go get -d vcs-test.golang.org/insecure/go/insecure +stderr 'redirected .* to insecure URL' + +go get -d -insecure vcs-test.golang.org/insecure/go/insecure + +# insecure host +env GOINSECURE=vcs-test.golang.org +go clean -modcache +go get -d vcs-test.golang.org/insecure/go/insecure + +# insecure glob host +env GOINSECURE=*.golang.org +go clean -modcache +go get -d vcs-test.golang.org/insecure/go/insecure + +# insecure multiple host +env GOINSECURE=somewhere-else.com,*.golang.org +go clean -modcache +go get -d vcs-test.golang.org/insecure/go/insecure + +# different insecure host does not fetch +env GOINSECURE=somewhere-else.com +go clean -modcache +! go get -d vcs-test.golang.org/insecure/go/insecure +stderr 'redirected .* to insecure URL' diff --git a/src/cmd/go/testdata/script/mod_get_issue37438.txt b/src/cmd/go/testdata/script/mod_get_issue37438.txt new file mode 100644 index 0000000..38b2031 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_issue37438.txt @@ -0,0 +1,37 @@ +# Regression test for https://golang.org/issue/37438. +# +# If a path exists at the requested version, but does not exist at the +# version of the module that is already required and does not exist at +# the version that would be selected by 'go mod tidy', then +# 'go get foo@requested' should resolve the requested version, +# not error out on the (unrelated) latest one. + +go get -d example.net/a/p@v0.2.0 + +-- go.mod -- +module example + +go 1.15 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a1 + example.net/a v0.2.0 => ./a2 + example.net/a v0.3.0 => ./a1 +) + +-- a1/go.mod -- +module example.net/a + +go 1.15 +-- a1/README -- +package example.net/a/p does not exist at this version. + +-- a2/go.mod -- +module example.net/a + +go 1.15 +-- a2/p/p.go -- +// Package p exists only at v0.2.0. +package p diff --git a/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt b/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt new file mode 100644 index 0000000..241a0c2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt @@ -0,0 +1,10 @@ +# Check that we can build a module with no tagged versions by querying +# "@latest" through a proxy. +# Verifies golang.org/issue/32636 + +env GO111MODULE=on + +go mod init m +go get -d example.com/notags +go list -m all +stdout '^example.com/notags v0.0.0-20190507143103-cc8cbe209b64$' diff --git a/src/cmd/go/testdata/script/mod_get_local.txt b/src/cmd/go/testdata/script/mod_get_local.txt new file mode 100644 index 0000000..eb09da5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_local.txt @@ -0,0 +1,62 @@ +# Test 'go get' with a local module with a name that is not valid for network lookup. +[short] skip + +env GO111MODULE=on +go mod edit -fmt +cp go.mod go.mod.orig + +# 'go get -u' within the main module should work, even if it has a local-only name. +cp go.mod.orig go.mod +go get -d -u ./... +grep 'rsc.io/quote.*v1.5.2' go.mod +grep 'golang.org/x/text.*v0.3.0' go.mod +cp go.mod go.mod.implicitmod + +# 'go get -u local/...' should be equivalent to 'go get -u ./...' +# (assuming no nested modules) +cp go.mod.orig go.mod +go get -d -u local/... +cmp go.mod go.mod.implicitmod + +# For the main module, @patch should be a no-op. +cp go.mod.orig go.mod +go get -d -u local/...@patch +cmp go.mod go.mod.implicitmod + +# 'go get -u -d' in the empty root of the main module should fail. +# 'go get -u -d .' should also fail. +cp go.mod.orig go.mod +! go get -u -d +! go get -u -d . + +# 'go get -u -d .' within a package in the main module updates the dependencies +# of that package. +cp go.mod.orig go.mod +cd uselang +go get -u -d . +cd .. +grep 'rsc.io/quote.*v1.3.0' go.mod +grep 'golang.org/x/text.*v0.3.0' go.mod +cp go.mod go.mod.dotpkg + +# 'go get -u -d' with an explicit package in the main module updates the +# dependencies of that package. +cp go.mod.orig go.mod +go get -u -d local/uselang +cmp go.mod go.mod.dotpkg + +-- go.mod -- +module local + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c + rsc.io/quote v1.3.0 +) + +-- uselang/uselang.go -- +package uselang +import _ "golang.org/x/text/language" + +-- usequote/usequote.go -- +package usequote +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_main.txt b/src/cmd/go/testdata/script/mod_get_main.txt new file mode 100644 index 0000000..50b2fee --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_main.txt @@ -0,0 +1,51 @@ +env GO111MODULE=on +cp go.mod.orig go.mod + +# relative and absolute paths must be within the main module. +! go get -d .. +stderr '^go get: \.\. \('$WORK'[/\\]gopath\) is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' +! go get -d $WORK +stderr '^go get: '$WORK' is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' +! go get -d ../... +stderr '^go get: \.\./\.\.\. \('$WORK'[/\\]gopath([/\\]...)?\) is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' +! go get -d $WORK/... +stderr '^go get: '$WORK'[/\\]\.\.\. is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' + +# @patch and @latest within the main module refer to the current version. +# The main module won't be upgraded, but missing dependencies will be added. +go get -d rsc.io/x +grep 'rsc.io/quote v1.5.2' go.mod +go get -d rsc.io/x@upgrade +grep 'rsc.io/quote v1.5.2' go.mod +cp go.mod.orig go.mod +go get -d rsc.io/x@patch +grep 'rsc.io/quote v1.5.2' go.mod +cp go.mod.orig go.mod + + +# Upgrading a package pattern not contained in the main module should not +# attempt to upgrade the main module. +go get -d rsc.io/quote/...@v1.5.1 +grep 'rsc.io/quote v1.5.1' go.mod + + +# The main module cannot be updated to a specific version. +! go get -d rsc.io@v0.1.0 +stderr '^go get: can''t request version "v0.1.0" of the main module \(rsc.io\)$' + +# A package in the main module can't be upgraded either. +! go get -d rsc.io/x@v0.1.0 +stderr '^go get: package rsc.io/x is in the main module, so can''t request version v0.1.0$' + +# Nor can a pattern matching packages in the main module. +! go get -d rsc.io/x/...@latest +stderr '^go get: pattern rsc.io/x/... matches package rsc.io/x in the main module, so can''t request version latest$' + +-- go.mod.orig -- +module rsc.io + +go 1.13 +-- x/x.go -- +package x + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_major.txt b/src/cmd/go/testdata/script/mod_get_major.txt new file mode 100644 index 0000000..367ede9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_major.txt @@ -0,0 +1,23 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# golang.org/issue/34383: if a module path ends in a major-version suffix, +# ensure that 'direct' mode can resolve the package to a module. + +go get -d vcs-test.golang.org/git/v3pkg.git/v3@v3.0.0 + +go list -m vcs-test.golang.org/git/v3pkg.git/v3 +stdout '^vcs-test.golang.org/git/v3pkg.git/v3 v3.0.0$' + +go get -d vcs-test.golang.org/git/empty-v2-without-v1.git/v2@v2.0.0 + +go list -m vcs-test.golang.org/git/empty-v2-without-v1.git/v2 +stdout '^vcs-test.golang.org/git/empty-v2-without-v1.git/v2 v2.0.0$' + +-- go.mod -- +module example.com +go 1.13 diff --git a/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt b/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt new file mode 100644 index 0000000..8f6793e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt @@ -0,0 +1,55 @@ +# Test that if the module cache contains an extracted source directory but not +# a ziphash, 'go build' complains about a missing sum, and 'go get' adds +# the sum. Verifies #44749. + +# With a tidy go.sum, go build succeeds. This also populates the module cache. +cp go.sum.tidy go.sum +go build -n use +env GOPROXY=off +env GOSUMDB=off + +# Control case: if we delete the hash for rsc.io/quote v1.5.2, +# 'go build' reports an error. 'go get' adds the sum. +cp go.sum.bug go.sum +! go build -n use +stderr '^use.go:3:8: missing go.sum entry for module providing package rsc.io/quote \(imported by use\); to add:\n\tgo get use$' +go get -d use +cmp go.sum go.sum.tidy +go build -n use + +# If we delete the hash *and* the ziphash file, we should see the same behavior. +cp go.sum.bug go.sum +rm $WORK/gopath/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.ziphash +! go build -n use +stderr '^use.go:3:8: missing go.sum entry for module providing package rsc.io/quote \(imported by use\); to add:\n\tgo get use$' +go get -d use +cmp go.sum go.sum.tidy +go build -n use + +-- go.mod -- +module use + +go 1.17 + +require rsc.io/quote v1.5.2 +-- go.sum.tidy -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= +-- go.sum.bug -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_moved.txt b/src/cmd/go/testdata/script/mod_get_moved.txt new file mode 100644 index 0000000..8430a73 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_moved.txt @@ -0,0 +1,40 @@ +env GO111MODULE=on +[short] skip + +# A 'go get' that worked at a previous version should continue to work at that version, +# even if the package was subsequently moved into a submodule. +go mod init example.com/foo +go get -d example.com/split/subpkg@v1.0.0 +go list -m all +stdout 'example.com/split v1.0.0' + +# A 'go get' that simultaneously upgrades away conflicting package defitions is not ambiguous. +go get -d example.com/split/subpkg@v1.1.0 + +# A 'go get' without an upgrade should find the package. +rm go.mod +go mod init example.com/foo +go get -d example.com/split/subpkg +go list -m all +stdout 'example.com/split/subpkg v1.1.0' + + +# A 'go get' that worked at a previous version should continue to work at that version, +# even if the package was subsequently moved into a parent module. +rm go.mod +go mod init example.com/foo +go get -d example.com/join/subpkg@v1.0.0 +go list -m all +stdout 'example.com/join/subpkg v1.0.0' + +# A 'go get' that simultaneously upgrades away conflicting package definitions is not ambiguous. +# (A wildcard pattern applies to both packages and modules, +# because we define wildcard matching to apply after version resolution.) +go get -d example.com/join/subpkg/...@v1.1.0 + +# A 'go get' without an upgrade should find the package. +rm go.mod +go mod init example.com/foo +go get -d example.com/join/subpkg@v1.1.0 +go list -m all +stdout 'example.com/join v1.1.0' diff --git a/src/cmd/go/testdata/script/mod_get_newcycle.txt b/src/cmd/go/testdata/script/mod_get_newcycle.txt new file mode 100644 index 0000000..f71620c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_newcycle.txt @@ -0,0 +1,14 @@ +env GO111MODULE=on + +# Download modules to avoid stderr chatter +go mod download example.com@v1.0.0 +go mod download example.com/newcycle/a@v1.0.0 +go mod download example.com/newcycle/a@v1.0.1 +go mod download example.com/newcycle/b@v1.0.0 + +go mod init m +! go get example.com/newcycle/a@v1.0.0 +cmp stderr stderr-expected + +-- stderr-expected -- +go get: example.com/newcycle/a@v1.0.0 requires example.com/newcycle/a@v1.0.1, not example.com/newcycle/a@v1.0.0 diff --git a/src/cmd/go/testdata/script/mod_get_none.txt b/src/cmd/go/testdata/script/mod_get_none.txt new file mode 100644 index 0000000..b358f05 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_none.txt @@ -0,0 +1,12 @@ +env GO111MODULE=on + +go mod init example.com/foo + +# 'go get bar@none' should be a no-op if module bar is not active. +go get -d example.com/bar@none +go list -m all +! stdout example.com/bar + +go get -d example.com/bar@none +go list -m all +! stdout example.com/bar diff --git a/src/cmd/go/testdata/script/mod_get_nopkgs.txt b/src/cmd/go/testdata/script/mod_get_nopkgs.txt new file mode 100644 index 0000000..078e71a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_nopkgs.txt @@ -0,0 +1,40 @@ +cd subdir + +# 'go get' on empty patterns that are necessarily local to the module +# should warn that the patterns are empty, exactly once. + +go get ./... +stderr -count=1 'matched no packages' + +go get -d ./... +stderr -count=1 'matched no packages' + +# 'go get' on patterns that could conceivably match nested modules +# should report a module resolution error. + +go get -d example.net/emptysubdir/... # control case + +! go get -d example.net/emptysubdir/subdir/... +! stderr 'matched no packages' +stderr '^go get example\.net/emptysubdir/subdir/\.\.\.: module example\.net/emptysubdir/subdir: reading http://.*: 404 Not Found\n\tserver response: 404 page not found\n\z' + +# It doesn't make sense to 'go get' a path in the standard library, +# since the standard library necessarily can't have unresolved imports. +# +# TODO(#30241): Maybe that won't always be the case? +# +# For that case, we emit a "malformed module path" error message, +# which isn't ideal either. + +! go get -d builtin/... # in GOROOT/src, but contains no packages +stderr '^go get builtin/...: malformed module path "builtin": missing dot in first path element$' + +-- go.mod -- +module example.net/emptysubdir + +go 1.16 +-- emptysubdir.go -- +// Package emptysubdir has a subdirectory containing no packages. +package emptysubdir +-- subdir/README.txt -- +This module intentionally does not contain any p diff --git a/src/cmd/go/testdata/script/mod_get_patch.txt b/src/cmd/go/testdata/script/mod_get_patch.txt new file mode 100644 index 0000000..053ef62 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patch.txt @@ -0,0 +1,130 @@ +# This test examines the behavior of 'go get …@patch' +# See also mod_upgrade_patch.txt (focused on "-u=patch" specifically) +# and mod_get_patchmod.txt (focused on module/package ambiguities). + +cp go.mod go.mod.orig + +# example.net/b@patch refers to the patch for the version of b that was selected +# at the start of 'go get', not the version after applying other changes. + +! go get -d example.net/a@v0.2.0 example.net/b@patch +stderr '^go get: example.net/a@v0.2.0 requires example.net/b@v0.2.0, not example.net/b@patch \(v0.1.1\)$' +cmp go.mod go.mod.orig + + +# -u=patch changes the default version for other arguments to '@patch', +# but they continue to be resolved against the originally-selected version, +# not the updated one. +# +# TODO(#42360): Reconsider the change in defaults. + +! go get -d -u=patch example.net/a@v0.2.0 example.net/b +stderr '^go get: example.net/a@v0.2.0 requires example.net/b@v0.2.0, not example.net/b@patch \(v0.1.1\)$' +cmp go.mod go.mod.orig + + +# -u=patch refers to the patches for the selected versions of dependencies *after* +# applying other version changes, not the versions that were selected at the start. +# However, it should not patch versions determined by explicit arguments. + +go get -d -u=patch example.net/a@v0.2.0 +go list -m all +stdout '^example.net/a v0.2.0 ' +stdout '^example.net/b v0.2.1 ' + + +# "-u=patch all" should be equivalent to "all@patch", and should fail if the +# patched versions result in a higher-than-patch upgrade. + +cp go.mod.orig go.mod +! go get -u=patch all +stderr '^go get: example.net/a@v0.1.1 \(matching all@patch\) requires example.net/b@v0.2.0, not example.net/b@v0.1.1 \(matching all@patch\)$' +cmp go.mod go.mod.orig + + +# On the other hand, "-u=patch ./..." should patch-upgrade dependencies until +# they reach a fixed point, even if that results in higher-than-patch upgrades. + +go get -u=patch ./... +go list -m all +stdout '^example.net/a v0.1.1 ' +stdout '^example.net/b v0.2.1 ' + + +-- go.mod -- +module example + +go 1.16 + +require ( + example.net/a v0.1.0 + example.net/b v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/a v0.2.1 => ./a21 + example.net/b v0.1.0 => ./b + example.net/b v0.1.1 => ./b + example.net/b v0.2.0 => ./b + example.net/b v0.2.1 => ./b + example.net/b v0.3.0 => ./b + example.net/b v0.3.1 => ./b +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a10/a.go -- +package a + +import _ "example.net/b" + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 // upgraded +-- a11/a.go -- +package a + +import _ "example.net/b" + +-- a20/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 +-- a20/a.go -- +package a + +import _ "example.net/b" + +-- a21/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 // not upgraded +-- a21/a.go -- +package a + +import _ "example.net/b" + +-- b/go.mod -- +module example.net/b + +go 1.16 +-- b/b.go -- +package b diff --git a/src/cmd/go/testdata/script/mod_get_patchbound.txt b/src/cmd/go/testdata/script/mod_get_patchbound.txt new file mode 100644 index 0000000..4fd1ec5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchbound.txt @@ -0,0 +1,84 @@ +# -u=patch will patch dependencies as far as possible, but not so far that they +# conflict with other command-line arguments. + +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' + +go get -d -u=patch example.net/a@v0.2.0 +go list -m all +stdout '^example.net/a v0.2.0 ' +stdout '^example.net/b v0.1.1 ' # not v0.1.2, which requires …/a v0.3.0. + +-- go.mod -- +module example + +go 1.16 + +require ( + example.net/a v0.1.0 + example.net/b v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/a v0.3.0 => ./a + example.net/b v0.1.0 => ./b10 + example.net/b v0.1.1 => ./b11 + example.net/b v0.1.2 => ./b12 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a/a.go -- +package a + +import _ "example.net/b" + +-- b10/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.1.0 +-- b10/b.go -- +package b +-- b10/b_test.go -- +package b_test + +import _ "example.net/a" + +-- b11/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b11/b.go -- +package b +-- b11/b_test.go -- +package b_test + +import _ "example.net/a" + +-- b12/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.3.0 +-- b12/b.go -- +package b +-- b12/b_test.go -- +package b_test + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_get_patchcycle.txt b/src/cmd/go/testdata/script/mod_get_patchcycle.txt new file mode 100644 index 0000000..d1db56f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchcycle.txt @@ -0,0 +1,64 @@ +# If a patch of a module requires a higher version of itself, +# it should be reported as its own conflict. +# +# This case is weird and unlikely to occur often at all, but it should not +# spuriously succeed. +# (It used to print v0.1.1 but then silently upgrade to v0.2.0.) + +! go get example.net/a@patch +stderr '^go get: example.net/a@patch \(v0.1.1\) requires example.net/a@v0.2.0, not example.net/a@patch \(v0.1.1\)$' # TODO: A mention of b v0.1.0 would be nice. + +-- go.mod -- +module example + +go 1.16 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/b v0.1.0 => ./b10 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 +-- a10/a.go -- +package a + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a11/a.go -- +package a + +import _ "example.net/b" + +-- a20/go.mod -- +module example.net/a + +go 1.16 +-- a20/a.go -- +package a + + +-- b10/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b10/b.go -- +package b + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_get_patchmod.txt b/src/cmd/go/testdata/script/mod_get_patchmod.txt new file mode 100644 index 0000000..e39d13a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchmod.txt @@ -0,0 +1,82 @@ +# example.net/pkgremoved@v0.1.0 refers to a package. +go get -d example.net/pkgremoved@v0.1.0 + +go list example.net/pkgremoved +stdout '^example.net/pkgremoved' + +cp go.mod go.mod.orig + + +# When we resolve a new dependency on example.net/other, +# it will change the meaning of the path "example.net/pkgremoved" +# from a package (at v0.1.0) to only a module (at v0.2.0). +# +# If we simultaneously 'get' that module at the query "patch", the module should +# be constrained to the latest patch of its originally-selected version (v0.1.0), +# not upgraded to the latest patch of the new transitive dependency. + +! go get -d example.net/pkgremoved@patch example.net/other@v0.1.0 +stderr '^go get: example.net/other@v0.1.0 requires example.net/pkgremoved@v0.2.0, not example.net/pkgremoved@patch \(v0.1.1\)$' +cmp go.mod.orig go.mod + + +# However, we should be able to patch from a package to a module and vice-versa. + +# Package to module ... + +go get -d example.net/pkgremoved@v0.3.0 +go list example.net/pkgremoved +stdout 'example.net/pkgremoved' + +go get -d example.net/pkgremoved@patch +! go list example.net/pkgremoved + +# ... and module to package. + +go get -d example.net/pkgremoved@v0.4.0 +! go list example.net/pkgremoved + +go get -d example.net/pkgremoved@patch +go list example.net/pkgremoved +stdout 'example.net/pkgremoved' + + +-- go.mod -- +module example + +go 1.16 + +replace ( + example.net/other v0.1.0 => ./other + + example.net/pkgremoved v0.1.0 => ./prpkg + example.net/pkgremoved v0.1.1 => ./prpkg + + example.net/pkgremoved v0.2.0 => ./prmod + example.net/pkgremoved v0.2.1 => ./prmod + + example.net/pkgremoved v0.3.0 => ./prpkg + example.net/pkgremoved v0.3.1 => ./prmod + + example.net/pkgremoved v0.4.0 => ./prmod + example.net/pkgremoved v0.4.1 => ./prpkg +) +-- other/go.mod -- +module example.net/other + +go 1.16 + +require example.net/pkgremoved v0.2.0 +-- other/other.go -- +package other +-- prpkg/go.mod -- +module example.net/pkgremoved + +go 1.16 +-- prpkg/pkgremoved.go -- +package pkgremoved +-- prmod/go.mod -- +module example.net/pkgremoved +-- prmod/README.txt -- +Package pkgremoved was removed in v0.2.0 and v0.3.1, +and added in v0.1.0 and v0.4.1. diff --git a/src/cmd/go/testdata/script/mod_get_patterns.txt b/src/cmd/go/testdata/script/mod_get_patterns.txt new file mode 100644 index 0000000..aee4374 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patterns.txt @@ -0,0 +1,42 @@ +env GO111MODULE=on +[short] skip + +# If a pattern doesn't match any packages provided by modules +# in the build list, we assume the pattern matches a single module +# whose path is a prefix of the part of the pattern before "...". +cp go.mod.orig go.mod +go get -d rsc.io/quote/... +grep 'require rsc.io/quote' go.mod + +cp go.mod.orig go.mod +! go get -d rsc.io/quote/x... +stderr 'go get: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x...' +! grep 'require rsc.io/quote' go.mod + +! go get -d rsc.io/quote/x/... +stderr 'go get: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x/...' +! grep 'require rsc.io/quote' go.mod + +# If a pattern matches no packages within a module, the module should not +# be upgraded, even if the module path is a prefix of the pattern. +cp go.mod.orig go.mod +go mod edit -require example.com/nest@v1.0.0 +go get -d example.com/nest/sub/y... +grep 'example.com/nest/sub v1.0.0' go.mod +grep 'example.com/nest v1.0.0' go.mod + +# However, if the pattern matches the module path itself, the module +# should be upgraded even if it contains no matching packages. +go get -d example.com/n...t +grep 'example.com/nest v1.1.0' go.mod +grep 'example.com/nest/sub v1.0.0' go.mod + +-- go.mod.orig -- +module m + +go 1.13 + +-- use/use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_pkgtags.txt b/src/cmd/go/testdata/script/mod_get_pkgtags.txt new file mode 100644 index 0000000..c0a57f3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_pkgtags.txt @@ -0,0 +1,116 @@ +# https://golang.org/issue/44106 +# 'go get' should fetch the transitive dependencies of packages regardless of +# tags, but shouldn't error out if the package is missing tag-guarded +# dependencies. + +# Control case: just adding the top-level module to the go.mod file does not +# fetch its dependencies. + +go mod edit -require example.net/tools@v0.1.0 +! go list -deps example.net/cmd/tool +stderr '^module example\.net/cmd provides package example\.net/cmd/tool and is replaced but not required; to add it:\n\tgo get example\.net/cmd@v0\.1\.0$' +go mod edit -droprequire example.net/tools + + +# 'go get -d' makes a best effort to fetch those dependencies, but shouldn't +# error out if dependencies of tag-guarded files are missing. + +go get -d example.net/tools@v0.1.0 + +! go list example.net/tools +stderr '^package example.net/tools: build constraints exclude all Go files in .*[/\\]tools$' + +go list -tags=tools -e -deps example.net/tools +stdout '^example.net/cmd/tool$' +stdout '^example.net/missing$' + +go list -deps example.net/cmd/tool + +! go list example.net/missing +stderr '^no required module provides package example.net/missing; to add it:\n\tgo get example.net/missing$' + + +# https://golang.org/issue/29268 +# 'go get' should fetch modules whose roots contain test-only packages, but +# without the -t flag shouldn't error out if the test has missing dependencies. + +go get -d example.net/testonly@v0.1.0 + +# With the -t flag, the test dependencies must resolve successfully. +! go get -d -t example.net/testonly@v0.1.0 +stderr '^example.net/testonly tested by\n\texample.net/testonly\.test imports\n\texample.net/missing: cannot find module providing package example.net/missing$' + + +# 'go get -d' should succeed for a module path that does not contain a package, +# but fail for a non-package subdirectory of a module. + +! go get -d example.net/missing/subdir@v0.1.0 +stderr '^go get: module example.net/missing@v0.1.0 found \(replaced by ./missing\), but does not contain package example.net/missing/subdir$' + +go get -d example.net/missing@v0.1.0 + + +# Getting the subdirectory should continue to fail even if the corresponding +# module is already present in the build list. + +! go get -d example.net/missing/subdir@v0.1.0 +stderr '^go get: module example.net/missing@v0.1.0 found \(replaced by ./missing\), but does not contain package example.net/missing/subdir$' + + +-- go.mod -- +module example.net/m + +go 1.15 + +replace ( + example.net/tools v0.1.0 => ./tools + example.net/cmd v0.1.0 => ./cmd + example.net/testonly v0.1.0 => ./testonly + example.net/missing v0.1.0 => ./missing +) + +-- tools/go.mod -- +module example.net/tools + +go 1.15 + +// Requirements intentionally omitted. + +-- tools/tools.go -- +// +build tools + +package tools + +import ( + _ "example.net/cmd/tool" + _ "example.net/missing" +) + +-- cmd/go.mod -- +module example.net/cmd + +go 1.16 +-- cmd/tool/tool.go -- +package main + +func main() {} + +-- testonly/go.mod -- +module example.net/testonly + +go 1.15 +-- testonly/testonly_test.go -- +package testonly_test + +import _ "example.net/missing" + +func Test(t *testing.T) {} + +-- missing/go.mod -- +module example.net/missing + +go 1.15 +-- missing/README.txt -- +There are no Go source files here. +-- missing/subdir/README.txt -- +There are no Go source files here either. diff --git a/src/cmd/go/testdata/script/mod_get_prefer_incompatible.txt b/src/cmd/go/testdata/script/mod_get_prefer_incompatible.txt new file mode 100644 index 0000000..be3db42 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_prefer_incompatible.txt @@ -0,0 +1,29 @@ +# Verifies golang.org/issue/37574. + +# If we are already using an +incompatible version, we shouldn't look up +# a lower compatible version when upgrading. +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod +grep '^example.com/incompatiblewithsub v2\.0\.0\+incompatible' go.sum +! grep '^example.com/incompatiblewithsub v1.0.0' go.sum + +go get -d example.com/incompatiblewithsub/sub +cmp go.mod.orig go.mod +! grep '^example.com/incompatiblewithsub v1.0.0' go.sum + +# TODO(golang.org/issue/31580): the 'go get' command above should not change +# go.sum. However, as part of the query above, we download example.com@v1.0.0, +# an unrelated module, since it's a possible prefix. The sum for that module +# should not be written to go.sum. + +-- go.mod -- +module m + +go 1.15 + +require example.com/incompatiblewithsub v2.0.0+incompatible +-- use.go -- +package use + +import _ "example.com/incompatiblewithsub/sub" diff --git a/src/cmd/go/testdata/script/mod_get_private_vcs.txt b/src/cmd/go/testdata/script/mod_get_private_vcs.txt new file mode 100644 index 0000000..514b0a7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_private_vcs.txt @@ -0,0 +1,11 @@ +env GO111MODULE=on + +# Testing stderr for git ls-remote; turn off proxy. +[!net] skip +[!exec:git] skip +env GOPROXY=direct + +! go get github.com/golang/nonexist +stderr 'Confirm the import path was entered correctly.' +stderr 'If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.' +! stdout . diff --git a/src/cmd/go/testdata/script/mod_get_promote_implicit.txt b/src/cmd/go/testdata/script/mod_get_promote_implicit.txt new file mode 100644 index 0000000..10ca659 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_promote_implicit.txt @@ -0,0 +1,92 @@ +cp go.mod.orig go.mod + +# If we list a package in an implicit dependency imported from the main module, +# we should get an error because the dependency should have an explicit +# requirement. +go list -m indirect-with-pkg +stdout '^indirect-with-pkg v1.0.0 => ./indirect-with-pkg$' +! go list ./use-indirect +stderr '^go: m/use-indirect: package indirect-with-pkg imported from implicitly required module; to add missing requirements, run:\n\tgo get indirect-with-pkg@v1.0.0$' + +# We can promote the implicit requirement by getting the importing package. +# NOTE: the hint recommends getting the imported package (tested below) since +# it's more obvious and doesn't require -d. However, that adds an '// indirect' +# comment on the requirement. +go get -d m/use-indirect +cmp go.mod go.mod.use +cp go.mod.orig go.mod + +# We can also promote implicit requirements using 'go get' on them, or their +# packages. This gives us "// indirect" requirements, since 'go get' doesn't +# know they're needed by the main module. See #43131 for the rationale. +# The hint above recommends this because it's more obvious usage and doesn't +# require the -d flag. +go get -d indirect-with-pkg indirect-without-pkg +cmp go.mod go.mod.indirect + +-- go.mod.orig -- +module m + +go 1.16 + +require direct v1.0.0 + +replace ( + direct v1.0.0 => ./direct + indirect-with-pkg v1.0.0 => ./indirect-with-pkg + indirect-without-pkg v1.0.0 => ./indirect-without-pkg +) +-- go.mod.use -- +module m + +go 1.16 + +require ( + direct v1.0.0 + indirect-with-pkg v1.0.0 +) + +replace ( + direct v1.0.0 => ./direct + indirect-with-pkg v1.0.0 => ./indirect-with-pkg + indirect-without-pkg v1.0.0 => ./indirect-without-pkg +) +-- go.mod.indirect -- +module m + +go 1.16 + +require ( + direct v1.0.0 + indirect-with-pkg v1.0.0 // indirect + indirect-without-pkg v1.0.0 // indirect +) + +replace ( + direct v1.0.0 => ./direct + indirect-with-pkg v1.0.0 => ./indirect-with-pkg + indirect-without-pkg v1.0.0 => ./indirect-without-pkg +) +-- use-indirect/use-indirect.go -- +package use + +import _ "indirect-with-pkg" +-- direct/go.mod -- +module direct + +go 1.16 + +require ( + indirect-with-pkg v1.0.0 + indirect-without-pkg v1.0.0 +) +-- indirect-with-pkg/go.mod -- +module indirect-with-pkg + +go 1.16 +-- indirect-with-pkg/p.go -- +package p +-- indirect-without-pkg/go.mod -- +module indirect-without-pkg + +go 1.16 diff --git a/src/cmd/go/testdata/script/mod_get_pseudo.txt b/src/cmd/go/testdata/script/mod_get_pseudo.txt new file mode 100644 index 0000000..582837a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_pseudo.txt @@ -0,0 +1,82 @@ +env GO111MODULE=on + +# Testing git->module converter's generation of +incompatible tags; turn off proxy. +[!net] skip +[!exec:git] skip +env GOPROXY=direct +env GOSUMDB=off + +# We can resolve the @master branch without unshallowing the local repository +# (even with older gits), so try that before we do anything else. +# (This replicates https://golang.org/issue/26713 with git 2.7.4.) +go get -d github.com/rsc/legacytest@master +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.1-0\.\d{14}-7303f7796364\+incompatible$' + +# get should include incompatible tags in "latest" calculation. +go mod edit -droprequire github.com/rsc/legacytest +go get -d github.com/rsc/legacytest@latest +go list +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.0\+incompatible$' + +# v2.0.1-0.pseudo+incompatible +go get -d ...test@7303f77 +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.1-0\.\d{14}-7303f7796364\+incompatible$' + +# v2.0.0+incompatible by tag+incompatible +go get -d ...test@v2.0.0+incompatible +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.0\+incompatible$' + +# v2.0.0+incompatible by tag +go get -d ...test@v2.0.0 +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.0\+incompatible$' + +# v2.0.0+incompatible by hash (back on master) +go get -d ...test@d7ae1e4 +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.0\+incompatible$' + +# v1.2.1-0.pseudo +go get -d ...test@d2d4c3e +go list -m all +stdout '^github.com/rsc/legacytest v1\.2\.1-0\.\d{14}-d2d4c3ea6623$' + +# v1.2.0 +go get -d ...test@9f6f860 +go list -m all +stdout '^github.com/rsc/legacytest v1\.2\.0$' + +# v1.1.0-pre.0.pseudo +go get -d ...test@fb3c628 +go list -m all +stdout '^github.com/rsc/legacytest v1\.1\.0-pre\.0\.\d{14}-fb3c628075e3$' + +# v1.1.0-pre (no longer on master) +go get -d ...test@731e3b1 +go list -m all +stdout '^github.com/rsc/legacytest v1\.1\.0-pre$' + +# v1.0.1-0.pseudo +go get -d ...test@fa4f5d6 +go list -m all +stdout '^github.com/rsc/legacytest v1\.0\.1-0\.\d{14}-fa4f5d6a71c6$' + +# v1.0.0 +go get -d ...test@7fff7f3 +go list -m all +stdout '^github.com/rsc/legacytest v1\.0\.0$' + +# v0.0.0-pseudo +go get -d ...test@52853eb +go list -m all +stdout '^github.com/rsc/legacytest v0\.0\.0-\d{14}-52853eb7b552$' + +-- go.mod -- +module x +-- x.go -- +package x +import "github.com/rsc/legacytest" diff --git a/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt b/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt new file mode 100644 index 0000000..0fbd041 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt @@ -0,0 +1,67 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Testing that a pseudo-version is based on the semantically-latest +# tag that appears in any commit that is a (transitive) parent of the commit +# supplied to 'go get', regardless of branches + +[!net] skip +[!exec:git] skip + +# For this test repository: +# tag v0.2.1 is most recent tag on master itself +# tag v0.2.2 is on branch2, which was then merged to master +# master is a merge commit with both tags as parents +# +# The pseudo-version hence sorts immediately after v0.2.2 rather +# than v0.2.1, even though the v0.2.2 tag is not on master. + +go get -d vcs-test.golang.org/git/tagtests.git@master +go list -m all +stdout '^vcs-test.golang.org/git/tagtests.git v0.2.3-0\.' + +-- go.mod -- +module x + +go 1.12 +-- x.go -- +package x + +import _ "vcs-test.golang.org/git/tagtests.git" +-- gen_testtags.sh -- +#!/bin/bash + +# This is not part of the test. +# Run this to generate and update the repository on vcs-test.golang.org. + +set -euo pipefail +cd "$(dirname "$0")" +rm -rf tagtests +mkdir tagtests +cd tagtests + +git init +echo module vcs-test.golang.org/git/tagtests.git >go.mod +echo package tagtests >tagtests.go +git add go.mod tagtests.go +git commit -m 'create module tagtests' + +git branch b + +echo v0.2.1 >v0.2.1 +git add v0.2.1 +git commit -m v0.2.1 +git tag v0.2.1 + +git checkout b +echo v0.2.2 >v0.2.2 +git add v0.2.2 +git commit -m v0.2.2 +git tag v0.2.2 + +git checkout master +git merge b -m merge + +zip -r ../tagtests.zip . +gsutil cp ../tagtests.zip gs://vcs-test/git/tagtests.zip diff --git a/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt b/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt new file mode 100644 index 0000000..b78e6e6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt @@ -0,0 +1,64 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Testing that a pseudo-version is based on the semantically-latest +# prefixed tag in any commit that is a parent of the commit supplied +# to 'go get', when using a repo with go.mod in a sub directory. + +[!net] skip +[!exec:git] skip + +# For this test repository go.mod resides in sub/ (only): +# master is not tagged +# tag v0.2.0 is most recent tag before master +# tag sub/v0.0.10 is most recent tag before v0.2.0 +# +# The pseudo-version is based on sub/v0.0.10, since v0.2.0 doesn't +# contain the prefix. +go get -d vcs-test.golang.org/git/prefixtagtests.git/sub +go list -m all +stdout '^vcs-test.golang.org/git/prefixtagtests.git/sub v0.0.10$' + +go get -d -u vcs-test.golang.org/git/prefixtagtests.git/sub@master +go list -m all +stdout '^vcs-test.golang.org/git/prefixtagtests.git/sub v0.0.11-0\.' + +-- go.mod -- +module x + +go 1.12 +-- x.go -- +package x + +import _ "vcs-test.golang.org/prefixtagtests.git/sub" +-- gen_prefixtagtests.sh -- +#!/bin/bash + +# This is not part of the test. +# Run this to generate and update the repository on vcs-test.golang.org. + +set -euo pipefail +cd "$(dirname "$0")" +rm -rf prefixtagtests +mkdir prefixtagtests +cd prefixtagtests + +git init +mkdir sub +echo module vcs-test.golang.org/git/prefixtagtests.git/sub >sub/go.mod +echo package sub >sub/sub.go +git add sub +git commit -m 'create module sub' +for i in v0.1.0 sub/v0.0.9 sub/v0.0.10 v0.2.0; do + echo $i >status + git add status + git commit -m $i + git tag $i +done +echo 'after last tag' >status +git add status +git commit -m 'after last tag' + +zip -r ../prefixtagtests.zip . +gsutil cp ../prefixtagtests.zip gs://vcs-test/git/prefixtagtests.zip diff --git a/src/cmd/go/testdata/script/mod_get_replaced.txt b/src/cmd/go/testdata/script/mod_get_replaced.txt new file mode 100644 index 0000000..d97f3f1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_replaced.txt @@ -0,0 +1,111 @@ +cp go.mod go.mod.orig + +env oldGOPROXY=$GOPROXY + +# If a wildcard replacement exists for an otherwise-nonexistent module, +# 'go get' should resolve it to the minimum valid pseudo-version. + +go mod edit -replace=example.com/x=./x +go get -d example.com/x + +go list -m example.com/x +stdout '^example.com/x v0.0.0-00010101000000-000000000000 ' + +# If specific-version replacements exist, the highest matching version should be used. +go mod edit -replace=example.com/x@v0.1.0=./x +go mod edit -replace=example.com/x@v0.2.0=./x + +go get -d example.com/x +go list -m example.com/x +stdout '^example.com/x v0.2.0 ' + +go get -d example.com/x@<v0.2.0 +go list -m example.com/x +stdout '^example.com/x v0.1.0 ' + + +# The same should work with GOPROXY=off. + +env GOPROXY=off +cp go.mod.orig go.mod + +go mod edit -replace=example.com/x=./x +go get -d example.com/x + +go list -m example.com/x +stdout '^example.com/x v0.0.0-00010101000000-000000000000 ' + +# If specific-version replacements exist, the highest matching version should be used. +go mod edit -replace=example.com/x@v0.1.0=./x +go mod edit -replace=example.com/x@v0.2.0=./x + +go get -d example.com/x +go list -m example.com/x +stdout '^example.com/x v0.2.0 ' + +go get -d example.com/x@<v0.2.0 +go list -m example.com/x +stdout '^example.com/x v0.1.0 ' + + +# Replacements should also be listed as known versions, and 'go get' should sort +# them in with ordinary versions. + +env GOPROXY=$oldGOPROXY + +cp go.mod.orig go.mod +go list -versions -m rsc.io/quote +stdout 'v1.3.0 v1.4.0' + +go get -d rsc.io/quote@v1.3 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.3.0' + +go mod edit -replace rsc.io/quote@v1.3.1=rsc.io/quote@v1.4.0 + +go list -versions -m rsc.io/quote +stdout 'v1.3.0 v1.3.1 v1.4.0' + +go get -d rsc.io/quote@v1.3 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.3.1 ' + +go get -d rsc.io/quote@>v1.3.1 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.4.0' + + +# Replacements should allow 'go get' to work even with dotless module paths. + +cp go.mod.orig go.mod + +! go list example +stderr '^package example is not in GOROOT \(.*\)$' +! go get -d example +stderr '^go get: malformed module path "example": missing dot in first path element$' + +go mod edit -replace example@v0.1.0=./example + +! go list example +stderr '^module example provides package example and is replaced but not required; to add it:\n\tgo get example@v0.1.0$' + +go get -d example +go list -m example +stdout '^example v0.1.0 ' + + +-- go.mod -- +module example.com + +go 1.16 +-- x/go.mod -- +module example.com/x + +go 1.16 +-- x/x.go -- +package x +-- example/go.mod -- +module example +go 1.16 +-- example/example.go -- +package example diff --git a/src/cmd/go/testdata/script/mod_get_retract.txt b/src/cmd/go/testdata/script/mod_get_retract.txt new file mode 100644 index 0000000..560fa7b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_retract.txt @@ -0,0 +1,59 @@ +# 'go get pkg' should not upgrade to a retracted version. +cp go.mod.orig go.mod +go mod edit -require example.com/retract/self/prev@v1.1.0 +go get -d example.com/retract/self/prev +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.1.0$' + +# 'go get pkg' should not downgrade from a retracted version when no higher +# version is available. +cp go.mod.orig go.mod +go mod edit -require example.com/retract/self/prev@v1.9.0 +go get -d example.com/retract/self/prev +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' +stderr '^go: to switch to the latest unretracted version, run:\n\tgo get example.com/retract/self/prev@latest\n$' +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.9.0$' + +# 'go get pkg@latest' should downgrade from a retracted version. +cp go.mod.orig go.mod +go mod edit -require example.com/retract/self/prev@v1.9.0 +go get -d example.com/retract/self/prev@latest +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.1.0$' + +# 'go get pkg@version' should update to a specific version, even if that +# version is retracted. +cp go.mod.orig go.mod +go get -d example.com/retract@v1.0.0-bad +stderr '^go: warning: example.com/retract@v1.0.0-bad: retracted by module author: bad$' +go list -m example.com/retract +stdout '^example.com/retract v1.0.0-bad$' + +# 'go get -u' should not downgrade from a retracted version when no higher +# version is available. +cp go.mod.orig go.mod +go mod edit -require example.com/retract/self/prev@v1.9.0 +go get -d -u ./use +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.9.0$' + +# 'go get' should warn if a module needed to build named packages is retracted. +# 'go get' should not warn about unrelated modules. +go get -d ./empty +! stderr retracted +go get -d ./use +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' + +-- go.mod.orig -- +module example.com/use + +go 1.15 + +-- use/use.go -- +package use + +import _ "example.com/retract/self/prev" +-- empty/empty.go -- +package empty diff --git a/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt b/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt new file mode 100644 index 0000000..b49ba54 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt @@ -0,0 +1,10 @@ +! go get -d example.com/retract/ambiguous/other +stderr 'ambiguous import: found package example.com/retract/ambiguous/nested in multiple modules:' +stderr '^go: warning: example.com/retract/ambiguous/nested@v1.9.0-bad: retracted by module author: nested modules are bad$' + +-- go.mod -- +module example.com/use + +go 1.16 + +require example.com/retract/ambiguous/nested v1.9.0-bad diff --git a/src/cmd/go/testdata/script/mod_get_split.txt b/src/cmd/go/testdata/script/mod_get_split.txt new file mode 100644 index 0000000..f4e7661 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_split.txt @@ -0,0 +1,157 @@ +cp go.mod go.mod.orig + + +# 'go get' on a package already provided by the build list should update +# the module already in the build list, not fail with an ambiguous import error. + +go get -d example.net/split/nested@patch +go list -m all +stdout '^example.net/split v0.2.1 ' +! stdout '^example.net/split/nested' + +# We should get the same behavior if we use a pattern that matches only that package. + +cp go.mod.orig go.mod + +go get -d example.net/split/nested/...@patch +go list -m all +stdout '^example.net/split v0.2.1 ' +! stdout '^example.net/split/nested' + + +# If we request a version for which the package only exists in one particular module, +# we should add that one particular module but not resolve import ambiguities. +# +# In particular, if the module that previously provided the package has a +# matching version, but does not itself match the pattern and contains no +# matching packages, we should not change its version. (We should *not* downgrade +# module example.net/split to v0.1.0, despite the fact that +# example.net/split v0.2.0 currently provides the package with the requested path.) +# +# TODO(#27899): Maybe we should resolve the ambiguities by upgrading. + +cp go.mod.orig go.mod + +! go get -d example.net/split/nested@v0.1.0 +stderr '^example.net/split/nested: ambiguous import: found package example.net/split/nested in multiple modules:\n\texample.net/split v0.2.0 \(.*split.2[/\\]nested\)\n\texample.net/split/nested v0.1.0 \(.*nested.1\)$' + +# A wildcard that matches packages in some module at its selected version +# but not at the requested version should fail. +# +# We can't set the module to the selected version, because that version doesn't +# even match the query: if we ran the same query twice, we wouldn't consider the +# module to match the wildcard during the second call, so why should we consider +# it to match during the first one? ('go get' should be idempotent, and if we +# did that then it would not be.) +# +# But we also can't leave it where it is: the user requested that we set everything +# matching the pattern to the given version, and right now we have packages +# that match the pattern but *not* the version. +# +# That only leaves two options: we can set the module to an arbitrary version +# (perhaps 'latest' or 'none'), or we can report an error and the let the user +# disambiguate. We would rather not choose arbitrarily, so we do the latter. +# +# TODO(#27899): Should we instead upgrade or downgrade to an arbirary version? + +! go get -d example.net/split/nested/...@v0.1.0 +stderr '^go get: example.net/split/nested/\.\.\.@v0.1.0 matches packages in example.net/split@v0.2.0 but not example.net/split@v0.1.0: specify a different version for module example.net/split$' + +cmp go.mod go.mod.orig + + +# If another argument resolves the ambiguity, we should be ok again. + +go get -d example.net/split@none example.net/split/nested@v0.1.0 +go list -m all +! stdout '^example.net/split ' +stdout '^example.net/split/nested v0.1.0 ' + +cp go.mod.orig go.mod + +go get -d example.net/split@v0.3.0 example.net/split/nested@v0.1.0 +go list -m all +stdout '^example.net/split v0.3.0 ' +stdout '^example.net/split/nested v0.1.0 ' + + +# If a pattern applies to modules and to packages, we should set all matching +# modules to the version indicated by the pattern, and also resolve packages +# to match the pattern if possible. + +cp go.mod.orig go.mod +go get -d example.net/split/nested@v0.0.0 + +go get -d example.net/...@v0.1.0 +go list -m all +stdout '^example.net/split v0.1.0 ' +stdout '^example.net/split/nested v0.1.0 ' + +go get -d example.net/... +go list -m all +stdout '^example.net/split v0.3.0 ' +stdout '^example.net/split/nested v0.2.0 ' + + +# @none applies to all matching module paths, +# regardless of whether they contain any packages. + +go get -d example.net/...@none +go list -m all +! stdout '^example.net' + +# Starting from no dependencies, a wildcard can resolve to an empty module with +# the same prefix even if it contains no packages. + +go get -d example.net/...@none +go get -d example.net/split/...@v0.1.0 +go list -m all +stdout '^example.net/split v0.1.0 ' + + +-- go.mod -- +module m + +go 1.16 + +require example.net/split v0.2.0 + +replace ( + example.net/split v0.1.0 => ./split.1 + example.net/split v0.2.0 => ./split.2 + example.net/split v0.2.1 => ./split.2 + example.net/split v0.3.0 => ./split.3 + example.net/split/nested v0.0.0 => ./nested.0 + example.net/split/nested v0.1.0 => ./nested.1 + example.net/split/nested v0.2.0 => ./nested.2 +) +-- split.1/go.mod -- +module example.net/split + +go 1.16 +-- split.2/go.mod -- +module example.net/split + +go 1.16 +-- split.2/nested/nested.go -- +package nested +-- split.3/go.mod -- +module example.net/split + +go 1.16 +-- nested.0/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.1/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.1/nested.go -- +package nested +-- nested.2/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.2/nested.go -- +package nested diff --git a/src/cmd/go/testdata/script/mod_get_sum_noroot.txt b/src/cmd/go/testdata/script/mod_get_sum_noroot.txt new file mode 100644 index 0000000..4f1cf03 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_sum_noroot.txt @@ -0,0 +1,11 @@ +# When 'go get' is invoked on a module without a package in the root directory, +# it should add sums for the module's go.mod file and its content to go.sum. +# Verifies golang.org/issue/41103. +go mod init m +go get -d rsc.io/QUOTE +grep '^rsc.io/QUOTE v1.5.2/go.mod ' go.sum +grep '^rsc.io/QUOTE v1.5.2 ' go.sum + +# Double-check rsc.io/QUOTE does not have a root package. +! go list -mod=readonly rsc.io/QUOTE +stderr '^cannot find module providing package rsc.io/QUOTE: import lookup disabled by -mod=readonly$' diff --git a/src/cmd/go/testdata/script/mod_get_svn.txt b/src/cmd/go/testdata/script/mod_get_svn.txt new file mode 100644 index 0000000..3817fce --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_svn.txt @@ -0,0 +1,36 @@ +[!net] skip +[!exec:svn] skip + +# 'go get' will fall back to svn+ssh once svn fails over protocols like https. +# If vcs-test.golang.org isn't in the user's known_hosts file, this will result +# in an ssh prompt, which will stop 'go test' entirely +# +# Unfortunately, there isn't a way to globally disable host checking for ssh, +# without modifying the real system's or user's configs. Changing $HOME won't +# affect ssh either, as it ignores the environment variable entirely. +# +# However, a useful trick is pointing SVN_SSH to a program that doesn't exist, +# resulting in svn skipping ssh entirely. Alternatives like +# SVN_SSH="ssh -o StrictHostKeyChecking=no" didn't avoid the prompt. +env SVN_SSH="svn_do_not_use_ssh" + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Attempting to get a module zip using svn should succeed. +go get vcs-test.golang.org/svn/hello.svn@000000000001 +exists $GOPATH/pkg/mod/cache/download/vcs-test.golang.org/svn/hello.svn/@v/v0.0.0-20170922011245-000000000001.zip +exists $GOPATH/bin/hello.svn$GOEXE + +# Attempting to get a nonexistent module using svn should fail with a +# reasonable message instead of a panic. +! go get -d vcs-test.golang.org/svn/nonexistent.svn +! stderr panic +stderr 'go get vcs-test.golang.org/svn/nonexistent.svn: no matching versions for query "upgrade"' + +-- go.mod -- +module golang/go/issues/28943/main +-- go.sum -- +vcs-test.golang.org/svn/hello.svn v0.0.0-20170922011245-000000000001 h1:rZjvboXMfQICKXdhx/QHqJ2Y/AQsJVrXnwGqwcTxQiw= +vcs-test.golang.org/svn/hello.svn v0.0.0-20170922011245-000000000001/go.mod h1:0memnh/BRLuxiK2zF4rvUgz6ts/fhhB28l3ULFWPusc= diff --git a/src/cmd/go/testdata/script/mod_get_tags.txt b/src/cmd/go/testdata/script/mod_get_tags.txt new file mode 100644 index 0000000..e9869e3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_tags.txt @@ -0,0 +1,45 @@ +env GO111MODULE=on + +[short] skip + +# get should add modules needed to build packages, even if those +# dependencies are in sources excluded by build tags. +# All build tags are considered true except "ignore". +go mod init m +go get -d . +go list -m all +stdout 'example.com/version v1.1.0' +stdout 'rsc.io/quote v1.5.2' + +[short] skip + +# Packages that are only imported in excluded files should not be built. +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. +go get -n -x . +stderr 'compile.* -p m ' +! stderr 'compile.* -p example.com/version ' +! stderr 'compile.* -p rsc.io/quote ' + +-- empty.go -- +package m + +-- excluded.go -- +// +build windows,mips + +package m + +import _ "example.com/version" + +-- tools.go -- +// +build tools + +package tools + +import _ "rsc.io/quote" + +-- ignore.go -- +// +build ignore + +package ignore + +import _ "example.com/doesnotexist" diff --git a/src/cmd/go/testdata/script/mod_get_test.txt b/src/cmd/go/testdata/script/mod_get_test.txt new file mode 100644 index 0000000..23722bd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_test.txt @@ -0,0 +1,58 @@ +env GO111MODULE=on + +# By default, 'go get' should ignore tests +cp go.mod.empty go.mod +go get -d m/a +! grep rsc.io/quote go.mod + +# 'go get -t' should consider test dependencies of the named package. +cp go.mod.empty go.mod +go get -d -t m/a +grep 'rsc.io/quote v1.5.2$' go.mod + +# 'go get -t' should not consider test dependencies of imported packages, +# including packages imported from tests. +cp go.mod.empty go.mod +go get -d -t m/b +! grep rsc.io/quote go.mod + +# 'go get -t -u' should update test dependencies of the named package. +cp go.mod.empty go.mod +go mod edit -require=rsc.io/quote@v1.5.1 +go get -d -t -u m/a +grep 'rsc.io/quote v1.5.2$' go.mod + +# 'go get -t -u' should not add or update test dependencies +# of imported packages, including packages imported from tests. +cp go.mod.empty go.mod +go get -d -t -u m/b +! grep rsc.io/quote go.mod +go mod edit -require=rsc.io/quote@v1.5.1 +go get -d -t -u m/b +grep 'rsc.io/quote v1.5.1$' go.mod + +# 'go get all' should consider test dependencies with or without -t. +cp go.mod.empty go.mod +go get -d all +grep 'rsc.io/quote v1.5.2$' go.mod + +-- go.mod.empty -- +module m + +-- a/a.go -- +package a + +-- a/a_test.go -- +package a_test + +import _ "rsc.io/quote" + +-- b/b.go -- +package b + +import _ "m/a" + +-- b/b_test.go -- +package b_test + +import _ "m/a" diff --git a/src/cmd/go/testdata/script/mod_get_too_many_redirects.txt b/src/cmd/go/testdata/script/mod_get_too_many_redirects.txt new file mode 100644 index 0000000..9cbe0d2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_too_many_redirects.txt @@ -0,0 +1,10 @@ +env GO111MODULE=on +env GOPROXYBASE=$GOPROXY +env GOPROXY=$GOPROXYBASE/redirect/11 +env GOSUMDB=off + +! go get -d rsc.io/quote@v1.2.0 +stderr 'stopped after 10 redirects' + +env GOPROXY=$GOPROXYBASE/redirect/9 +go get -d rsc.io/quote@v1.2.0 diff --git a/src/cmd/go/testdata/script/mod_get_trailing_slash.txt b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt new file mode 100644 index 0000000..c536693 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt @@ -0,0 +1,37 @@ +# go list should succeed to load a package ending with ".go" if the path does +# not correspond to an existing local file. Listing a pattern ending with +# ".go/" should try to list a package regardless of whether a file exists at the +# path without the suffixed "/" or not. +go list example.com/dotgo.go +stdout ^example.com/dotgo.go$ +go list example.com/dotgo.go/ +stdout ^example.com/dotgo.go$ + +# go get -d should succeed in either case, with or without a version. +# Arguments are interpreted as packages or package patterns with versions, +# not source files. +go get -d example.com/dotgo.go +go get -d example.com/dotgo.go/ +go get -d example.com/dotgo.go@v1.0.0 +go get -d example.com/dotgo.go/@v1.0.0 + +# go get (without -d) should also succeed in either case. +[short] skip +go get example.com/dotgo.go +go get example.com/dotgo.go/ +go get example.com/dotgo.go@v1.0.0 +go get example.com/dotgo.go/@v1.0.0 + +-- go.mod -- +module m + +go 1.13 + +require example.com/dotgo.go v1.0.0 +-- go.sum -- +example.com/dotgo.go v1.0.0 h1:XKJfs0V8x2PvY2tX8bJBCEbCDLnt15ma2onwhVpew/I= +example.com/dotgo.go v1.0.0/go.mod h1:Qi6z/X3AC5vHiuMt6HF2ICx3KhIBGrMdrA7YoPDKqR0= +-- use.go -- +package use + +import _ "example.com/dotgo.go" diff --git a/src/cmd/go/testdata/script/mod_get_upgrade.txt b/src/cmd/go/testdata/script/mod_get_upgrade.txt new file mode 100644 index 0000000..eeb6d6f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_upgrade.txt @@ -0,0 +1,46 @@ +env GO111MODULE=on + +go get -d rsc.io/quote@v1.5.1 +go list -m all +stdout 'rsc.io/quote v1.5.1' +grep 'rsc.io/quote v1.5.1$' go.mod + +# get -u should update dependencies of the package in the current directory +go get -d -u +grep 'rsc.io/quote v1.5.2$' go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+ // indirect' go.mod + +# get -u rsc.io/sampler should update only sampler's dependencies +cp go.mod-v1.5.1 go.mod +go get -d -u rsc.io/sampler +grep 'rsc.io/quote v1.5.1$' go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+ // indirect' go.mod + +# move to a pseudo-version after any tags +go get -d rsc.io/quote@dd9747d +grep 'rsc.io/quote v0.0.0-20180628003336-dd9747d19b04' go.mod + +# get -u should not jump off newer pseudo-version to earlier tag +go get -d -u +grep 'rsc.io/quote v0.0.0-20180628003336-dd9747d19b04' go.mod + +# move to earlier pseudo-version +go get -d rsc.io/quote@e7a685a342 +grep 'rsc.io/quote v0.0.0-20180214005133-e7a685a342c0' go.mod + +# get -u should jump off earlier pseudo-version to newer tag +go get -d -u +grep 'rsc.io/quote v1.5.2' go.mod + +-- go.mod -- +module x +require rsc.io/quote v1.1.0 + +-- go.mod-v1.5.1 -- +module x +require rsc.io/quote v1.5.1 + +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt b/src/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt new file mode 100644 index 0000000..f5f415a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt @@ -0,0 +1,70 @@ +env GO111MODULE=on + +# For this test module there are three versions: +# * v0.1.1-0.20190429073117-b5426c86b553 +# * v0.1.0 +# * v0.0.0-20190430073000-30950c05d534 +# Only v0.1.0 is tagged. +# +# The v0.1.1 pseudo-version is semantically higher than the latest tag. +# The v0.0.0 pseudo-version is chronologically newer. + +# Start at v0.1.1-0.20190429073117-b5426c86b553 +go get -d example.com/pseudoupgrade@b5426c8 +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get -u' should not downgrade to the (lower) tagged version. +go get -d -u +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get example.com/pseudoupgrade@upgrade' should not downgrade. +go get -d example.com/pseudoupgrade@upgrade +go list -m all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get example.com/pseudoupgrade' should not downgrade. +# This is equivalent to 'get example.com/pseudoupgrade@upgrade'. +go get -d example.com/pseudoupgrade +go list -m all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get example.com/pseudoupgrade@latest' should downgrade. +# @latest should not consider the current version. +go get -d example.com/pseudoupgrade@latest +go list -m all +stdout '^example.com/pseudoupgrade v0.1.0$' + +# We should observe the same behavior with the newer pseudo-version. +go get -d example.com/pseudoupgrade@v0.0.0-20190430073000-30950c05d534 + +# 'get -u' should not downgrade to the chronologically older tagged version. +go get -d -u +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +# 'get example.com/pseudoupgrade@upgrade should not downgrade. +go get -d example.com/pseudoupgrade@upgrade +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +# 'get example.com/pseudoupgrade' should not downgrade. +go get -d example.com/pseudoupgrade +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +# 'get example.com/pseudoupgrade@latest' should downgrade. +go get -d example.com/pseudoupgrade@latest +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.0$' + +-- go.mod -- +module x + +go 1.12 + +-- main.go -- +package x + +import _ "example.com/pseudoupgrade" diff --git a/src/cmd/go/testdata/script/mod_get_wild.txt b/src/cmd/go/testdata/script/mod_get_wild.txt new file mode 100644 index 0000000..78c645c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_wild.txt @@ -0,0 +1,95 @@ +# This test covers a crazy edge-case involving wildcards and multiple passes of +# patch-upgrades, but if we get it right we probably get many other edge-cases +# right too. + +go list -m all +stdout '^example.net/a v0.1.0 ' +! stdout '^example.net/b ' + + +# Requesting pattern example.../b by itself fails: there is no such module +# already in the build list, and the wildcard in the first element prevents us +# from attempting to resolve a new module whose path is a prefix of the pattern. + +! go get -d -u=patch example.../b@upgrade +stderr '^go get: no modules to query for example\.\.\./b@upgrade because first path element contains a wildcard$' + + +# Patching . causes a patch to example.net/a, which introduces a new match +# for example.net/b/..., which is itself patched and causes another upgrade to +# example.net/a, which is then patched again. + +go get -d -u=patch . example.../b@upgrade +go list -m all +stdout '^example.net/a v0.2.1 ' # upgraded by dependency of b and -u=patch +stdout '^example.net/b v0.2.0 ' # introduced by patch of a and upgraded by wildcard + + +-- go.mod -- +module example + +go 1.16 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/a v0.2.1 => ./a20 + example.net/b v0.1.0 => ./b1 + example.net/b v0.1.1 => ./b1 + example.net/b v0.2.0 => ./b2 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 +-- a10/a.go -- +package a + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a11/a.go -- +package a +-- a11/unimported/unimported.go -- +package unimported + +import _ "example.net/b" + + +-- a20/go.mod -- +module example.net/a + +go 1.16 +-- a20/a.go -- +package a + +-- b1/go.mod -- +module example.net/b + +go 1.16 +-- b1/b.go -- +package b + +-- b2/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b2/b.go -- +package b +-- b2/b_test.go -- +package b_test + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_getmode_vendor.txt b/src/cmd/go/testdata/script/mod_getmode_vendor.txt new file mode 100644 index 0000000..d3df207 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_getmode_vendor.txt @@ -0,0 +1,30 @@ +env GO111MODULE=on + +go get -d rsc.io/quote@v1.5.1 +go mod vendor +env GOPATH=$WORK/empty +env GOPROXY=file:///nonexist + +go list -mod=vendor +go list -mod=vendor -f '{{with .Module}}{{.Path}} {{.Version}}{{end}} {{.Dir}}' all +stdout '^rsc.io/quote v1.5.1 .*vendor[\\/]rsc.io[\\/]quote$' +stdout '^golang.org/x/text v0.0.0.* .*vendor[\\/]golang.org[\\/]x[\\/]text[\\/]language$' + +! go list -mod=vendor -m rsc.io/quote@latest +stderr 'go list -m: rsc.io/quote@latest: cannot query module due to -mod=vendor' +! go get -mod=vendor -u +stderr 'flag provided but not defined: -mod' + +# Since we don't have a complete module graph, 'go list -m' queries +# that require the complete graph should fail with a useful error. +! go list -mod=vendor -m all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' +! go list -mod=vendor -m ... +stderr 'go list -m: can''t match module patterns using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +-- go.mod -- +module x + +-- x.go -- +package x +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_getx.txt b/src/cmd/go/testdata/script/mod_getx.txt new file mode 100644 index 0000000..ccb8d13 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_getx.txt @@ -0,0 +1,14 @@ +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# 'go get -x' should log URLs with an HTTP or HTTPS scheme. +# A bug had caused us to log schemeless URLs instead. +go get -x -d golang.org/x/text@v0.1.0 +stderr '^# get https://golang.org/x/text\?go-get=1$' +stderr '^# get https://golang.org/x/text\?go-get=1: 200 OK \([0-9.]+s\)$' +! stderr '^# get //.*' diff --git a/src/cmd/go/testdata/script/mod_git_export_subst.txt b/src/cmd/go/testdata/script/mod_git_export_subst.txt new file mode 100644 index 0000000..a28b4f2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_git_export_subst.txt @@ -0,0 +1,21 @@ +env GO111MODULE=on +env GOPROXY=direct + +# Testing that git export-subst is disabled +[!net] skip +[!exec:git] skip +go build + +-- x.go -- +package x + +import _ "github.com/jasonkeene/export-subst" + +-- go.mod -- +module x + +require github.com/jasonkeene/export-subst v0.0.0-20180927204031-5845945ec626 + +-- go.sum -- +github.com/jasonkeene/export-subst v0.0.0-20180927204031-5845945ec626 h1:AUkXi/xFnm7lH2pgtvVkGb7buRn1ywFHw+xDpZ29Rz0= +github.com/jasonkeene/export-subst v0.0.0-20180927204031-5845945ec626/go.mod h1:DwJXqVtrgrQkv3Giuf2Jh4YyubVe7y41S1eOIaysTJw= diff --git a/src/cmd/go/testdata/script/mod_go_version.txt b/src/cmd/go/testdata/script/mod_go_version.txt new file mode 100644 index 0000000..97d9975 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_go_version.txt @@ -0,0 +1,110 @@ +# Test support for declaring needed Go version in module. + +env GO111MODULE=on + +go list +go build +go build sub.1 +go build subver.1 +! stderr 'module requires' +! go build badsub.1 +stderr '^note: module requires Go 1.11111$' + +go build versioned.1 +go mod edit -require versioned.1@v1.1.0 +! go build versioned.1 +stderr '^note: module requires Go 1.99999$' + +[short] stop + +# The message should be printed even if the compiler emits no output. +go build -o $WORK/nooutput.exe nooutput.go +! go build -toolexec=$WORK/nooutput.exe versioned.1 +stderr '^# versioned.1\nnote: module requires Go 1.99999$' + +-- go.mod -- +module m +go 1.999 +require ( + sub.1 v1.0.0 + subver.1 v1.0.0 + badsub.1 v1.0.0 + versioned.1 v1.0.0 +) +replace ( + sub.1 => ./sub + subver.1 => ./subver + badsub.1 => ./badsub + versioned.1 v1.0.0 => ./versioned1 + versioned.1 v1.1.0 => ./versioned2 +) + +-- x.go -- +package x + +-- sub/go.mod -- +module m +go 1.11 + +-- sub/x.go -- +package x + +-- subver/go.mod -- +module m +go 1.11111 + +-- subver/x.go -- +package x + +-- badsub/go.mod -- +module m +go 1.11111 + +-- badsub/x.go -- +package x +invalid syntax + +-- versioned1/go.mod -- +module versioned +go 1.0 + +-- versioned1/x.go -- +package x + +-- versioned2/go.mod -- +module versioned +go 1.99999 + +-- versioned2/x.go -- +package x +invalid syntax + +-- nooutput.go -- +// +build ignore + +package main + +import ( + "bytes" + "os" + "os/exec" + "strings" +) + +func main() { + stderr := new(bytes.Buffer) + stdout := new(bytes.Buffer) + + cmd := exec.Command(os.Args[1], os.Args[2:]...) + cmd.Stderr = stderr + cmd.Stdout = stdout + + err := cmd.Run() + if strings.HasPrefix(os.Args[2], "-V") { + os.Stderr.Write(stderr.Bytes()) + os.Stdout.Write(stdout.Bytes()) + } + if err != nil { + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/mod_go_version_mixed.txt b/src/cmd/go/testdata/script/mod_go_version_mixed.txt new file mode 100644 index 0000000..d6216ae --- /dev/null +++ b/src/cmd/go/testdata/script/mod_go_version_mixed.txt @@ -0,0 +1,43 @@ +# Test that dependencies can use Go language features newer than the +# Go version specified by the main module. + +env GO111MODULE=on + +go build + +-- go.mod -- +module m +go 1.12 +require ( + sub.1 v1.0.0 +) +replace ( + sub.1 => ./sub +) + +-- x.go -- +package x + +import "sub.1" + +func F() { sub.F(0, 0) } + +var A sub.Alias +var D sub.Defined + +-- sub/go.mod -- +module m +go 1.14 + +-- sub/sub.go -- +package sub + +// signed shift counts added in Go 1.13 +func F(l, r int) int { return l << r } + +type m1 interface { M() } +type m2 interface { M() } + +// overlapping interfaces added in Go 1.14 +type Alias = interface { m1; m2; M() } +type Defined interface { m1; m2; M() } diff --git a/src/cmd/go/testdata/script/mod_gobuild_import.txt b/src/cmd/go/testdata/script/mod_gobuild_import.txt new file mode 100644 index 0000000..c13ae84 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gobuild_import.txt @@ -0,0 +1,133 @@ +[short] skip + +# go/build's Import should find modules by invoking the go command + +go build -o $WORK ./testimport ./testfindonly + +# GO111MODULE=off +env GO111MODULE=off +! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . + +# GO111MODULE=auto in GOPATH/src +env GO111MODULE=auto +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . + +# GO111MODULE=auto outside GOPATH/src +cd $GOPATH/other +env GO111MODULE=auto +exec $WORK/testimport$GOEXE other/x/y/z/w . +stdout w2.go + +! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . +stderr 'no required module provides package gobuild.example.com/x/y/z/w; to add it:\n\tgo get gobuild.example.com/x/y/z/w' + +cd z +exec $WORK/testimport$GOEXE other/x/y/z/w . +stdout w2.go + +# GO111MODULE=on outside GOPATH/src +env GO111MODULE= +exec $WORK/testimport$GOEXE other/x/y/z/w . +stdout w2.go +env GO111MODULE=on +exec $WORK/testimport$GOEXE other/x/y/z/w . +stdout w2.go + +# GO111MODULE=on in GOPATH/src +cd $GOPATH/src +env GO111MODULE= +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . +stdout w1.go +env GO111MODULE=on +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . +stdout w1.go +cd w +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .. +stdout w1.go + +# go/build's Import in FindOnly mode should find directories by invoking the go command +# +# Calling build.Import in build.FindOnly mode on an import path of a Go package +# that produces errors when loading (e.g., due to build constraints not matching +# the current build context) should return the package directory and nil error. + +# Issue 31603: Import with non-empty srcDir should work. +env GO111MODULE=on +exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i $WORK +! stdout 'build constraints' +stdout '^dir=\$WORK.+i err=<nil>$' + +# Issue 37153: Import with empty srcDir should work. +env GO111MODULE=on +exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i '' +! stdout 'build constraints' +stdout '^dir=\$WORK.+i err=<nil>$' + +-- go.mod -- +module gobuild.example.com/x/y/z + +-- z.go -- +package z + +-- w/w1.go -- +package w + +-- i/i.go -- +// +build i + +package i + +-- testimport/x.go -- +package main + +import ( + "fmt" + "go/build" + "log" + "os" + "path/filepath" + "strings" +) + +func main() { + // build.Import should support relative and absolute source dir paths. + path := os.Args[1] + srcDir := os.Args[2] + p1, err := build.Import(path, srcDir, 0) + if err != nil { + log.Fatal(err) + } + absSrcDir, err := filepath.Abs(srcDir) + if err != nil { + log.Fatal(err) + } + p2, err := build.Import(path, absSrcDir, 0) + if err != nil { + log.Fatal(err) + } + if p1.Dir != p2.Dir { + log.Fatalf("different packages loaded with relative and absolute paths:\n\t%s\n\t%s", p1.Dir, p2.Dir) + } + + fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " ")) +} + +-- testfindonly/x.go -- +package main + +import ( + "fmt" + "go/build" + "os" +) + +func main() { + p, err := build.Import(os.Args[1], os.Args[2], build.FindOnly) + fmt.Printf("dir=%s err=%v\n", p.Dir, err) +} + +-- $GOPATH/other/go.mod -- +module other/x/y + +-- $GOPATH/other/z/w/w2.go -- +package w diff --git a/src/cmd/go/testdata/script/mod_gofmt_invalid.txt b/src/cmd/go/testdata/script/mod_gofmt_invalid.txt new file mode 100644 index 0000000..21edc7d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gofmt_invalid.txt @@ -0,0 +1,13 @@ +# Test for a crash in go fmt on invalid input when using modules. +# Issue 26792. + +env GO111MODULE=on +! go fmt x.go +! stderr panic + +-- go.mod -- +module x + +-- x.go -- +// Missing package declaration. +var V int diff --git a/src/cmd/go/testdata/script/mod_gomodcache.txt b/src/cmd/go/testdata/script/mod_gomodcache.txt new file mode 100644 index 0000000..b2143e2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gomodcache.txt @@ -0,0 +1,60 @@ +# Test GOMODCACHE +env GO111MODULE=on + +# Explicitly set GOMODCACHE +env GOMODCACHE=$WORK/modcache +go env GOMODCACHE +stdout $WORK[/\\]modcache +go get -d rsc.io/quote@v1.0.0 +exists $WORK/modcache/cache/download/rsc.io/quote/@v/v1.0.0.info +grep '{"Version":"v1.0.0","Time":"2018-02-14T00:45:20Z"}' $WORK/modcache/cache/download/rsc.io/quote/@v/v1.0.0.info + +# Ensure GOMODCACHE doesn't affect location of sumdb, but $GOMODCACHE/cache/download/sumdb is still written +exists $GOPATH/pkg/sumdb +! exists $WORK/modcache/sumdb +exists $WORK/modcache/cache/download/sumdb + +# Test that the default GOMODCACHE is $GOPATH[0]/pkg/mod +env GOMODCACHE= +go env GOMODCACHE +stdout $GOPATH[/\\]pkg[/\\]mod +go get -d rsc.io/quote@v1.0.0 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.0.0.info +grep '{"Version":"v1.0.0","Time":"2018-02-14T00:45:20Z"}' $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.0.0.info + +# If neither GOMODCACHE or GOPATH are set, GOPATH defaults to the user's $HOME/go, so GOMODCACHE becomes $HOME/go/pkg/mod +[windows] env USERPROFILE=$WORK/home # Ensure USERPROFILE is a valid path (rather than /no-home/ so we don't run into the logic that "uninfers" GOPATH in cmd/go/main.go +[plan9] env home=$WORK/home +[!windows] [!plan9] env HOME=$WORK/home +env GOMODCACHE= +env GOPATH= +go env GOMODCACHE +stdout $HOME[/\\]go[/\\]pkg[/\\]mod + +# If GOMODCACHE isn't set and GOPATH starts with the path list separator, it's an error. +env GOMODCACHE= +env GOPATH=${:}$WORK/this/is/ignored +! go env GOMODCACHE +stderr 'missing \$GOPATH' + +# If GOMODCACHE isn't set and GOPATH has multiple elements only the first is used. +env GOMODCACHE= +env GOPATH=$WORK/first/path${:}$WORK/this/is/ignored +go env GOMODCACHE +stdout $WORK[/\\]first[/\\]path[/\\]pkg[/\\]mod + +env GOMODCACHE=$WORK/modcache +go mod download rsc.io/quote@v1.0.0 +exists $WORK/modcache/cache/download/rsc.io/quote/@v/v1.0.0.info + +# Test that the following work even with GO111MODULE=off +env GO111MODULE=off + +# Cleaning modcache +exists $WORK/modcache +env GOMODCACHE=$WORK/modcache +go clean -modcache +! exists $WORK/modcache + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_gonoproxy.txt b/src/cmd/go/testdata/script/mod_gonoproxy.txt new file mode 100644 index 0000000..2047869 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gonoproxy.txt @@ -0,0 +1,54 @@ +env GO111MODULE=on +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPRIVATE GOPROXY GONOPROXY GOSUMDB GONOSUMDB +env dbname=localhost.localdev/sumdb + +# disagree with sumdb fails +cp go.mod.orig go.mod +env GOSUMDB=$sumdb' '$proxy/sumdb-wrong +! go get -d rsc.io/quote +stderr 'SECURITY ERROR' + +# GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text +env GONOSUMDB='*/quote,*/*mple*,golang.org/x' +go get -d rsc.io/quote +rm go.sum +env GOPRIVATE='*/quote,*/*mple*,golang.org/x' +env GONOPROXY=none # that is, proxy all despite GOPRIVATE +go get -d rsc.io/quote + +# Download .info files needed for 'go list -m all' later. +# TODO(#42723): either 'go list -m' should not read these files, +# or 'go get' and 'go mod tidy' should download them. +go list -m all +stdout '^golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c$' + +# When GOPROXY is not empty but contains no entries, an error should be reported. +env GOPROXY=',' +! go get -d golang.org/x/text +stderr '^go get golang.org/x/text: GOPROXY list is not the empty string, but contains no entries$' + +# When GOPROXY=off, fetching modules not matched by GONOPROXY fails. +env GONOPROXY=*/fortune +env GOPROXY=off +! go get -d golang.org/x/text +stderr '^go get golang.org/x/text: module lookup disabled by GOPROXY=off$' + +# GONOPROXY bypasses proxy +[!net] skip +[!exec:git] skip +env GOPRIVATE=none +env GONOPROXY='*/fortune' +! go get -d rsc.io/fortune # does not exist in real world, only on test proxy +stderr 'git ls-remote' + +env GOSUMDB= +env GONOPROXY= +env GOPRIVATE='*/x' +go get -d golang.org/x/text +go list -m all +! stdout 'text.*v0.0.0-2017' # should not have the version from the proxy + +-- go.mod.orig -- +module m diff --git a/src/cmd/go/testdata/script/mod_gopkg_unstable.txt b/src/cmd/go/testdata/script/mod_gopkg_unstable.txt new file mode 100644 index 0000000..5ad9106 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gopkg_unstable.txt @@ -0,0 +1,24 @@ +env GO111MODULE=on + +cp go.mod.empty go.mod +go get -d gopkg.in/dummy.v2-unstable + +cp x.go.txt x.go +cp go.mod.empty go.mod +go list + +[!net] skip +[!exec:git] skip + +env GOPROXY=direct +env GOSUMDB=off +go get -d gopkg.in/macaroon-bakery.v2-unstable/bakery +go list -m all +stdout 'gopkg.in/macaroon-bakery.v2-unstable v2.0.0-[0-9]+-[0-9a-f]+$' + +-- go.mod.empty -- +module m + +-- x.go.txt -- +package x +import _ "gopkg.in/dummy.v2-unstable" diff --git a/src/cmd/go/testdata/script/mod_goroot_errors.txt b/src/cmd/go/testdata/script/mod_goroot_errors.txt new file mode 100644 index 0000000..9d7a94d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_goroot_errors.txt @@ -0,0 +1,53 @@ +env GO111MODULE=on + +# Regression test for https://golang.org/issue/34769. +# Missing standard-library imports should refer to GOROOT rather than +# complaining about a malformed module path. +# This is especially important when GOROOT is set incorrectly, +# since such an error will occur for every package in std. + +# Building a nonexistent std package directly should fail usefully. + +! go build -mod=readonly nonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +! go build nonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +# Building a nonexistent std package indirectly should also fail usefully. + +! go build -mod=readonly ./importnonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^importnonexist[/\\]x.go:2:8: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +! go build ./importnonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^importnonexist[/\\]x.go:2:8: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +# Building an *actual* std package should fail if GOROOT is set to something bogus. + +[!short] go build ./importjson # Prove that it works when GOROOT is valid. + +env GOROOT=$WORK/not-a-valid-goroot +! go build ./importjson +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr 'importjson[/\\]x.go:2:8: package encoding/json is not in GOROOT \('$WORK'[/\\]not-a-valid-goroot[/\\]src[/\\]encoding[/\\]json\)$' + +-- go.mod -- +module example.com +go 1.14 +-- importnonexist/x.go -- +package importnonexist +import _ "nonexist" +-- importjson/x.go -- +package importjson +import _ "encoding/json" +-- $WORK/not-a-valid-goroot/README -- +This directory is not a valid GOROOT. diff --git a/src/cmd/go/testdata/script/mod_graph.txt b/src/cmd/go/testdata/script/mod_graph.txt new file mode 100644 index 0000000..07968f5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_graph.txt @@ -0,0 +1,10 @@ +env GO111MODULE=on + +go mod graph +stdout '^m rsc.io/quote@v1.5.2$' +stdout '^rsc.io/quote@v1.5.2 rsc.io/sampler@v1.3.0$' +! stdout '^m rsc.io/sampler@v1.3.0$' + +-- go.mod -- +module m +require rsc.io/quote v1.5.2 diff --git a/src/cmd/go/testdata/script/mod_help.txt b/src/cmd/go/testdata/script/mod_help.txt new file mode 100644 index 0000000..b5cd30c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_help.txt @@ -0,0 +1,6 @@ +env GO111MODULE=on + +# go help get shows usage for get +go help get +stdout 'usage: go get' +stdout 'get using modules to manage source'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/mod_import.txt b/src/cmd/go/testdata/script/mod_import.txt new file mode 100644 index 0000000..28358b5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# latest rsc.io/quote should be v1.5.2 not v1.5.3-pre1 +go get -d +go list -m all +stdout 'rsc.io/quote v1.5.2' + +# but v1.5.3-pre1 should be a known version +go list -m -versions rsc.io/quote +stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$' + +-- go.mod -- +module x + +-- x.go -- +package x +import _ "rsc.io/quote" + diff --git a/src/cmd/go/testdata/script/mod_import_cycle.txt b/src/cmd/go/testdata/script/mod_import_cycle.txt new file mode 100644 index 0000000..7be0749 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_cycle.txt @@ -0,0 +1,40 @@ +env GO111MODULE=on + +# 'go list all' should fail with a reasonable error message +! go list all +stderr '^package m\n\timports m/a\n\timports m/b\n\timports m/a: import cycle not allowed' + +# 'go list -e' should not print to stderr, but should mark all three +# packages (m, m/a, and m/b) as Incomplete. +go list -e -json all +! stderr . +stdout -count=3 '"Incomplete": true,' + +-- go.mod -- +module m + +require ( + m/a v0.0.0 + m/b v0.0.0 +) + +replace ( + m/a => ./a + m/b => ./b +) +-- m.go -- +package m +import ( + _ "m/a" + _ "m/b" +) +-- a/go.mod -- +module m/a +-- a/a.go -- +package a +import _ "m/b" +-- b/go.mod -- +module m/b +-- b/b.go -- +package b +import _ "m/a" diff --git a/src/cmd/go/testdata/script/mod_import_issue41113.txt b/src/cmd/go/testdata/script/mod_import_issue41113.txt new file mode 100644 index 0000000..fed2510 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_issue41113.txt @@ -0,0 +1,28 @@ +# Regression test for https://golang.org/issue/41113. +# +# When resolving a missing import path, the inability to add the package from +# one module path should not interfere with adding a nested path. + +# Initially, our module depends on split-incompatible v2.1.0-pre+incompatible, +# from which an imported package has been removed (and relocated to the nested +# split-incompatible/subpkg module). modload.QueryPattern will suggest +# split-incompatible v2.0.0+incompatible, which we cannot use (because it would +# be an implicit downgrade), and split-incompatible/subpkg v0.1.0, which we +# *should* use. + +go mod tidy + +go list -m all +stdout '^example.com/split-incompatible/subpkg v0\.1\.0$' +! stdout '^example.com/split-incompatible .*' + +-- go.mod -- +module golang.org/issue/41113 + +go 1.16 + +require example.com/split-incompatible v2.1.0-pre+incompatible +-- x.go -- +package issue41113 + +import _ "example.com/split-incompatible/subpkg" diff --git a/src/cmd/go/testdata/script/mod_import_issue42891.txt b/src/cmd/go/testdata/script/mod_import_issue42891.txt new file mode 100644 index 0000000..a78cab2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_issue42891.txt @@ -0,0 +1,14 @@ +# If an import declaration is an absolute path, most commands should report +# an error instead of going into an infinite loop. +# Verifies golang.org/issue/42891. +go list . +stdout '^m$' + +-- go.mod -- +module m + +go 1.16 +-- m.go -- +package m + +import "/" diff --git a/src/cmd/go/testdata/script/mod_import_meta.txt b/src/cmd/go/testdata/script/mod_import_meta.txt new file mode 100644 index 0000000..0e469d0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_meta.txt @@ -0,0 +1,45 @@ +# The loader should not attempt to resolve imports of the "all", "std", and "cmd" meta-packages. + +! go list -deps ./importall +! stderr 'internal error' +stderr '^importall[/\\]x.go:3:8: "all" is not an importable package; see ''go help packages''$' + +! go list -deps ./importcmd +! stderr 'internal error' +stderr '^importcmd[/\\]x.go:3:8: "cmd" is not an importable package; see ''go help packages''$' + +! go list -deps ./importstd +! stderr 'internal error' +stderr '^importstd[/\\]x.go:3:8: "std" is not an importable package; see ''go help packages''$' + + +# Not even if such a path is theoretically provided by a (necessarily replaced) module. + +go mod edit -replace std@v0.1.0=./modstd +go mod edit -require std@v0.1.0 + +! go list -deps ./importstd +stderr '^importstd[/\\]x.go:3:8: "std" is not an importable package; see ''go help packages''$' + + +-- go.mod -- +module example.com +go 1.16 +-- importall/x.go -- +package importall + +import _ "all" +-- importcmd/x.go -- +package importcmd + +import _ "cmd" +-- importstd/x.go -- +package importstd + +import _ "std" +-- modstd/go.mod -- +module std +go 1.16 +-- modstd/std.go -- +// Package std is an incredibly confusingly-named package. +package std diff --git a/src/cmd/go/testdata/script/mod_import_mod.txt b/src/cmd/go/testdata/script/mod_import_mod.txt new file mode 100644 index 0000000..b035e3d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_mod.txt @@ -0,0 +1,7 @@ +# Test that GOPATH/pkg/mod is excluded +env GO111MODULE=off +! go list mod/foo +stderr 'disallowed import path' + +-- mod/foo/foo.go -- +package foo diff --git a/src/cmd/go/testdata/script/mod_import_v1suffix.txt b/src/cmd/go/testdata/script/mod_import_v1suffix.txt new file mode 100644 index 0000000..a429450 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_v1suffix.txt @@ -0,0 +1,11 @@ +env GO111MODULE=on + +! go get -d example.com/invalidpath/v1 +! go install . + +-- go.mod -- +module example.com +-- main.go -- +package main +import _ "example.com/invalidpath/v1" +func main() {} diff --git a/src/cmd/go/testdata/script/mod_in_testdata_dir.txt b/src/cmd/go/testdata/script/mod_in_testdata_dir.txt new file mode 100644 index 0000000..66f79fa --- /dev/null +++ b/src/cmd/go/testdata/script/mod_in_testdata_dir.txt @@ -0,0 +1,45 @@ +# Regression test for golang.org/issue/28481: +# 'mod tidy' removed dependencies if the module root was +# within a directory named 'testdata' or '_foo'. + +env GO111MODULE=on + +# A module should be allowed in a directory named testdata. +cd $WORK/testdata +go mod init testdata.tld/foo + +# Getting a package within that module should resolve its dependencies. +go get -d +grep 'rsc.io/quote' go.mod + +# Tidying the module should preserve those dependencies. +go mod tidy +grep 'rsc.io/quote' go.mod + +[short] stop + +# Vendoring the module's dependencies should work too. +go mod vendor +exists vendor/rsc.io/quote + +# The same should work in directories with names starting with underscores. +cd $WORK/_ignored +go mod init testdata.tld/foo + +go get +grep 'rsc.io/quote' go.mod + +go mod tidy +grep 'rsc.io/quote' go.mod + +go mod vendor +exists vendor/rsc.io/quote + +-- $WORK/testdata/main.go -- +package foo + +import _ "rsc.io/quote" +-- $WORK/_ignored/main.go -- +package foo + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_indirect.txt b/src/cmd/go/testdata/script/mod_indirect.txt new file mode 100644 index 0000000..6ea1cae --- /dev/null +++ b/src/cmd/go/testdata/script/mod_indirect.txt @@ -0,0 +1,81 @@ +env GO111MODULE=on + +# golang.org/issue/31248: required modules imposed by dependency versions +# older than the selected version must still be taken into account. + +env GOFLAGS=-mod=readonly + +# Indirect dependencies required via older-than-selected versions must exist in +# the module graph, but do not need to be listed explicitly in the go.mod file +# (since they are implied). +go mod graph +stdout i@v0.1.0 + +# The modules must also appear in the build list, not just the graph. +go list -m all +stdout '^i v0.1.0' + +# The packages provided by those dependencies must resolve. +go list all +stdout '^i$' + +-- go.mod -- +module main + +go 1.13 + +require ( + a v0.0.0 + b v0.0.0 + c v0.0.0 +) + +// Apply replacements so that the test can be self-contained. +// (It's easier to see all of the modules here than to go +// rooting around in testdata/mod.) +replace ( + a => ./a + b => ./b + c => ./c + x v0.1.0 => ./x1 + x v0.2.0 => ./x2 + i => ./i +) +-- main.go -- +package main + +import ( + _ "a" + _ "b" + _ "c" +) + +func main() {} +-- a/go.mod -- +module a +go 1.13 +require x v0.1.0 +-- a/a.go -- +package a +-- b/go.mod -- +module b +go 1.13 +require x v0.2.0 +-- b/b.go -- +package b +-- c/go.mod -- +module c +go 1.13 +-- c/c.go -- +package c +import _ "i" +-- x1/go.mod -- +module x +go1.13 +require i v0.1.0 +-- x2/go.mod -- +module x +go1.13 +-- i/go.mod -- +-- i/i.go -- +package i diff --git a/src/cmd/go/testdata/script/mod_indirect_main.txt b/src/cmd/go/testdata/script/mod_indirect_main.txt new file mode 100644 index 0000000..eeb93f1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_indirect_main.txt @@ -0,0 +1,65 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/29773: 'go list -m' was not following +# dependencies through older versions of the main module. + +go list -f '{{with .Module}}{{.Path}}{{with .Version}} {{.}}{{end}}{{end}}' all +cmp stdout pkgmods.txt + +go list -m all +cmp stdout mods.txt + +go mod graph +cmp stdout graph.txt + +-- go.mod -- +module golang.org/issue/root + +go 1.12 + +replace ( + golang.org/issue/mirror v0.1.0 => ./mirror-v0.1.0 + golang.org/issue/pkg v0.1.0 => ./pkg-v0.1.0 + golang.org/issue/root v0.1.0 => ./root-v0.1.0 +) + +require golang.org/issue/mirror v0.1.0 + +-- root.go -- +package root + +import _ "golang.org/issue/mirror" + +-- mirror-v0.1.0/go.mod -- +module golang.org/issue/mirror + +require golang.org/issue/root v0.1.0 + +-- mirror-v0.1.0/mirror.go -- +package mirror + +import _ "golang.org/issue/pkg" + +-- pkg-v0.1.0/go.mod -- +module golang.org/issue/pkg + +-- pkg-v0.1.0/pkg.go -- +package pkg + +-- root-v0.1.0/go.mod -- +module golang.org/issue/root + +require golang.org/issue/pkg v0.1.0 + +-- pkgmods.txt -- +golang.org/issue/mirror v0.1.0 +golang.org/issue/pkg v0.1.0 +golang.org/issue/root +-- mods.txt -- +golang.org/issue/root +golang.org/issue/mirror v0.1.0 => ./mirror-v0.1.0 +golang.org/issue/pkg v0.1.0 => ./pkg-v0.1.0 +-- graph.txt -- +golang.org/issue/root golang.org/issue/mirror@v0.1.0 +golang.org/issue/mirror@v0.1.0 golang.org/issue/root@v0.1.0 +golang.org/issue/root@v0.1.0 golang.org/issue/pkg@v0.1.0 diff --git a/src/cmd/go/testdata/script/mod_indirect_tidy.txt b/src/cmd/go/testdata/script/mod_indirect_tidy.txt new file mode 100644 index 0000000..a12b35c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_indirect_tidy.txt @@ -0,0 +1,60 @@ +env GO111MODULE=on + +# golang.org/issue/31248: loading the build list must not add explicit entries +# for indirect dependencies already implied by older-than-selected versions +# already in the build list. + +cp go.mod.orig go.mod +go mod tidy +cmp go.mod go.mod.orig + +cp go.mod.orig go.mod +go list -m all +cmp go.mod go.mod.orig + +-- go.mod.orig -- +module main + +go 1.13 + +require a v0.0.0 + +replace ( + a v0.0.0 => ./a + b v0.0.0 => ./b + i v0.0.0 => ./i + x v0.1.0 => ./x1 + x v0.2.0 => ./x2 +) +-- main.go -- +package main + +import _ "a" + +func main() {} +-- a/go.mod -- +module a +go 1.13 +require ( + x v0.2.0 + b v0.0.0 +) +-- a/a.go -- +package a +-- b/go.mod -- +module b +go 1.13 +require x v0.1.0 +-- x1/go.mod -- +module x +go 1.13 +require ( + b v0.0.0 + i v0.0.0 +) +-- x2/go.mod -- +module x +go 1.13 +-- i/go.mod -- +module i +go 1.13 diff --git a/src/cmd/go/testdata/script/mod_init_dep.txt b/src/cmd/go/testdata/script/mod_init_dep.txt new file mode 100644 index 0000000..f8cf1d5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_dep.txt @@ -0,0 +1,44 @@ +env GO111MODULE=on +env GOFLAGS=-mod=mod + +# modconv uses git directly to examine what old 'go get' would +[!net] skip +[!exec:git] skip + +# go mod init should populate go.mod from Gopkg.lock +go mod init x +stderr 'copying requirements from Gopkg.lock' +go list -m all +stdout 'rsc.io/sampler v1.0.0' + +# test dep replacement +cd y +go mod init +cmpenv go.mod go.mod.replace + +-- x.go -- +package x + +-- Gopkg.lock -- +[[projects]] + name = "rsc.io/sampler" + version = "v1.0.0" + +-- y/Gopkg.lock -- +[[projects]] + name = "z" + revision = "v1.0.0" + source = "rsc.io/quote" + +-- y/y.go -- +package y // import "y" +import _ "z" + +-- y/go.mod.replace -- +module y + +go $goversion + +replace z v1.0.0 => rsc.io/quote v1.0.0 + +require rsc.io/quote v1.0.0 diff --git a/src/cmd/go/testdata/script/mod_init_empty.txt b/src/cmd/go/testdata/script/mod_init_empty.txt new file mode 100644 index 0000000..1c3888c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_empty.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +env GOPATH=$devnull + +go list -m +stdout '^example.com$' + +go list +stdout '^example.com$' + +-- go.mod -- +module example.com + +go 1.13 +-- main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_init_glide.txt b/src/cmd/go/testdata/script/mod_init_glide.txt new file mode 100644 index 0000000..a351a6a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_glide.txt @@ -0,0 +1,34 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct + +# Regression test for golang.org/issue/32161: +# 'go mod init' did not locate tags when resolving a commit to a pseudo-version. +go mod init x +cmpenv go.mod go.mod.out + +-- main.go -- +package main + +import ( + _ "github.com/rsc/legacytest" +) + +func main() {} + +-- glide.lock -- +imports: +- name: github.com/rsc/legacytest + version: fb3c628075e32f7f3c248a3abbdafd69ad6e21e1 + +-- glide.yaml -- +package: x + +-- go.mod.out -- +module x + +go $goversion + +require github.com/rsc/legacytest v1.1.0-pre.0.20180717164849-fb3c628075e3 diff --git a/src/cmd/go/testdata/script/mod_init_path.txt b/src/cmd/go/testdata/script/mod_init_path.txt new file mode 100644 index 0000000..ccdfc92 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_path.txt @@ -0,0 +1,20 @@ +env GO111MODULE=on + +! go mod init . +stderr '^go: invalid module path "\.": is a local import path$' + +cd x +go mod init example.com/x + +cd ../y +go mod init m + +-- x/main.go -- +package main + +func main() {} + +-- y/main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_init_tidy.txt b/src/cmd/go/testdata/script/mod_init_tidy.txt new file mode 100644 index 0000000..4a52590 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_tidy.txt @@ -0,0 +1,30 @@ +# 'go mod init' should not recommend 'go mod tidy' in an empty directory +# (one that contains no non-hidden .go files or subdirectories). +cd empty +go mod init m +! stderr tidy +cd .. + +# 'go mod init' should recommend 'go mod tidy' if the directory has a .go file. +cd pkginroot +go mod init m +stderr '^go: to add module requirements and sums:\n\tgo mod tidy$' +cd .. + +# 'go mod init' should recommend 'go mod tidy' if the directory has a +# subdirectory. We don't walk the tree to see if it has .go files. +cd subdir +go mod init m +stderr '^go: to add module requirements and sums:\n\tgo mod tidy$' +cd .. + +-- empty/empty.txt -- +Not a .go file. Still counts as an empty project. +-- empty/.hidden/empty.go -- +File in hidden directory. Still as an empty project. +-- empty/_hidden/empty.go -- +File in hidden directory. Still as an empty project. +-- pkginroot/hello.go -- +package vendorimport +-- subdir/sub/empty.txt -- +Subdirectory doesn't need to contain a package. diff --git a/src/cmd/go/testdata/script/mod_install_hint.txt b/src/cmd/go/testdata/script/mod_install_hint.txt new file mode 100644 index 0000000..ab02840 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_install_hint.txt @@ -0,0 +1,5 @@ +# Module is replaced but not required. No hint appears as no module is suggested.
+go mod init m
+go mod edit -replace=github.com/notrequired@v0.5.0=github.com/doesnotexist@v0.5.0
+! go install github.com/notrequired
+! stderr 'to add it:'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/mod_install_pkg_version.txt b/src/cmd/go/testdata/script/mod_install_pkg_version.txt new file mode 100644 index 0000000..6ed600f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_install_pkg_version.txt @@ -0,0 +1,203 @@ +# 'go install pkg@version' works outside a module. +env GO111MODULE=auto +go install example.com/cmd/a@v1.0.0 +exists $GOPATH/bin/a$GOEXE +rm $GOPATH/bin + + +# 'go install pkg@version' reports an error if modules are disabled. +env GO111MODULE=off +! go install example.com/cmd/a@v1.0.0 +stderr '^go: modules disabled by GO111MODULE=off; see ''go help modules''$' +env GO111MODULE=auto + + +# 'go install pkg@version' ignores go.mod in current directory. +cd m +cp go.mod go.mod.orig +! go list -m all +stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$' +go install example.com/cmd/a@latest +cmp go.mod go.mod.orig +exists $GOPATH/bin/a$GOEXE +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.0.0\t' # "latest", not from go.mod +rm $GOPATH/bin/a +cd .. + + +# 'go install -modfile=x.mod pkg@version' reports an error, but only if +# -modfile is specified explicitly on the command line. +cd m +env GOFLAGS=-modfile=go.mod +go install example.com/cmd/a@latest # same as above +env GOFLAGS= +! go install -modfile=go.mod example.com/cmd/a@latest +stderr '^go: -modfile cannot be used with commands that ignore the current module$' +cd .. + + +# Every test case requires linking, so we only cover the most important cases +# when -short is set. +[short] stop + + +# 'go install pkg@version' works on a module that doesn't have a go.mod file +# and with a module whose go.mod file has missing requirements. +# With a proxy, the two cases are indistinguishable. +go install rsc.io/fortune@v1.0.0 +stderr '^go: found rsc.io/quote in rsc.io/quote v1.5.2$' +exists $GOPATH/bin/fortune$GOEXE +! exists $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0/go.mod # no go.mod file +go version -m $GOPATH/bin/fortune$GOEXE +stdout '^\tdep\trsc.io/quote\tv1.5.2\t' # latest version of fortune's dependency +rm $GOPATH/bin + + +# 'go install dir@version' works like a normal 'go install' command if +# dir is a relative or absolute path. +env GO111MODULE=on +go mod download rsc.io/fortune@v1.0.0 +! go install $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: go\.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go install ../pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: go\.mod file not found in current directory or any parent directory; see ''go help modules''$' +mkdir tmp +cd tmp +go mod init tmp +go mod edit -require=rsc.io/fortune@v1.0.0 +! go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download rsc.io/fortune$' +! go install -mod=readonly ../../pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download rsc.io/fortune$' +go get -d rsc.io/fortune@v1.0.0 +go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +exists $GOPATH/bin/fortune$GOEXE +cd .. +rm tmp +rm $GOPATH/bin +env GO111MODULE=auto + +# 'go install pkg@version' reports errors for meta packages, std packages, +# and directories. +! go install std@v1.0.0 +stderr '^go install std@v1.0.0: argument must be a package path, not a meta-package$' +! go install fmt@v1.0.0 +stderr '^go install fmt@v1.0.0: argument must not be a package in the standard library$' +! go install example.com//cmd/a@v1.0.0 +stderr '^go install example.com//cmd/a@v1.0.0: argument must be a clean package path$' +! go install example.com/cmd/a@v1.0.0 ./x@v1.0.0 +stderr '^go install ./x@v1.0.0: argument must be a package path, not a relative path$' +! go install example.com/cmd/a@v1.0.0 $GOPATH/src/x@v1.0.0 +stderr '^go install '$WORK'[/\\]gopath/src/x@v1.0.0: argument must be a package path, not an absolute path$' +! go install example.com/cmd/a@v1.0.0 cmd/...@v1.0.0 +stderr '^go install: package cmd/go not provided by module example.com/cmd@v1.0.0$' + +# 'go install pkg@version' should accept multiple arguments but report an error +# if the version suffixes are different, even if they refer to the same version. +go install example.com/cmd/a@v1.0.0 example.com/cmd/b@v1.0.0 +exists $GOPATH/bin/a$GOEXE +exists $GOPATH/bin/b$GOEXE +rm $GOPATH/bin + +env GO111MODULE=on +go list -m example.com/cmd@latest +stdout '^example.com/cmd v1.0.0$' +env GO111MODULE=auto + +! go install example.com/cmd/a@v1.0.0 example.com/cmd/b@latest +stderr '^go install example.com/cmd/b@latest: all arguments must have the same version \(@v1.0.0\)$' + + +# 'go install pkg@version' should report an error if the arguments are in +# different modules. +! go install example.com/cmd/a@v1.0.0 rsc.io/fortune@v1.0.0 +stderr '^go install: package rsc.io/fortune provided by module rsc.io/fortune@v1.0.0\n\tAll packages must be provided by the same module \(example.com/cmd@v1.0.0\).$' + + +# 'go install pkg@version' should report an error if an argument is not +# a main package. +! go install example.com/cmd/a@v1.0.0 example.com/cmd/err@v1.0.0 +stderr '^go install: package example.com/cmd/err is not a main package$' + +# Wildcards should match only main packages. This module has a non-main package +# with an error, so we'll know if that gets built. +mkdir tmp +cd tmp +go mod init m +go get -d example.com/cmd@v1.0.0 +! go build example.com/cmd/... +stderr 'err[/\\]err.go:3:9: undefined: DoesNotCompile$' +cd .. + +go install example.com/cmd/...@v1.0.0 +exists $GOPATH/bin/a$GOEXE +exists $GOPATH/bin/b$GOEXE +rm $GOPATH/bin + +# If a wildcard matches no packages, we should see a warning. +! go install example.com/cmd/nomatch...@v1.0.0 +stderr '^go install example.com/cmd/nomatch\.\.\.@v1.0.0: module example.com/cmd@v1.0.0 found, but does not contain packages matching example.com/cmd/nomatch\.\.\.$' +go install example.com/cmd/a@v1.0.0 example.com/cmd/nomatch...@v1.0.0 +stderr '^go: warning: "example.com/cmd/nomatch\.\.\." matched no packages$' + +# If a wildcard matches only non-main packges, we should see a different warning. +go install example.com/cmd/err...@v1.0.0 +stderr '^go: warning: "example.com/cmd/err\.\.\." matched no main packages$' + + +# 'go install pkg@version' should report errors if the module contains +# replace or exclude directives. +go mod download example.com/cmd@v1.0.0-replace +! go install example.com/cmd/a@v1.0.0-replace +cmp stderr replace-err + +go mod download example.com/cmd@v1.0.0-exclude +! go install example.com/cmd/a@v1.0.0-exclude +cmp stderr exclude-err + +# 'go install pkg@version' should report an error if the module requires a +# higher version of itself. +! go install example.com/cmd/a@v1.0.0-newerself +stderr '^go install example.com/cmd/a@v1.0.0-newerself: version constraints conflict:\n\texample.com/cmd@v1.0.0-newerself requires example.com/cmd@v1.0.0, but example.com/cmd@v1.0.0-newerself is requested$' + + +# 'go install pkg@version' will only match a retracted version if it's +# explicitly requested. +env GO111MODULE=on +go list -m -versions example.com/cmd +! stdout v1.9.0 +go list -m -versions -retracted example.com/cmd +stdout v1.9.0 +go install example.com/cmd/a@latest +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.0.0\t' +go install example.com/cmd/a@v1.9.0 +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.9.0\t' +env GO111MODULE= + +# 'go install pkg@version' succeeds when -mod=readonly is set explicitly. +# Verifies #43278. +go install -mod=readonly example.com/cmd/a@v1.0.0 + +-- m/go.mod -- +module m + +go 1.16 + +require example.com/cmd v1.1.0-doesnotexist +-- x/x.go -- +package main + +func main() {} +-- replace-err -- +go install example.com/cmd/a@v1.0.0-replace: example.com/cmd@v1.0.0-replace + The go.mod file for the module providing named packages contains one or + more replace directives. It must not contain directives that would cause + it to be interpreted differently than if it were the main module. +-- exclude-err -- +go install example.com/cmd/a@v1.0.0-exclude: example.com/cmd@v1.0.0-exclude + The go.mod file for the module providing named packages contains one or + more exclude directives. It must not contain directives that would cause + it to be interpreted differently than if it were the main module. diff --git a/src/cmd/go/testdata/script/mod_install_versioned.txt b/src/cmd/go/testdata/script/mod_install_versioned.txt new file mode 100644 index 0000000..c6bce41 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_install_versioned.txt @@ -0,0 +1,14 @@ +env GO111MODULE=on + +go get -d rsc.io/fortune +go list -f '{{.Target}}' rsc.io/fortune +! stdout fortune@v1 +stdout 'fortune(\.exe)?$' + +go get -d rsc.io/fortune/v2 +go list -f '{{.Target}}' rsc.io/fortune/v2 +! stdout v2 +stdout 'fortune(\.exe)?$' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_internal.txt b/src/cmd/go/testdata/script/mod_internal.txt new file mode 100644 index 0000000..687269d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_internal.txt @@ -0,0 +1,96 @@ +env GO111MODULE=on +[short] skip + +# golang.org/x/internal should be importable from other golang.org/x modules. +go mod edit -module=golang.org/x/anything +go get -d . + +# ...and their tests... +go test +stdout PASS + +# ...but that should not leak into other modules. +go get -d ./baddep +! go build ./baddep +stderr golang.org[/\\]notx[/\\]useinternal +stderr 'use of internal package golang.org/x/.* not allowed' + +# Internal packages in the standard library should not leak into modules. +go get -d ./fromstd +! go build ./fromstd +stderr 'use of internal package internal/testenv not allowed' + +# Dependencies should be able to use their own internal modules... +go mod edit -module=golang.org/notx +go get -d ./throughdep + +# ... but other modules should not, even if they have transitive dependencies. +go get -d . +! go build . +stderr 'use of internal package golang.org/x/.* not allowed' + +# And transitive dependencies still should not leak. +go get -d ./baddep +! go build ./baddep +stderr golang.org[/\\]notx[/\\]useinternal +stderr 'use of internal package golang.org/x/.* not allowed' + +# Replacing an internal module should keep it internal to the same paths. +go mod edit -module=golang.org/notx +go mod edit -replace golang.org/x/internal=./replace/golang.org/notx/internal +go get -d ./throughdep + +go get -d ./baddep +! go build ./baddep +stderr golang.org[/\\]notx[/\\]useinternal +stderr 'use of internal package golang.org/x/.* not allowed' + +go mod edit -replace golang.org/x/internal=./vendor/golang.org/x/internal +go get -d ./throughdep + +go get -d ./baddep +! go build ./baddep +stderr golang.org[/\\]notx[/\\]useinternal +stderr 'use of internal package golang.org/x/.* not allowed' + +-- go.mod -- +module TBD +go 1.12 +-- useinternal.go -- +package useinternal +import _ "golang.org/x/internal/subtle" + +-- useinternal_test.go -- +package useinternal_test +import ( + "testing" + _ "golang.org/x/internal/subtle" +) + +func Test(*testing.T) {} + +-- throughdep/useinternal.go -- +package throughdep +import _ "golang.org/x/useinternal" + +-- baddep/useinternal.go -- +package baddep +import _ "golang.org/notx/useinternal" + +-- fromstd/useinternal.go -- +package fromstd +import _ "internal/testenv" + +-- replace/golang.org/notx/internal/go.mod -- +module golang.org/x/internal + +-- replace/golang.org/notx/internal/subtle/subtle.go -- +package subtle +// Ha ha! Nothing here! + +-- vendor/golang.org/x/internal/go.mod -- +module golang.org/x/internal + +-- vendor/golang.org/x/internal/subtle/subtle.go -- +package subtle +// Ha ha! Nothing here! diff --git a/src/cmd/go/testdata/script/mod_invalid_path.txt b/src/cmd/go/testdata/script/mod_invalid_path.txt new file mode 100644 index 0000000..c8c075d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_invalid_path.txt @@ -0,0 +1,64 @@ +# Test that mod files with invalid or missing paths produce an error. + +# Test that go list fails on a go.mod with no module declaration. +cd $WORK/gopath/src/mod +! go list . +stderr '^go: no module declaration in go.mod. To specify the module path:\n\tgo mod edit -module=example.com/mod$' + +# Test that go mod init in GOPATH doesn't add a module declaration +# with a path that can't possibly be a module path, because +# it isn't even a valid import path. +# The single quote and backtick are the only characters we don't allow +# in checkModulePathLax, but is allowed in a Windows file name. +# TODO(matloob): choose a different character once +# module.CheckImportPath is laxened and replaces +# checkModulePathLax. +cd $WORK/'gopath/src/m''d' +! go mod init +stderr 'cannot determine module path' + +# Test that a go.mod file is rejected when its module declaration has a path that can't +# possibly be a module path, because it isn't even a valid import path +cd $WORK/gopath/src/badname +! go list . +stderr 'invalid module path' + +# Test that an import path containing an element with a leading dot is valid, +# but such a module path is not. +# Verifies #43985. +cd $WORK/gopath/src/dotname +go list ./.dot +stdout '^example.com/dotname/.dot$' +go list ./use +stdout '^example.com/dotname/use$' +! go list -m example.com/dotname/.dot@latest +stderr '^go list -m: example.com/dotname/.dot@latest: malformed module path "example.com/dotname/.dot": leading dot in path element$' +go get -d example.com/dotname/.dot +go get -d example.com/dotname/use +go mod tidy + +-- mod/go.mod -- + +-- mod/foo.go -- +package foo + +-- m'd/foo.go -- +package mad + +-- badname/go.mod -- + +module .\. + +-- badname/foo.go -- +package badname + +-- dotname/go.mod -- +module example.com/dotname + +go 1.16 +-- dotname/.dot/dot.go -- +package dot +-- dotname/use/use.go -- +package use + +import _ "example.com/dotname/.dot" diff --git a/src/cmd/go/testdata/script/mod_invalid_path_plus.txt b/src/cmd/go/testdata/script/mod_invalid_path_plus.txt new file mode 100644 index 0000000..2f2488f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_invalid_path_plus.txt @@ -0,0 +1,32 @@ +# https://golang.org/issue/44776 +# The '+' character should be disallowed in module paths, but allowed in package +# paths within valid modules. + +go get -d example.net/cmd +go list example.net/cmd/x++ + +! go list -versions -m 'example.net/bad++' +stderr '^go list -m: module example.net/bad\+\+: malformed module path "example.net/bad\+\+": invalid char ''\+''$' + +# TODO(bcmills): 'go get -d example.net/cmd/x++' should also work, but currently +# it does not. This might be fixed by https://golang.org/cl/297891. +! go get -d example.net/cmd/x++ +stderr '^go get: malformed module path "example.net/cmd/x\+\+": invalid char ''\+''$' + +-- go.mod -- +module example.com/m + +go 1.16 + +replace ( + example.net/cmd => ./cmd +) + +-- cmd/go.mod -- +module example.net/cmd + +go 1.16 +-- cmd/x++/main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_invalid_version.txt b/src/cmd/go/testdata/script/mod_invalid_version.txt new file mode 100644 index 0000000..43b9564 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_invalid_version.txt @@ -0,0 +1,251 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off +env GOFLAGS=-mod=mod + +# Regression test for golang.org/issue/27173: if the user (or go.mod file) +# requests a pseudo-version that does not match both the module path and commit +# metadata, reject it with a helpful error message. +# +# TODO(bcmills): Replace the github.com/pierrec/lz4 examples with something +# equivalent on vcs-test.golang.org. + +# An incomplete commit hash is not a valid semantic version, +# but can appear in the main go.mod file anyway and should be resolved. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 \(replaced by \./\..\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3' +cd .. +go list -m golang.org/x/text +stdout 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c' +grep 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c' go.mod + +# A module path below the repo root that does not contain a go.mod file is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c: invalid version: missing golang.org/x/text/unicode/go.mod at revision 14c0d48ead0c' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c: invalid version: missing golang.org/x/text/unicode/go.mod at revision 14c0d48ead0c' + +# However, arguments to 'go get' can name packages above the root. +cp go.mod.orig go.mod +go get -d golang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c +go list -m golang.org/x/text/... +stdout 'golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c' +! stdout 'golang.org/x/text/unicode' + +# A major version that does not match the module path is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v2.1.1-0.20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2' +cd .. +! go list -m golang.org/x/text +stderr $WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2' + +# A pseudo-version with fewer than 12 digits of SHA-1 prefix is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0 +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0: invalid pseudo-version: revision is shorter than canonical \(14c0d48ead0c\)' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0: invalid pseudo-version: revision is shorter than canonical \(14c0d48ead0c\)' + +# A pseudo-version with more than 12 digits of SHA-1 prefix is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a: invalid pseudo-version: revision is longer than canonical \(14c0d48ead0c\)' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a: invalid pseudo-version: revision is longer than canonical \(14c0d48ead0c\)' + +# A pseudo-version that does not match the commit timestamp is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' + +# A 'replace' directive in the main module can replace an invalid timestamp +# with a valid one. +go mod edit -replace golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c=golang.org/x/text@14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' +cd .. +go list -m golang.org/x/text +stdout 'golang.org/x/text v0.1.1-0.20190915032832-14c0d48ead0c => golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c' + +# A pseudo-version that is not derived from a tag is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c: invalid pseudo-version: preceding tag \(v1.999.998\) not found' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c: invalid pseudo-version: preceding tag \(v1.999.998\) not found' + +# A v1.0.0- pseudo-version that is not derived from a tag is invalid: +# v1.0.0- implies no tag, but the correct no-tag prefix for a module path +# without a major-version suffix is v0.0.0-. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c: invalid pseudo-version: major version without preceding tag must be v0, not v1' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c: invalid pseudo-version: major version without preceding tag must be v0, not v1' + +# A pseudo-version vX.Y.Z+1 cannot have Z+1 == 0, since that would +# imply a base tag with a negative patch field. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number' + +# A 'replace' directive in the main module can replace an +# invalid pseudo-version base with a valid one. +go mod edit -replace golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c=golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number' +cd .. +go list -m golang.org/x/text +stdout 'golang.org/x/text v0.0.0-0.20170915032832-14c0d48ead0c => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c' + +# A 'replace' directive can replace an invalid 'latest' version, and +# should suppress errors for that version in 'go get -u' +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v1.999999.0 +go mod edit -replace golang.org/x/text@v1.999999.0=golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c +cd outside +! go get -d golang.org/x/text@upgrade +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.999999.0: reading golang.org/x/text/go.mod at revision v1.999999.0: unknown revision v1.999999.0' +cd .. +go get -d golang.org/x/text@upgrade +go list -m golang.org/x/text +stdout 'golang.org/x/text v1.999999.0 => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c' + +# A pseudo-version derived from a non-ancestor tag is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)' + +# A pseudo-version derived from a canonical tag on the same revision is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag' + +# A +incompatible suffix is not allowed on a version that is actually compatible. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c+incompatible +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c\+incompatible: invalid version: \+incompatible suffix not allowed: major version v0 is compatible' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c\+incompatible: invalid version: \+incompatible suffix not allowed: major version v0 is compatible' + +# The pseudo-version for a commit after a tag with a non-matching major version +# should instead be based on the last matching tag. +cp go.mod.orig go.mod +go mod edit -require github.com/pierrec/lz4@473cd7ce01a1 +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1' +cd outside +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1' +cd .. + +# A +incompatible pseudo-version for a module that has an explicit go.mod file is invalid. +cp go.mod.orig go.mod +go mod edit -require github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d+incompatible +cd outside +! go list -m github.com/pierrec/lz4 +stderr 'go: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required' +cd .. +! go list -m github.com/pierrec/lz4 +stderr 'github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required' + +# A +incompatible pseudo-version is valid for a revision of the module +# that lacks a go.mod file. +cp go.mod.orig go.mod +go mod edit -require github.com/pierrec/lz4@v2.0.4-0.20180826165652-dbe9298ce099+incompatible +cd outside +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v2.0.4-0.20180826165652-dbe9298ce099\+incompatible' +cd .. +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v2.0.4-0.20180826165652-dbe9298ce099\+incompatible' + +# 'go get' for a mismatched major version without a go.mod file should resolve +# to the equivalent +incompatible version, not a pseudo-version with a different +# major version. +cp go.mod.orig go.mod +go get -d github.com/pierrec/lz4@v2.0.5 +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v2.0.5\+incompatible' + +# 'go get' for a mismatched major version with a go.mod file should error out, +# not resolve to a pseudo-version with a different major version. +cp go.mod.orig go.mod +! go get -d github.com/pierrec/lz4@v2.0.8 +stderr 'go get: github.com/pierrec/lz4@v2.0.8: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2' + +# An invalid +incompatible suffix for a canonical version should error out, +# not resolve to a pseudo-version. +# +# TODO(bcmills): The "outside" view for this failure mode is missing its import stack. +# Figure out why and fix it. +cp go.mod.orig go.mod +go mod edit -require github.com/pierrec/lz4@v2.0.8+incompatible +cd outside +! go list -m github.com/pierrec/lz4 +stderr 'github.com/pierrec/lz4@v2.0.8\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required' +cd .. +! go list -m github.com/pierrec/lz4 +stderr 'github.com/pierrec/lz4@v2.0.8\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required' + +-- go.mod.orig -- +module example.com + +go 1.13 +-- outside/go.mod -- +module example.com/outside + +go 1.13 + +require example.com v0.0.0 +replace example.com v0.0.0 => ./.. diff --git a/src/cmd/go/testdata/script/mod_issue35317.txt b/src/cmd/go/testdata/script/mod_issue35317.txt new file mode 100644 index 0000000..b1852ab --- /dev/null +++ b/src/cmd/go/testdata/script/mod_issue35317.txt @@ -0,0 +1,8 @@ +# Regression test for golang.org/issue/35317: +# 'go get' with multiple module-only arguments was racy. + +env GO111MODULE=on +[short] skip + +go mod init example.com +go get -d golang.org/x/text@v0.3.0 golang.org/x/internal@v0.1.0 golang.org/x/exp@none diff --git a/src/cmd/go/testdata/script/mod_lazy_downgrade.txt b/src/cmd/go/testdata/script/mod_lazy_downgrade.txt new file mode 100644 index 0000000..1e84820 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_downgrade.txt @@ -0,0 +1,145 @@ +# This test illustrates the interaction between lazy loading and downgrading in +# 'go get. + +# The package import graph used in this test looks like: +# +# lazy ---- a +# | +# a_test ---- b +# b_test ---- c +# +# The module dependency graph initially looks like: +# +# lazy ---- a.1 ---- b.1 ---- c.1 +# \ / +# b.3 ---- c.2 b.2 +# +# (Note that lazy loading will prune out the dependency from b.1 on c.1.) + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.3.0 ' +stdout '^example.com/c v0.2.0 ' + +# Downgrading c should also downgrade the b that requires it. + +go get -d example.com/c@v0.1.0 +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.2.0 ' +stdout '^example.com/c v0.1.0 ' + +# Removing c entirely should also remove the a and b that require it. + +go get -d example.com/c@none +go list -m all +! stdout '^example.com/a ' +! stdout '^example.com/b ' +! stdout '^example.com/c ' + + +# With lazy loading, downgrading c should work the same way, but dependencies +# outside of the deepening scan should not affect the downgrade. + +cp go.mod.orig go.mod +go mod edit -go=1.16 + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.3.0 ' +stdout '^example.com/c v0.2.0 ' + +go get -d example.com/c@v0.1.0 +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.2.0 ' +stdout '^example.com/c v0.1.0 ' + +go get -d example.com/c@none +go list -m all +! stdout '^example.com/a ' # TODO(#36460): example.com/a v0.1.0 +! stdout '^example.com/b ' # TODO(#36460): example.com/b v0.1.0 +! stdout '^example.com/c ' + +-- go.mod -- +module example.com/lazy + +go 1.15 + +require ( + example.com/a v0.1.0 + example.com/b v0.3.0 // indirect +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0 => ./b2 + example.com/b v0.3.0 => ./b3 + example.com/c v0.1.0 => ./c + example.com/c v0.2.0 => ./c +) +-- lazy.go -- +package lazy + +import _ "example.com/a" + +-- a/go.mod -- +module example.com/a + +go 1.15 + +require example.com/b v0.1.0 +-- a/a.go -- +package a +-- a/a_test.go -- +package a_test + +import _ "example.com/b" + +-- b1/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.1.0 +-- b1/b.go -- +package b +-- b1/b_test.go -- +package b_test +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 +-- b2/b_test.go -- +package b_test +import _ "example.com/c" + +-- b3/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.2.0 +-- b3/b.go -- +package b +-- b3/b_test.go -- +package b_test +import _ "example.com/c" + +-- c/go.mod -- +module example.com/c + +go 1.15 +-- c/c.go -- +package c diff --git a/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt b/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt new file mode 100644 index 0000000..4ad8cbf --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt @@ -0,0 +1,172 @@ +# This test demonstrates dependency resolution when the main module imports a +# new package from a previously-test-only dependency. +# +# When lazy loading is active, the loader will not load dependencies of any +# module whose packages are *only* imported by tests outside the main module. If +# the main module is changed to import a package from such a module, the +# dependencies of that module will need to be reloaded. + +# The import graph used in this test looks like: +# +# m ---- a +# \ | +# \ a_test ---- b/x +# \ +# --------------b/y (new) ---- c +# +# Where b/x and b/y are disjoint packages, but both contained in module b. +# +# The module dependency graph initially looks like: +# +# m ---- a.1 ---- b.1 ---- c.1 +# +# This configuration is similar to that used in mod_lazy_new_import, +# but the new import is from what is initially a test-only dependency. + +# Control case: in Go 1.14, the original go.mod is tidy, +# and the dependency on c is eagerly loaded. + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go list -m all +stdout '^a v0.1.0 ' +stdout '^b v0.1.0 ' +stdout '^c v0.1.0 ' + +# After adding a new import of b/y, +# the import of c from b/y should resolve to the version required by b. + +cp m.go m.go.orig +cp m.go.new m.go +go mod tidy +cmp go.mod.new go.mod + +go list -m all +stdout '^a v0.1.0 ' +stdout '^b v0.1.0 ' +stdout '^c v0.1.0 ' + +# With lazy loading, the go.mod requirements are the same, +# but the dependency on c is initially pruned out. + +cp m.go.orig m.go +cp go.mod.orig go.mod +go mod edit -go=1.16 +go mod edit -go=1.16 go.mod.new + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go list -m all +stdout '^a v0.1.0 ' +stdout '^b v0.1.0 ' +stdout '^c v0.1.0 ' # TODO(#36460): This should be pruned out. + +# After adding a new import of b/y, +# the import of c from b/y should again resolve to the version required by b. + +cp m.go.new m.go +go mod tidy +cmp go.mod.new go.mod + +go list -m all +stdout '^a v0.1.0 ' +stdout '^b v0.1.0 ' +stdout '^c v0.1.0 ' + +-- m.go -- +package main + +import ( + "fmt" + + _ "a" // a_test imports b/x. +) + +func main() { +} +-- m.go.new -- +package main + +import ( + "fmt" + + _ "a" // a_test imports b/x. + "b/y" // This is a new import, not yet reflected in the go.mod file. +) + +func main() { + fmt.Println(b.CVersion()) +} +-- go.mod -- +module m + +go 1.14 + +require a v0.1.0 + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 +) +-- go.mod.new -- +module m + +go 1.14 + +require ( + a v0.1.0 + b v0.1.0 +) + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 +) +-- a1/go.mod -- +module a + +go 1.16 + +require b v0.1.0 +-- a1/a.go -- +package a +-- a1/a_test.go -- +package a_test + +import _ "b/x" +-- b1/go.mod -- +module b + +go 1.16 + +require c v0.1.0 +-- b1/x/x.go -- +package x +-- b1/y/y.go -- +package y + +import "c" + +func CVersion() string { + return c.Version +} +-- c1/go.mod -- +module c + +go 1.16 +-- c1/c.go -- +package c + +const Version = "v0.1.0" +-- c2/go.mod -- +This file should be unused. +-- c2/c.go -- +This file should be unused. diff --git a/src/cmd/go/testdata/script/mod_lazy_new_import.txt b/src/cmd/go/testdata/script/mod_lazy_new_import.txt new file mode 100644 index 0000000..02935bf --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_new_import.txt @@ -0,0 +1,107 @@ +# This test illustrates the use of a deepening scan to resolve transitive +# imports of imports of new packages from within existing dependencies. + +# The package import graph used in this test looks like: +# +# lazy ---- a/x ---- b +# \ +# ---- a/y ---- c +# +# Where a/x and x/y are disjoint packages, but both contained in module a. +# +# The module dependency graph initially looks like: +# +# lazy ---- a.1 ---- b.1 +# \ +# c.1 + + +cp go.mod go.mod.old +cp lazy.go lazy.go.old +go mod tidy +cmp go.mod go.mod.old + +# Before adding a new import, the go.mod file should +# enumerate modules for all packages already imported. +go list all +cmp go.mod go.mod.old + +# When we add a new import of a package in an existing dependency, +# and that dependency is already tidy, its transitive dependencies +# should already be present. +cp lazy.go.new lazy.go +go list all +go list -m all +stdout '^example.com/c v0.1.0' # not v0.2.0 as would be be resolved by 'latest' +cmp go.mod go.mod.old + +# TODO(#36460): +cp lazy.go.old lazy.go +cp go.mod.old go.mod +go mod edit -go=1.16 + +# When a new import is found, we should perform a deepening scan of the existing +# dependencies and add a requirement on the version required by those +# dependencies — not re-resolve 'latest'. + + +-- go.mod -- +module example.com/lazy + +go 1.15 + +require example.com/a v0.1.0 + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b + example.com/c v0.1.0 => ./c1 + example.com/c v0.2.0 => ./c2 +) +-- lazy.go -- +package lazy + +import ( + _ "example.com/a/x" +) +-- lazy.go.new -- +package lazy + +import ( + _ "example.com/a/x" + _ "example.com/a/y" +) +-- a/go.mod -- +module example.com/a + +go 1.15 + +require ( + example.com/b v0.1.0 + example.com/c v0.1.0 +) +-- a/x/x.go -- +package x +import _ "example.com/b" +-- a/y/y.go -- +package y +import _ "example.com/c" +-- b/go.mod -- +module example.com/b + +go 1.15 +-- b/b.go -- +package b +-- c1/go.mod -- +module example.com/c + +go 1.15 +-- c1/c.go -- +package c +-- c2/go.mod -- +module example.com/c + +go 1.15 +-- c2/c.go -- +package c +This file should not be used, so this syntax error should be ignored. diff --git a/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt b/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt new file mode 100644 index 0000000..9cdfad7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt @@ -0,0 +1,131 @@ +# This file demonstrates the effect of lazy loading on the selected +# versions of test dependencies. + +# The package import graph used in this test looks like: +# +# m ---- a +# \ | +# \ a_test ---- b +# \ | +# x b_test +# | \ +# x_test -------------- c +# +# And the module dependency graph looks like: +# +# m -- a.1 -- b.1 -- c.2 +# \ +# x.1 ------------ c.1 + +# Control case: in Go 1.15, the version of c imported by 'go test x' is the +# version required by module b, even though b_test is not relevant to the main +# module. (The main module imports a, and a_test imports b, but all of the +# packages and tests in the main module can be built without b.) + +go list -m c +stdout '^c v0.2.0 ' + +[!short] go test -v x +[!short] stdout ' c v0.2.0$' + +# With lazy loading, the go.mod requirements are the same, +# but the irrelevant dependency on c v0.2.0 should be pruned out, +# leaving only the relevant dependency on c v0.1.0. + +go mod edit -go=1.16 +go list -m c +stdout '^c v0.2.0' # TODO(#36460): v0.1.0 + +[!short] go test -v x +[!short] stdout ' c v0.2.0$' # TODO(#36460): v0.1.0 + +-- m.go -- +package m + +import ( + _ "a" + _ "x" +) +-- go.mod -- +module m + +go 1.15 + +require ( + a v0.1.0 + x v0.1.0 +) + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 + x v0.1.0 => ./x1 +) +-- a1/go.mod -- +module a + +go 1.16 + +require b v0.1.0 +-- a1/a.go -- +package a +-- a1/a_test.go -- +package a_test + +import _ "b" +-- b1/go.mod -- +module b + +go 1.16 + +require c v0.2.0 +-- b1/b.go -- +package b +-- b1/b_test.go -- +package b_test + +import ( + "c" + "testing" +) + +func TestCVersion(t *testing.T) { + t.Log(c.Version) +} +-- c1/go.mod -- +module c + +go 1.16 +-- c1/c.go -- +package c + +const Version = "v0.1.0" +-- c2/go.mod -- +module c + +go 1.16 +-- c2/c.go -- +package c + +const Version = "v0.2.0" +-- x1/go.mod -- +module x + +go 1.16 + +require c v0.1.0 +-- x1/x.go -- +package x +-- x1/x_test.go -- +package x_test + +import ( + "c" + "testing" +) + +func TestCVersion(t *testing.T) { + t.Log("c", c.Version) +} diff --git a/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt b/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt new file mode 100644 index 0000000..ca6c550 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt @@ -0,0 +1,145 @@ +# This file demonstrates the effect of lazy loading on the reproducibility of +# tests (and tests of test dependencies) outside the main module. +# +# It is similar to the cases in mod_all.txt and mod_lazy_test_horizon.txt, but +# focuses on the effect of "go test" on specific packages instead of the "all" +# pattern. + +# The package import graph used in this test looks like: +# +# lazy ---- a +# | +# a_test ---- b +# | +# b_test ---- c +# +# And the non-lazy module dependency graph looks like: +# +# lazy ---- a.1 ---- b.1 ---- c.1 + +cp go.mod go.mod.old +go mod tidy +cmp go.mod go.mod.old + +# In Go 1.15 mode, 'go list -m all' includes modules needed by the +# transitive closure of tests of dependencies of tests of dependencies of …. + +go list -m all +stdout 'example.com/b v0.1.0' +stdout 'example.com/c v0.1.0' +cmp go.mod go.mod.old + +# 'go test' (or equivalent) of any such dependency, no matter how remote, does +# not update the go.mod file. + +go list -test -deps example.com/a +stdout example.com/b +! stdout example.com/c + +[!short] go test -c example.com/a +[!short] cmp go.mod go.mod.old + +go list -test -deps example.com/b +stdout example.com/c + +[!short] go test -c example.com/b +[!short] cmp go.mod go.mod.old + +# TODO(#36460): + +# After changing to 'go 1.16` uniformly, 'go list -m all' should prune out +# example.com/c, because it is not imported by any package (or test of a package) +# transitively imported by the main module. +# +# example.com/a is imported, +# and example.com/b is needed in order to run 'go test example.com/a', +# but example.com/c is not needed because we don't expect the user to need to run +# 'go test example.com/b'. + +# If we skip directly to adding a new import of c, the dependency is too far +# away for a deepening scan to find, which is fine because the package whose +# test imported it wasn't even it "all". It should resolve from the latest +# version of its module. + +# However, if we reach c by running successive tests starting from the main +# module, we should end up with exactly the version require by c, with an update +# to the go.mod file as soon as we test a test dependency that is not itself in +# "all". + +-- go.mod -- +module example.com/lazy + +go 1.15 + +require example.com/a v0.1.0 + +replace ( + example.com/a v0.1.0 => ./a + 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 +) +-- lazy.go -- +package lazy + +import ( + _ "example.com/a" +) +-- a/go.mod -- +module example.com/a + +go 1.15 + +require example.com/b v0.1.0 +-- a/a.go -- +package a +-- a/a_test.go -- +package a + +import ( + "testing" + + _ "example.com/b" +) + +func TestUsingB(t *testing.T) { + // … +} +-- b1/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.1.0 +-- b1/b.go -- +package b +-- b1/b_test.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 +This file should not be used, so this syntax error should be ignored. +-- b2/b_test.go -- +package b +This file should not be used, so this syntax error should be ignored. +-- c1/go.mod -- +module example.com/c + +go 1.15 +-- c1/c.go -- +package c +-- c2/go.mod -- +module example.com/c + +go 1.15 +-- c2/c.go -- +package c +This file should not be used, so this syntax error should be ignored. diff --git a/src/cmd/go/testdata/script/mod_list.txt b/src/cmd/go/testdata/script/mod_list.txt new file mode 100644 index 0000000..1ba6d7c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list.txt @@ -0,0 +1,61 @@ +env GO111MODULE=on +[short] skip + +# list {{.Dir}} shows main module and go.mod but not not-yet-downloaded dependency dir. +go list -mod=mod -m -f '{{.Path}} {{.Main}} {{.GoMod}} {{.Dir}}' all +stdout '^x true .*[\\/]src[\\/]go.mod .*[\\/]src$' +stdout '^rsc.io/quote false .*[\\/]v1.5.2.mod $' + +# list {{.Dir}} shows dependency after download (and go list without -m downloads it) +go list -mod=mod -f '{{.Dir}}' rsc.io/quote +stdout '.*mod[\\/]rsc.io[\\/]quote@v1.5.2$' + +# downloaded dependencies are read-only +exists -readonly $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +exists -readonly $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/buggy + +# go clean -modcache can delete read-only dependencies +go clean -modcache +! exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 + +# list {{.Dir}} shows replaced directories +cp go.mod2 go.mod +go list -mod=mod -f {{.Dir}} rsc.io/quote +go list -m -f '{{.Path}} {{.Version}} {{.Dir}}{{with .Replace}} {{.GoMod}} => {{.Version}} {{.Dir}} {{.GoMod}}{{end}}' all +stdout 'mod[\\/]rsc.io[\\/]quote@v1.5.1' +stdout 'v1.3.0.*mod[\\/]rsc.io[\\/]sampler@v1.3.1 .*[\\/]v1.3.1.mod => v1.3.1.*sampler@v1.3.1 .*[\\/]v1.3.1.mod' + +# list std should work +go list std +stdout ^math/big + +# rsc.io/quote/buggy should be listable as a package +go list -mod=mod rsc.io/quote/buggy + +# rsc.io/quote/buggy should not be listable as a module +go list -m -e -f '{{.Error.Err}}' nonexist rsc.io/quote/buggy +stdout '^module nonexist: not a known dependency$' +stdout '^module rsc.io/quote/buggy: not a known dependency$' + +! go list -m nonexist rsc.io/quote/buggy +stderr '^go list -m: module nonexist: not a known dependency' +stderr '^go list -m: module rsc.io/quote/buggy: not a known dependency' + +# Module loader does not interfere with list -e (golang.org/issue/24149). +go list -e -f '{{.Error.Err}}' database +stdout 'no Go files in ' +! go list database +stderr 'no Go files in ' + +-- go.mod -- +module x +require rsc.io/quote v1.5.2 + +-- go.mod2 -- +module x +require rsc.io/quote v1.5.1 +replace rsc.io/sampler v1.3.0 => rsc.io/sampler v1.3.1 + +-- x.go -- +package x +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_list_bad_import.txt b/src/cmd/go/testdata/script/mod_list_bad_import.txt new file mode 100644 index 0000000..b128408 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_bad_import.txt @@ -0,0 +1,75 @@ +# This test matches list_bad_import, but in module mode. +# Please keep them in sync. + +env GO111MODULE=on +cd example.com + +# Without -e, listing an otherwise-valid package with an unsatisfied direct import should fail. +# BUG: Today it succeeds. +go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}} {{range .DepsErrors}}bad dep: {{.Err}}{{end}}' example.com/direct +! stdout ^error +stdout 'incomplete' +stdout 'bad dep: .*example.com/notfound' + +# Listing with -deps should also fail. +! go list -deps example.com/direct +stderr example.com/notfound + +# But -e -deps should succeed. +go list -e -deps example.com/direct +stdout example.com/notfound + + +# Listing an otherwise-valid package that imports some *other* package with an +# unsatisfied import should also fail. +# BUG: Today, it succeeds. +go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}} {{range .DepsErrors}}bad dep: {{.Err}}{{end}}' example.com/indirect +! stdout ^error +stdout incomplete +stdout 'bad dep: .*example.com/notfound' + +# Again, -deps should fail. +! go list -deps example.com/indirect +stderr example.com/notfound + +# But -e -deps should succeed. +go list -e -deps example.com/indirect +stdout example.com/notfound + + +# Listing the missing dependency directly should fail outright... +! go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound +stderr 'no required module provides package example.com/notfound; to add it:\n\tgo get example.com/notfound' +! stdout error +! stdout incomplete + +# ...but listing with -e should succeed. +go list -e -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound +stdout error +stdout incomplete + + +# The pattern "all" should match only packages that actually exist, +# ignoring those whose existence is merely implied by imports. +go list -e -f '{{.ImportPath}} {{.Error}}' all +stdout example.com/direct +stdout example.com/indirect +# TODO: go list creates a dummy package with the import-not-found +# but really the Error belongs on example.com/direct, and this package +# should not be printed. +# ! stdout example.com/notfound + + +-- example.com/go.mod -- +module example.com + +-- example.com/direct/direct.go -- +package direct +import _ "example.com/notfound" + +-- example.com/indirect/indirect.go -- +package indirect +import _ "example.com/direct" + +-- example.com/notfound/README -- +This directory intentionally left blank. diff --git a/src/cmd/go/testdata/script/mod_list_compiled_concurrent.txt b/src/cmd/go/testdata/script/mod_list_compiled_concurrent.txt new file mode 100644 index 0000000..b08713d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_compiled_concurrent.txt @@ -0,0 +1,41 @@ +env GO111MODULE=on + +[short] skip + +# Regression test for golang.org/issue/29667: +# spurious 'failed to cache compiled Go files' errors. +# This test failed reliably when run with -count=10 +# on a Linux workstation. + +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & + +wait + +-- go.mod -- +module sandbox/bar +-- bar.go -- +package bar + +import "C" diff --git a/src/cmd/go/testdata/script/mod_list_dir.txt b/src/cmd/go/testdata/script/mod_list_dir.txt new file mode 100644 index 0000000..1adab8f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_dir.txt @@ -0,0 +1,36 @@ +[short] skip + +# go list with path to directory should work + +# populate go.sum +go get -d + +env GO111MODULE=off +go list -f '{{.ImportPath}}' $GOROOT/src/math +stdout ^math$ + +env GO111MODULE=on +go list -f '{{.ImportPath}}' $GOROOT/src/math +stdout ^math$ +go list -f '{{.ImportPath}}' . +stdout ^x$ + +go mod download rsc.io/quote@v1.5.2 +go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +stdout '^rsc.io/quote$' +go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.0 +stdout '^rsc.io/sampler$' +go get -d rsc.io/sampler@v1.3.1 +go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.1 +stdout '^rsc.io/sampler$' +! go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.0 +stderr 'outside available modules' + +-- go.mod -- +module x +require rsc.io/quote v1.5.2 + +-- x.go -- +package x + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_list_direct.txt b/src/cmd/go/testdata/script/mod_list_direct.txt new file mode 100644 index 0000000..62a472f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_direct.txt @@ -0,0 +1,24 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +[!net] skip +[!exec:git] skip + +# golang.org/issue/33099: if an import path ends in a major-version suffix, +# ensure that 'direct' mode can resolve the package to the module. +# For a while, (*modfetch.codeRepo).Stat was not checking for a go.mod file, +# which would produce a hard error at the subsequent call to GoMod. + +go get -d + +-- go.mod -- +module example.com +go 1.13 + +-- main.go -- +package main + +import _ "vcs-test.golang.org/git/v3pkg.git/v3" + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_list_e_readonly.txt b/src/cmd/go/testdata/script/mod_list_e_readonly.txt new file mode 100644 index 0000000..4969434 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_e_readonly.txt @@ -0,0 +1,15 @@ +# 'go list -mod=readonly -e should attribute errors +# to individual missing packages. +# Verifies golang.org/issue/34829. +go list -mod=readonly -e -deps -f '{{if .Error}}{{.ImportPath}}: {{.Error}}{{end}}' . +stdout 'example.com/missing: use.go:3:8: cannot find module providing package example.com/missing: import lookup disabled by -mod=readonly' + +-- go.mod -- +module example.com/m + +go 1.14 + +-- use.go -- +package use + +import _ "example.com/missing" diff --git a/src/cmd/go/testdata/script/mod_list_pseudo.txt b/src/cmd/go/testdata/script/mod_list_pseudo.txt new file mode 100644 index 0000000..056c093 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_pseudo.txt @@ -0,0 +1,39 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/32715. + +# When using $GOPATH/pkg/mod/cache/download as a proxy, +# 'latest' queries should prefer tagged versions over pseudo-versions. + +go mod download github.com/dmitshur-test/modtest5@v0.0.0-20190619020302-197a620e0c9a +go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha +go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha.0.20190619023908-3da23a9deb9e +cmp $GOPATH/pkg/mod/cache/download/github.com/dmitshur-test/modtest5/@v/list $WORK/modtest5.list + +env GOSUMDB=off # don't verify go.mod files when loading retractions +env GOPROXY=file:///$GOPATH/pkg/mod/cache/download +env GOPATH=$WORK/gopath2 +mkdir $GOPATH + +go list -m -f '{{.Path}} {{.Version}} {{.Time.Format "2006-01-02"}}' github.com/dmitshur-test/modtest5@latest +stdout '^github.com/dmitshur-test/modtest5 v0.5.0-alpha 2019-06-18$' + +# If the module proxy contains only pseudo-versions, 'latest' should stat +# the version with the most recent timestamp — not the highest semantic +# version — and return its metadata. +env GOPROXY=file:///$WORK/tinyproxy +go list -m -f '{{.Path}} {{.Version}} {{.Time.Format "2006-01-02"}}' dmitri.shuralyov.com/test/modtest3@latest +stdout '^dmitri.shuralyov.com/test/modtest3 v0.0.0-20181023043359-a85b471d5412 2018-10-22$' + +-- $WORK/modtest5.list -- +v0.0.0-20190619020302-197a620e0c9a +v0.5.0-alpha +v0.5.0-alpha.0.20190619023908-3da23a9deb9e +-- $WORK/tinyproxy/dmitri.shuralyov.com/test/modtest3/@v/list -- +v0.1.0-0.20161023043300-000000000000 +v0.0.0-20181023043359-a85b471d5412 +-- $WORK/tinyproxy/dmitri.shuralyov.com/test/modtest3/@v/v0.0.0-20181023043359-a85b471d5412.info -- +{ + "Version": "v0.0.0-20181023043359-a85b471d5412", + "Time": "2018-10-22T21:33:59-07:00" +} diff --git a/src/cmd/go/testdata/script/mod_list_replace_dir.txt b/src/cmd/go/testdata/script/mod_list_replace_dir.txt new file mode 100644 index 0000000..f2f2d2b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_replace_dir.txt @@ -0,0 +1,27 @@ +# Test that "go list" succeeds when given a directory in a replacement +# module within the module cache. +# Verifies golang.org/issue/29548 + +# Populate go.sum and download dependencies. +go get -d + +# Ensure v1.5.2 is also in the cache so we can list it. +go mod download rsc.io/quote@v1.5.2 + +! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +stderr '^directory ..[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2 outside available modules$' + +go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.1 +stdout 'rsc.io/quote' + +-- go.mod -- +module example.com/quoter + +require rsc.io/quote v1.5.2 + +replace rsc.io/quote => rsc.io/quote v1.5.1 + +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_list_retract.txt b/src/cmd/go/testdata/script/mod_list_retract.txt new file mode 100644 index 0000000..3ba53bc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_retract.txt @@ -0,0 +1,108 @@ +# 'go list -mod=vendor -retracted' reports an error. +go mod vendor +! go list -m -retracted -mod=vendor +stderr '^go list -retracted cannot be used when vendoring is enabled$' +rm vendor + +# 'go list -retracted' reports an error in GOPATH mode. +env GO111MODULE=off +! go list -retracted +stderr '^go list -retracted can only be used in module-aware mode$' +env GO111MODULE= + +# 'go list pkg' does not show retraction. +go list -f '{{with .Module}}{{with .Retracted}}retracted{{end}}{{end}}' example.com/retract +! stdout . + +# 'go list -retracted pkg' shows retraction. +go list -retracted -f '{{with .Module}}{{with .Retracted}}retracted{{end}}{{end}}' example.com/retract +stdout retracted + +# 'go list -m' does not show retraction. +go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract +! stdout . + +# 'go list -m -retracted' shows retraction. +go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract + +# 'go list -m mod@version' does not show retraction. +go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-unused +! stdout . + +# 'go list -m -retracted mod@version' shows an error if the go.mod that should +# contain the retractions is not available. +! go list -m -retracted example.com/retract/missingmod@v1.0.0 +stderr '^go list -m: loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$' +go list -e -m -retracted -f '{{.Error.Err}}' example.com/retract/missingmod@v1.0.0 +stdout '^loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$' + +# 'go list -m -retracted mod@version' shows retractions. +go list -m -retracted example.com/retract@v1.0.0-unused +stdout '^example.com/retract v1.0.0-unused \(retracted\)$' +go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-unused +stdout retracted + +# 'go list -m mod@latest' selects a previous release version, not self-retracted latest. +go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@latest +stdout '^v1.1.0$' + +# 'go list -m -retracted mod@latest' selects the self-retracted latest version. +go list -m -retracted -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@latest +stdout '^v1.9.0 retracted$' + +# 'go list -m mod@latest' selects a pre-release version if all release versions are retracted. +go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prerelease@latest +stdout '^v1.9.1-pre$' + +# 'go list -m -retracted mod@latest' selects the self-retracted latest version. +go list -m -retracted -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prerelease@latest +stdout '^v1.9.0 retracted$' + +# 'go list -m mod@latest' selects a pseudo-version if all versions are retracted. +# TODO(golang.org/issue/24031): the proxy does not expose the pseudo-version, +# even if all release versions are retracted. +go list -m -e -f '{{.Error.Err}}' example.com/retract/self/pseudo@latest +stdout '^module example.com/retract/self/pseudo: no matching versions for query "latest"$' + +# 'go list -m mod@latest' reports an error if all versions are retracted. +go list -m -e -f '{{.Error.Err}}' example.com/retract/self/all@latest +stdout '^module example.com/retract/self/all: no matching versions for query "latest"$' + +# 'go list -m mod@<v1.10' selects a previous release version, not self-retracted latest. +# The @latest query is not special with respect to retractions. +go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@<v1.10 +stdout '^v1.1.0$' + +# 'go list -m -versions' hides retracted versions. +go list -m -versions example.com/retract +stdout '^example.com/retract v1.0.0-good v1.1.0$' + +# 'go list -m -retracted -versions' shows retracted versions. +go list -m -retracted -versions example.com/retract +stdout '^example.com/retract v1.0.0-bad v1.0.0-good v1.0.0-unused v1.1.0$' + +# 'go list -m -u -versions' loads retractions and does not show retracted versions. +go list -m -u -versions example.com/retract +stdout '^example.com/retract v1.0.0-good v1.1.0$' +go list -m -u -versions -f '{{with .Retracted}}retracted{{end}}' example.com/retract +stdout retracted + +# 'go list -m -u' shows retraction. +go list -m -u -f '{{with .Retracted}}retracted{{end}}' example.com/retract +stdout retracted + +# 'go list -m -u' does not suggest an update to a self-retracted latest version. +go list -m -u -f '{{with .Update}}{{.Version}}{{with .Retracted}} retracted{{end}}{{end}}' example.com/retract/self/prev@v1.0.0-bad +stdout '^v1.1.0$' + +-- go.mod -- +module example.com/use + +go 1.15 + +require example.com/retract v1.0.0-bad + +-- use.go -- +package use + +import _ "example.com/retract" diff --git a/src/cmd/go/testdata/script/mod_list_std.txt b/src/cmd/go/testdata/script/mod_list_std.txt new file mode 100644 index 0000000..baf7908 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_std.txt @@ -0,0 +1,90 @@ +env GO111MODULE=on +env GOPROXY=off + +[!gc] skip +[short] skip + +# Outside of GOROOT, our vendored packages should be reported as part of the standard library. +go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' std cmd +stdout ^vendor/golang\.org/x/net/http2/hpack +stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm +! stdout ^golang\.org/x/ + +# The dependencies of those packages should also be vendored. +go list -deps vendor/golang.org/x/crypto/chacha20 +stdout ^vendor/golang\.org/x/crypto/internal/subtle + +# cmd/... should match the same packages it used to match in GOPATH mode. +go list cmd/... +stdout ^cmd/compile +! stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm + +# GOROOT/src/... should list the packages in std as if it were a module +# dependency: omitting vendored dependencies and stopping at the 'cmd' module +# boundary. + +go list $GOROOT/src/... +stdout ^bytes$ +! stdout ^builtin$ +! stdout ^cmd/ +! stdout ^vendor/ +! stdout ^golang\.org/x/ + + +# Vendored dependencies should appear with their 'vendor/' paths in std (they're +# in GOROOT/src, but not in the 'std' module following the usual module-boundary +# rules). + +cd $GOROOT/src + +go list std +stdout ^vendor/golang.org/x/net/http2/hpack +! stdout ^golang\.org/x + +# The dependencies of packages with an explicit 'vendor/' prefix should +# still themselves resolve to vendored packages. +go list -deps vendor/golang.org/x/crypto/chacha20 +stdout ^vendor/golang.org/x/crypto/internal/subtle +! stdout ^golang\.org/x + +# Within the std module, the dependencies of the non-vendored packages within +# std should appear to come from modules, but they should be loaded from the +# vendor directory (just like ordinary vendored module dependencies). + +go list all +stdout ^golang.org/x/ +! stdout ^std/ +! stdout ^cmd/ +! stdout ^vendor/ + +go list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' std +! stdout ^vendor/golang.org/x/net/http2/hpack +stdout ^golang.org/x/net/http2/hpack + +go list -f '{{.Dir}}' golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor + +# Within the std module, the packages within the module should omit the 'std/' +# prefix (they retain their own identities), but should respect normal module +# boundaries (vendored packages are not included in the module, even though they +# are included in the 'std' pattern). + +go list ./... +stdout ^bytes$ +! stdout ^builtin$ +! stdout ^cmd/ +! stdout ^vendor/ +! stdout ^golang\.org/x/ + + +# Within std, the vendored dependencies of cmd should still appear to be part of cmd. + +go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' cmd +stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm + +go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' cmd +! stdout . + +go list cmd/... +stdout ^cmd/compile +! stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm diff --git a/src/cmd/go/testdata/script/mod_list_test.txt b/src/cmd/go/testdata/script/mod_list_test.txt new file mode 100644 index 0000000..f697af6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_test.txt @@ -0,0 +1,30 @@ +env GO111MODULE=on + +# go list -compiled -test must handle test-only packages +# golang.org/issue/27097. +go list -compiled -test +stdout -count=4 '^.' # 4 lines +stdout '^m$' +stdout '^m\.test$' +stdout '^m \[m\.test\]$' +stdout '^m_test \[m\.test\]$' + +# https://golang.org/issue/39974: test packages should have the Module field populated. +go list -test -f '{{.ImportPath}}{{with .Module}}: {{.Path}}{{end}}' +stdout -count=4 '^.' # 4 lines +stdout '^m: m$' +stdout '^m\.test: m$' +stdout '^m \[m\.test\]: m$' +stdout '^m_test \[m\.test\]: m$' + +-- go.mod -- +module m + +-- x_test.go -- +package x +import "testing" +func Test(t *testing.T) {} +-- x_x_test.go -- +package x_test +import "testing" +func Test(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/mod_list_upgrade.txt b/src/cmd/go/testdata/script/mod_list_upgrade.txt new file mode 100644 index 0000000..0cef04b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_upgrade.txt @@ -0,0 +1,12 @@ +env GO111MODULE=on + +# Populate go.sum +go list -m -mod=mod all + +# Check for upgrades. +go list -m -u all +stdout 'rsc.io/quote v1.2.0 \[v1\.5\.2\]' + +-- go.mod -- +module x +require rsc.io/quote v1.2.0 diff --git a/src/cmd/go/testdata/script/mod_list_upgrade_pseudo.txt b/src/cmd/go/testdata/script/mod_list_upgrade_pseudo.txt new file mode 100644 index 0000000..b983bec --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_upgrade_pseudo.txt @@ -0,0 +1,26 @@ +env GO111MODULE=on + +# For this test module there are three versions: +# * v0.1.1-0.20190429073117-b5426c86b553 +# * v0.1.0 +# * v0.0.0-20190430073000-30950c05d534 +# Only v0.1.0 is tagged. +# +# The v0.1.1 pseudo-version is semantically higher than the latest tag. +# The v0.0.0 pseudo-version is chronologically newer. + +# The latest pseudo-version is semantically higher than the latest tag. +# 'list -u' should not suggest a lower version as an upgrade. + +go get -d example.com/pseudoupgrade@b5426c8 +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +go get -d example.com/pseudoupgrade@v0.0.0-20190430073000-30950c05d534 +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +-- go.mod -- +module x + +go 1.12 diff --git a/src/cmd/go/testdata/script/mod_load_badchain.txt b/src/cmd/go/testdata/script/mod_load_badchain.txt new file mode 100644 index 0000000..c0c382b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_load_badchain.txt @@ -0,0 +1,103 @@ +[short] skip +env GO111MODULE=on + +# Download everything to avoid "finding" messages in stderr later. +cp go.mod.orig go.mod +go mod download +go mod download example.com@v1.0.0 +go mod download example.com/badchain/a@v1.1.0 +go mod download example.com/badchain/b@v1.1.0 +go mod download example.com/badchain/c@v1.1.0 + +# Try to update example.com/badchain/a (and its dependencies). +! go get -d example.com/badchain/a +cmp stderr update-a-expected +cmp go.mod go.mod.orig + +# Try to update the main module. This updates everything, including +# modules that aren't direct requirements, so the error stack is shorter. +! go get -d -u ./... +cmp stderr update-main-expected +cmp go.mod go.mod.orig + +# Update manually. Listing modules should produce an error. +go mod edit -require=example.com/badchain/a@v1.1.0 +! go list -m +cmp stderr list-expected + +# Try listing a package that imports a package +# in a module without a requirement. +go mod edit -droprequire example.com/badchain/a +! go list -mod=mod m/use +cmp stderr list-missing-expected + +! go list -mod=mod -test m/testuse +cmp stderr list-missing-test-expected + +-- go.mod.orig -- +module m + +go 1.13 + +require example.com/badchain/a v1.0.0 +-- go.sum -- +example.com/badchain/a v1.0.0 h1:iJDLiHLmpQgr9Zrv+44UqywAE2IG6WkHnH4uG08vf+s= +example.com/badchain/a v1.0.0/go.mod h1:6/gnCYHdVrs6mUgatUYUSbuHxEY+/yWedmTggLz23EI= +example.com/badchain/a v1.1.0 h1:cPxQpsOjaIrn05yDfl4dFFgGSbjYmytLqtIIBfTsEqA= +example.com/badchain/a v1.1.0/go.mod h1:T15b2BEK+RY7h7Lr2dgS38p1pgH5/t7Kf5nQXBlcW/A= +example.com/badchain/b v1.0.0 h1:kjDVlBxpjQavYxHE7ECCyyXhfwsfhWIqvghfRgPktSA= +example.com/badchain/b v1.0.0/go.mod h1:sYsH934pMc3/A2vQZh019qrWmp4+k87l3O0VFUYqL+I= +example.com/badchain/b v1.1.0 h1:iEALV+DRN62FArnYylBR4YwCALn/hCdITvhdagHa0L4= +example.com/badchain/b v1.1.0/go.mod h1:mlCgKO7lRZ+ijwMFIBFRPCGt5r5oqCcHdhSSE0VL4uY= +example.com/badchain/c v1.0.0 h1:lOeUHQKR7SboSH7Bj6eIDWoNHaDQXI0T2GfaH2x9fNA= +example.com/badchain/c v1.0.0/go.mod h1:4U3gzno17SaQ2koSVNxITu9r60CeLSgye9y4/5LnfOE= +example.com/badchain/c v1.1.0 h1:VtTg1g7fOutWKHQf+ag04KLRpdMGSfQ9s9tagVtGW14= +example.com/badchain/c v1.1.0/go.mod h1:tyoJj5qh+qtb48sflwdVvk4R+OjPQEY2UJOoibsVLPk= +-- use/use.go -- +package use + +import _ "example.com/badchain/c" +-- testuse/testuse.go -- +package testuse +-- testuse/testuse_test.go -- +package testuse + +import ( + "testing" + _ "example.com/badchain/c" +) + +func Test(t *testing.T) {} +-- update-main-expected -- +go get: example.com/badchain/c@v1.0.0 updating to + example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c +-- update-a-expected -- +go get: example.com/badchain/a@v1.0.0 updating to + example.com/badchain/a@v1.1.0 requires + example.com/badchain/b@v1.1.0 requires + example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c +-- list-expected -- +go: example.com/badchain/a@v1.1.0 requires + example.com/badchain/b@v1.1.0 requires + example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c +-- list-missing-expected -- +go: finding module for package example.com/badchain/c +go: found example.com/badchain/c in example.com/badchain/c v1.1.0 +go: m/use imports + example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c +-- list-missing-test-expected -- +go: finding module for package example.com/badchain/c +go: found example.com/badchain/c in example.com/badchain/c v1.1.0 +go: m/testuse tested by + m/testuse.test imports + example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c diff --git a/src/cmd/go/testdata/script/mod_load_badmod.txt b/src/cmd/go/testdata/script/mod_load_badmod.txt new file mode 100644 index 0000000..fa22e18 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_load_badmod.txt @@ -0,0 +1,25 @@ +# Unknown lines should be ignored in dependency go.mod files. +go list -m -mod=mod all + +# ... and in replaced dependency go.mod files. +cp go.mod go.mod.usesub +go list -m -mod=mod all + +# ... but not in the main module. +cp go.mod.bad go.mod +! go list -m -mod=mod all +stderr 'unknown directive: hello' + +-- go.mod -- +module m +require rsc.io/badmod v1.0.0 +-- go.mod.bad -- +module m +hello world +-- go.mod.usesub -- +module m +require rsc.io/badmod v1.0.0 +replace rsc.io/badmod v1.0.0 => ./sub +-- sub/go.mod -- +module sub +hello world diff --git a/src/cmd/go/testdata/script/mod_load_badzip.txt b/src/cmd/go/testdata/script/mod_load_badzip.txt new file mode 100644 index 0000000..65374d2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_load_badzip.txt @@ -0,0 +1,13 @@ +# Zip files with unexpected file names inside should be rejected. +env GO111MODULE=on + +! go get -d rsc.io/badzip +stderr 'zip for rsc.io/badzip@v1.0.0 has unexpected file rsc.io/badzip@v1.0.0.txt' +! grep rsc.io/badzip go.mod + +go mod edit -require rsc.io/badzip@v1.0.0 +! go build -mod=mod rsc.io/badzip +stderr 'zip for rsc.io/badzip@v1.0.0 has unexpected file rsc.io/badzip@v1.0.0.txt' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt b/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt new file mode 100644 index 0000000..2ca8b3c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt @@ -0,0 +1,23 @@ +# If a replacement module declares a module path different from both +# the original module and its location, report an error with all three paths. +# In particular, the "required as" path should be the original. +# Verifies golang.org/issue/38220. +! go mod download +cmp stderr want + +-- go.mod -- +module m + +require rsc.io/quote v1.5.2 + +replace rsc.io/quote v1.5.2 => example.com/quote v1.5.2 + +-- use.go -- +package use + +import _ "rsc.io/quote" + +-- want -- +go: rsc.io/quote@v1.5.2 (replaced by example.com/quote@v1.5.2): parsing go.mod: + module declares its path as: rsc.io/Quote + but was required as: rsc.io/quote diff --git a/src/cmd/go/testdata/script/mod_local_replace.txt b/src/cmd/go/testdata/script/mod_local_replace.txt new file mode 100644 index 0000000..19bc8f3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_local_replace.txt @@ -0,0 +1,23 @@ +# Test that local replacements work even with dummy module names. +# golang.org/issue/24100. + +env GO111MODULE=on + +cd x/y +go list -f '{{.Dir}}' zz +stdout x[/\\]z$ + +-- x/y/go.mod -- +module x/y +require zz v1.0.0 +replace zz v1.0.0 => ../z + +-- x/y/y.go -- +package y +import _ "zz" + +-- x/z/go.mod -- +module x/z + +-- x/z/z.go -- +package z diff --git a/src/cmd/go/testdata/script/mod_missing_repo.txt b/src/cmd/go/testdata/script/mod_missing_repo.txt new file mode 100644 index 0000000..8dae85f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_missing_repo.txt @@ -0,0 +1,15 @@ +# Regression test for golang.org/issue/34094: modules hosted within gitlab.com +# subgroups could not be fetched because the server returned bogus go-import +# tags for prefixes of the module path. + +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +! go get -d vcs-test.golang.org/go/missingrepo/missingrepo-git +stderr 'vcs-test.golang.org/go/missingrepo/missingrepo-git: git ls-remote .*: exit status .*' + +go get -d vcs-test.golang.org/go/missingrepo/missingrepo-git/notmissing diff --git a/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt b/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt new file mode 100644 index 0000000..9c250e7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt @@ -0,0 +1,17 @@ +env GO111MODULE=on + +! go list -mod=mod -deps use.go +stderr '^use.go:4:2: package example.com/missingpkg/deprecated provided by example.com/missingpkg at latest version v1.0.0 but not at required version v1.0.1-beta$' + +-- go.mod -- +module m + +go 1.14 + +-- use.go -- +package use + +import ( + _ "example.com/missingpkg/deprecated" + _ "example.com/usemissingpre" +) diff --git a/src/cmd/go/testdata/script/mod_modinfo.txt b/src/cmd/go/testdata/script/mod_modinfo.txt new file mode 100644 index 0000000..8d77e22 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_modinfo.txt @@ -0,0 +1,89 @@ +# Test to ensure runtime/debug.ReadBuildInfo parses +# the modinfo embedded in a binary by the go tool +# when module is enabled. +env GO111MODULE=on + +cd x +go mod edit -require=rsc.io/quote@v1.5.2 +go mod edit -replace=rsc.io/quote@v1.5.2=rsc.io/quote@v1.0.0 +go mod tidy # populate go.sum + +# Build a binary and ensure that it can output its own debug info. +# The debug info should be accessible before main starts (golang.org/issue/29628). +go build +exec ./x$GOEXE +stderr 'mod\s+x\s+\(devel\)' +stderr 'dep\s+rsc.io/quote\s+v1.5.2\s+' +stderr '=>\s+rsc.io/quote\s+v1.0.0\s+h1:' +stderr 'Hello, world.' + +[short] skip + +# Build a binary that accesses its debug info by reading the binary directly +# (rather than through debug.ReadBuildInfo). +# The debug info should still be present (golang.org/issue/28753). +cd unused +go build +exec ./unused$GOEXE + +-- x/go.mod -- +module x + +-- x/lib/lib.go -- +// Package lib accesses runtime/debug.modinfo before package main's init +// functions have run. +package lib + +import "runtime/debug" + +func init() { + m, ok := debug.ReadBuildInfo() + if !ok { + panic("failed debug.ReadBuildInfo") + } + println("mod", m.Main.Path, m.Main.Version) + for _, d := range m.Deps { + println("dep", d.Path, d.Version, d.Sum) + if r := d.Replace; r != nil { + println("=>", r.Path, r.Version, r.Sum) + } + } +} + +-- x/main.go -- +package main + +import ( + "rsc.io/quote" + _ "x/lib" +) + +func main() { + println(quote.Hello()) +} + +-- x/unused/main.go -- +// The unused binary does not access runtime/debug.modinfo. +package main + +import ( + "bytes" + "encoding/hex" + "log" + "os" + + _ "rsc.io/quote" +) + +func main() { + b, err := os.ReadFile(os.Args[0]) + if err != nil { + log.Fatal(err) + } + + infoStart, _ := hex.DecodeString("3077af0c9274080241e1c107e6d618e6") + if !bytes.Contains(b, infoStart) { + log.Fatal("infoStart not found in binary") + } + log.Println("ok") +} diff --git a/src/cmd/go/testdata/script/mod_multirepo.txt b/src/cmd/go/testdata/script/mod_multirepo.txt new file mode 100644 index 0000000..0f335a1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_multirepo.txt @@ -0,0 +1,41 @@ +env GO111MODULE=on + +# initial standalone module should use no downloaded modules +go list -deps -f {{.Dir}} +! stdout 'pkg[\\/]mod' + +# v2 import should use a downloaded module +# both without an explicit go.mod entry ... +cp tmp/use_v2.go x.go +go get -d . +go list -deps -f {{.Dir}} +stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$' + +# ... and with one ... +cp tmp/use_v2.mod go.mod +go list -deps -f {{.Dir}} +stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$' + +# ... and even if there is a v2 module in a subdirectory. +mkdir v2 +cp x.go v2/x.go +cp tmp/v2.mod v2/go.mod +go list -deps -f {{.Dir}} +stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$' + +-- go.mod -- +module rsc.io/quote + +-- x.go -- +package quote + +-- tmp/use_v2.go -- +package quote +import _ "rsc.io/quote/v2" + +-- tmp/use_v2.mod -- +module rsc.io/quote +require rsc.io/quote/v2 v2.0.1 + +-- tmp/v2.mod -- +package rsc.io/quote/v2 diff --git a/src/cmd/go/testdata/script/mod_nomod.txt b/src/cmd/go/testdata/script/mod_nomod.txt new file mode 100644 index 0000000..7e0f55a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_nomod.txt @@ -0,0 +1,43 @@ +# Test go commands with no module. +env GO111MODULE=on + +# go mod edit fails unless given explicit mod file argument +! go mod edit -json +go mod edit -json x.mod + +# bug succeeds +[exec:echo] env BROWSER=echo +[exec:echo] go bug + +# commands that load the package in the current directory fail +! go build +! go fmt +! go generate +! go get +! go install +! go list +! go run +! go test +! go vet + +# clean succeeds, even with -modcache +go clean -modcache + +# doc succeeds for standard library +go doc unsafe + +# env succeeds +go env + +# tool succeeds +go tool -n test2json + +# version succeeds +go version + +-- x.mod -- +module m + +-- x.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/mod_notall.txt b/src/cmd/go/testdata/script/mod_notall.txt new file mode 100644 index 0000000..1657c8d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_notall.txt @@ -0,0 +1,99 @@ +# This test demonstrates go commands that combine the 'all' pattern +# with packages outside of 'all'. + +# With -deps, 'all' should include test dependencies of packages in the main +# module, but not should not include test dependencies of packages imported only +# by other root patterns. + +env GOFLAGS=-mod=mod +cp go.mod go.mod.orig + +go list -deps all x/otherroot + +stdout '^x/inall$' +stdout '^x/inall/fromtest$' +stdout '^x/inall/fromtestinall$' +stdout '^x/otherroot$' +stdout '^x/otherdep$' + +! stdout '^x/fromotherroottest$' +! stdout '^y/fromotherdeptest$' + +cmp go.mod go.mod.orig + +# With -deps -test, test dependencies of other roots should be included, +# but test dependencies of non-roots should not. + +go list -deps -test all x/otherroot +stdout '^x/inall$' +stdout '^x/inall/fromtest$' +stdout '^x/inall/fromtestinall$' +stdout '^x/otherroot$' +stdout '^x/otherdep$' + +stdout '^x/fromotherroottest$' +! stdout '^y/fromotherdeptest$' + +cmp go.mod go.mod.orig + +-- m.go -- +package m + +import _ "x/inall" +-- m_test.go -- +package m_test + +import _ "x/inall/fromtest" +-- go.mod -- +module m + +go 1.15 + +require x v0.1.0 + +replace ( + x v0.1.0 => ./x + y v0.1.0 => ./y +) +-- x/go.mod -- +module x + +go 1.15 +-- x/inall/inall.go -- +package inall +-- x/inall/inall_test.go -- +package inall_test + +import _ "x/inall/fromtestinall" +-- x/inall/fromtest/fromtest.go -- +package fromtest +-- x/inall/fromtestinall/fromtestinall.go -- +package fromtestinall +-- x/otherroot/otherroot.go -- +package otherroot + +import _ "x/otherdep" +-- x/otherroot/otherroot_test.go -- +package otherroot_test + +import _ "x/fromotherroottest" +-- x/fromotherroottest/fromotherroottest.go -- +package fromotherroottest +-- x/otherdep/otherdep.go -- +package otherdep +-- x/otherdep/otherdep_test.go -- +package otherdep_test + +import _ "y/fromotherdeptest" +-- x/otherroot/testonly/testonly.go -- +package testonly +-- y/go.mod -- +module y + +go 1.15 +-- y/fromotherdeptest/fromotherdeptest.go -- +// Package fromotherdeptest is a test dependency of x/otherdep that is +// not declared in x/go.mod. If the loader resolves this package, +// it will add this module to the main module's go.mod file, +// and we can detect the mistake. +package fromotherdeptest diff --git a/src/cmd/go/testdata/script/mod_off.txt b/src/cmd/go/testdata/script/mod_off.txt new file mode 100644 index 0000000..a73a58d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_off.txt @@ -0,0 +1,35 @@ +env GO111MODULE=off + +# This script tests that running go mod with +# GO111MODULE=off when outside of GOPATH will fatal +# with an error message, even with some source code in the directory and a go.mod. +! go mod init +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod graph +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod verify +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod download +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' + +# Same result in an empty directory +mkdir z +cd z +! go mod init +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod graph +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod verify +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod download +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' + +-- sample.go -- +package sample + +func main() {} + +-- go.mod -- +module sample + +go 1.12 diff --git a/src/cmd/go/testdata/script/mod_off_init.txt b/src/cmd/go/testdata/script/mod_off_init.txt new file mode 100644 index 0000000..2aec0b3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_off_init.txt @@ -0,0 +1,5 @@ +# 'go mod init' should refuse to initialize a module if it will be +# ignored anyway due to GO111MODULE=off. +env GO111MODULE=off +! go mod init +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' diff --git a/src/cmd/go/testdata/script/mod_outside.txt b/src/cmd/go/testdata/script/mod_outside.txt new file mode 100644 index 0000000..5655892 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_outside.txt @@ -0,0 +1,328 @@ +env GO111MODULE=on +[short] skip + +# This script tests commands in module mode outside of any module. +# +# First, ensure that we really are in module mode, and that we really don't have +# a go.mod file. +go env GOMOD +stdout 'NUL|/dev/null' + + +# 'go list' without arguments implicitly operates on the current directory, +# which is not in a module. +! go list +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +go list -m +stdout '^command-line-arguments$' +# 'go list' in the working directory should fail even if there is a a 'package +# main' present: without a main module, we do not know its package path. +! go list ./needmod +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go list all' lists the transitive import graph of the main module, +# which is empty if there is no main module. +go list all +! stdout . +stderr 'warning: "all" matched no packages' + +# 'go list' on standard-library packages should work, since they do not depend +# on the contents of any module. +go list -deps cmd +stdout '^fmt$' +stdout '^cmd/go$' + +go list $GOROOT/src/fmt +stdout '^fmt$' + +# 'go list' should work with file arguments. +go list ./needmod/needmod.go +stdout 'command-line-arguments' + +# 'go list' on a package from a module should fail. +! go list example.com/printversion +stderr '^no required module provides package example.com/printversion: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go list -m' with an explicit version should resolve that version. +go list -m example.com/version@latest +stdout 'example.com/version v1.1.0' + +# 'go list -m -versions' should succeed even without an explicit version. +go list -m -versions example.com/version +stdout 'v1.0.0\s+v1.0.1\s+v1.1.0' + +# 'go list -m all' should fail. "all" is not meaningful outside of a module. +! go list -m all +stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go list -m <mods> all' should also fail. +! go list -m example.com/printversion@v1.0.0 all +stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! stdout 'example.com/version' + +# 'go list -m' with wildcards should fail. Wildcards match modules in the +# build list, so they aren't meaningful outside a module. +! go list -m ... +stderr 'go: cannot match "...": go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go list -m rsc.io/quote/... +stderr 'go: cannot match "rsc.io/quote/...": go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go clean' should skip the current directory if it isn't in a module. +go clean -n +! stdout . +! stderr . + +# 'go mod graph' should fail, since there's no module graph. +! go mod graph +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go mod why' should fail, since there is no main module to depend on anything. +! go mod why -m example.com/version +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go mod edit', 'go mod tidy', and 'go mod fmt' should fail: +# there is no go.mod file to edit. +! go mod tidy +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go mod edit -fmt +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go mod edit -require example.com/version@v1.0.0 +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go mod download' without arguments should report an error. +! go mod download +stderr 'no modules specified' + +# 'go mod download' should download exactly the requested module without dependencies. +rm -r $GOPATH/pkg/mod/cache/download/example.com +go mod download example.com/printversion@v1.0.0 +exists $GOPATH/pkg/mod/cache/download/example.com/printversion/@v/v1.0.0.zip +! exists $GOPATH/pkg/mod/cache/download/example.com/version/@v/v1.0.0.zip + +# 'go mod download all' should fail. "all" is not meaningful outside of a module. +! go mod download all +stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go mod vendor' should fail: it starts by clearing the existing vendor +# directory, and we don't know where that is. +! go mod vendor +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go mod verify' should fail: we have no modules to verify. +! go mod verify +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go get' without arguments implicitly operates on the main module, and thus +# should fail. +! go get +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go get -u +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go get -u ./needmod +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go get -u all' upgrades the transitive import graph of the main module, +# which is empty. +! go get -u all +stderr '^go get: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go get' should check the proposed module graph for consistency, +# even though we won't write it anywhere. +! go get -d example.com/printversion@v1.0.0 example.com/version@none +stderr '^go get: example.com/printversion@v1.0.0 requires example.com/version@v1.0.0, not example.com/version@none$' + +# 'go get -d' should download and extract the source code needed to build the requested version. +rm -r $GOPATH/pkg/mod/example.com +go get -d example.com/printversion@v1.0.0 +exists $GOPATH/pkg/mod/example.com/printversion@v1.0.0 +exists $GOPATH/pkg/mod/example.com/version@v1.0.0 + + +# 'go build' without arguments implicitly operates on the current directory, and should fail. +cd needmod +! go build +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +cd .. + +# 'go build' of a non-module directory should fail too. +! go build ./needmod +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go build' of source files should fail if they import anything outside std. +! go build -n ./needmod/needmod.go +stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go build' of source files should succeed if they do not import anything outside std. +go build -n -o ignore ./stdonly/stdonly.go + +# 'go build' should succeed for standard-library packages. +go build -n fmt + + +# 'go doc' without arguments implicitly operates on the current directory, and should fail. +# TODO(golang.org/issue/32027): currently, it succeeds. +cd needmod +go doc +cd .. + +# 'go doc' of a non-module directory should also succeed. +go doc ./needmod + +# 'go doc' should succeed for standard-library packages. +go doc fmt + +# 'go doc' should fail for a package path outside a module. +! go doc example.com/version +stderr 'doc: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go install' with a version should succeed if all constraints are met. +# See mod_install_pkg_version. +rm $GOPATH/bin +go install example.com/printversion@v0.1.0 +exists $GOPATH/bin/printversion$GOEXE + +# 'go install' should fail if a package argument must be resolved to a module. +! go install example.com/printversion +stderr '^go install: version is required when current directory is not in a module\n\tTry ''go install example.com/printversion@latest'' to install the latest version$' + +# 'go install' should fail if a source file imports a package that must be +# resolved to a module. +! go install ./needmod/needmod.go +stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go install' should succeed with a package in GOROOT. +go install cmd/addr2line +! stderr . + +# 'go run' with a verison should fail due to syntax. +! go run example.com/printversion@v1.0.0 +stderr 'can only use path@version syntax with' + +# 'go run' should fail if a package argument must be resolved to a module. +! go run example.com/printversion +stderr '^no required module provides package example.com/printversion: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go run' should fail if a source file imports a package that must be +# resolved to a module. +! go run ./needmod/needmod.go +stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go fmt' should be able to format files outside of a module. +go fmt needmod/needmod.go + + +# The remainder of the test checks dependencies by linking and running binaries. + +# 'go get' of a binary without a go.mod should install the requested version, +# resolving outside dependencies to the latest available versions. +go get example.com/printversion@v0.1.0 +exec ../bin/printversion +stdout 'path is example.com/printversion' +stdout 'main is example.com/printversion v0.1.0' +stdout 'using example.com/version v1.1.0' + +# 'go get' of a versioned binary should build and install the latest version +# using its minimal required modules, ignoring replacements and exclusions. +go get example.com/printversion +exec ../bin/printversion +stdout 'path is example.com/printversion' +stdout 'main is example.com/printversion v1.0.0' +stdout 'using example.com/version v1.0.0' + +# 'go get -u=patch' should patch dependencies before installing, +# again ignoring replacements and exclusions. +go get -u=patch example.com/printversion@v1.0.0 +exec ../bin/printversion +stdout 'path is example.com/printversion' +stdout 'main is example.com/printversion v1.0.0' +stdout 'using example.com/version v1.0.1' + +# 'go run' should work with file arguments if they don't import anything +# outside std. +go run ./stdonly/stdonly.go +stdout 'path is command-line-arguments$' +stdout 'main is command-line-arguments \(devel\)' + +# 'go generate' should work with file arguments. +[exec:touch] go generate ./needmod/needmod.go +[exec:touch] exists ./needmod/gen.txt + +# 'go install' should work with file arguments. +go install ./stdonly/stdonly.go + +# 'go test' should work with file arguments. +go test -v ./stdonly/stdonly_test.go +stdout 'stdonly was tested' + +# 'go vet' should work with file arguments. +go vet ./stdonly/stdonly.go + + +-- README.txt -- +There is no go.mod file in the working directory. + +-- needmod/needmod.go -- +//go:generate touch gen.txt + +package main + +import ( + "fmt" + "os" + "runtime/debug" + + _ "example.com/version" +) + +func main() { + info, ok := debug.ReadBuildInfo() + if !ok { + panic("missing build info") + } + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + } +} + +-- stdonly/stdonly.go -- +package main + +import ( + "fmt" + "os" + "runtime/debug" +) + +func main() { + info, ok := debug.ReadBuildInfo() + if !ok { + panic("missing build info") + } + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + } +} + +-- stdonly/stdonly_test.go -- +package main + +import ( + "fmt" + "testing" +) + +func Test(t *testing.T) { + fmt.Println("stdonly was tested") +} + diff --git a/src/cmd/go/testdata/script/mod_overlay.txt b/src/cmd/go/testdata/script/mod_overlay.txt new file mode 100644 index 0000000..92e79c7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_overlay.txt @@ -0,0 +1,254 @@ +# Test overlays that affect go.mod files + +# The go.mod file can exist only in the overlay. +cd $WORK/gopath/src/no-go-mod +go list -overlay overlay.json . +stdout example.com/simple + +# Check content of overlaid go.mod is used. +cd $WORK/gopath/src/overlay-go-mod +go list -overlay overlay.json . +stdout use.this/module/name + +# Check content of overlaid go.mod in a replacement module is used. +# The go.mod in the replacement module is missing a requirement +# that the overlay has, so it will fail to list without the overlay. +cd $WORK/gopath/src/overlay-replaced-go-mod +! go list -deps . +go list -deps -overlay overlay.json . + +# Overlaid go.mod is not rewritten by 'go get'. +cd $WORK/gopath/src/get-doesnt-add-dep +cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod +! go get -d -overlay overlay.json . +stderr 'overlaid files can''t be opened for write' +cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod + +# Content of overlaid go.sum is used. +# The go.sum in the module directory has garbage values for its +# hashes, but the overlaid file has the correct values. If +# the correct go.sum is used with the overlay, 'go get .' should +# not report a security error. +cd $WORK/gopath/src/overlay-sum-used +! go get -d . +stderr 'SECURITY ERROR' +! go mod verify +stderr 'SECURITY ERROR' +go get -d -overlay overlay.json . +go mod verify -overlay overlay.json +# Overlaid go.sum is not rewritten. +# Copy an incomplete file to the overlay file, and expect an error +# attempting to update the file +cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums +! go get -d -overlay overlay.json . +stderr 'overlaid files can''t be opened for write' +cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums +! go mod tidy -overlay overlay.json +stderr 'overlaid files can''t be opened for write' +cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums + +# -overlay works with -modfile. +# There's an empty go.mod file in the directory, and the file alternate.mod is +# overlaid to the true go.mod file, so the -modfile flag and the overlay +# mechanism need to work together to determine the name of the module. +cd $WORK/gopath/src/overlay-and-dash-modfile +go list -modfile=alternate.mod -overlay overlay.json . +stdout 'found.the/module' +# Even with -modfile, overlaid files can't be opened for write. +! go get -modfile=alternate.mod -overlay overlay.json -d rsc.io/quote +stderr 'overlaid files can''t be opened for write' + +# Carving out a module by adding an overlaid go.mod file +cd $WORK/gopath/src/carve +go list ./... # without an overlay, hasmod is carved out and nomod isn't +stdout carve/nomod +! stdout carve/hasmod +go list -overlay overlay_carve_module.json ./... # The overlay carves out nomod, leaving nothing +! stdout . +stderr 'matched no packages' +go list -overlay overlay_uncarve_module.json ./... # The overlay uncarves out hasmod +stdout carve/nomod +stdout carve/hasmod + +# Carving out a module by adding an overlaid go.mod file and using +# -modfile to write to that file. +cd $WORK/gopath/src/carve2/nomod +go list -overlay overlay.json all +! stdout ^carve2$ +stdout ^carve2/nomod$ +# Editing go.mod file fails because overlay is read only +! go get -overlay overlay.json -d rsc.io/quote +stderr 'overlaid files can''t be opened for write' +! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod +# Editing go.mod file succeeds because we use -modfile to redirect to same file +go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod -d rsc.io/quote +grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod + +-- no-go-mod/file.go -- +package simple +-- no-go-mod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/simple_go_mod" + } +} +-- $WORK/overlay/simple_go_mod -- +module example.com/simple +-- overlay-go-mod/file.go -- +package name +-- overlay-go-mod/go.mod -- +module dont.use/this/module/name +-- overlay-go-mod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/use_this_go_mod" + } +} +-- $WORK/overlay/use_this_go_mod -- +module use.this/module/name +-- overlay-replaced-go-mod/go.mod -- +module m + +go 1.15 + +require replaced/mod v1.0.0 +replace replaced/mod v1.0.0 => ../replaced-mod +replace dep/mod v1.0.0 => ../dep-mod +-- overlay-replaced-go-mod/source.go -- +package m + +import "replaced/mod/foo" + +func main() { + foo.f() +} +-- overlay-replaced-go-mod/overlay.json -- +{ + "Replace": { + "../replaced-mod/go.mod": "../../../overlay/replacement_module_go_mod" + } +} +-- replaced-mod/go.mod -- +module replaced/mod +-- replaced-mod/foo/foo.go -- +package foo + +import "dep/mod/foo" + +func f() { foo.g() } +-- dep-mod/go.mod -- +invalid +-- dep-mod/foo/foo.go -- +package foo + +func g() { fmt.Println("hello") } +-- $WORK/overlay/replacement_module_go_mod -- +module replaced/mod + +require dep/mod v1.0.0 + +-- get-doesnt-add-dep/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/get_doesnt_add_dep_go_mod" + } +} +-- get-doesnt-add-dep/p.go -- +package p + +import "dependency/mod" + +func f() { mod.G() } +-- get-doesnt-add-dep-dependency/go.mod -- +module dependency/mod +-- get-doesnt-add-dep-dependency/mod.go -- +package mod + +func G() {} +-- $WORK/overlay/get_doesnt_add_dep_go_mod -- +module get.doesnt/add/dep + +replace dependency/mod v1.0.0 => ../get-doesnt-add-dep-dependency +-- overlay-sum-used/go.mod -- +module overlay.sum/used + +require rsc.io/quote v1.5.0 +-- overlay-sum-used/p.go -- +package p + +import "rsc.io/quote" + +func f() string { + return quote.Hello() +} +-- overlay-sum-used/incomplete-sum-file -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +rsc.io/quote v1.5.0 h1:6fJa6E+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +-- overlay-sum-used/overlay.json -- +{ + "Replace": { + "go.sum": "../../../overlay/overlay-sum-used-correct-sums" + } +} +-- overlay-sum-used/go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:garbage+hash +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:garbage+hash +rsc.io/quote v1.5.0 h1:garbage+hash +rsc.io/quote v1.5.0/go.mod h1:garbage+hash +rsc.io/sampler v1.3.0 h1:garbage+hash +rsc.io/sampler v1.3.0/go.mod h1:garbage+hash +-- $WORK/overlay/overlay-sum-used-correct-sums -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.0 h1:6fJa6E+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE= +rsc.io/quote v1.5.0/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- overlay-and-dash-modfile/p.go -- +package module +-- overlay-and-dash-modfile/go.mod -- +-- overlay-and-dash-modfile/overlay.json -- +{ + "Replace": { + "alternate.mod": "../../../overlay/overlay-and-dash-modfile-alternate-mod" + } +} +-- $WORK/overlay/overlay-and-dash-modfile-alternate-mod -- +module found.the/module +-- carve/go.mod -- +module carve +-- carve/overlay_carve_module.json -- +{ + "Replace": { + "nomod/go.mod": "../../../overlay/carve-nomod-go-mod" + } +} +-- carve/overlay_uncarve_module.json -- +{ + "Replace": { + "hasmod/go.mod": "" + } +} +-- carve/hasmod/a.go -- +package hasmod +-- carve/hasmod/go.mod -- +module carve/hasmod +-- carve/nomod/b.go -- +package nomod +-- $WORK/overlay/carve-nomod-go-mod -- +module carve/nomod +-- carve2/go.mod -- +module carve2 +-- carve2/p.go -- +package p +-- carve2/nomod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../../overlay/carve2-nomod-go.mod" + } +} +-- carve2/nomod/b.go -- +package nomod +-- $WORK/overlay/carve2-nomod-go.mod -- +module carve2/nomod diff --git a/src/cmd/go/testdata/script/mod_patterns.txt b/src/cmd/go/testdata/script/mod_patterns.txt new file mode 100644 index 0000000..1b4b438 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_patterns.txt @@ -0,0 +1,78 @@ +env GO111MODULE=on +[short] skip + +cd m + +# 'go list all' should list all of the packages used (directly or indirectly) by +# the packages in the main module, but no other packages from the standard +# library or active modules. +# +# 'go list ...' should list packages in all active modules and the standard library. +# +# 'go list example.com/m/...' should list packages in all modules that begin with 'example.com/m/'. +# +# 'go list ./...' should list only packages in the current module, not other active modules. +# +# Warnings about unmatched patterns should only be printed once. +# +# And the go command should be able to keep track of all this! +go list -f '{{.ImportPath}}: {{.Match}}' all ... example.com/m/... ./... ./xyz... +stdout 'example.com/m/useunicode: \[all \.\.\. example.com/m/... ./...\]' +stdout 'example.com/m/useunsafe: \[all \.\.\. example.com/m/... ./...\]' +[cgo] stdout 'example.com/m/useC: \[all \.\.\. example.com/m/... ./...\]' +[!cgo] ! stdout example.com/m/useC +stdout 'example.com/unused/useerrors: \[\.\.\.\]' # but not "all" +stdout 'example.com/m/nested/useencoding: \[\.\.\. example.com/m/...\]' # but NOT "all" or "./..." +stdout '^unicode: \[all \.\.\.\]' +stdout '^unsafe: \[all \.\.\.\]' +stdout 'index/suffixarray: \[\.\.\.\]' +stdout 'cmd/pprof: \[\.\.\.\]' + +stderr -count=1 '^go: warning: "./xyz..." matched no packages$' + +# 'go list ./...' should not try to resolve the main module. +cd ../empty +go list -deps ./... +! stdout . +! stderr 'finding' +stderr -count=1 '^go: warning: "./..." matched no packages' + +# disabling cgo should drop useC +[short] skip +env CGO_ENABLED=0 +go list -f '{{.ImportPath}}: {{.Match}}' all ... example.com/m/... ./... ./xyz... +! stdout example.com/m/useC + +-- m/go.mod -- +module example.com/m + +require example.com/unused v0.0.0 // indirect +replace example.com/unused => ../unused + +require example.com/m/nested v0.0.0 // indirect +replace example.com/m/nested => ../nested + +-- m/useC/useC.go -- +package useC +import _ "C" // "C" is a pseudo-package, not an actual one +-- m/useunicode/useunicode.go -- +package useunicode +import _ "unicode" +-- m/useunsafe/useunsafe.go -- +package useunsafe +import _ "unsafe" + +-- unused/go.mod -- +module example.com/unused +-- unused/useerrors/useerrors.go -- +package useerrors +import _ "errors" + +-- nested/go.mod -- +module example.com/m/nested +-- nested/useencoding/useencoding.go -- +package useencoding +import _ "encoding" + +-- empty/go.mod -- +module example.com/empty diff --git a/src/cmd/go/testdata/script/mod_patterns_vendor.txt b/src/cmd/go/testdata/script/mod_patterns_vendor.txt new file mode 100644 index 0000000..b4dc401 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_patterns_vendor.txt @@ -0,0 +1,28 @@ +env GO111MODULE=on + +go list -mod=vendor example.com/... +stdout ^example.com/x$ +stdout ^example.com/x/y$ +! stdout ^example.com/x/vendor + +-- go.mod -- +module example.com/m + +-- vendor/modules.txt -- +# example.com/x v0.0.0 +example.com/x +# example.com/x/y v0.1.0 +example.com/x/y + +-- vendor/example.com/x/go.mod -- +module example.com/x +-- vendor/example.com/x/x.go -- +package x + +-- vendor/example.com/x/y/go.mod -- +module example.com/x/y +-- vendor/example.com/x/y/y.go -- +package y + +-- vendor/example.com/x/vendor/z/z.go -- +package z diff --git a/src/cmd/go/testdata/script/mod_permissions.txt b/src/cmd/go/testdata/script/mod_permissions.txt new file mode 100644 index 0000000..2d32dcd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_permissions.txt @@ -0,0 +1,57 @@ +# Regression test for golang.org/issue/34634: permissions for the go.sum and +# go.mod files should be preserved when overwriting them. + +env GO111MODULE=on +[short] skip + +# Skip platforms that do not have Unix-style file permissions. +[windows] skip +[plan9] skip + +chmod 0640 go.mod +chmod 0604 go.sum +go mod edit -module=golang.org/issue/34634 + +go get -d +cmp go.mod go.mod.want +cmp go.sum go.sum.want + +go run . +stdout 'go.mod: 0640' +stdout 'go.sum: 0604' + +-- read_perm.go -- +package main + +import ( + "fmt" + "os" + _ "rsc.io/sampler" +) + +func main() { + for _, name := range []string{"go.mod", "go.sum"} { + fi, err := os.Stat(name) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", err) + continue + } + fmt.Printf("%s: 0%o\n", name, fi.Mode().Perm()) + } +} +-- go.mod -- +module TODO + +go 1.14 +-- go.sum -- +-- go.mod.want -- +module golang.org/issue/34634 + +go 1.14 + +require rsc.io/sampler v1.99.99 +-- go.sum.want -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/sampler v1.99.99 h1:iMG9lbEG/8MdeR4lgL+Q8IcwbLNw7ijW7fTiK8Miqts= +rsc.io/sampler v1.99.99/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_prefer_compatible.txt b/src/cmd/go/testdata/script/mod_prefer_compatible.txt new file mode 100644 index 0000000..aa6260f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_prefer_compatible.txt @@ -0,0 +1,65 @@ +# Regression test for golang.org/issue/34189 and golang.org/issue/34165: +# @latest, @upgrade, and @patch should prefer compatible versions over +# +incompatible ones, even if offered by a proxy. + +[!net] skip + +env GO111MODULE=on +env GOPROXY= +env GOSUMDB= + +# github.com/russross/blackfriday v2.0.0+incompatible exists, +# and should be resolved if we ask for v2.0 explicitly. + +go list -m github.com/russross/blackfriday@v2.0 +stdout '^github.com/russross/blackfriday v2\.0\.0\+incompatible$' + +# blackfriday v1.5.2 has a go.mod file, so v1.5.2 should be preferred over +# v2.0.0+incompatible when resolving latest, upgrade, and patch. + +go list -m github.com/russross/blackfriday@latest +stdout '^github.com/russross/blackfriday v1\.' + +go list -m github.com/russross/blackfriday@upgrade +stdout '^github.com/russross/blackfriday v1\.' + +go list -m github.com/russross/blackfriday@patch +stdout '^github.com/russross/blackfriday v1\.' + +# If we're fetching directly from version control, ignored +incompatible +# versions should also be omitted by 'go list'. + +# (Note that they may still be included in results from a proxy: in proxy mode, +# we would need to fetch the whole zipfile for the latest compatible version in +# order to determine whether it contains a go.mod file, and part of the point of +# the proxy is to avoid fetching unnecessary data.) + +[!exec:git] stop +env GOPROXY=direct + +go list -versions -m github.com/russross/blackfriday github.com/russross/blackfriday +stdout '^github.com/russross/blackfriday v1\.5\.1 v1\.5\.2' # and possibly others +! stdout ' v2\.' + +# However, if the latest compatible version does not include a go.mod file, +# +incompatible versions should still be listed, as they may still reflect the +# intent of the module author. + +go list -versions -m github.com/rsc/legacytest +stdout '^github.com/rsc/legacytest v1\.0\.0 v1\.1\.0-pre v1\.2\.0 v2\.0\.0\+incompatible' + +# If we're fetching directly from version control, asking for a commit hash +# corresponding to a +incompatible version should continue to produce the +# +incompatible version tagged for that commit, even if it is no longer listed. + +go list -m github.com/russross/blackfriday@cadec560ec52 +stdout '^github.com/russross/blackfriday v2\.0\.0\+incompatible$' + +# Similarly, requesting an untagged commit should continue to produce a +incompatible +# pseudo-version. + +go list -m github.com/rsc/legacytest@7303f7796364 +stdout '^github.com/rsc/legacytest v2\.0\.1-0\.20180717164253-7303f7796364\+incompatible$' + +-- go.mod -- +module github.com/golang.org/issue/34165 diff --git a/src/cmd/go/testdata/script/mod_proxy_errors.txt b/src/cmd/go/testdata/script/mod_proxy_errors.txt new file mode 100644 index 0000000..9cd1a82 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_proxy_errors.txt @@ -0,0 +1,19 @@ +[!net] skip + +env GO111MODULE=on +env GOSUMDB=off +env GOPROXY=direct + +# Server responses should be truncated to some reasonable number of lines. +# (For now, exactly eight.) +! go list -m vcs-test.golang.org/auth/ormanylines@latest +stderr '\tserver response:\n(.|\n)*\tline 8\n\t\[Truncated: too many lines.\]$' + +# Server responses should be truncated to some reasonable number of characters. +! go list -m vcs-test.golang.org/auth/oronelongline@latest +! stderr 'blah{40}' +stderr '\tserver response: \[Truncated: too long\.\]$' + +# Responses from servers using the 'mod' protocol should be propagated. +! go list -m vcs-test.golang.org/go/modauth404@latest +stderr '\tserver response: File\? What file\?' diff --git a/src/cmd/go/testdata/script/mod_proxy_https.txt b/src/cmd/go/testdata/script/mod_proxy_https.txt new file mode 100644 index 0000000..a23090c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_proxy_https.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on + +# GOPROXY file paths must provide the "file://" prefix explicitly. +env GOPROXY=$WORK/proxydir +! go list -versions -m golang.org/x/text +stderr 'invalid proxy URL.*proxydir' + +[!net] stop + +# GOPROXY HTTPS paths may elide the "https://" prefix. +# (See golang.org/issue/32191.) +env GOPROXY=proxy.golang.org +go list -versions -m golang.org/x/text + +-- go.mod -- +module example.com +go 1.13 +-- $WORK/proxydir/README.md -- +This proxy contains no data. diff --git a/src/cmd/go/testdata/script/mod_proxy_invalid.txt b/src/cmd/go/testdata/script/mod_proxy_invalid.txt new file mode 100644 index 0000000..6427cc1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_proxy_invalid.txt @@ -0,0 +1,8 @@ +env GO111MODULE=on +env GOPROXY=$GOPROXY/invalid + +! go list -m rsc.io/quote@latest +stderr '^go list -m: module rsc.io/quote: invalid response from proxy "'$GOPROXY'": invalid character ''i'' looking for beginning of value$' + +! go list -m rsc.io/quote@1.5.2 +stderr '^go list -m: rsc.io/quote@1.5.2: invalid version: invalid response from proxy "'$GOPROXY'": invalid character ''i'' looking for beginning of value$' diff --git a/src/cmd/go/testdata/script/mod_proxy_list.txt b/src/cmd/go/testdata/script/mod_proxy_list.txt new file mode 100644 index 0000000..89129f4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_proxy_list.txt @@ -0,0 +1,37 @@ +env GO111MODULE=on +env proxy=$GOPROXY + +# Proxy that can't serve should fail. +env GOPROXY=$proxy/404 +! go get -d rsc.io/quote@v1.0.0 +stderr '404 Not Found' + +# get should walk down the proxy list past 404 and 410 responses. +env GOPROXY=$proxy/404,$proxy/410,$proxy +go get -d rsc.io/quote@v1.1.0 + +# get should not walk past other 4xx errors if proxies are separated with ','. +env GOPROXY=$proxy/403,$proxy +! go get -d rsc.io/quote@v1.2.0 +stderr 'reading.*/403/rsc.io/.*: 403 Forbidden' + +# get should not walk past non-4xx errors if proxies are separated with ','. +env GOPROXY=$proxy/500,$proxy +! go get -d rsc.io/quote@v1.3.0 +stderr 'reading.*/500/rsc.io/.*: 500 Internal Server Error' + +# get should walk past other 4xx errors if proxies are separated with '|'. +env GOPROXY=$proxy/403|https://0.0.0.0|$proxy +go get -d rsc.io/quote@v1.2.0 + +# get should walk past non-4xx errors if proxies are separated with '|'. +env GOPROXY=$proxy/500|https://0.0.0.0|$proxy +go get -d rsc.io/quote@v1.3.0 + +# get should return the final error if that's all we have. +env GOPROXY=$proxy/404,$proxy/410 +! go get -d rsc.io/quote@v1.4.0 +stderr 'reading.*/410/rsc.io/.*: 410 Gone' + +-- go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_pseudo_cache.txt b/src/cmd/go/testdata/script/mod_pseudo_cache.txt new file mode 100644 index 0000000..dd89614 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_pseudo_cache.txt @@ -0,0 +1,29 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Regression test for golang.org/issue/27171: after resolving an older +# pseudo-version of a commit, future resolution of that commit by hash should +# choose the highest appropriate pseudo-version instead of the cached one. + +go mod download -json golang.org/x/text@v0.0.0-20171215141712-a1b916ed6726 +stdout '"Version": "v0.0.0-20171215141712-a1b916ed6726",' + +# If GOPROXY is 'off', lookups should use whatever pseudo-version is available. +env GOPROXY=off +go mod download -json golang.org/x/text@a1b916ed6726 +stdout '"Version": "v0.0.0-20171215141712-a1b916ed6726",' + +# If we can re-resolve the commit to a pseudo-version, fetching the commit by +# hash should use the highest such pseudo-version appropriate to the commit. +env GOPROXY=direct +go mod download -json golang.org/x/text@a1b916ed6726 +stdout '"Version": "v0.3.1-0.20171215141712-a1b916ed6726",' + +# If GOPROXY is 'off', lookups should use the highest pseudo-version in the cache. +env GOPROXY=off +go mod download -json golang.org/x/text@a1b916ed6726 +stdout '"Version": "v0.3.1-0.20171215141712-a1b916ed6726",' diff --git a/src/cmd/go/testdata/script/mod_query.txt b/src/cmd/go/testdata/script/mod_query.txt new file mode 100644 index 0000000..a75f86e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query.txt @@ -0,0 +1,43 @@ +env GO111MODULE=on + +# TODO(golang.org/issue/41297): we shouldn't need go.sum. None of the commands +# below depend on the build list. + +go list -m -versions rsc.io/quote +stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$' + +# Latest rsc.io/quote should be v1.5.2, not v1.5.3-pre1. +go list -m rsc.io/quote@latest +stdout 'rsc.io/quote v1.5.2$' + +# Same for rsc.io/quote@v1 and rsc.io/quote@v1.5 (with no patch version). +go list -m rsc.io/quote@v1 +stdout 'rsc.io/quote v1.5.2$' +go list -m rsc.io/quote@v1.5 +stdout 'rsc.io/quote v1.5.2$' + +# We should fall back to prereleases if no release tags match... +go list -m rsc.io/quote@>v1.5.2 +stdout 'rsc.io/quote v1.5.3-pre1$' + +# ...but prefer release versions when given the option. +go list -m rsc.io/quote@<v1.5.4 +stdout 'rsc.io/quote v1.5.2$' + +! go list -m rsc.io/quote@>v1.5.3 +stderr 'go list -m: module rsc.io/quote: no matching versions for query ">v1.5.3"' + +go list -m -e -f '{{.Error.Err}}' rsc.io/quote@>v1.5.3 +stdout 'no matching versions for query ">v1.5.3"' + +-- go.mod -- +module x +require rsc.io/quote v1.0.0 + +-- go.sum -- +rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw= +rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA= +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_query_empty.txt b/src/cmd/go/testdata/script/mod_query_empty.txt new file mode 100644 index 0000000..f8b6e3e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query_empty.txt @@ -0,0 +1,73 @@ +env GO111MODULE=on +env GOSUMDB=off + +go mod download example.com/join@v1.1.0 + +# If the proxy serves a bogus result for the @latest version, +# reading that version should cause 'go get' to fail. +env GOPROXY=file:///$WORK/badproxy +cp go.mod.orig go.mod +! go get -d example.com/join/subpkg +stderr 'go get: example.com/join/subpkg@v0.0.0-20190624000000-123456abcdef: .*' + +# If @v/list is empty, the 'go' command should still try to resolve +# other module paths. +env GOPROXY=file:///$WORK/emptysub +cp go.mod.orig go.mod +go get -d example.com/join/subpkg +go list -m example.com/join/... +! stdout 'example.com/join/subpkg' +stdout 'example.com/join v1.1.0' + +# If @v/list includes a version that the proxy does not actually serve, +# that version is treated as nonexistent. +env GOPROXY=file:///$WORK/notfound +cp go.mod.orig go.mod +go get -d example.com/join/subpkg +go list -m example.com/join/... +! stdout 'example.com/join/subpkg' +stdout 'example.com/join v1.1.0' + +# If the proxy provides an empty @v/list but rejects @latest with +# some other explicit error (for example, a "permission denied" error), +# that error should be reported to the user (and override a successful +# result for other possible module paths). +# +# Depending on how the specific platform enforces permissions, the 'go get' may +# fail either due to the intended permission error or due to a parse error. +# We accept either failure message. +env GOPROXY=file:///$WORK/gatekeeper +chmod 0000 $WORK/gatekeeper/example.com/join/subpkg/@latest +cp go.mod.orig go.mod +! go get -d example.com/join/subpkg +stderr 'go get: module example.com/join/subpkg: (invalid response from proxy ".+": invalid character .+|reading file://.*/gatekeeper/example.com/join/subpkg/@latest: .+)' + +-- go.mod.orig -- +module example.com/othermodule +go 1.13 +-- $WORK/badproxy/example.com/join/subpkg/@v/list -- +v0.0.0-20190624000000-123456abcdef +-- $WORK/badproxy/example.com/join/subpkg/@v/v0.0.0-20190624000000-123456abcdef.info -- +This file is not valid JSON. +-- $WORK/badproxy/example.com/join/@v/list -- +v1.1.0 +-- $WORK/badproxy/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} +-- $WORK/emptysub/example.com/join/subpkg/@v/list -- +-- $WORK/emptysub/example.com/join/@v/list -- +v1.1.0 +-- $WORK/emptysub/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} +-- $WORK/notfound/example.com/join/subpkg/@v/list -- +v1.0.0-does-not-exist +-- $WORK/notfound/example.com/join/@v/list -- +v1.1.0 +-- $WORK/notfound/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} +-- $WORK/gatekeeper/example.com/join/subpkg/@v/list -- +-- $WORK/gatekeeper/example.com/join/subpkg/@latest -- +ERROR: Latest version is forbidden. +-- $WORK/gatekeeper/example.com/join/@v/list -- +v1.1.0 +-- $WORK/gatekeeper/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} diff --git a/src/cmd/go/testdata/script/mod_query_exclude.txt b/src/cmd/go/testdata/script/mod_query_exclude.txt new file mode 100644 index 0000000..b001969 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query_exclude.txt @@ -0,0 +1,46 @@ +env GO111MODULE=on + +# list excluded version +go list -modfile=go.exclude.mod -m rsc.io/quote@v1.5.0 +stdout '^rsc.io/quote v1.5.0$' + +# list versions should not print excluded versions +go list -m -versions rsc.io/quote +stdout '\bv1.5.0\b' +go list -modfile=go.exclude.mod -m -versions rsc.io/quote +! stdout '\bv1.5.0\b' + +# list query with excluded version +go list -m rsc.io/quote@>=v1.5 +stdout '^rsc.io/quote v1.5.0$' +go list -modfile=go.exclude.mod -m rsc.io/quote@>=v1.5 +stdout '^rsc.io/quote v1.5.1$' + +# get excluded version +cp go.exclude.mod go.exclude.mod.orig +! go get -modfile=go.exclude.mod -d rsc.io/quote@v1.5.0 +stderr '^go get: rsc.io/quote@v1.5.0: excluded by go.mod$' + +# get non-excluded version +cp go.exclude.mod.orig go.exclude.mod +go get -modfile=go.exclude.mod -d rsc.io/quote@v1.5.1 +stderr 'rsc.io/quote v1.5.1' + +# get query with excluded version +cp go.exclude.mod.orig go.exclude.mod +go get -modfile=go.exclude.mod -d rsc.io/quote@>=v1.5 +go list -modfile=go.exclude.mod -m ...quote +stdout 'rsc.io/quote v1.5.[1-9]' + +-- go.mod -- +module x + +-- go.exclude.mod -- +module x + +exclude rsc.io/quote v1.5.0 + +-- x.go -- +package x +import _ "rsc.io/quote" + diff --git a/src/cmd/go/testdata/script/mod_query_main.txt b/src/cmd/go/testdata/script/mod_query_main.txt new file mode 100644 index 0000000..39e5841 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query_main.txt @@ -0,0 +1,43 @@ +# 'go mod download' can download specific versions of the main module. +go mod download rsc.io/quote@5d9f230b +go mod download rsc.io/quote@v1.5.2 +go mod download rsc.io/quote@latest + +# 'go mod download' will not download @upgrade or @patch, since they always +# resolve to the main module. +go mod download rsc.io/quote@upgrade +stderr '^go mod download: skipping argument rsc.io/quote@upgrade that resolves to the main module$' +go mod download rsc.io/quote@patch +stderr '^go mod download: skipping argument rsc.io/quote@patch that resolves to the main module$' + +# 'go list -m' can show a version of the main module. +go list -m rsc.io/quote@5d9f230b +stdout '^rsc.io/quote v0.0.0-20180710144737-5d9f230bcfba$' +go list -m rsc.io/quote@v1.5.2 +stdout '^rsc.io/quote v1.5.2$' +go list -m rsc.io/quote@latest +stdout '^rsc.io/quote v1.5.2$' + +# 'go list -m -versions' shows available versions. +go list -m -versions rsc.io/quote +stdout '^rsc.io/quote.*v1.5.2' + +# 'go list -m' resolves @upgrade and @patch to the main module. +go list -m rsc.io/quote@upgrade +stdout '^rsc.io/quote$' +go list -m rsc.io/quote@patch +stdout '^rsc.io/quote$' + +# 'go get' will not attempt to upgrade the main module to any specific version. +# See also: mod_get_main.txt. +! go get rsc.io/quote@5d9f230b +stderr '^go get: can''t request version "5d9f230b" of the main module \(rsc.io/quote\)$' +! go get rsc.io/quote@v1.5.2 +stderr '^go get: can''t request version "v1.5.2" of the main module \(rsc.io/quote\)$' +! go get rsc.io/quote@latest +stderr '^go get: can''t request version "latest" of the main module \(rsc.io/quote\)$' + +-- go.mod -- +module rsc.io/quote + +go 1.16 diff --git a/src/cmd/go/testdata/script/mod_readonly.txt b/src/cmd/go/testdata/script/mod_readonly.txt new file mode 100644 index 0000000..d05ad2a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_readonly.txt @@ -0,0 +1,131 @@ +env GO111MODULE=on +[short] skip + +# -mod=readonly must not resolve missing modules nor update go.mod +env GOFLAGS=-mod=readonly +go mod edit -fmt +cp go.mod go.mod.empty +! go list all +stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly' +! stderr '\(\)' # If we don't have a reason for -mod=readonly, don't log an empty one. +cmp go.mod go.mod.empty + +# -mod=readonly should be set by default. +env GOFLAGS= +! go list all +stderr '^x.go:2:8: no required module provides package rsc\.io/quote; to add it:\n\tgo get rsc\.io/quote$' +cmp go.mod go.mod.empty + +env GOFLAGS=-mod=readonly + +# update go.mod - go get allowed +go get -d rsc.io/quote +grep rsc.io/quote go.mod + +# update go.mod - go mod tidy allowed +cp go.mod.empty go.mod +go mod tidy +cp go.mod go.mod.tidy + +# -mod=readonly must succeed once go.mod is up-to-date... +go list all + +# ... even if it needs downloads +go clean -modcache +go list all + +# -mod=readonly must not cause 'go list -m' to fail. +# (golang.org/issue/36478) +go list -m all +! stderr 'cannot query module' + +# -mod=readonly should reject inconsistent go.mod files +# (ones that would be rewritten). +go get -d rsc.io/sampler@v1.2.0 +go mod edit -require rsc.io/quote@v1.5.2 +cp go.mod go.mod.inconsistent +! go list +stderr 'go: updates to go.mod needed, disabled by -mod=readonly' +cmp go.mod go.mod.inconsistent + +# We get a different message when -mod=readonly is used by default. +env GOFLAGS= +! go list +stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy' + +# However, it should not reject files missing a 'go' directive, +# since that was not always required. +cp go.mod.nogo go.mod +go list all +cmp go.mod go.mod.nogo + +# Nor should it reject files with redundant (not incorrect) +# requirements. +cp go.mod.redundant go.mod +go list all +cmp go.mod go.mod.redundant + +cp go.mod.indirect go.mod +go list all +cmp go.mod go.mod.indirect + + +# If we identify a missing package as a dependency of some other package in the +# main module, we should suggest 'go mod tidy' instead of resolving it. + +cp go.mod.untidy go.mod +! go list all +stderr '^x.go:2:8: no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$' + +! go list -deps . +stderr '^x.go:2:8: no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$' + +# However, if we didn't see an import from the main module, we should suggest +# 'go get -d' instead, because we don't know whether 'go mod tidy' would add it. +! go list rsc.io/quote +stderr '^no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$' + + +-- go.mod -- +module m + +go 1.16 + +-- x.go -- +package x +import _ "rsc.io/quote" +-- go.mod.nogo -- +module m + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.redundant -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.indirect -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.untidy -- +module m + +go 1.16 + +require ( + rsc.io/sampler v1.3.0 // indirect +) diff --git a/src/cmd/go/testdata/script/mod_replace.txt b/src/cmd/go/testdata/script/mod_replace.txt new file mode 100644 index 0000000..dc9667f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace.txt @@ -0,0 +1,129 @@ +env GO111MODULE=on +[short] skip + +cp go.mod go.mod.orig + +# Make sure the test builds without replacement. +go build -mod=mod -o a1.exe . +exec ./a1.exe +stdout 'Don''t communicate by sharing memory' + +# Modules can be replaced by local packages. +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=./local/rsc.io/quote/v3 +go build -o a2.exe . +exec ./a2.exe +stdout 'Concurrency is not parallelism.' + +# The module path of the replacement doesn't need to match. +# (For example, it could be a long-running fork with its own import path.) +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=./local/not-rsc.io/quote/v3 +go build -o a3.exe . +exec ./a3.exe +stdout 'Clear is better than clever.' + +# However, the same module can't be used as two different paths. +cp go.mod.orig go.mod +go mod edit -replace=not-rsc.io/quote/v3@v3.0.0=rsc.io/quote/v3@v3.0.0 -require=not-rsc.io/quote/v3@v3.0.0 +! go build -o a4.exe . +stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)' + +# Modules that do not (yet) exist upstream can be replaced too. +cp go.mod.orig go.mod +go mod edit -replace=not-rsc.io/quote/v3@v3.1.0=./local/rsc.io/quote/v3 +go build -mod=mod -o a5.exe ./usenewmodule +! stderr 'finding not-rsc.io/quote/v3' +grep 'not-rsc.io/quote/v3 v3.1.0' go.mod +exec ./a5.exe +stdout 'Concurrency is not parallelism.' + +# Error messages for modules not found in replacements should +# indicate the replacement module. +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=./local/rsc.io/quote/v3 +! go get -d rsc.io/quote/v3/missing-package +stderr 'module rsc.io/quote/v3@upgrade found \(v3.0.0, replaced by ./local/rsc.io/quote/v3\), but does not contain package' + +# The reported Dir and GoMod for a replaced module should be accurate. +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=not-rsc.io/quote@v0.1.0-nomod +go mod download +go list -m -f '{{.Path}} {{.Version}} {{.Dir}} {{.GoMod}}{{with .Replace}} => {{.Path}} {{.Version}} {{.Dir}} {{.GoMod}}{{end}}' rsc.io/quote/v3 +stdout '^rsc.io/quote/v3 v3.0.0 '$GOPATH'[/\\]pkg[/\\]mod[/\\]not-rsc.io[/\\]quote@v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]not-rsc.io[/\\]quote[/\\]@v[/\\]v0.1.0-nomod.mod => not-rsc.io/quote v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]not-rsc.io[/\\]quote@v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]not-rsc.io[/\\]quote[/\\]@v[/\\]v0.1.0-nomod.mod$' + +-- go.mod -- +module quoter + +require rsc.io/quote/v3 v3.0.0 + +-- main.go -- +package main + +import ( + "fmt" + "rsc.io/quote/v3" +) + +func main() { + fmt.Println(quote.GoV3()) +} + +-- usenewmodule/main.go -- +package main + +import ( + "fmt" + "not-rsc.io/quote/v3" +) + +func main() { + fmt.Println(quote.GoV3()) +} + +-- local/rsc.io/quote/v3/go.mod -- +module rsc.io/quote/v3 + +require rsc.io/sampler v1.3.0 + +-- local/rsc.io/quote/v3/quote.go -- +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package quote collects pithy sayings. +package quote + +import "rsc.io/sampler" + +// Hello returns a greeting. +func HelloV3() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func GlassV3() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a REPLACED Go proverb. +func GoV3() string { + return "Concurrency is not parallelism." +} + +// Opt returns a optimization truth. +func OptV3() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} + +-- local/not-rsc.io/quote/v3/go.mod -- +module not-rsc.io/quote/v3 + +-- local/not-rsc.io/quote/v3/quote.go -- +package quote + +func GoV3() string { + return "Clear is better than clever." +} diff --git a/src/cmd/go/testdata/script/mod_replace_gopkgin.txt b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt new file mode 100644 index 0000000..df752d9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt @@ -0,0 +1,80 @@ +# Regression test for golang.org/issue/34254: +# a clone of gopkg.in/[…].vN should be replaceable by +# a fork hosted at corp.example.com/[…]/vN, +# even if there is an explicit go.mod file containing the +# gopkg.in path. + +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off +env GOFLAGS=-mod=mod + +# Replacing gopkg.in/[…].vN with a repository with a root go.mod file +# specifying […].vN and a compatible version should succeed, even if +# the replacement path is not a gopkg.in path. +cd 4-to-4 +go list -m gopkg.in/src-d/go-git.v4 + +# Previous versions of the "go" command accepted v0 and v1 pseudo-versions +# as replacements for gopkg.in/[…].v4. +# As a special case, we continue to accept those. + +cd ../4-to-0 +go list -m gopkg.in/src-d/go-git.v4 + +cd ../4-to-1 +go list -m gopkg.in/src-d/go-git.v4 + +cd ../4-to-incompatible +go list -m gopkg.in/src-d/go-git.v4 + +# A mismatched gopkg.in path should not be able to replace a different major version. +cd ../3-to-gomod-4 +! go list -m gopkg.in/src-d/go-git.v3 +stderr '^go: gopkg\.in/src-d/go-git\.v3@v3\.2\.0 \(replaced by gopkg\.in/src-d/go-git\.v3@v3\.0\.0-20190801152248-0d1a009cbb60\): version "v3\.0\.0-20190801152248-0d1a009cbb60" invalid: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$' + +-- 4-to-4/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git/v4 v4.13.1 +-- 4-to-1/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v1.0.1-0.20190801152248-0d1a009cbb60 +-- 4-to-0/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v0.0.0-20190801152248-0d1a009cbb60 +-- 4-to-incompatible/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v4.6.0+incompatible +-- 3-to-gomod-4/go.mod -- +module golang.org/issue/34254 +go 1.13 + +require gopkg.in/src-d/go-git.v3 v3.2.0 + +// This replacement has a go.mod file declaring its path to be +// gopkg.in/src-d/go-git.v4, so it cannot be used as a replacement for v3. +replace gopkg.in/src-d/go-git.v3 v3.2.0 => gopkg.in/src-d/go-git.v3 v3.0.0-20190801152248-0d1a009cbb60 diff --git a/src/cmd/go/testdata/script/mod_replace_import.txt b/src/cmd/go/testdata/script/mod_replace_import.txt new file mode 100644 index 0000000..2add31f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace_import.txt @@ -0,0 +1,144 @@ +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 -d +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 diff --git a/src/cmd/go/testdata/script/mod_replace_readonly.txt b/src/cmd/go/testdata/script/mod_replace_readonly.txt new file mode 100644 index 0000000..d950d78 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace_readonly.txt @@ -0,0 +1,62 @@ +# Check that with -mod=readonly, when we load a package in a module that is +# replaced but not required, we emit an error with the command to add the +# requirement. +# Verifies golang.org/issue/41416, golang.org/issue/41577. +cp go.mod go.mod.orig + +# Replace all versions of a module without requiring it. +# With -mod=mod, we'd add a requirement for a "zero" pseudo-version, but we +# can't in readonly mode, since its go.mod may alter the build list. +go mod edit -replace rsc.io/quote=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote$' +go get -d rsc.io/quote +cmp go.mod go.mod.latest +go list rsc.io/quote +cp go.mod.orig go.mod + +# Same test with a specific version. +go mod edit -replace rsc.io/quote@v1.0.0-doesnotexist=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote@v1.0.0-doesnotexist$' +go get -d rsc.io/quote@v1.0.0-doesnotexist +cmp go.mod go.mod.specific +go list rsc.io/quote +cp go.mod.orig go.mod + +# If there are multiple versions, the highest is suggested. +go mod edit -replace rsc.io/quote@v1.0.0-doesnotexist=./quote +go mod edit -replace rsc.io/quote@v1.1.0-doesnotexist=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote@v1.1.0-doesnotexist$' + +-- go.mod -- +module m + +go 1.16 +-- go.mod.latest -- +module m + +go 1.16 + +replace rsc.io/quote => ./quote + +require rsc.io/quote v1.5.2 // indirect +-- go.mod.specific -- +module m + +go 1.16 + +replace rsc.io/quote v1.0.0-doesnotexist => ./quote + +require rsc.io/quote v1.0.0-doesnotexist // indirect +-- use.go -- +package use + +import _ "rsc.io/quote" +-- quote/go.mod -- +module rsc.io/quote + +go 1.16 +-- quote/quote.go -- +package quote diff --git a/src/cmd/go/testdata/script/mod_require_exclude.txt b/src/cmd/go/testdata/script/mod_require_exclude.txt new file mode 100644 index 0000000..9156d4c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_require_exclude.txt @@ -0,0 +1,81 @@ +# build with no newer version to satisfy exclude +env GO111MODULE=on +cp go.mod go.mod.orig + +# With the selected version excluded, commands that query that version without +# updating go.mod should fail. + +! go list -mod=readonly -m all +stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$' +stderr '^go: updates to go.mod needed, disabled by -mod=readonly$' +! stdout '^rsc.io/sampler v1.99.99' +cmp go.mod go.mod.orig + +! go list -mod=vendor -m rsc.io/sampler +stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$' +stderr '^go list -m: module rsc.io/sampler: can''t resolve module using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass\.\)$' +! stdout '^rsc.io/sampler v1.99.99' +cmp go.mod go.mod.orig + +# With the selected version excluded, commands that load only modules should +# drop the excluded module. + +go list -m -mod=mod all +stderr '^go: dropping requirement on excluded version rsc.io/sampler v1\.99\.99$' +stdout '^x$' +! stdout '^rsc.io/sampler' +cmp go.mod go.moddrop + +# With the latest version excluded, 'go list' should resolve needed packages +# from the next-highest version. + +cp go.mod.orig go.mod +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +stderr '^go: dropping requirement on excluded version rsc.io/sampler v1\.99\.99$' +stdout '^x $' +! stdout '^rsc.io/sampler v1.99.99' +stdout '^rsc.io/sampler v1.3.0' + +# build with newer version available +cp go.mod2 go.mod +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +stderr '^go: dropping requirement on excluded version rsc.io/quote v1\.5\.1$' +stdout 'rsc.io/quote v1.5.2' + +# build with excluded newer version +cp go.mod3 go.mod +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +! stderr '^go: dropping requirement' +stdout 'rsc.io/quote v1.5.1' + +-- x.go -- +package x +import _ "rsc.io/quote" + +-- go.mod -- +module x + +go 1.13 + +exclude rsc.io/sampler v1.99.99 +require rsc.io/sampler v1.99.99 +-- go.moddrop -- +module x + +go 1.13 + +exclude rsc.io/sampler v1.99.99 +-- go.mod2 -- +module x + +go 1.13 + +exclude rsc.io/quote v1.5.1 +require rsc.io/quote v1.5.1 +-- go.mod3 -- +module x + +go 1.13 + +exclude rsc.io/quote v1.5.2 +require rsc.io/quote v1.5.1 diff --git a/src/cmd/go/testdata/script/mod_retention.txt b/src/cmd/go/testdata/script/mod_retention.txt new file mode 100644 index 0000000..a4441c4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retention.txt @@ -0,0 +1,145 @@ +# Regression test for golang.org/issue/34822: the 'go' command should prefer not +# to update the go.mod file if the changes only affect formatting, and should only +# remove redundant requirements in 'go mod tidy'. + +env GO111MODULE=on +[short] skip + +# Control case: verify that go.mod.tidy is actually tidy. +cp go.mod.tidy go.mod +go list -mod=mod all +cmp go.mod go.mod.tidy + + +# If the only difference in the go.mod file is the line endings, +# it should not be overwritten automatically. +cp go.mod.crlf go.mod +go list all +cmp go.mod go.mod.crlf + +# However, 'go mod tidy' should fix whitespace even if there are no other changes. +go mod tidy +cmp go.mod go.mod.tidy + + +# Out-of-order requirements should not be overwritten automatically... +cp go.mod.unsorted go.mod +go list all +cmp go.mod go.mod.unsorted + +# ...but 'go mod edit -fmt' should sort them. +go mod edit -fmt +cmp go.mod go.mod.tidy + + +# "// indirect" comments should be removed if direct dependencies are seen. +# changes. +cp go.mod.indirect go.mod +go list -mod=mod all +cmp go.mod go.mod.tidy + +# "// indirect" comments should be added if appropriate. +cp go.mod.toodirect go.mod +go list all +cmp go.mod go.mod.toodirect +go mod vendor # loads everything, so adds "// indirect" comments. +cmp go.mod go.mod.tidy +rm -r vendor + + +# Redundant requirements should be preserved... +cp go.mod.redundant go.mod +go list all +cmp go.mod go.mod.redundant +go mod vendor +cmp go.mod go.mod.redundant +rm -r vendor + +# ...except by 'go mod tidy'. +go mod tidy +cmp go.mod go.mod.tidy + + +# A missing "go" version directive should be added. +# However, that should not remove other redundant requirements. +cp go.mod.nogo go.mod +go list -mod=mod all +cmpenv go.mod go.mod.currentgo + + +-- go.mod.tidy -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 // indirect +) +-- x.go -- +package x +import _ "rsc.io/quote" +-- go.mod.crlf -- +module m
+
+go 1.14
+
+require (
+ rsc.io/quote v1.5.2
+ rsc.io/testonly v1.0.0 // indirect
+)
+-- go.mod.unsorted -- +module m + +go 1.14 + +require ( + rsc.io/testonly v1.0.0 // indirect + rsc.io/quote v1.5.2 +) +-- go.mod.indirect -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.toodirect -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 +) +-- go.mod.redundant -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.nogo -- +module m + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.currentgo -- +module m + +go $goversion + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) diff --git a/src/cmd/go/testdata/script/mod_retract.txt b/src/cmd/go/testdata/script/mod_retract.txt new file mode 100644 index 0000000..4f95ece --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract.txt @@ -0,0 +1,45 @@ +cp go.mod go.mod.orig + +# 'go list pkg' does not report an error when a retracted version is used. +go list -e -f '{{if .Error}}{{.Error}}{{end}}' ./use +! stdout . +cmp go.mod go.mod.orig + +# Nor does 'go build'. +[!short] go build ./use +[!short] ! stderr . +[!short] cmp go.mod go.mod.orig + +# Neither 'go list' nor 'go build' should download go.mod from the version +# that would list retractions. +exists $GOPATH/pkg/mod/cache/download/example.com/retract/@v/v1.0.0-bad.mod +! exists $GOPATH/pkg/mod/cache/download/example.com/retract/@v/v1.1.0.mod + +# Importing a package from a module with a retracted latest version will +# select the latest non-retracted version. +go get -d ./use_self_prev +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.1.0$' +exists $GOPATH/pkg/mod/cache/download/example.com/retract/self/prev/@v/v1.9.0.mod + +-- go.mod -- +module example.com/use + +go 1.15 + +require example.com/retract v1.0.0-bad + +-- go.sum -- +example.com/retract v1.0.0-bad h1:liAW69rbtjY67x2CcNzat668L/w+YGgNX3lhJsWIJis= +example.com/retract v1.0.0-bad/go.mod h1:0DvGGofJ9hr1q63cBrOY/jSY52OwhRGA0K47NE80I5Y= +example.com/retract/self/prev v1.1.0 h1:0/8I/GTG+1eJTFeDQ/fUbgrMsVHHyKhh3Z8DSZp1fuA= +example.com/retract/self/prev v1.1.0/go.mod h1:xl2EcklWuZZHVtHWcpzfSJQmnzAGpKZYpA/Wto7SZN4= +-- use/use.go -- +package use + +import _ "example.com/retract" + +-- use_self_prev/use.go -- +package use_self_prev + +import _ "example.com/retract/self/prev" diff --git a/src/cmd/go/testdata/script/mod_retract_fix_version.txt b/src/cmd/go/testdata/script/mod_retract_fix_version.txt new file mode 100644 index 0000000..e45758b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_fix_version.txt @@ -0,0 +1,48 @@ +# retract must not be used without a module directive. +! go list -m all +stderr 'go.mod:3: no module directive found, so retract cannot be used$' + +# Commands that update go.mod should fix non-canonical versions in +# retract directives. +# Verifies #44494. +go mod edit -module=rsc.io/quote/v2 +! go list -m all +stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy$' +go mod tidy +go list -m all +cmp go.mod go.mod.want + +# If a retracted version doesn't match the module's major version suffx, +# an error should be reported. +! go mod edit -retract=v3.0.1 +stderr '^go mod: -retract=v3.0.1: version "v3.0.1" invalid: should be v2, not v3$' +cp go.mod.mismatch-v2 go.mod +! go list -m all +stderr 'go.mod:3: retract rsc.io/quote/v2: version "v3.0.1" invalid: should be v2, not v3$' + +cp go.mod.mismatch-v1 go.mod +! go list -m all +stderr 'go.mod:3: retract rsc.io/quote: version "v3.0.1" invalid: should be v0 or v1, not v3$' + +-- go.mod -- +go 1.16 + +retract latest +-- go.mod.want -- +go 1.16 + +retract v2.0.1 + +module rsc.io/quote/v2 +-- go.mod.mismatch-v2 -- +go 1.16 + +retract v3.0.1 + +module rsc.io/quote/v2 +-- go.mod.mismatch-v1 -- +go 1.16 + +retract v3.0.1 + +module rsc.io/quote diff --git a/src/cmd/go/testdata/script/mod_retract_incompatible.txt b/src/cmd/go/testdata/script/mod_retract_incompatible.txt new file mode 100644 index 0000000..61538e8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_incompatible.txt @@ -0,0 +1,15 @@ +# The current version of a module should not be considered when loading +# retractions. If the current version is +incompatible, we should not prefer +# +incompatible versions when looking for retractions. +# Verifies #42601. + +go mod init m + +# Request a +incompatible version retracted in v1.0.0. +go get -d example.com/retract/incompatible@v2.0.0+incompatible +stderr '^go: warning: example.com/retract/incompatible@v2.0.0\+incompatible: retracted by module author$' + +# We should still see a warning if the +incompatible was previously in the +# build list. +go get -d example.com/retract/incompatible@v2.0.0+incompatible +stderr '^go: warning: example.com/retract/incompatible@v2.0.0\+incompatible: retracted by module author$' diff --git a/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt b/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt new file mode 100644 index 0000000..eb00e84 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt @@ -0,0 +1,62 @@ +# When converting a commit to a pseudo-version, don't use a retracted version +# as the base. +# Verifies golang.org/issue/41700. + +[!net] skip +[!exec:git] skip +env GOPROXY=direct +env GOSUMDB=off +go mod init m + +# Control: check that v1.0.0 is the only version and is retracted. +go list -m -versions vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git$' +go list -m -versions -retracted vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git v1.0.0$' + +# 713affd19d7b is a commit after v1.0.0. Don't use v1.0.0 as the base. +go list -m vcs-test.golang.org/git/retract-pseudo.git@713affd19d7b +stdout '^vcs-test.golang.org/git/retract-pseudo.git v0.0.0-20201009173747-713affd19d7b$' + +# 64c061ed4371 is the commit v1.0.0 refers to. Don't convert to v1.0.0. +go list -m vcs-test.golang.org/git/retract-pseudo.git@64c061ed4371 +stdout '^vcs-test.golang.org/git/retract-pseudo.git v0.0.0-20201009173747-64c061ed4371' + +# A retracted version is a valid base. Retraction should not validate existing +# pseudo-versions, nor should it turn invalid pseudo-versions valid. +go get -d vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-713affd19d7b +go list -m vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git v1.0.1-0.20201009173747-713affd19d7b$' + +! go get -d vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-64c061ed4371 +stderr '^go get: vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-64c061ed4371: invalid pseudo-version: tag \(v1.0.0\) found on revision 64c061ed4371 is already canonical, so should not be replaced with a pseudo-version derived from that tag$' + +-- retract-pseudo.sh -- +#!/bin/bash + +# This is not part of the test. +# Run this to generate and update the repository on vcs-test.golang.org. + +set -euo pipefail + +rm -rf retract-pseudo +mkdir retract-pseudo +cd retract-pseudo +git init + +# Create the module. +# Retract v1.0.0 and tag v1.0.0 at the same commit. +# The module has no unretracted release versions. +go mod init vcs-test.golang.org/git/retract-pseudo.git +go mod edit -retract v1.0.0 +echo 'package p' >p.go +git add -A +git commit -m 'create module retract-pseudo' +git tag v1.0.0 + +# Commit a trivial change so the default branch does not point to v1.0.0. +git mv p.go q.go +git commit -m 'trivial change' + +zip -r ../retract-pseudo.zip . +gsutil cp ../retract-pseudo.zip gs://vcs-test/git/retract-pseudo.zip diff --git a/src/cmd/go/testdata/script/mod_retract_rationale.txt b/src/cmd/go/testdata/script/mod_retract_rationale.txt new file mode 100644 index 0000000..4d3a3d6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_rationale.txt @@ -0,0 +1,79 @@ +# When there is no rationale, 'go get' should print a hard-coded message. +go get -d example.com/retract/rationale@v1.0.0-empty +stderr '^go: warning: example.com/retract/rationale@v1.0.0-empty: retracted by module author$' + +# 'go list' should print the same hard-coded message. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +stdout '^\[retracted by module author\]$' + + +# When there is a multi-line message, 'go get' should print the first line. +go get -d example.com/retract/rationale@v1.0.0-multiline1 +stderr '^go: warning: example.com/retract/rationale@v1.0.0-multiline1: retracted by module author: short description$' +! stderr 'detail' + +# 'go list' should show the full message. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +cmp stdout multiline + +# 'go get' output should be the same whether the retraction appears at top-level +# or in a block. +go get -d example.com/retract/rationale@v1.0.0-multiline2 +stderr '^go: warning: example.com/retract/rationale@v1.0.0-multiline2: retracted by module author: short description$' +! stderr 'detail' + +# Same for 'go list'. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +cmp stdout multiline + + +# 'go get' should omit long messages. +go get -d example.com/retract/rationale@v1.0.0-long +stderr '^go: warning: example.com/retract/rationale@v1.0.0-long: retracted by module author: \(rationale omitted: too long\)' + +# 'go list' should show the full message. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +stdout '^\[lo{500}ng\]$' + + +# 'go get' should omit messages with unprintable characters. +go get -d example.com/retract/rationale@v1.0.0-unprintable +stderr '^go: warning: example.com/retract/rationale@v1.0.0-unprintable: retracted by module author: \(rationale omitted: contains non-printable characters\)' + +# 'go list' should show the full message. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +stdout '^\[Ends with a BEL character. Beep!\x07\]$' + + +# When there is a comment on a block, but not on individual retractions within +# the block, the rationale should come from the block comment. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale@v1.0.0-block +stdout '^\[block comment\]$' +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale@v1.0.0-blockwithcomment +stdout '^\[inner comment\]$' + + +# When a version is covered by multiple retractions, all retractions should +# be reported in the order they appear in the file. +go list -m -retracted -f '{{range .Retracted}}{{.}},{{end}}' example.com/retract/rationale@v1.0.0-order +stdout '^degenerate range,single version,$' +go list -m -retracted -f '{{range .Retracted}}{{.}},{{end}}' example.com/retract/rationale@v1.0.1-order +stdout '^single version,degenerate range,$' + +# 'go get' will only report the first retraction to avoid being too verbose. +go get -d example.com/retract/rationale@v1.0.0-order +stderr '^go: warning: example.com/retract/rationale@v1.0.0-order: retracted by module author: degenerate range$' +go get -d example.com/retract/rationale@v1.0.1-order +stderr '^go: warning: example.com/retract/rationale@v1.0.1-order: retracted by module author: single version$' + +-- go.mod -- +module m + +go 1.14 + +-- multiline -- +[short description +more + +detail +suffix] diff --git a/src/cmd/go/testdata/script/mod_retract_rename.txt b/src/cmd/go/testdata/script/mod_retract_rename.txt new file mode 100644 index 0000000..f54742c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_rename.txt @@ -0,0 +1,28 @@ +# Populate go.sum. +go get -d + +# 'go list -m -retracted' should load retractions, even if the version +# containing retractions has a different module path. +go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract/rename + +# 'go list -m -u' should load retractions, too. +go list -m -u -f '{{with .Retracted}}retracted{{end}}' example.com/retract/rename + +# 'go get' should warn about the retracted version. +go get -d +stderr '^go: warning: example.com/retract/rename@v1.0.0-bad: retracted by module author: bad$' + +# We can't upgrade, since this latest version has a different module path. +! go get -d example.com/retract/rename +stderr 'module declares its path as: example.com/retract/newname' + +-- go.mod -- +module example.com/use + +go 1.16 + +require example.com/retract/rename v1.0.0-bad +-- use.go -- +package use + +import _ "example.com/retract/rename" diff --git a/src/cmd/go/testdata/script/mod_retract_replace.txt b/src/cmd/go/testdata/script/mod_retract_replace.txt new file mode 100644 index 0000000..770aea4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_replace.txt @@ -0,0 +1,61 @@ +# If the latest unretracted version of a module is replaced, 'go list' should +# obtain retractions from the replacement. + +# Populate go.sum. +go get -d + +# The latest version, v1.9.0, is not available on the proxy. +! go list -m -retracted example.com/retract/missingmod +stderr '^go list -m: loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$' + +# If we replace that version, we should see retractions. +go mod edit -replace=example.com/retract/missingmod@v1.9.0=./missingmod-v1.9.0 +go list -m -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract/missingmod +stdout '^bad version$' + +# If we replace the retracted version, we should not see a retraction. +go mod edit -replace=example.com/retract/missingmod=./missingmod-v1.9.0 +go list -m -retracted -f '{{if not .Retracted}}good version{{end}}' example.com/retract/missingmod +stdout '^good version$' + + +# If a replacement version is retracted, we should see a retraction. +# It should appear in both the replaced module and the replacement, as other +# fields like GoMod do. +go list -m -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract +! stdout . +go list -m -retracted -f '{{if .Replace}}replaced{{end}}' example.com/retract +! stdout . +go mod edit -replace example.com/retract@v1.0.0-good=example.com/retract@v1.0.0-bad +go list -m -mod=mod -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract +stdout '^bad$' +go list -m -mod=mod -retracted -f '{{with .Replace}}{{range .Retracted}}{{.}}{{end}}{{end}}' example.com/retract +stdout '^bad$' + +-- go.mod -- +module m + +go 1.14 + +require ( + example.com/retract v1.0.0-good + example.com/retract/missingmod v1.0.0 +) +-- use.go -- +package use + +import ( + _ "example.com/retract" + _ "example.com/retract/missingmod" +) +-- missingmod-v1.0.0/go.mod -- +module example.com/retract/missingmod + +go 1.14 +-- missingmod-v1.9.0/go.mod -- +module example.com/retract/missingmod + +go 1.14 + +// bad version +retract v1.0.0 diff --git a/src/cmd/go/testdata/script/mod_run_path.txt b/src/cmd/go/testdata/script/mod_run_path.txt new file mode 100644 index 0000000..4369ee4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_run_path.txt @@ -0,0 +1,15 @@ +# Test that go run does not get confused by conflict +# between go.mod's module path and what you'd +# expect from GOPATH. golang.org/issue/26046. + +env GO111MODULE=on + +cd $GOPATH/src/example.com/hello +go run main.go + +-- $GOPATH/src/example.com/hello/go.mod -- +module example.com/hello/v2 + +-- $GOPATH/src/example.com/hello/main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/mod_std_vendor.txt b/src/cmd/go/testdata/script/mod_std_vendor.txt new file mode 100644 index 0000000..fb954d7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_std_vendor.txt @@ -0,0 +1,78 @@ +env GO111MODULE=on +env GOPROXY=off + +[!gc] skip + +# 'go list' should report imports from _test.go in the TestImports field. +go list -f '{{.TestImports}}' +stdout net/http # from .TestImports + +# 'go list' should find standard-vendored packages. +go list -f '{{.Dir}}' vendor/golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor + +# 'go list -test' should report vendored transitive dependencies of _test.go +# imports in the Deps field. +go list -test -f '{{range .Deps}}{{.}}{{"\n"}}{{end}}' +stdout ^vendor/golang.org/x/crypto # dep of .TestImports + + +# Modules outside the standard library should not use the packages vendored there... +cd broken +! go build -mod=readonly +stderr 'disabled by -mod=readonly' +! go build -mod=vendor +stderr 'cannot find package' +stderr 'hpack' + +# ...even if they explicitly use the "cmd/vendor/" or "vendor/" prefix. +cd ../importcmd +! go build . +stderr 'use of vendored package' + +cd ../importstd +! go build . +stderr 'use of vendored package' + + +# When run within the 'std' module, 'go list -test' should report vendored +# transitive dependencies at their original module paths. +cd $GOROOT/src +go list -test -f '{{range .Deps}}{{.}}{{"\n"}}{{end}}' net/http +stdout ^golang.org/x/net/http2/hpack +! stdout ^vendor/golang.org/x/net/http2/hpack + +-- go.mod -- +module m + +-- x.go -- +package x + +-- x_test.go -- +package x +import "testing" +import _ "net/http" +func Test(t *testing.T) {} + +-- broken/go.mod -- +module broken +-- broken/http.go -- +package broken + +import ( + _ "net/http" + _ "golang.org/x/net/http2/hpack" +) + +-- importcmd/go.mod -- +module importcmd +-- importcmd/x.go -- +package importcmd + +import _ "cmd/vendor/golang.org/x/tools/go/analysis" +-- importstd/go.mod -- +module importvendor +-- importstd/x.go -- +package importstd + +import _ "vendor/golang.org/x/net/http2/hpack" diff --git a/src/cmd/go/testdata/script/mod_string_alias.txt b/src/cmd/go/testdata/script/mod_string_alias.txt new file mode 100644 index 0000000..5c3d428 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_string_alias.txt @@ -0,0 +1,14 @@ +[short] skip + +env GO111MODULE=on + +go mod init golang.org/issue/27584 + +go build . + +-- main.go -- +package main + +type string = []int + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_sum_ambiguous.txt b/src/cmd/go/testdata/script/mod_sum_ambiguous.txt new file mode 100644 index 0000000..07c6659 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_ambiguous.txt @@ -0,0 +1,62 @@ +# Confirm our build list. +cp go.sum.buildlist-only go.sum +go list -m all +stdout '^example.com/ambiguous/a v1.0.0$' +stdout '^example.com/ambiguous/a/b v0.0.0-empty$' + +# If two modules could provide a package, but only one does, +# 'go mod tidy' should retain sums for both zips. +go mod tidy +grep '^example.com/ambiguous/a v1.0.0 h1:' go.sum +grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum + +# 'go mod download' should also add sums. +cp go.sum.buildlist-only go.sum +go mod download example.com/ambiguous/a +grep '^example.com/ambiguous/a v1.0.0 h1:' go.sum +! grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum +go mod download example.com/ambiguous/a/b +grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum + +# If two modules could provide a package, and we're missing a sum for one, +# we should see a missing sum error, even if we have a sum for a module that +# provides the package. +cp go.sum.a-only go.sum +! go list example.com/ambiguous/a/b +stderr '^missing go.sum entry needed to verify package example.com/ambiguous/a/b is provided by exactly one module; to add:\n\tgo mod download example.com/ambiguous/a/b$' +! go list -deps . +stderr '^use.go:3:8: missing go.sum entry needed to verify package example.com/ambiguous/a/b \(imported by m\) is provided by exactly one module; to add:\n\tgo get m$' + +cp go.sum.b-only go.sum +! go list example.com/ambiguous/a/b +stderr '^missing go.sum entry for module providing package example.com/ambiguous/a/b; to add:\n\tgo mod download example.com/ambiguous/a$' +! go list -deps . +stderr '^use.go:3:8: missing go.sum entry for module providing package example.com/ambiguous/a/b \(imported by m\); to add:\n\tgo get m$' + +cp go.sum.buildlist-only go.sum +! go list example.com/ambiguous/a/b +stderr '^missing go.sum entry for module providing package example.com/ambiguous/a/b; to add:\n\tgo mod download example.com/ambiguous/a example.com/ambiguous/a/b$' +! go list -deps . +stderr '^use.go:3:8: missing go.sum entry for module providing package example.com/ambiguous/a/b \(imported by m\); to add:\n\tgo get m$' + +-- go.mod -- +module m + +go 1.15 + +require example.com/ambiguous/a v1.0.0 +-- go.sum.buildlist-only -- +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- go.sum.a-only -- +example.com/ambiguous/a v1.0.0 h1:pGZhTXy6+titE2rNfwHwJykSjXDR4plO52PfZrBM0T8= +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- go.sum.b-only -- +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty h1:xS29ReXXuhjT7jc79mo91h/PevaZ2oS9PciF1DucXtg= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- use.go -- +package use + +import _ "example.com/ambiguous/a/b" diff --git a/src/cmd/go/testdata/script/mod_sum_lookup.txt b/src/cmd/go/testdata/script/mod_sum_lookup.txt new file mode 100644 index 0000000..e021921 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_lookup.txt @@ -0,0 +1,34 @@ +# When we attempt to resolve an import that doesn't exist, we should not save +# hashes for downloaded modules. +# Verifies golang.org/issue/36260. +# TODO(golang.org/issue/26603): use 'go mod tidy -e' when implemented. +go list -e -mod=mod -tags=ignore ./noexist +! exists go.sum + +# When an import is resolved successfully, we should only save hashes for +# the module that provides the package, not for other modules looked up. +# Verifies golang.org/issue/31580. +go get -d ./exist +grep '^example.com/join v1.1.0 h1:' go.sum +! grep '^example.com/join/subpkg' go.sum +cp go.sum go.list.sum +go mod tidy +cmp go.sum go.list.sum + +-- go.mod -- +module m + +go 1.15 + +-- noexist/use.go -- +// ignore tags prevents errors in 'go mod tidy' +// +build ignore + +package use + +import _ "example.com/join/subpkg/noexist" + +-- exist/use.go -- +package use + +import _ "example.com/join/subpkg" diff --git a/src/cmd/go/testdata/script/mod_sum_readonly.txt b/src/cmd/go/testdata/script/mod_sum_readonly.txt new file mode 100644 index 0000000..57c5bbe --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_readonly.txt @@ -0,0 +1,87 @@ +# Test that go.sum does not get updated when -mod=readonly flag is set +env GO111MODULE=on + +# When a sum is needed to load the build list, we get an error for the +# specific module. The .mod file is not downloaded, and go.sum is not written. +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +! exists go.sum + +# If go.sum exists but contains hashes from an algorithm we don't know about, +# we should see the same error. +cp go.sum.h2only go.sum +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +cmp go.sum go.sum.h2only +rm go.sum + +# If we replace a module, we should see a missing sum error for the replacement. +cp go.mod go.mod.orig +go mod edit -replace rsc.io/quote@v1.5.2=rsc.io/quote@v1.5.1 +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.mod +! exists go.sum +cp go.mod.orig go.mod + +# Control: when sums are present, loading the build list downloads .mod files. +cp go.sum.buildlistonly go.sum +go list -m all +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod + + +# When a sum is needed to load a .mod file for a package outside the build list, +# we get a generic missing import error. +! go list example.com/doesnotexist +stderr '^no required module provides package example.com/doesnotexist; to add it:\n\tgo get example.com/doesnotexist$' + +# When a sum is needed to load a .zip file, we get a more specific error. +# The .zip file is not downloaded. +! go list rsc.io/quote +stderr '^missing go.sum entry for module providing package rsc.io/quote; to add:\n\tgo mod download rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# The error is attached to the package from the missing module. We can load +# a package that imports it without that error. +go list -e -deps -f '{{.ImportPath}}{{with .Error}} {{.Err}}{{end}}' . +stdout '^m$' +stdout '^rsc.io/quote missing go.sum entry for module providing package rsc.io/quote \(imported by m\); to add:\n\tgo get m$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# go.sum should not have been written. +cmp go.sum go.sum.buildlistonly + +# Control: when sums are present, 'go list' downloads .zip files. +cp go.sum.tidy go.sum +go list . +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +-- go.mod -- +module m + +go 1.15 + +require rsc.io/quote v1.5.2 +-- use.go -- +package use + +import _ "rsc.io/quote" +-- go.sum.h2only -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h2:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h2:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h2:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- go.sum.buildlistonly -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- go.sum.tidy -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= diff --git a/src/cmd/go/testdata/script/mod_sum_replaced.txt b/src/cmd/go/testdata/script/mod_sum_replaced.txt new file mode 100644 index 0000000..b03982d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_replaced.txt @@ -0,0 +1,28 @@ +env GO111MODULE=on + +# After 'go get -d', the go.sum file should contain the sum for the module. +go get -d rsc.io/quote@v1.5.0 +grep 'rsc.io/quote v1.5.0' go.sum + +# If we replace the module and run 'go mod tidy', we should get a sum for the replacement. +go mod edit -replace rsc.io/quote@v1.5.0=rsc.io/quote@v1.5.1 +go mod tidy +grep 'rsc.io/quote v1.5.1' go.sum +cp go.sum go.sum.tidy + +# 'go mod vendor' should preserve that sum, and should not need to add any new entries. +go mod vendor +grep 'rsc.io/quote v1.5.1' go.sum +cmp go.sum go.sum.tidy + +-- go.mod -- +module golang.org/issue/27868 + +require rsc.io/quote v1.5.0 + +-- main.go -- +package main + +import _ "rsc.io/quote" + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_sumdb.txt b/src/cmd/go/testdata/script/mod_sumdb.txt new file mode 100644 index 0000000..9a688e1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb.txt @@ -0,0 +1,39 @@ +env GO111MODULE=on +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPROXY GONOPROXY GOSUMDB GONOSUMDB +env dbname=localhost.localdev/sumdb + +# disagreeing with the sumdb produces security errors +# (this also populates tiles on the sumdb server). +cp go.mod.orig go.mod +env GOSUMDB=$sumdb' '$proxy/sumdb-wrong +! go get -d rsc.io/quote +stderr 'go get: rsc.io/quote@v1.5.2: verifying module: checksum mismatch' +stderr 'downloaded: h1:3fEy' +stderr 'localhost.localdev/sumdb: h1:wrong' +stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the checksum server.' +! go get -d rsc.io/sampler +! go get -d golang.org/x/text + +go mod edit -require rsc.io/quote@v1.5.2 +! go mod tidy +stderr 'go: rsc.io/quote@v1.5.2: verifying go.mod: checksum mismatch' +stderr 'SECURITY ERROR\n' + +rm go.sum + +# switching to truthful sumdb detects timeline inconsistency +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +! go get -d rsc.io/fortune +stderr 'SECURITY ERROR\ngo.sum database server misbehavior detected!' +stderr 'proof of misbehavior:' + +# removing the cached wrong tree head and cached tiles clears the bad data +rm $GOPATH/pkg/sumdb/$dbname/latest +go clean -modcache +go get -d rsc.io/fortune + +-- go.mod.orig -- +module m diff --git a/src/cmd/go/testdata/script/mod_sumdb_cache.txt b/src/cmd/go/testdata/script/mod_sumdb_cache.txt new file mode 100644 index 0000000..2937b2e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb_cache.txt @@ -0,0 +1,54 @@ +env GO111MODULE=on +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPROXY GONOPROXY GOSUMDB GONOSUMDB + +# rejected proxy fails verification +cp go.mod.orig go.mod +rm go.sum +env GOPROXY=$proxy/sumdb-503 +! go get -d rsc.io/quote +stderr 503 + +# fetch through working proxy is OK +cp go.mod.orig go.mod +rm go.sum +env GOPROXY=$proxy +go get -d rsc.io/quote + +# repeated fetch works entirely from cache, does not consult sumdb +cp go.mod.orig go.mod +rm go.sum +env GOPROXY=$proxy/sumdb-503 +go get -d rsc.io/quote +rm go.sum + +# fetch specific module can work without proxy, using cache or go.sum +cp go.mod.orig go.mod +rm go.sum +env GOPROXY=off +go get -d rsc.io/quote@v1.5.2 # using cache +rm $GOPATH/pkg/mod/cache/download/sumdb/localhost.localdev/sumdb/lookup/rsc.io/quote@v1.5.2 +go get -d rsc.io/quote@v1.5.2 # using go.sum + +# fetch fails once we lose access to both cache and go.sum +rm go.sum +env GOPROXY=$proxy/sumdb-504 +! go get -d rsc.io/quote@v1.5.2 +stderr 504 + +# GOINSECURE does not bypass checksum lookup +env GOINSECURE=rsc.io +env GOPROXY=$proxy/sumdb-504 +! go get -d rsc.io/quote@v1.5.2 +stderr 504 + +# but -insecure bypasses the checksum lookup entirely +env GOINSECURE= +go get -d -insecure rsc.io/quote@v1.5.2 + +# and then it is in go.sum again +go get -d rsc.io/quote@v1.5.2 + +-- go.mod.orig -- +module m diff --git a/src/cmd/go/testdata/script/mod_sumdb_file_path.txt b/src/cmd/go/testdata/script/mod_sumdb_file_path.txt new file mode 100644 index 0000000..22fcbf3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb_file_path.txt @@ -0,0 +1,56 @@ +[!net] skip + +env GO111MODULE=on +env GOSUMDB= +env GOPATH=$WORK/gopath1 + +# With a file-based proxy with an empty checksum directory, +# downloading a new module should fail, even if a subsequent +# proxy contains a more complete mirror of the sum database. +# +# TODO(bcmills): The error message here is a bit redundant. +# It comes from the sumweb package, which isn't yet producing structured errors. +[windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org +[!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org +! go get -d golang.org/x/text@v0.3.2 +stderr '^go get: golang.org/x/text@v0.3.2: verifying module: golang.org/x/text@v0.3.2: reading file://.*/sumdb/sum.golang.org/lookup/golang.org/x/text@v0.3.2: (no such file or directory|.*cannot find the path specified.*)' + +# If the proxy does not claim to support the database, +# checksum verification should fall through to the next proxy, +# and downloading should succeed. +[windows] env GOPROXY=file:///$WORK/emptyproxy,https://proxy.golang.org +[!windows] env GOPROXY=file://$WORK/emptyproxy,https://proxy.golang.org +go get -d golang.org/x/text@v0.3.2 + +# After a successful sumdb lookup, the lookup can be repeated +# using the download cache as a proxy. +cp supported $GOPATH/pkg/mod/cache/download/sumdb/sum.golang.org/supported +[windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download,file:///$WORK/sumproxy +[!windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download,file://$WORK/sumproxy +env GOPATH=$WORK/gopath2 +rm go.sum +go get -d -x -v golang.org/x/text@v0.3.2 + +# Once the checksum is present in the go.sum file, +# an empty file-based sumdb can be used in conjunction with +# a fallback module mirror. +grep golang.org/x/text go.sum +env GOPATH=$WORK/gopath3 +[windows] env GOPROXY=file:///$WORK/sumproxy +[!windows] env GOPROXY=file://$WORK/sumproxy +! go get -d golang.org/x/text@v0.3.2 +[windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org +[!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org +go get -d golang.org/x/text@v0.3.2 + +-- supported -- + +-- go.mod -- +module example.com +go 1.13 +-- $WORK/emptyproxy/README.md -- +This proxy contains no modules. +-- $WORK/sumproxy/README.md -- +This proxy contains no modules. +-- $WORK/sumproxy/sumdb/sum.golang.org/supported -- +This proxy blocks checksum downloads from sum.golang.org. diff --git a/src/cmd/go/testdata/script/mod_sumdb_golang.txt b/src/cmd/go/testdata/script/mod_sumdb_golang.txt new file mode 100644 index 0000000..cc0b0da --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb_golang.txt @@ -0,0 +1,54 @@ +# Test default GOPROXY and GOSUMDB +env GOPROXY= +env GOSUMDB= +go env GOPROXY +stdout '^https://proxy.golang.org,direct$' +go env GOSUMDB +stdout '^sum.golang.org$' +env GOPROXY=https://proxy.golang.org +go env GOSUMDB +stdout '^sum.golang.org$' + +# Download direct from github. +[!net] skip +[!exec:git] skip +env GOSUMDB=sum.golang.org +env GOPROXY=direct +go get -d rsc.io/quote@v1.5.2 +cp go.sum saved.sum + +# Download from proxy.golang.org with go.sum entry already. +# Use 'go list' instead of 'go get' since the latter may download extra go.mod +# files not listed in go.sum. +go clean -modcache +env GOSUMDB= +env GOPROXY= +go list -x -deps rsc.io/quote +! stderr github +stderr proxy.golang.org/rsc.io/quote +! stderr sum.golang.org/tile +! stderr sum.golang.org/lookup/rsc.io/quote +cmp go.sum saved.sum + +# Download again. +# Should use the checksum database to validate new go.sum lines, +# but not need to fetch any new data from the proxy. +rm go.sum +go list -mod=mod -x rsc.io/quote +! stderr github +! stderr proxy.golang.org/rsc.io/quote +stderr sum.golang.org/tile +stderr sum.golang.org/lookup/rsc.io/quote +cmp go.sum saved.sum + +# test fallback to direct +env TESTGOPROXY404=1 +go clean -modcache +rm go.sum +go list -mod=mod -x rsc.io/quote +stderr 'proxy.golang.org.*404 testing' +stderr github.com/rsc +cmp go.sum saved.sum + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_sumdb_proxy.txt b/src/cmd/go/testdata/script/mod_sumdb_proxy.txt new file mode 100644 index 0000000..70b8e3f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb_proxy.txt @@ -0,0 +1,65 @@ +env GO111MODULE=on +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPROXY GONOPROXY GOSUMDB GONOSUMDB + +# basic fetch (through proxy) works +cp go.mod.orig go.mod +go get -d rsc.io/fortune@v1.0.0 # note: must use test proxy, does not exist in real world +rm $GOPATH/pkg/mod/cache/download/sumdb # rm sumdb cache but NOT package download cache +rm go.sum + +# can fetch by explicit URL +cp go.mod.orig go.mod +env GOSUMDB=$sumdb' '$proxy/sumdb-direct +go get -d rsc.io/fortune@v1.0.0 +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# direct access fails (because localhost.localdev does not exist) +# web.get is providing the error message - there's no actual network access. +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=direct +! go get -d rsc.io/fortune@v1.0.0 +stderr 'verifying module: rsc.io/fortune@v1.0.0: .*: no such host localhost.localdev' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# proxy 404 falls back to direct access (which fails) +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-404 +! go get -d rsc.io/fortune@v1.0.0 +stderr 'verifying.*localhost.localdev' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# proxy non-200/404/410 stops direct access +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-503 +! go get -d rsc.io/fortune@v1.0.0 +stderr '503 Service Unavailable' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# the error from the last attempted proxy should be returned. +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-404,$proxy/sumdb-503 +! go get -d rsc.io/fortune@v1.0.0 +stderr '503 Service Unavailable' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# if proxies are separated with '|', fallback is allowed on any error. +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-503|https://0.0.0.0|$proxy +go get -d rsc.io/fortune@v1.0.0 +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +-- go.mod.orig -- +module m diff --git a/src/cmd/go/testdata/script/mod_symlink.txt b/src/cmd/go/testdata/script/mod_symlink.txt new file mode 100644 index 0000000..dbc23fb --- /dev/null +++ b/src/cmd/go/testdata/script/mod_symlink.txt @@ -0,0 +1,45 @@ +env GO111MODULE=on +[!symlink] skip + +# 'go get -d' should resolve modules of imported packages. +go get -d +go list -deps -f '{{.Module}}' . +stdout golang.org/x/text + +go get -d ./subpkg +go list -deps -f '{{.Module}}' ./subpkg +stdout golang.org/x/text + +# Create a copy of the module using symlinks in src/links. +mkdir links +symlink links/go.mod -> $GOPATH/src/go.mod +symlink links/go.sum -> $GOPATH/src/go.sum +symlink links/issue.go -> $GOPATH/src/issue.go +mkdir links/subpkg +symlink links/subpkg/issue.go -> $GOPATH/src/subpkg/issue.go + +# We should see the copy as a valid module root. +cd links +go env GOMOD +stdout links[/\\]go.mod +go list -m +stdout golang.org/issue/28107 + +# The symlink-based copy should contain the same packages +# and have the same dependencies as the original. +go list -deps -f '{{.Module}}' . +stdout golang.org/x/text +go list -deps -f '{{.Module}}' ./subpkg +stdout golang.org/x/text + +-- go.mod -- +module golang.org/issue/28107 + +-- issue.go -- +package issue + +import _ "golang.org/x/text/language" +-- subpkg/issue.go -- +package issue + +import _ "golang.org/x/text/language" diff --git a/src/cmd/go/testdata/script/mod_symlink_dotgo.txt b/src/cmd/go/testdata/script/mod_symlink_dotgo.txt new file mode 100644 index 0000000..d4cc143 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_symlink_dotgo.txt @@ -0,0 +1,17 @@ +env GO111MODULE=on +[!symlink] skip + +symlink dir.go -> dir + +# Issue #39841: symlinks to directories should be ignored, not treated as source files. +go list -f '{{range .GoFiles}}{{.}}{{"\n"}}{{end}}' . +stdout 'p\.go$' +! stdout 'dir\.go$' + +-- go.mod -- +module example.com +go 1.15 +-- p.go -- +package p +-- dir/README.txt -- +This file exists to ensure that dir is a directory. diff --git a/src/cmd/go/testdata/script/mod_tagged_import_cycle.txt b/src/cmd/go/testdata/script/mod_tagged_import_cycle.txt new file mode 100644 index 0000000..0491acb --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tagged_import_cycle.txt @@ -0,0 +1,106 @@ +# Because 'go mod' subcommands ignore build constraints, they can encounter +# package-import cycles that are not possible in an ordinary build. This test +# verifies that such cycles are handled even when they cross module boundaries. + +# First, verify that the import graph depends on build tags as expected. +go list -deps example.com/left +stdout '^example.com/right$' +go list -deps example.com/right +! stdout left + +env GOFLAGS=-tags=mirror +go list -deps example.com/left +! stdout right +go list -deps example.com/right +stdout '^example.com/left$' +env GOFLAGS='' + +# 'go mod why' should be agnostic to build tags. +go mod why example.com/left +stdout '^example.com/chiral$\n^example.com/left$' +go mod why example.com/right +stdout '^example.com/chiral$\n^example.com/right$' + +env GOFLAGS='-tags=mirror' +go mod why example.com/left +stdout '^example.com/chiral$\n^example.com/left$' +go mod why example.com/right +stdout '^example.com/chiral$\n^example.com/right$' +env GOFLAGS='' + +# 'go mod tidy' should successfully handle the cycle. +env GOFLAGS=-mod=readonly +go mod tidy + +# 'go mod vendor' should copy in both packages without crashing. +go mod vendor +exists vendor/example.com/left/default.go +exists vendor/example.com/left/mirror.go +exists vendor/example.com/right/default.go +exists vendor/example.com/right/mirror.go + +-- go.mod -- +module example.com/chiral + +go 1.14 + +require ( + example.com/left v0.1.0 + example.com/right v0.1.0 +) + +replace ( + example.com/left => ./left + example.com/right => ./right +) +-- chiral.go -- +// Package chiral imports packages in an order that depends on build tags. +package chiral +-- default.go -- +// +build !mirror + +package chiral + +import _ "example.com/left" +-- mirror.go -- +// +build mirror + +package chiral + +import _ "example.com/right" +-- left/go.mod -- +module example.com/left + +go 1.14 + +require example.com/right v0.1.0 + +replace example.com/right v0.1.0 => ../right +-- left/default.go -- +// +build !mirror + +package left + +import _ "example.com/right" +-- left/mirror.go -- +// +build mirror + +package left +-- right/go.mod -- +module example.com/right + +go 1.14 + +require example.com/left v0.1.0 + +replace example.com/left v0.1.0 => ../left +-- right/default.go -- +// +build !mirror + +package right +-- right/mirror.go -- +// +build mirror + +package right + +import _ "example.com/left" diff --git a/src/cmd/go/testdata/script/mod_test.txt b/src/cmd/go/testdata/script/mod_test.txt new file mode 100644 index 0000000..50f0035 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_test.txt @@ -0,0 +1,128 @@ +env GO111MODULE=on +env GOFLAGS=-mod=mod +[short] skip + +# TODO(bcmills): Convert the 'go test' calls below to 'go list -test' once 'go +# list' is more sensitive to package loading errors. + +# A test in the module's root package should work. +cd a/ +cp go.mod.empty go.mod +go list -test +! stderr error + +cp go.mod.empty go.mod +go list -deps +! stdout ^testing$ + +# list all should include test dependencies, like testing +cp go.mod.empty go.mod +go list all +stdout ^testing$ +stdout ^rsc.io/quote$ +stdout ^rsc.io/testonly$ + +# list -deps -tests should also include testing +# but not deps of tests of deps (rsc.io/testonly). +go list -deps -test +stdout ^testing$ +stdout ^rsc.io/quote$ +! stdout ^rsc.io/testonly$ + +# list -test all should succeed +cp go.mod.empty go.mod +go list -test all +stdout '^testing' + +cp go.mod.empty go.mod +go list -test +! stderr error + +# A test with the "_test" suffix in the module root should also work. +cd ../b/ +go list -test +! stderr error + +# A test with the "_test" suffix of a *package* with a "_test" suffix should +# even work (not that you should ever do that). +cd ../c_test +go list -test +! stderr error + +cd ../d_test +go list -test +! stderr error + +cd ../e +go list -test +! stderr error + +-- a/go.mod.empty -- +module example.com/user/a + +-- a/a.go -- +package a + +-- a/a_test.go -- +package a + +import "testing" +import _ "rsc.io/quote" + +func Test(t *testing.T) {} + +-- b/go.mod -- +module example.com/user/b + +-- b/b.go -- +package b + +-- b/b_test.go -- +package b_test + +import "testing" + +func Test(t *testing.T) {} + +-- c_test/go.mod -- +module example.com/c_test + +-- c_test/umm.go -- +// Package c_test is the non-test package for its import path! +package c_test + +-- c_test/c_test_test.go -- +package c_test_test + +import "testing" + +func Test(t *testing.T) {} + +-- d_test/go.mod -- +// Package d is an ordinary package in a deceptively-named directory. +module example.com/d + +-- d_test/d.go -- +package d + +-- d_test/d_test.go -- +package d_test + +import "testing" + +func Test(t *testing.T) {} + +-- e/go.mod -- +module example.com/e_test + +-- e/wat.go -- +// Package e_test is the non-test package for its import path, +// in a deceptively-named directory! +package e_test + +-- e/e_test.go -- +package e_test_test + +import "testing" + +func Test(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/mod_test_cached.txt b/src/cmd/go/testdata/script/mod_test_cached.txt new file mode 100644 index 0000000..3da4358 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_test_cached.txt @@ -0,0 +1,76 @@ +[short] skip + +env GO111MODULE=on +env GOCACHE=$WORK/gocache +env GODEBUG=gocachetest=1 + +# The first run of a test should not be cached. +# The second run should be. +go test -run=WriteTmp . +! stdout '(cached)' +go test -run=WriteTmp . +stdout '(cached)' + +# 'go test' without arguments should never be cached. +go test -run=WriteTmp +! stdout '(cached)' +go test -run=WriteTmp +! stdout '(cached)' + +# We should never cache a test run from command-line files. +go test -run=WriteTmp ./foo_test.go +! stdout '(cached)' +go test -run=WriteTmp ./foo_test.go +! stdout '(cached)' + +[!exec:sleep] stop +# The go command refuses to cache access to files younger than 2s, so sleep that long. +exec sleep 2 + +# Touching a file that the test reads from within its testdata should invalidate the cache. +go test -run=ReadTestdata . +! stdout '(cached)' +go test -run=ReadTestdata . +stdout '(cached)' +cp testdata/bar.txt testdata/foo.txt +go test -run=ReadTestdata . +! stdout '(cached)' + +-- go.mod -- +module golang.org/issue/29111/foo + +-- foo.go -- +package foo + +-- testdata/foo.txt -- +foo +-- testdata/bar.txt -- +bar + +-- foo_test.go -- +package foo_test + +import ( + "os" + "path/filepath" + "testing" +) + +func TestWriteTmp(t *testing.T) { + dir, err := os.MkdirTemp("", "") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + err = os.WriteFile(filepath.Join(dir, "x"), nil, 0666) + if err != nil { + t.Fatal(err) + } +} + +func TestReadTestdata(t *testing.T) { + _, err := os.ReadFile("testdata/foo.txt") + if err != nil { + t.Fatal(err) + } +} diff --git a/src/cmd/go/testdata/script/mod_test_files.txt b/src/cmd/go/testdata/script/mod_test_files.txt new file mode 100644 index 0000000..6f520c7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_test_files.txt @@ -0,0 +1,50 @@ +env GO111MODULE=on + +cd foo + +# Testing an explicit source file should use the same import visibility as the +# package in the same directory. +go list -test -deps +go list -test -deps foo_test.go + +# If the file is inside the main module's vendor directory, it should have +# visibility based on the vendor-relative import path. +mkdir vendor/example.com/foo +cp foo_test.go vendor/example.com/foo +go list -test -deps vendor/example.com/foo/foo_test.go + +# If the file is outside the main module entirely, it should be treated as outside. +cp foo_test.go ../foo_test.go +! go list -test -deps ../foo_test.go +stderr 'use of internal package' + +-- foo/go.mod -- +module example.com/foo +go 1.12 +require example.com/internal v0.0.0 +replace example.com/internal => ../internal + +-- foo/internal.go -- +package foo +import _ "example.com/internal" + +-- foo/foo_test.go -- +package foo_test + +import ( + "testing" + "example.com/internal" +) + +func TestHacksEnabled(t *testing.T) { + if !internal.Hacks { + t.Fatal("hacks not enabled") + } +} + +-- internal/go.mod -- +module example.com/internal + +-- internal/internal.go -- +package internal +const Hacks = true diff --git a/src/cmd/go/testdata/script/mod_tidy.txt b/src/cmd/go/testdata/script/mod_tidy.txt new file mode 100644 index 0000000..b1d9371 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy.txt @@ -0,0 +1,72 @@ +env GO111MODULE=on + +# tidy removes unused y, but everything else is used +go mod tidy -v +stderr '^unused y.1' +! stderr '^unused [^y]' + +grep 'go 1.10' go.mod + +go list -m all +! stdout '^y' +stdout '^w.1 v1.2.0' +stdout '^z.1 v1.2.0' + +# empty tidy should not crash +cd triv +! grep 'go ' go.mod +go mod tidy + +# tidy should add missing go line +grep 'go ' go.mod + +-- go.mod -- +module m + +go 1.10 + +require ( + x.1 v1.0.0 + y.1 v1.0.0 + w.1 v1.2.0 +) + +replace x.1 v1.0.0 => ./x +replace y.1 v1.0.0 => ./y +replace z.1 v1.1.0 => ./z +replace z.1 v1.2.0 => ./z +replace w.1 => ./w + +-- m.go -- +package m + +import _ "x.1" +import _ "z.1/sub" + +-- w/go.mod -- +module w + +-- w/w.go -- +package w + +-- x/go.mod -- +module x +require w.1 v1.1.0 +require z.1 v1.1.0 + +-- x/x.go -- +package x +import _ "w.1" + +-- y/go.mod -- +module y +require z.1 v1.2.0 + +-- z/go.mod -- +module z + +-- z/sub/sub.go -- +package sub + +-- triv/go.mod -- +module triv diff --git a/src/cmd/go/testdata/script/mod_tidy_cycle.txt b/src/cmd/go/testdata/script/mod_tidy_cycle.txt new file mode 100644 index 0000000..e46f37d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_cycle.txt @@ -0,0 +1,75 @@ +# Regression test for https://golang.org/issue/34086: +# 'go mod tidy' produced different go.mod file from other +# subcommands when certain kinds of cycles were present +# in the build graph. + +env GO111MODULE=on + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +# If the go.mod file is already tidy, 'go mod graph' should not modify it. +go mod graph +cmp go.mod go.mod.orig + +-- go.mod -- +module root + +go 1.13 + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + b v0.2.0 => ./b2 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 +) + +require ( + a v0.1.0 + b v0.2.0 // indirect +) +-- main.go -- +package main + +import _ "a" + +func main() {} + +-- a1/go.mod -- +module a + +go 1.13 + +require b v0.1.0 +-- a1/a.go -- +package a + +import _ "c" +-- b1/go.mod -- +module b + +go 1.13 + +require c v0.1.0 +-- b2/go.mod -- +module b + +go 1.13 + +require c v0.2.0 +-- c1/go.mod -- +module c + +go 1.13 +-- c2/c.go -- +package c +-- c2/go.mod -- +module c + +go 1.13 + +require b v0.2.0 +-- c2/c.go -- +package c diff --git a/src/cmd/go/testdata/script/mod_tidy_error.txt b/src/cmd/go/testdata/script/mod_tidy_error.txt new file mode 100644 index 0000000..395537b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_error.txt @@ -0,0 +1,39 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/27063: +# 'go mod tidy' and 'go mod vendor' should not hide loading errors. + +! go mod tidy +! stderr 'package nonexist is not in GOROOT' +stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com' +stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist' + +! go mod vendor +! stderr 'package nonexist is not in GOROOT' +stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com' +stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist' + +-- go.mod -- +module issue27063 + +go 1.13 + +require issue27063/other v0.0.0 +replace issue27063/other => ./other +-- x.go -- +package main + +import ( + "nonexist" + + "nonexist.example.com" + "issue27063/other" +) + +func main() {} +-- other/go.mod -- +module issue27063/other +-- other/other.go -- +package other + +import "other.example.com/nonexist" diff --git a/src/cmd/go/testdata/script/mod_tidy_old.txt b/src/cmd/go/testdata/script/mod_tidy_old.txt new file mode 100644 index 0000000..7428f0c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_old.txt @@ -0,0 +1,46 @@ +# 'go mod tidy' should remove content sums for module versions that aren't +# in the build list. It should preserve go.mod sums for module versions that +# are in the module graph though. +# Verifies golang.org/issue/33008. +go mod tidy +! grep '^rsc.io/quote v1.5.0 h1:' go.sum +grep '^rsc.io/quote v1.5.0/go.mod h1:' go.sum + +-- go.mod -- +module m + +go 1.15 + +require ( + rsc.io/quote v1.5.2 + example.com/r v0.0.0 +) + +replace example.com/r => ./r + +-- go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.0 h1:6fJa6E+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE= +rsc.io/quote v1.5.0/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= + +-- r/go.mod -- +module example.com/r + +require rsc.io/quote v1.5.0 + +-- use.go -- +package use + +import _ "example.com/r" + +-- r/use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_tidy_quote.txt b/src/cmd/go/testdata/script/mod_tidy_quote.txt new file mode 100644 index 0000000..423c7c2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_quote.txt @@ -0,0 +1,26 @@ +# Check that mod tidy does not introduce repeated +# require statements when input go.mod has quoted requirements. +env GO111MODULE=on + +go mod tidy +grep -count=1 rsc.io/quote go.mod + +cp go.mod2 go.mod +go mod tidy +grep -count=1 rsc.io/quote go.mod + + +-- go.mod -- +module x + +-- x.go -- +package x +import "rsc.io/quote" +func main() { _ = quote.Hello } + +-- go.mod2 -- +module x +require ( + "rsc.io/sampler" v1.3.0 + "rsc.io/quote" v1.5.2 +) diff --git a/src/cmd/go/testdata/script/mod_tidy_replace.txt b/src/cmd/go/testdata/script/mod_tidy_replace.txt new file mode 100644 index 0000000..dd99438 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_replace.txt @@ -0,0 +1,138 @@ +env GO111MODULE=on +env GOFLAGS=-mod=mod +[short] skip + +# golang.org/issue/30166: 'go mod tidy' should not crash if a replaced module is +# involved in a cycle. +cd cycle +env GOTRACEBACK=off +go mod tidy +cd .. + +# From inside the module, 'go list -m all' should NOT include transitive +# requirements of modules that have been replaced. +go list -m all +stdout 'rsc.io/quote/v3 v3.0.0' +! stdout 'rsc.io/sampler' +! stdout 'golang.org/x/text' + +# From outside the module, 'go list -m all' should include them. +cd outside +go list -m all +stdout 'rsc.io/quote/v3 v3.0.0' +stdout 'rsc.io/sampler v1.3.0' +stdout 'golang.org/x/text' +cd .. + +# 'go list all' should add indirect requirements to satisfy the packages +# imported from replacement modules. +! grep 'rsc.io/sampler' go.mod +! grep 'golang.org/x/text' go.mod +go list all +grep 'rsc.io/sampler' go.mod +grep 'golang.org/x/text' go.mod + +# 'go get' and 'go mod tidy' should follow the requirements of the replacements, +# not the originals, even if that results in a set of versions that are +# misleading or redundant without those replacements. +go get -d rsc.io/sampler@v1.2.0 +go mod tidy +go list -m all +stdout 'rsc.io/quote/v3 v3.0.0' +stdout 'rsc.io/sampler v1.2.0' +stdout 'golang.org/x/text' + +# The requirements seen from outside may be higher (or lower) +# than those seen from within the module. +grep 'rsc.io/sampler v1.2.0' go.mod +cd outside +go list -m all +stdout 'rsc.io/sampler v1.3.0' +cd .. + +# The same module can't be used as two different paths. +cd multiple-paths +! go mod tidy +stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)' + +-- go.mod -- +module example.com/tidy + +require rsc.io/quote/v3 v3.0.0 +replace rsc.io/quote/v3 => ./not-rsc.io/quote/v3 + +-- imports.go -- +package tidy + +import _ "rsc.io/quote/v3" + +-- outside/go.mod -- +module example.com/tidy/outside + +require example.com/tidy v0.0.0 +replace example.com/tidy => ./.. + +-- not-rsc.io/quote/v3/go.mod -- +module not-rsc.io/quote/v3 + +// No requirements specified! + +-- not-rsc.io/quote/v3/quote.go -- +package quote + +import ( + _ "rsc.io/sampler" + _ "golang.org/x/text/language" +) + +-- cycle/go.mod -- +module golang.org/issue/30166 + +require ( + golang.org/issue/30166/a v0.0.0 + golang.org/issue/30166/b v0.0.0 +) + +replace ( + golang.org/issue/30166/a => ./a + golang.org/issue/30166/b => ./b +) +-- cycle/cycle.go -- +package cycle + +import ( + _ "golang.org/issue/30166/a" + _ "golang.org/issue/30166/b" +) +-- cycle/a/a.go -- +package a +-- cycle/a/go.mod -- +module golang.org/issue/30166/a + +require golang.org/issue/30166/b v0.0.0 +-- cycle/b/b.go -- +package b +-- cycle/b/go.mod -- +module golang.org/issue/30166/b + +require golang.org/issue/30166/a v0.0.0 +-- multiple-paths/main.go -- +package main + +import ( + "fmt" + "rsc.io/quote/v3" +) + +func main() { + fmt.Println(quote.GoV3()) +} +-- multiple-paths/go.mod -- +module quoter + +require ( + rsc.io/quote/v3 v3.0.0 + not-rsc.io/quote/v3 v3.0.0 +) + +replace not-rsc.io/quote/v3 => rsc.io/quote/v3 v3.0.0 diff --git a/src/cmd/go/testdata/script/mod_tidy_sum.txt b/src/cmd/go/testdata/script/mod_tidy_sum.txt new file mode 100644 index 0000000..c583f56 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_sum.txt @@ -0,0 +1,33 @@ +env GO111MODULE=on + +# go.sum should list directly used modules and dependencies +go get -d rsc.io/quote@v1.5.2 +go mod tidy +grep rsc.io/sampler go.sum + +# go.sum should not normally lose old entries +go get -d rsc.io/quote@v1.0.0 +grep 'rsc.io/quote v1.0.0' go.sum +grep 'rsc.io/quote v1.5.2' go.sum +grep rsc.io/sampler go.sum + +# go mod tidy should clear dead entries from go.sum +go mod tidy +grep 'rsc.io/quote v1.0.0' go.sum +! grep 'rsc.io/quote v1.5.2' go.sum +! grep rsc.io/sampler go.sum + +# go.sum with no entries is OK to keep +# (better for version control not to delete and recreate.) +cp x.go.noimports x.go +go mod tidy +exists go.sum +! grep . go.sum + +-- go.mod -- +module x +-- x.go -- +package x +import _ "rsc.io/quote" +-- x.go.noimports -- +package x diff --git a/src/cmd/go/testdata/script/mod_tidy_too_new.txt b/src/cmd/go/testdata/script/mod_tidy_too_new.txt new file mode 100644 index 0000000..ca3163e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_too_new.txt @@ -0,0 +1,48 @@ +# https://golang.org/issue/46142: 'go mod tidy' should error out if the version +# in the go.mod file is newer than the most recent supported version. + +cp go.mod go.mod.orig + + +# If the go.mod file specifies an unsupported Go version, 'go mod tidy' should +# refuse to edit it: we don't know what a tidy go.mod file for that version +# would look like. + +! go mod tidy +stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$' +cmp go.mod go.mod.orig + + +# The -e flag should push past the error and edit the file anyway, +# but preserve the too-high version. + +cp go.mod.orig go.mod +go mod tidy -e +stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$' +cmp go.mod go.mod.tidy + + +-- go.mod -- +module example.net/from/the/future + +go 2000.0 + +replace example.net/m v0.0.0 => ./m +-- go.mod.tidy -- +module example.net/from/the/future + +go 2000.0 + +replace example.net/m v0.0.0 => ./m + +require example.net/m v0.0.0 +-- x.go -- +package x + +import "example.net/m" +-- m/go.mod -- +module example.net/m + +go 1.17 +-- m/m.go -- +package m diff --git a/src/cmd/go/testdata/script/mod_upgrade_patch.txt b/src/cmd/go/testdata/script/mod_upgrade_patch.txt new file mode 100644 index 0000000..8b34f8b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_upgrade_patch.txt @@ -0,0 +1,110 @@ +env GO111MODULE=on +[short] skip + +# Initially, we are at v1.0.0 for all dependencies. +go get -d +cp go.mod go.mod.orig +go list -m all +stdout '^patch.example.com/direct v1.0.0' +stdout '^patch.example.com/indirect v1.0.0' +! stdout '^patch.example.com/depofdirectpatch' + +# @patch should be rejected for modules not already in the build list. +! go get -d patch.example.com/depofdirectpatch@patch +stderr '^go get: can''t query version "patch" of module patch.example.com/depofdirectpatch: no existing version is required$' +cmp go.mod.orig go.mod + +# get -u=patch, with no arguments, should patch-update all dependencies +# of the package in the current directory, pulling in transitive dependencies +# and also patching those. +cp go.mod.orig go.mod +go get -d -u=patch +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.0.1' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# 'get all@patch' should patch the modules that provide packages in 'all'. +cp go.mod.orig go.mod +go get -d all@patch +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.0.1' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# ...but 'all@patch' should fail if any of the affected modules do not already +# have a selected version. +cp go.mod.orig go.mod +go mod edit -droprequire=patch.example.com/direct +cp go.mod go.mod.dropped +! go get -d all@patch +stderr '^go get all@patch: can''t query version "patch" of module patch.example.com/direct: no existing version is required$' +cmp go.mod.dropped go.mod + +# Requesting the direct dependency with -u=patch but without an explicit version +# should patch-update it and its dependencies. +cp go.mod.orig go.mod +go get -d -u=patch patch.example.com/direct +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.0.1' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# Requesting only the indirect dependency should not update the direct one. +cp go.mod.orig go.mod +go get -d -u=patch patch.example.com/indirect +go list -m all +stdout '^patch.example.com/direct v1.0.0' +stdout '^patch.example.com/indirect v1.0.1' +! stdout '^patch.example.com/depofdirectpatch' + +# @patch should apply only to the specific module, +# but the result must reflect its upgraded requirements. +cp go.mod.orig go.mod +go get -d patch.example.com/direct@patch +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.0.0' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# An explicit @patch should override a general -u. +cp go.mod.orig go.mod +go get -d -u patch.example.com/direct@patch +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.1.0' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# An explicit @latest should override a general -u=patch. +cp go.mod.orig go.mod +go get -d -u=patch patch.example.com/direct@latest +go list -m all +stdout '^patch.example.com/direct v1.1.0' +stdout '^patch.example.com/indirect v1.0.1' +! stdout '^patch.example.com/depofdirectpatch' + +# Standard library packages cannot be upgraded explicitly. +cp go.mod.orig go.mod +! go get cmd/vet@patch +stderr 'go get: can''t request explicit version "patch" of standard library package cmd/vet$' + +# However, standard-library packages without explicit versions are fine. +go get -d -u=patch -d cmd/go + +# We can upgrade to a new version of a module with no root package. +go get -d example.com/noroot@v1.0.0 +go list -m all +stdout '^example.com/noroot v1.0.0$' +go get -d example.com/noroot@patch +go list -m all +stdout '^example.com/noroot v1.0.1$' + + +-- go.mod -- +module x + +require patch.example.com/direct v1.0.0 + +-- main.go -- +package x +import _ "patch.example.com/direct" diff --git a/src/cmd/go/testdata/script/mod_vcs_missing.txt b/src/cmd/go/testdata/script/mod_vcs_missing.txt new file mode 100644 index 0000000..f8be43c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vcs_missing.txt @@ -0,0 +1,28 @@ +[exec:bzr] skip 'tests NOT having bzr' +[!net] skip + +env GO111MODULE=on +env GOPROXY=direct + +cd empty +! go get -d launchpad.net/gocheck +stderr '"bzr": executable file not found' +cd .. + +# 1.11 used to give the cryptic error "cannot find module for path" here, but +# only for a main package. +cd main +! go build -mod=mod +stderr '"bzr": executable file not found' +cd .. + +-- empty/go.mod -- +module m +-- main/go.mod -- +module m +-- main/main.go -- +package main + +import _ "launchpad.net/gocheck" + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_vendor.txt b/src/cmd/go/testdata/script/mod_vendor.txt new file mode 100644 index 0000000..2622916 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor.txt @@ -0,0 +1,312 @@ +env GO111MODULE=on + +# Without vendoring, a build should succeed unless -mod=vendor is set. +[!short] go build +[!short] ! go build -mod=vendor + +# Without vendoring, 'go list' should report the replacement directory for +# a package in a replaced module. +go list -f {{.Dir}} x +stdout 'src[\\/]x' + +# 'go mod vendor' should copy all replaced modules to the vendor directory. +go mod vendor -v +stderr '^# x v1.0.0 => ./x' +stderr '^x' +stderr '^# y v1.0.0 => ./y' +stderr '^y' +stderr '^# z v1.0.0 => ./z' +stderr '^z' +! stderr '^w' +grep 'a/foo/bar/b\na/foo/bar/c' vendor/modules.txt # must be sorted + +# An explicit '-mod=mod' should ignore the vendor directory. +go list -mod=mod -f {{.Dir}} x +stdout 'src[\\/]x' + +go list -mod=mod -f {{.Dir}} -m x +stdout 'src[\\/]x' + +# An explicit '-mod=vendor' should report package directories within +# the vendor directory. +go list -mod=vendor -f {{.Dir}} x +stdout 'src[\\/]vendor[\\/]x' + +# 'go list -mod=vendor -m' should successfully list vendored modules, +# but should not provide a module directory because no directory contains +# the complete module. +go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m x +stdout '^v1.0.0 $' + +# -mod=vendor should cause 'go list' flags that look up versions to fail. +! go list -mod=vendor -versions -m x +stderr '^go list -m: can''t determine available versions using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)$' +! go list -mod=vendor -u -m x +stderr '^go list -m: can''t determine available upgrades using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)$' + +# 'go list -mod=vendor -m' on a transitive dependency that does not +# provide vendored packages should give a helpful error rather than +# 'not a known dependency'. +! go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m diamondright +stderr 'go list -m: module diamondright: can''t resolve module using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +# 'go list -mod=mod' should report packages outside the import graph, +# but 'go list -mod=vendor' should error out for them. +go list -mod=mod -f {{.Dir}} w +stdout 'src[\\/]w' +! go list -mod=vendor -f {{.Dir}} w +stderr 'src[\\/]vendor[\\/]w' + +go list -mod=mod -f {{.Dir}} diamondright +stdout 'src[\\/]diamondright' + +# Test dependencies should not be copied. +! exists vendor/x/testdata +! exists vendor/a/foo/bar/b/ignored.go +! exists vendor/a/foo/bar/b/main_test.go + +# Licenses and other metadata for each module should be copied +# if any package within their module is copied. +exists vendor/a/foo/AUTHORS.txt +exists vendor/a/foo/CONTRIBUTORS +exists vendor/a/foo/LICENSE +exists vendor/a/foo/PATENTS +exists vendor/a/foo/COPYING +exists vendor/a/foo/COPYLEFT +exists vendor/x/NOTICE! +exists vendor/mysite/myname/mypkg/LICENSE.txt + +! exists vendor/a/foo/licensed-to-kill +! exists vendor/w +! exists vendor/w/LICENSE +! exists vendor/x/x2 +! exists vendor/x/x2/LICENSE + +[short] stop + +# 'go build' and 'go test' using vendored packages should succeed. +go build -mod=mod +go build -mod=vendor +go test -mod=vendor . ./subdir +go test -mod=vendor ./... +go fmt -mod=vendor ./... + +-- go.mod -- +module m + +go 1.13 + +require ( + a v1.0.0 + diamondroot v0.0.0 + mysite/myname/mypkg v1.0.0 + w v1.0.0 // indirect + x v1.0.0 + y v1.0.0 + z v1.0.0 +) + +replace ( + a v1.0.0 => ./a + diamondleft => ./diamondleft + diamondpoint => ./diamondpoint + diamondright => ./diamondright + diamondroot => ./diamondroot + mysite/myname/mypkg v1.0.0 => ./mypkg + w v1.0.0 => ./w + x v1.0.0 => ./x + y v1.0.0 => ./y + z v1.0.0 => ./z +) + +-- a/foo/AUTHORS.txt -- +-- a/foo/CONTRIBUTORS -- +-- a/foo/LICENSE -- +-- a/foo/PATENTS -- +-- a/foo/COPYING -- +-- a/foo/COPYLEFT -- +-- a/foo/licensed-to-kill -- +-- w/LICENSE -- +-- x/NOTICE! -- +-- x/x2/LICENSE -- +-- mypkg/LICENSE.txt -- + +-- a/foo/bar/b/main.go -- +package b +-- a/foo/bar/b/ignored.go -- +// This file is intended for use with "go run"; it isn't really part of the package. + +// +build ignore + +package main + +func main() {} +-- a/foo/bar/b/main_test.go -- +package b + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("../testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/foo/bar/c/main.go -- +package c +import _ "a/foo/bar/b" +-- a/foo/bar/c/main_test.go -- +package c + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("../../../testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } + if _, err := os.Stat("./testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/foo/bar/c/testdata/1 -- +-- a/foo/bar/testdata/1 -- +-- a/go.mod -- +module a +-- a/main.go -- +package a +-- a/main_test.go -- +package a + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("./testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/testdata/1 -- +-- appengine.go -- +// +build appengine + +package m + +import _ "appengine" +import _ "appengine/datastore" +-- mypkg/go.mod -- +module me +-- mypkg/mydir/d.go -- +package mydir +-- subdir/v1_test.go -- +package m + +import _ "mysite/myname/mypkg/mydir" +-- testdata1.go -- +package m + +import _ "a" +-- testdata2.go -- +package m + +import _ "a/foo/bar/c" +-- v1.go -- +package m + +import _ "x" +-- v2.go -- +// +build abc + +package mMmMmMm + +import _ "y" +-- v3.go -- +// +build !abc + +package m + +import _ "z" +-- v4.go -- +// +build notmytag + +package m + +import _ "x/x1" +-- importdiamond.go -- +package m + +import _ "diamondroot" +-- w/go.mod -- +module w +-- w/w.go -- +package w +-- x/go.mod -- +module x +-- x/testdata/x.txt -- +placeholder - want directory with no go files +-- x/x.go -- +package x +-- x/x1/x1.go -- +// +build notmytag + +package x1 +-- x/x2/dummy.txt -- +dummy +-- x/x_test.go -- +package x + +import _ "w" +-- y/go.mod -- +module y +-- y/y.go -- +package y +-- z/go.mod -- +module z +-- z/z.go -- +package z + +-- diamondroot/go.mod -- +module diamondroot + +require ( + diamondleft v0.0.0 + diamondright v0.0.0 +) +-- diamondroot/x.go -- +package diamondroot + +import _ "diamondleft" +-- diamondroot/unused/unused.go -- +package unused + +import _ "diamondright" +-- diamondleft/go.mod -- +module diamondleft + +require ( + diamondpoint v0.0.0 +) +-- diamondleft/x.go -- +package diamondleft + +import _ "diamondpoint" +-- diamondright/go.mod -- +module diamondright + +require ( + diamondpoint v0.0.0 +) +-- diamondright/x.go -- +package diamondright + +import _ "diamondpoint" +-- diamondpoint/go.mod -- +module diamondpoint +-- diamondpoint/x.go -- +package diamondpoint diff --git a/src/cmd/go/testdata/script/mod_vendor_auto.txt b/src/cmd/go/testdata/script/mod_vendor_auto.txt new file mode 100644 index 0000000..b0ea907 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_auto.txt @@ -0,0 +1,256 @@ +# Integration test for golang.org/issue/33848: automatically check and use vendored packages. + +env GO111MODULE=on + +[short] skip + +cd $WORK/auto +cp go.mod go.mod.orig +cp $WORK/modules-1.13.txt $WORK/auto/modules.txt + +# An explicit -mod=vendor should force use of the vendor directory. +env GOFLAGS=-mod=vendor + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +! go list -m all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +! go list -m -f '{{.Dir}}' all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +# An explicit -mod=mod should force the vendor directory to be ignored. +env GOFLAGS=-mod=mod + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m all +stdout '^example.com/auto$' +stdout 'example.com/printversion v1.0.0' +stdout 'example.com/version v1.0.0' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# If the main module's "go" directive says 1.13, we should default to -mod=mod. +env GOFLAGS= +go mod edit -go=1.13 + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# A 'go 1.14' directive in the main module's go.mod file should enable +# -mod=vendor by default, along with stronger checks for consistency +# between the go.mod file and vendor/modules.txt. +# A 'go 1.13' vendor/modules.txt file is not usually sufficient +# to pass those checks. +go mod edit -go=1.14 + +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt' +stderr '^\texample.com/unused: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\texample.com/version@v1.2.0: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$' + +# Module-specific subcommands should continue to load the full module graph. +go mod graph +stdout '^example.com/printversion@v1.0.0 example.com/version@v1.0.0$' + +# An explicit -mod=mod should still force the vendor directory to be ignored. +env GOFLAGS=-mod=mod + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m all +stdout '^example.com/auto$' +stdout 'example.com/printversion v1.0.0' +stdout 'example.com/version v1.0.0' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# 'go mod vendor' should repair vendor/modules.txt so that the implicit +# -mod=vendor works again. +env GOFLAGS= + +go mod edit -go=1.14 +go mod vendor + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# ...but 'go list -m' should continue to fail, this time without +# referring to a -mod default that the user didn't set. +! go list -m all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +! go list -m -f '{{.Dir}}' all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + + +# 'go mod init' should work if there is already a GOPATH-mode vendor directory +# present. If there are no module dependencies, -mod=vendor should be used by +# default and should not fail the consistency check even though no module +# information is present. + +rm go.mod +rm vendor/modules.txt + +go mod init example.com/auto +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# If information about dependencies is added to a 1.14 go.mod file, subsequent +# list commands should error out if vendor/modules.txt is missing or incomplete. + +cp go.mod.orig go.mod +go mod edit -go=1.14 +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt' +stderr '^\texample.com/unused: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\texample.com/version@v1.2.0: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$' + +# If -mod=vendor is set, limited consistency checks should apply even when +# the go version is 1.13 or earlier. +# An incomplete or missing vendor/modules.txt should resolve the vendored packages... +go mod edit -go=1.13 +go list -mod=vendor -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# ...but a version mismatch for an explicit dependency should be noticed. +cp $WORK/modules-bad-1.13.txt vendor/modules.txt +! go list -mod=vendor -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but vendor/modules.txt indicates example.com/printversion@v1.1.0$' +stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$' + +# If the go version is still 1.13, 'go mod vendor' should write a +# matching vendor/modules.txt containing the corrected 1.13 data. +go mod vendor +cmp $WORK/modules-1.13.txt vendor/modules.txt + +go list -mod=vendor -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# When the version is upgraded to 1.14, 'go mod vendor' should write a +# vendor/modules.txt with the updated 1.14 annotations. +go mod edit -go=1.14 +go mod vendor +cmp $WORK/modules-1.14.txt vendor/modules.txt + +# Then, -mod=vendor should kick in automatically and succeed. +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# 'go get' should update from the network or module cache, +# even if a vendor directory is present. +go get -d example.com/version@v1.1.0 +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring' + +-- $WORK/auto/go.mod -- +module example.com/auto + +go 1.13 + +require example.com/printversion v1.0.0 + +replace ( + example.com/unused => nonexistent.example.com/unused v1.0.0-whatever + example.com/version v1.0.0 => ./replacement-version + example.com/version v1.2.0 => nonexistent.example.com/version v1.2.0 +) +-- $WORK/auto/tools.go -- +// +build tools + +package auto + +import _ "example.com/printversion" +-- $WORK/auto/auto.go -- +package auto +-- $WORK/auto/replacement-version/go.mod -- +module example.com/version +-- $WORK/auto/replacement-version/version.go -- +package version + +const V = "v1.0.0-replaced" +-- $WORK/modules-1.14.txt -- +# example.com/printversion v1.0.0 +## explicit +example.com/printversion +# example.com/version v1.0.0 => ./replacement-version +example.com/version +# example.com/unused => nonexistent.example.com/unused v1.0.0-whatever +# example.com/version v1.2.0 => nonexistent.example.com/version v1.2.0 +-- $WORK/modules-1.13.txt -- +# example.com/printversion v1.0.0 +example.com/printversion +# example.com/version v1.0.0 => ./replacement-version +example.com/version +-- $WORK/modules-bad-1.13.txt -- +# example.com/printversion v1.1.0 +example.com/printversion +# example.com/version v1.1.0 +example.com/version +-- $WORK/auto/vendor/example.com/printversion/go.mod -- +module example.com/printversion + +require example.com/version v1.0.0 +replace example.com/version v1.0.0 => ../oops v0.0.0 +exclude example.com/version v1.0.1 +-- $WORK/auto/vendor/example.com/printversion/printversion.go -- +package main + +import ( + "fmt" + "os" + "runtime/debug" + + _ "example.com/version" +) + +func main() { + info, _ := debug.ReadBuildInfo() + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + } +} +-- $WORK/auto/vendor/example.com/version/version.go -- +package version + +const V = "v1.0.0-replaced" diff --git a/src/cmd/go/testdata/script/mod_vendor_build.txt b/src/cmd/go/testdata/script/mod_vendor_build.txt new file mode 100644 index 0000000..3b8eec0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_build.txt @@ -0,0 +1,41 @@ +env GO111MODULE=on +[short] skip + +# Populate go.mod and go.sum. +go mod tidy + +# initial conditions: using sampler v1.3.0, not listed in go.mod. +go list -deps +stdout rsc.io/sampler +! grep 'rsc.io/sampler v1.3.0' go.mod + +# update to v1.3.1, now indirect in go.mod. +go get -d rsc.io/sampler@v1.3.1 +grep 'rsc.io/sampler v1.3.1 // indirect' go.mod +cp go.mod go.mod.good + +# vendoring can but should not need to make changes. +go mod vendor +cmp go.mod go.mod.good + +# go list -mod=vendor (or go build -mod=vendor) must not modify go.mod. +# golang.org/issue/26704 +go list -mod=vendor +cmp go.mod go.mod.good + +# With a clean (and empty) module cache, 'go list -mod=vendor' should not download modules. +go clean -modcache +env GOPROXY=off +! go list ... +go list -mod=vendor ... + +# However, it should still list packages in the main module. +go list -mod=vendor m/... +stdout m + +-- go.mod -- +module m +go 1.12 +-- x.go -- +package x +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_vendor_embed.txt b/src/cmd/go/testdata/script/mod_vendor_embed.txt new file mode 100644 index 0000000..be11415 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_embed.txt @@ -0,0 +1,179 @@ +go mod vendor +cmp vendor/example.com/a/samedir_embed.txt a/samedir_embed.txt +cmp vendor/example.com/a/subdir/embed.txt a/subdir/embed.txt +cmp vendor/example.com/a/subdir/test/embed.txt a/subdir/test/embed.txt +cmp vendor/example.com/a/subdir/test/xtest/embed.txt a/subdir/test/xtest/embed.txt + +cd broken_no_matching_files +! go mod vendor +stderr 'go mod vendor: pattern foo.txt: no matching files found' + +cd ../broken_bad_pattern +! go mod vendor +stderr 'go mod vendor: pattern ../foo.txt: invalid pattern syntax' + +# matchPotentialSourceFile prunes out tests and unbuilt code. +# Make sure that they are vendored if they are embedded files. +cd ../embed_unbuilt +go mod vendor +cmp vendor/example.com/dep/unbuilt.go dep/unbuilt.go +cmp vendor/example.com/dep/dep_test.go dep/dep_test.go +! exists vendor/example.com/dep/not_embedded_unbuilt.go +! exists vendor/example.com/dep/not_embedded_dep_test.go +-- go.mod -- +module example.com/foo +go 1.16 + +require ( + example.com/a v0.1.0 +) + +replace ( + example.com/a v0.1.0 => ./a +) +-- foo.go -- +package main + +import ( + "fmt" + + "example.com/a" +) + +func main() { + fmt.Println(a.Str()) +} +-- a/go.mod -- +module example.com/a +-- a/a.go -- +package a + +import _ "embed" + +//go:embed samedir_embed.txt +var sameDir string + +//go:embed subdir/embed.txt +var subDir string + +func Str() string { + return sameDir + subDir +} +-- a/a_test.go -- +package a + +import _ "embed" + +//go:embed subdir/test/embed.txt +var subderTest string +-- a/a_x_test.go -- +package a_test + +import _ "embed" + +//go:embed subdir/test/xtest/embed.txt +var subdirXtest string +-- a/samedir_embed.txt -- +embedded file in same directory as package +-- a/subdir/embed.txt -- +embedded file in subdirectory of package +-- a/subdir/test/embed.txt -- +embedded file of test in subdirectory of package +-- a/subdir/test/xtest/embed.txt -- +embedded file of xtest in subdirectory of package +-- broken_no_matching_files/go.mod -- +module example.com/broken +go 1.16 + +require ( + example.com/brokendep v0.1.0 +) + +replace ( + example.com/brokendep v0.1.0 => ./brokendep +) +-- broken_no_matching_files/f.go -- +package broken + +import _ "example.com/brokendep" + +func F() {} +-- broken_no_matching_files/brokendep/go.mod -- +module example.com/brokendep +go 1.16 +-- broken_no_matching_files/brokendep/f.go -- +package brokendep + +import _ "embed" + +//go:embed foo.txt +var foo string +-- broken_bad_pattern/go.mod -- +module example.com/broken +go 1.16 + +require ( + example.com/brokendep v0.1.0 +) + +replace ( + example.com/brokendep v0.1.0 => ./brokendep +) +-- broken_bad_pattern/f.go -- +package broken + +import _ "example.com/brokendep" + +func F() {} +-- broken_bad_pattern/brokendep/go.mod -- +module example.com/brokendep +go 1.16 +-- broken_bad_pattern/brokendep/f.go -- +package brokendep + +import _ "embed" + +//go:embed ../foo.txt +var foo string +-- embed_unbuilt/go.mod -- +module example.com/foo +go 1.16 + +require ( + example.com/dep v0.1.0 +) + +replace ( + example.com/dep v0.1.0 => ./dep +) +-- embed_unbuilt/foo.go -- +package a + +import _ "example.com/dep" + +func F() {} +-- embed_unbuilt/dep/go.mod -- +module example.com/dep +go 1.16 +-- embed_unbuilt/dep/dep.go -- +package dep + +import _ "embed" + +//go:embed unbuilt.go +var unbuilt string + +//go:embed dep_test.go +var depTest string +-- embed_unbuilt/dep/unbuilt.go -- +// +build ignore + +package dep +-- embed_unbuilt/dep/not_embedded_unbuilt.go -- +// +build ignore + +package dep +-- embed_unbuilt/dep/dep_test.go -- +package dep +-- embed_unbuilt/dep/not_embedded_dep_test.go -- +package dep diff --git a/src/cmd/go/testdata/script/mod_vendor_nodeps.txt b/src/cmd/go/testdata/script/mod_vendor_nodeps.txt new file mode 100644 index 0000000..e9a84ca --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_nodeps.txt @@ -0,0 +1,9 @@ +env GO111MODULE=on + +go mod vendor +stderr '^go: no dependencies to vendor' + +-- go.mod -- +module x +-- x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_vendor_replace.txt b/src/cmd/go/testdata/script/mod_vendor_replace.txt new file mode 100644 index 0000000..0c1c1d2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_replace.txt @@ -0,0 +1,66 @@ +env GO111MODULE=on + +# Before vendoring, we expect to see the original directory. +go list -f '{{with .Module}}{{.Version}}{{end}} {{.Dir}}' rsc.io/quote/v3 +stdout 'v3.0.0' +stdout '.*[/\\]not-rsc.io[/\\]quote[/\\]v3' + +# Since all dependencies are replaced, 'go mod vendor' should not +# have to download anything from the network. +go mod vendor +! stderr 'downloading' +! stderr 'finding' + +# After vendoring, we expect to see the replacement in the vendor directory, +# without attempting to look up the non-replaced version. +cmp vendor/rsc.io/quote/v3/quote.go local/not-rsc.io/quote/v3/quote.go + +go list -mod=vendor -f '{{with .Module}}{{.Version}}{{end}} {{.Dir}}' rsc.io/quote/v3 +stdout 'v3.0.0' +stdout '.*[/\\]vendor[/\\]rsc.io[/\\]quote[/\\]v3' +! stderr 'finding' +! stderr 'lookup disabled' + +# 'go list' should provide the original replacement directory as the module's +# replacement path. +go list -mod=vendor -f '{{with .Module}}{{with .Replace}}{{.Path}}{{end}}{{end}}' rsc.io/quote/v3 +stdout '.*[/\\]not-rsc.io[/\\]quote[/\\]v3' + +# The same module can't be used as two different paths. +cd multiple-paths +! go mod vendor +stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)' + +-- go.mod -- +module example.com/replace + +require rsc.io/quote/v3 v3.0.0 +replace rsc.io/quote/v3 => ./local/not-rsc.io/quote/v3 + +-- imports.go -- +package replace + +import _ "rsc.io/quote/v3" + +-- local/not-rsc.io/quote/v3/go.mod -- +module not-rsc.io/quote/v3 + +-- local/not-rsc.io/quote/v3/quote.go -- +package quote + +-- multiple-paths/main.go -- +package main +import ( + "fmt" + "rsc.io/quote/v3" +) +func main() { + fmt.Println(quote.GoV3()) +} +-- multiple-paths/go.mod -- +module quoter +require ( + rsc.io/quote/v3 v3.0.0 + not-rsc.io/quote/v3 v3.0.0 +) +replace not-rsc.io/quote/v3 => rsc.io/quote/v3 v3.0.0 diff --git a/src/cmd/go/testdata/script/mod_vendor_trimpath.txt b/src/cmd/go/testdata/script/mod_vendor_trimpath.txt new file mode 100644 index 0000000..5451aa7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_trimpath.txt @@ -0,0 +1,45 @@ +# Check that when -trimpath and -mod=vendor are used together, +# paths in vendored packages are properly trimmed. +# Verifies golang.org/issue/36566. + +[short] skip + +# Only the main module has a root directory in vendor mode. +go mod vendor +go list -f {{.Module.Dir}} example.com/main +stdout $PWD +go list -f {{.Module.Dir}} example.com/stack +! stdout . + +# The program prints a file name from a vendored package. +# Without -trimpath, the name should include the vendor directory. +go run main.go +stdout vendor + +# With -trimpath, everything before the package path should be trimmed. +# As with -mod=mod, the version should appear as part of the module path. +go run -mod=vendor -trimpath main.go +stdout '^example.com/stack@v1.0.0/stack.go$' + +# With pristinely vendored source code, a trimmed binary built from vendored +# code should have the same behavior as one build from the module cache. +go run -mod=mod -trimpath main.go +stdout '^example.com/stack@v1.0.0/stack.go$' + +-- go.mod -- +module example.com/main + +require example.com/stack v1.0.0 + +-- main.go -- +package main + +import ( + "fmt" + + "example.com/stack" +) + +func main() { + fmt.Println(stack.TopFile()) +} diff --git a/src/cmd/go/testdata/script/mod_vendor_unused.txt b/src/cmd/go/testdata/script/mod_vendor_unused.txt new file mode 100644 index 0000000..96251bb --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_unused.txt @@ -0,0 +1,67 @@ +# Auxiliary test for inclusion of otherwise-unused replacements in +# vendor/modules.txt for golang.org/issue/33848. +# We need metadata about replacements in order to verify that modules.txt +# remains in sync with the main module's go.mod file. + +env GO111MODULE=on + +go mod vendor +cmp go1.14-modules.txt vendor/modules.txt + +-- go.mod -- +module example.com/foo +go 1.14 + +require ( + example.com/a v0.1.0 +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0-unused => ./b2 + example.com/c => ./c + example.com/d v0.1.0 => ./d1 + example.com/d v0.2.0 => ./d2 + example.com/e => example.com/e v0.1.0-unused +) +-- foo.go -- +package foo +import _ "example.com/a" +-- a/go.mod -- +module example.com/a +require ( + example.com/b v0.1.0 // indirect + example.com/c v0.1.0 // indirect +) +-- a/a.go -- +package a +import _ "example.com/d" +-- b1/go.mod -- +module example.com/b +require example.com/d v0.1.0 +-- b2/go.mod -- +module example.com/b +require example.com/c v0.2.0 +-- c/go.mod -- +module example.com/c +require example.com/d v0.2.0 +-- d1/go.mod -- +module example.com/d +-- d1/d1.go -- +package d +-- d2/go.mod -- +module example.com/d +-- d2/d2.go -- +package d +-- go1.14-modules.txt -- +# example.com/a v0.1.0 => ./a +## explicit +example.com/a +# example.com/d v0.2.0 => ./d2 +example.com/d +# example.com/b v0.1.0 => ./b1 +# example.com/b v0.2.0-unused => ./b2 +# example.com/c => ./c +# example.com/d v0.1.0 => ./d1 +# example.com/e => example.com/e v0.1.0-unused diff --git a/src/cmd/go/testdata/script/mod_vendor_unused_only.txt b/src/cmd/go/testdata/script/mod_vendor_unused_only.txt new file mode 100644 index 0000000..839c645 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_unused_only.txt @@ -0,0 +1,17 @@ +# Ensure that we generate a vendor/modules.txt file even when the only +# requirements in go.mod are unused. Regression test for +# golang.org/issue/36580 + +env GO111MODULE=on + +go mod vendor +cmp go1.14-modules.txt vendor/modules.txt + +-- go.mod -- +module example.com/m +go 1.14 + +require example.com v1.0.0 // indirect +-- go1.14-modules.txt -- +# example.com v1.0.0 +## explicit diff --git a/src/cmd/go/testdata/script/mod_verify.txt b/src/cmd/go/testdata/script/mod_verify.txt new file mode 100644 index 0000000..b510665 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_verify.txt @@ -0,0 +1,87 @@ +env GO111MODULE=on +[short] skip + +# With good go.sum, verify succeeds by avoiding download. +cp go.sum.good go.sum +go mod verify +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip + +# With bad go.sum, verify succeeds by avoiding download. +cp go.sum.bad go.sum +go mod verify +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip + +# With bad go.sum, sync (which must download) fails. +rm go.sum +cp go.sum.bad go.sum +! go mod tidy +stderr 'checksum mismatch' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip + +# With good go.sum, sync works. +rm go.sum +cp go.sum.good go.sum +go mod tidy +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip +exists $GOPATH/pkg/mod/rsc.io/quote@v1.1.0/quote.go + +# go.sum should have the new checksum for go.mod +grep '^rsc.io/quote v1.1.0/go.mod ' go.sum + +# verify should work +go mod verify + +# basic loading of module graph should detect incorrect go.mod files. +go mod graph +cp go.sum.bad2 go.sum +! go mod graph +stderr 'go.mod: checksum mismatch' + +# go.sum should be created and updated automatically. +rm go.sum +go mod graph +exists go.sum +grep '^rsc.io/quote v1.1.0/go.mod ' go.sum +! grep '^rsc.io/quote v1.1.0 ' go.sum + +go mod tidy +grep '^rsc.io/quote v1.1.0/go.mod ' go.sum +grep '^rsc.io/quote v1.1.0 ' go.sum + +# verify should fail on a missing ziphash. tidy should restore it. +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.ziphash +! go mod verify +stderr '^rsc.io/quote v1.1.0: missing ziphash: open '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]rsc.io[/\\]quote[/\\]@v[/\\]v1.1.0.ziphash' +go mod tidy +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.ziphash +go mod verify + +# Packages below module root should not be mentioned in go.sum. +rm go.sum +go mod edit -droprequire rsc.io/quote +go get -d rsc.io/quote/buggy +grep '^rsc.io/quote v1.5.2/go.mod ' go.sum +! grep buggy go.sum + +# non-existent packages below module root should not be mentioned in go.sum +go mod edit -droprequire rsc.io/quote +! go list rsc.io/quote/morebuggy +grep '^rsc.io/quote v1.5.2/go.mod ' go.sum +! grep buggy go.sum + +-- go.mod -- +module x +require rsc.io/quote v1.1.0 + +-- x.go -- +package x +import _ "rsc.io/quote" + +-- go.sum.good -- +rsc.io/quote v1.1.0 h1:a3YaZoizPtXyv6ZsJ74oo2L4/bwOSTKMY7MAyo4O/0c= + +-- go.sum.bad -- +rsc.io/quote v1.1.0 h1:a3YaZoizPtXyv6ZsJ74oo2L4/bwOSTKMY7MAyo4O/1c= + +-- go.sum.bad2 -- +rsc.io/quote v1.1.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl1= diff --git a/src/cmd/go/testdata/script/mod_versions.txt b/src/cmd/go/testdata/script/mod_versions.txt new file mode 100644 index 0000000..9e6322b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_versions.txt @@ -0,0 +1,14 @@ +# Test rejection of pkg@version in GOPATH mode. +env GO111MODULE=off +! go get rsc.io/quote@v1.5.1 +stderr '^go: can only use path@version syntax with ''go get'' and ''go install'' in module-aware mode$' +! go build rsc.io/quote@v1.5.1 +stderr '^package rsc.io/quote@v1.5.1: can only use path@version syntax with ''go get'' and ''go install'' in module-aware mode$' + +env GO111MODULE=on +cd x +! go build rsc.io/quote@v1.5.1 +stderr '^package rsc.io/quote@v1.5.1: can only use path@version syntax with ''go get'' and ''go install'' in module-aware mode$' + +-- x/go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_why.txt b/src/cmd/go/testdata/script/mod_why.txt new file mode 100644 index 0000000..b3036fa --- /dev/null +++ b/src/cmd/go/testdata/script/mod_why.txt @@ -0,0 +1,130 @@ +env GO111MODULE=on +[short] skip + +# Populate go.sum. +go mod tidy +cp go.mod go.mod.orig + +go list -test all +stdout rsc.io/quote +stdout golang.org/x/text/language + +# why a package? +go mod why golang.org/x/text/language +cmp stdout why-language.txt + +# why a module? +go mod why -m golang.org... +cmp stdout why-text-module.txt + +# why a package used only in tests? +go mod why rsc.io/testonly +cmp stdout why-testonly.txt + +# why a module used only in a test of a dependency? +go mod why -m rsc.io/testonly +cmp stdout why-testonly.txt + +# test package not needed +go mod why golang.org/x/text/unused +cmp stdout why-unused.txt + +# vendor doesn't use packages used only in tests. +go mod why -vendor rsc.io/testonly +cmp stdout why-vendor.txt + +# vendor doesn't use modules used only in tests. +go mod why -vendor -m rsc.io/testonly +cmp stdout why-vendor-module.txt + +# test multiple packages +go mod why golang.org/x/text/language golang.org/x/text/unused +cmp stdout why-both.txt + +# test multiple modules +go mod why -m rsc.io/quote rsc.io/sampler +cmp stdout why-both-module.txt + +# package in a module that isn't even in the module graph +# (https://golang.org/issue/26977) +go mod why rsc.io/fortune +cmp stdout why-missing.txt + +# None of these command should have changed the go.mod file. +cmp go.mod go.mod.orig + +-- go.mod -- +module mymodule +require rsc.io/quote v1.5.2 + +-- x/x.go -- +package x +import _ "mymodule/z" + +-- y/y.go -- +package y + +-- y/y_test.go -- +package y +import _ "rsc.io/quote" + +-- z/z.go -- +package z +import _ "mymodule/y" + + +-- why-language.txt -- +# golang.org/x/text/language +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +golang.org/x/text/language +-- why-unused.txt -- +# golang.org/x/text/unused +(main module does not need package golang.org/x/text/unused) +-- why-text-module.txt -- +# golang.org/x/text +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +golang.org/x/text/language +-- why-testonly.txt -- +# rsc.io/testonly +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +rsc.io/sampler.test +rsc.io/testonly +-- why-vendor.txt -- +# rsc.io/testonly +(main module does not need to vendor package rsc.io/testonly) +-- why-vendor-module.txt -- +# rsc.io/testonly +(main module does not need to vendor module rsc.io/testonly) +-- why-both.txt -- +# golang.org/x/text/language +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +golang.org/x/text/language + +# golang.org/x/text/unused +(main module does not need package golang.org/x/text/unused) +-- why-both-module.txt -- +# rsc.io/quote +mymodule/y +mymodule/y.test +rsc.io/quote + +# rsc.io/sampler +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +-- why-missing.txt -- +# rsc.io/fortune +(main module does not need package rsc.io/fortune) diff --git a/src/cmd/go/testdata/script/modfile_flag.txt b/src/cmd/go/testdata/script/modfile_flag.txt new file mode 100644 index 0000000..0ad0880 --- /dev/null +++ b/src/cmd/go/testdata/script/modfile_flag.txt @@ -0,0 +1,93 @@ +# Tests the behavior of the -modfile flag in commands that support it. +# The go.mod file exists but should not be read or written. +# Same with go.sum. + +env GOFLAGS=-modfile=go.alt.mod +cp go.mod go.mod.orig +cp go.sum go.sum.orig + + +# go mod init should create a new file, even though go.mod already exists. +go mod init example.com/m +grep example.com/m go.alt.mod + +# 'go env GOMOD' should print the path to the real file. +# 'go env' does not recognize the '-modfile' flag. +go env GOMOD +stdout '^\$WORK[/\\]gopath[/\\]src[/\\]go.mod$' + +# 'go list -m' should print the effective go.mod file as GoMod though. +go list -m -f '{{.GoMod}}' +stdout '^go.alt.mod$' + +# go mod edit should operate on the alternate file +go mod edit -require rsc.io/quote@v1.5.2 +grep rsc.io/quote go.alt.mod + +# other 'go mod' commands should work. 'go mod vendor' is tested later. +go mod download rsc.io/quote +go mod graph +stdout rsc.io/quote +go mod tidy +grep rsc.io/quote go.alt.sum +go mod verify +go mod why rsc.io/quote + + +# 'go list' and other commands with build flags should work. +# They should update the alternate go.mod when a dependency is missing. +go mod edit -droprequire rsc.io/quote +go list -mod=mod . +grep rsc.io/quote go.alt.mod +go build -n -mod=mod . +go test -n -mod=mod . +go get -d rsc.io/quote + + +# 'go mod vendor' should work. +go mod vendor +exists vendor + +# Automatic vendoring should be broken by editing an explicit requirement +# in the alternate go.mod file. +go mod edit -require rsc.io/quote@v1.5.1 +! go list . +go list -mod=mod +rm vendor + + +# 'go generate' should use the alternate file when resolving packages. +# Recursive go commands started with 'go generate' should not get an explicitly +# passed -modfile, but they should see arguments from GOFLAGS. +cp go.alt.mod go.gen.mod +env OLD_GOFLAGS=$GOFLAGS +env GOFLAGS=-modfile=go.gen.mod +go generate -modfile=go.alt.mod . +env GOFLAGS=$OLD_GOFLAGS +grep example.com/exclude go.gen.mod +! grep example.com/exclude go.alt.mod + + +# The original files should not have been modified. +cmp go.mod go.mod.orig +cmp go.sum go.sum.orig + + +# If the altnernate mod file does not have a ".mod" suffix, an error +# should be reported. +cp go.alt.mod goaltmod +! go mod tidy -modfile=goaltmod +stderr '-modfile=goaltmod: file does not have .mod extension' + +-- go.mod -- +ʕ◔ϖ◔ʔ +-- go.sum -- +ʕ◔ϖ◔ʔ +-- use.go -- +package main + +import _ "rsc.io/quote" +-- gen.go -- +//go:generate go mod edit -exclude example.com/exclude@v1.0.0 + +package main diff --git a/src/cmd/go/testdata/script/noncanonical_import.txt b/src/cmd/go/testdata/script/noncanonical_import.txt new file mode 100644 index 0000000..018cb01 --- /dev/null +++ b/src/cmd/go/testdata/script/noncanonical_import.txt @@ -0,0 +1,19 @@ +env GO111MODULE=off + +! go build canonical/d +stderr '^canonical[/\\]b[/\\]b.go:3:8: non-canonical import path "canonical/a/": should be "canonical/a"$' + +-- canonical/a/a.go -- +package a + +import _ "c" +-- canonical/b/b.go -- +package b + +import _ "canonical/a/" +-- canonical/a/vendor/c/c.go -- +package c +-- canonical/d/d.go -- +package d + +import _ "canonical/b" diff --git a/src/cmd/go/testdata/script/pattern_syntax_error.txt b/src/cmd/go/testdata/script/pattern_syntax_error.txt new file mode 100644 index 0000000..9a1f5e5 --- /dev/null +++ b/src/cmd/go/testdata/script/pattern_syntax_error.txt @@ -0,0 +1,12 @@ +env GO111MODULE=off + +# patterns match directories with syntax errors +! go list ./... +! go build ./... +! go install ./... + +-- mypkg/x.go -- +package mypkg + +-- mypkg/y.go -- +pkg mypackage diff --git a/src/cmd/go/testdata/script/prevent_sys_unix_import.txt b/src/cmd/go/testdata/script/prevent_sys_unix_import.txt new file mode 100644 index 0000000..ea1ad78 --- /dev/null +++ b/src/cmd/go/testdata/script/prevent_sys_unix_import.txt @@ -0,0 +1,6 @@ +# Policy decision: we shouldn't vendor golang.org/x/sys/unix in std +# See https://golang.org/issue/32102 + +env GO111MODULE=on +go list std +! stdout vendor/golang.org/x/sys/unix diff --git a/src/cmd/go/testdata/script/run_dirs.txt b/src/cmd/go/testdata/script/run_dirs.txt new file mode 100644 index 0000000..538a6ac --- /dev/null +++ b/src/cmd/go/testdata/script/run_dirs.txt @@ -0,0 +1,11 @@ +cd rundir + +! go run x.go sub/sub.go +stderr 'named files must all be in one directory; have ./ and sub/' +! go run sub/sub.go x.go +stderr 'named files must all be in one directory; have sub/ and ./' + +-- rundir/sub/sub.go -- +package main +-- rundir/x.go -- +package main diff --git a/src/cmd/go/testdata/script/run_hello.txt b/src/cmd/go/testdata/script/run_hello.txt new file mode 100644 index 0000000..939b661 --- /dev/null +++ b/src/cmd/go/testdata/script/run_hello.txt @@ -0,0 +1,9 @@ +env GO111MODULE=off + +# hello world +go run hello.go +stderr 'hello world' + +-- hello.go -- +package main +func main() { println("hello world") } diff --git a/src/cmd/go/testdata/script/run_hello_pkg.txt b/src/cmd/go/testdata/script/run_hello_pkg.txt new file mode 100644 index 0000000..ea2b4d7 --- /dev/null +++ b/src/cmd/go/testdata/script/run_hello_pkg.txt @@ -0,0 +1,17 @@ +go run m/hello +stderr 'hello, world' + +cd hello +go run . +stderr 'hello, world' + +-- go.mod -- +module m + +go 1.16 +-- hello/hello.go -- +package main + +func main() { + println("hello, world") +} diff --git a/src/cmd/go/testdata/script/run_internal.txt b/src/cmd/go/testdata/script/run_internal.txt new file mode 100644 index 0000000..d021850 --- /dev/null +++ b/src/cmd/go/testdata/script/run_internal.txt @@ -0,0 +1,64 @@ +env GO111MODULE=off + +go list -e -f '{{.Incomplete}}' m/runbad1.go +stdout true +! go run m/runbad1.go +stderr 'use of internal package m/x/internal not allowed' + +go list -e -f '{{.Incomplete}}' m/runbad2.go +stdout true +! go run m/runbad2.go +stderr 'use of internal package m/x/internal/y not allowed' + +go list -e -f '{{.Incomplete}}' m/runok.go +stdout false +go run m/runok.go + +cd m +env GO111MODULE=on + +go list -e -f '{{.Incomplete}}' runbad1.go +stdout true +! go run runbad1.go +stderr 'use of internal package m/x/internal not allowed' + +go list -e -f '{{.Incomplete}}' runbad2.go +stdout true +! go run runbad2.go +stderr 'use of internal package m/x/internal/y not allowed' + +go list -e -f '{{.Incomplete}}' runok.go +stdout false +go run runok.go + + +-- m/go.mod -- +module m + +-- m/x/internal/internal.go -- +package internal + +-- m/x/internal/y/y.go -- +package y + +-- m/internal/internal.go -- +package internal + +-- m/internal/z/z.go -- +package z + +-- m/runbad1.go -- +package main +import _ "m/x/internal" +func main() {} + +-- m/runbad2.go -- +package main +import _ "m/x/internal/y" +func main() {} + +-- m/runok.go -- +package main +import _ "m/internal" +import _ "m/internal/z" +func main() {} diff --git a/src/cmd/go/testdata/script/run_issue11709.txt b/src/cmd/go/testdata/script/run_issue11709.txt new file mode 100644 index 0000000..c8ba998 --- /dev/null +++ b/src/cmd/go/testdata/script/run_issue11709.txt @@ -0,0 +1,15 @@ +# 'go run' should not pass extraneous environment variables to the subprocess. +go run run.go +! stdout . +! stderr . + +-- run.go -- +package main + +import "os" + +func main() { + if os.Getenv("TERM") != "" { + os.Exit(1) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/run_set_executable_name.txt b/src/cmd/go/testdata/script/run_set_executable_name.txt new file mode 100644 index 0000000..54ddee9 --- /dev/null +++ b/src/cmd/go/testdata/script/run_set_executable_name.txt @@ -0,0 +1,50 @@ +env GO111MODULE=on +[short] skip + +# Check for correct naming of temporary executable + +#Test for single file specified +cd x/y/z +go run foo.go +stderr 'foo' + +#Test for current directory +go run . +stderr 'z' + +#Test for set path +go run m/x/y/z/ +stderr 'z' + +-- m/x/y/z/foo.go -- +package main +import( + "os" + "path/filepath" +) +func main() { + println(filepath.Base(os.Args[0])) +} + +-- x/y/z/foo.go -- +package main +import( + "os" + "path/filepath" +) +func main() { + println(filepath.Base(os.Args[0])) +} + +-- x/y/z/foo.go -- +package main +import( + "os" + "path/filepath" +) +func main() { + println(filepath.Base(os.Args[0])) +} + +-- go.mod -- +module m
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/run_vendor.txt b/src/cmd/go/testdata/script/run_vendor.txt new file mode 100644 index 0000000..46cac06 --- /dev/null +++ b/src/cmd/go/testdata/script/run_vendor.txt @@ -0,0 +1,34 @@ +# Run +env GO111MODULE=off +cd vend/hello +go run hello.go +stdout 'hello, world' + +-- vend/hello/hello.go -- +package main + +import ( + "fmt" + "strings" // really ../vendor/strings +) + +func main() { + fmt.Printf("%s\n", strings.Msg) +} +-- vend/hello/hello_test.go -- +package main + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgInternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/vendor/strings/msg.go -- +package strings + +var Msg = "hello, world" diff --git a/src/cmd/go/testdata/script/run_wildcard.txt b/src/cmd/go/testdata/script/run_wildcard.txt new file mode 100644 index 0000000..72036d1 --- /dev/null +++ b/src/cmd/go/testdata/script/run_wildcard.txt @@ -0,0 +1,7 @@ +env GO111MODULE=off + +# Fix for https://github.com/golang/go/issues/28696: +# go run x/... should not panic when directory x doesn't exist. + +! go run nonexistent/... +stderr '^go run: no packages loaded from nonexistent/...$' diff --git a/src/cmd/go/testdata/script/script_wait.txt b/src/cmd/go/testdata/script/script_wait.txt new file mode 100644 index 0000000..acaccfe --- /dev/null +++ b/src/cmd/go/testdata/script/script_wait.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +[!exec:echo] skip +[!exec:false] skip + +exec echo foo +stdout foo + +exec echo foo & +exec echo bar & +! exec false & + +# Starting a background process should clear previous output. +! stdout foo + +# Wait should set the output to the concatenated outputs of the background +# programs, in the order in which they were started. +wait +stdout 'foo\nbar' + +# The end of the test should interrupt or kill any remaining background +# programs, but that should not cause the test to fail if it does not +# care about the exit status of those programs. +[!exec:sleep] stop +? exec sleep 86400 & diff --git a/src/cmd/go/testdata/script/std_vendor.txt b/src/cmd/go/testdata/script/std_vendor.txt new file mode 100644 index 0000000..6cb015f --- /dev/null +++ b/src/cmd/go/testdata/script/std_vendor.txt @@ -0,0 +1,43 @@ +env GO111MODULE=off + +[!gc] skip + +# 'go list' should report imports from _test.go in the TestImports field. +go list -f '{{.TestImports}}' +stdout net/http # from .TestImports + +# 'go list' should report standard-vendored packages by path. +go list -f '{{.Dir}}' vendor/golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor + +# 'go list -test' should report vendored transitive dependencies of _test.go +# imports in the Deps field, with a 'vendor' prefix on their import paths. +go list -test -f '{{.Deps}}' +stdout golang.org/x/crypto # dep of .TestImports + +# Packages outside the standard library should not use its copy of vendored packages. +cd broken +! go build +stderr 'cannot find package' + +-- go.mod -- +module m + +-- x.go -- +package x + +-- x_test.go -- +package x +import "testing" +import _ "net/http" +func Test(t *testing.T) {} + +-- broken/go.mod -- +module broken +-- broken/http.go -- +package broken + +import ( + _ "net/http" + _ "golang.org/x/net/http/httpproxy" +) diff --git a/src/cmd/go/testdata/script/test_bad_example.txt b/src/cmd/go/testdata/script/test_bad_example.txt new file mode 100644 index 0000000..1d147b6 --- /dev/null +++ b/src/cmd/go/testdata/script/test_bad_example.txt @@ -0,0 +1,13 @@ +# Tests that invalid examples are ignored. +# Verifies golang.org/issue/35284 +go test x_test.go + +-- x_test.go -- +package x + +import "fmt" + +func ExampleThisShouldNotHaveAParameter(thisShouldntExist int) { + fmt.Println("X") + // Output: +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_badtest.txt b/src/cmd/go/testdata/script/test_badtest.txt new file mode 100644 index 0000000..e79fc51 --- /dev/null +++ b/src/cmd/go/testdata/script/test_badtest.txt @@ -0,0 +1,49 @@ +env GO111MODULE=off + +! go test badtest/badexec +! stdout ^ok +stdout ^FAIL\tbadtest/badexec + +! go test badtest/badsyntax +! stdout ^ok +stdout ^FAIL\tbadtest/badsyntax + +! go test badtest/badvar +! stdout ^ok +stdout ^FAIL\tbadtest/badvar + +! go test notest +! stdout ^ok +stderr '^notest.hello.go:6:1: syntax error: non-declaration statement outside function body' # Exercise issue #7108 + +-- badtest/badexec/x_test.go -- +package badexec + +func init() { + panic("badexec") +} + +-- badtest/badsyntax/x.go -- +package badsyntax + +-- badtest/badsyntax/x_test.go -- +package badsyntax + +func func func func func! + +-- badtest/badvar/x.go -- +package badvar + +-- badtest/badvar/x_test.go -- +package badvar_test + +func f() { + _ = notdefined +} +-- notest/hello.go -- +package notest + +func hello() { + println("hello world") +} +Hello world
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_benchmark_chatty_fail.txt b/src/cmd/go/testdata/script/test_benchmark_chatty_fail.txt new file mode 100644 index 0000000..6031ead --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_chatty_fail.txt @@ -0,0 +1,32 @@ +# Run chatty tests. Assert on CONT lines. +! go test chatty_test.go -v -bench . chatty_bench + +# Sanity check that output occurs. +stdout -count=2 'this is sub-0' +stdout -count=2 'this is sub-1' +stdout -count=2 'this is sub-2' +stdout -count=1 'error from sub-0' +stdout -count=1 'error from sub-1' +stdout -count=1 'error from sub-2' + +# Benchmarks should not print CONT. +! stdout CONT + +-- chatty_test.go -- +package chatty_bench + +import ( + "testing" + "fmt" +) + +func BenchmarkChatty(b *testing.B) { + for i := 0; i < 3; i++ { + b.Run(fmt.Sprintf("sub-%d", i), func(b *testing.B) { + for j := 0; j < 2; j++ { + b.Logf("this is sub-%d", i) + } + b.Errorf("error from sub-%d", i) + }) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_benchmark_chatty_success.txt b/src/cmd/go/testdata/script/test_benchmark_chatty_success.txt new file mode 100644 index 0000000..a1c0d65 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_chatty_success.txt @@ -0,0 +1,29 @@ +# Run chatty tests. Assert on CONT lines. +go test chatty_test.go -v -bench . chatty_bench + +# Sanity check that output happens. We don't provide -count because the amount +# of output is variable. +stdout 'this is sub-0' +stdout 'this is sub-1' +stdout 'this is sub-2' + +# Benchmarks should not print CONT. +! stdout CONT + +-- chatty_test.go -- +package chatty_bench + +import ( + "testing" + "fmt" +) + +func BenchmarkChatty(b *testing.B) { + for i := 0; i < 3; i++ { + b.Run(fmt.Sprintf("sub-%d", i), func(b *testing.B) { + for j := 0; j < 2; j++ { + b.Logf("this is sub-%d", i) + } + }) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_benchmark_fatal.txt b/src/cmd/go/testdata/script/test_benchmark_fatal.txt new file mode 100644 index 0000000..e281379 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_fatal.txt @@ -0,0 +1,19 @@ +# Test that calling t.Fatal in a benchmark causes a non-zero exit status. + +! go test -run '^$' -bench . benchfatal +! stdout ^ok +! stderr ^ok +stdout FAIL.*benchfatal + +-- go.mod -- +module benchfatal + +go 1.16 +-- x_test.go -- +package benchfatal + +import "testing" + +func BenchmarkThatCallsFatal(b *testing.B) { + b.Fatal("called by benchmark") +} diff --git a/src/cmd/go/testdata/script/test_benchmark_labels.txt b/src/cmd/go/testdata/script/test_benchmark_labels.txt new file mode 100644 index 0000000..6b424c1 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_labels.txt @@ -0,0 +1,23 @@ +# Tests that go test -bench prints out goos, goarch, and pkg. + +# Check for goos, goarch, and pkg. +go test -run ^$ -bench . bench +stdout '^goos: '$GOOS +stdout '^goarch: '$GOARCH +stdout '^pkg: bench' + +# Check go test does not print pkg multiple times +! stdout 'pkg:.*pkg: ' +! stderr 'pkg:.*pkg:' + +-- go.mod -- +module bench + +go 1.16 +-- x_test.go -- +package bench + +import "testing" + +func Benchmark(b *testing.B) { +} diff --git a/src/cmd/go/testdata/script/test_benchmark_timeout.txt b/src/cmd/go/testdata/script/test_benchmark_timeout.txt new file mode 100644 index 0000000..4bae7e7 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_timeout.txt @@ -0,0 +1,18 @@ +# Tests issue #18845 +[short] skip + +go test -bench . -timeout=750ms timeoutbench_test.go +stdout ok +stdout PASS + +-- timeoutbench_test.go -- +package timeoutbench_test + +import ( + "testing" + "time" +) + +func BenchmarkSleep1s(b *testing.B) { + time.Sleep(1 * time.Second) +} diff --git a/src/cmd/go/testdata/script/test_build_failure.txt b/src/cmd/go/testdata/script/test_build_failure.txt new file mode 100644 index 0000000..8d13634 --- /dev/null +++ b/src/cmd/go/testdata/script/test_build_failure.txt @@ -0,0 +1,31 @@ +[short] skip + +! go test -x coverbad +! stderr '[\\/]coverbad\.test( |$)' # 'go test' should not claim to have run the test. +stderr 'undefined: g' +stderr 'undefined: j' + +-- go.mod -- +module coverbad + +go 1.16 +-- p.go -- +package p + +func f() { + g() +} +-- p1.go -- +package p + +import "C" + +func h() { + j() +} +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/test_cache_inputs.txt b/src/cmd/go/testdata/script/test_cache_inputs.txt new file mode 100644 index 0000000..50486e1 --- /dev/null +++ b/src/cmd/go/testdata/script/test_cache_inputs.txt @@ -0,0 +1,251 @@ +env GO111MODULE=off + +# Test that cached test results are invalidated in response to +# changes to the external inputs to the test. + +[short] skip +[GODEBUG:gocacheverify=1] skip + +# We're testing cache behavior, so start with a clean GOCACHE. +env GOCACHE=$WORK/cache + +# Build a helper binary to invoke os.Chtimes. +go build -o mkold$GOEXE mkold.go + +# Make test input files appear to be a minute old. +exec ./mkold$GOEXE 1m testcache/file.txt +exec ./mkold$GOEXE 1m testcache/script.sh + +# If the test reads an environment variable, changes to that variable +# should invalidate cached test results. +env TESTKEY=x +go test testcache -run=TestLookupEnv +go test testcache -run=TestLookupEnv +stdout '\(cached\)' + +env TESTKEY=y +go test testcache -run=TestLookupEnv +! stdout '\(cached\)' +go test testcache -run=TestLookupEnv +stdout '\(cached\)' + +# Changes in arguments forwarded to the test should invalidate cached test +# results. +go test testcache -run=TestOSArgs -v hello +! stdout '\(cached\)' +stdout 'hello' +go test testcache -run=TestOSArgs -v goodbye +! stdout '\(cached\)' +stdout 'goodbye' + +# golang.org/issue/36134: that includes the `-timeout` argument. +go test testcache -run=TestOSArgs -timeout=20m -v +! stdout '\(cached\)' +stdout '-test\.timeout[= ]20m' +go test testcache -run=TestOSArgs -timeout=5s -v +! stdout '\(cached\)' +stdout '-test\.timeout[= ]5s' + +# If the test stats a file, changes to the file should invalidate the cache. +go test testcache -run=FileSize +go test testcache -run=FileSize +stdout '\(cached\)' + +cp 4x.txt testcache/file.txt +go test testcache -run=FileSize +! stdout '\(cached\)' +go test testcache -run=FileSize +stdout '\(cached\)' + +# Files should be tracked even if the test changes its working directory. +go test testcache -run=Chdir +go test testcache -run=Chdir +stdout '\(cached\)' +cp 6x.txt testcache/file.txt +go test testcache -run=Chdir +! stdout '\(cached\)' +go test testcache -run=Chdir +stdout '\(cached\)' + +# The content of files should affect caching, provided that the mtime also changes. +exec ./mkold$GOEXE 1m testcache/file.txt +go test testcache -run=FileContent +go test testcache -run=FileContent +stdout '\(cached\)' +cp 2y.txt testcache/file.txt +exec ./mkold$GOEXE 50s testcache/file.txt +go test testcache -run=FileContent +! stdout '\(cached\)' +go test testcache -run=FileContent +stdout '\(cached\)' + +# Directory contents read via os.ReadDirNames should affect caching. +go test testcache -run=DirList +go test testcache -run=DirList +stdout '\(cached\)' +rm testcache/file.txt +go test testcache -run=DirList +! stdout '\(cached\)' +go test testcache -run=DirList +stdout '\(cached\)' + +# Files outside GOROOT and GOPATH should not affect caching. +env TEST_EXTERNAL_FILE=$WORK/external.txt +go test testcache -run=ExternalFile +go test testcache -run=ExternalFile +stdout '\(cached\)' + +rm $WORK/external.txt +go test testcache -run=ExternalFile +stdout '\(cached\)' + +# Executables within GOROOT and GOPATH should affect caching, +# even if the test does not stat them explicitly. + +[!exec:/bin/sh] skip +chmod 0755 ./testcache/script.sh + +exec ./mkold$GOEXEC 1m testcache/script.sh +go test testcache -run=Exec +go test testcache -run=Exec +stdout '\(cached\)' + +exec ./mkold$GOEXE 50s testcache/script.sh +go test testcache -run=Exec +! stdout '\(cached\)' +go test testcache -run=Exec +stdout '\(cached\)' + +-- testcache/file.txt -- +xx +-- 4x.txt -- +xxxx +-- 6x.txt -- +xxxxxx +-- 2y.txt -- +yy +-- $WORK/external.txt -- +This file is outside of GOPATH. +-- testcache/script.sh -- +#!/bin/sh +exit 0 +-- testcache/testcache_test.go -- +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testcache + +import ( + "io" + "os" + "testing" +) + +func TestChdir(t *testing.T) { + os.Chdir("..") + defer os.Chdir("testcache") + info, err := os.Stat("testcache/file.txt") + if err != nil { + t.Fatal(err) + } + if info.Size()%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddFileContent(t *testing.T) { + f, err := os.Open("file.txt") + if err != nil { + t.Fatal(err) + } + data, err := io.ReadAll(f) + f.Close() + if err != nil { + t.Fatal(err) + } + if len(data)%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddFileSize(t *testing.T) { + info, err := os.Stat("file.txt") + if err != nil { + t.Fatal(err) + } + if info.Size()%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddGetenv(t *testing.T) { + val := os.Getenv("TESTKEY") + if len(val)%2 != 1 { + t.Fatal("even env value") + } +} + +func TestLookupEnv(t *testing.T) { + _, ok := os.LookupEnv("TESTKEY") + if !ok { + t.Fatal("env missing") + } +} + +func TestDirList(t *testing.T) { + f, err := os.Open(".") + if err != nil { + t.Fatal(err) + } + f.Readdirnames(-1) + f.Close() +} + +func TestExec(t *testing.T) { + // Note: not using os/exec to make sure there is no unexpected stat. + p, err := os.StartProcess("./script.sh", []string{"script"}, new(os.ProcAttr)) + if err != nil { + t.Fatal(err) + } + ps, err := p.Wait() + if err != nil { + t.Fatal(err) + } + if !ps.Success() { + t.Fatalf("script failed: %v", err) + } +} + +func TestExternalFile(t *testing.T) { + os.Open(os.Getenv("TEST_EXTERNAL_FILE")) + _, err := os.Stat(os.Getenv("TEST_EXTERNAL_FILE")) + if err != nil { + t.Fatal(err) + } +} + +func TestOSArgs(t *testing.T) { + t.Log(os.Args) +} +-- mkold.go -- +package main + +import ( + "log" + "os" + "time" +) + +func main() { + d, err := time.ParseDuration(os.Args[1]) + if err != nil { + log.Fatal(err) + } + path := os.Args[2] + old := time.Now().Add(-d) + err = os.Chtimes(path, old, old) + if err != nil { + log.Fatal(err) + } +} diff --git a/src/cmd/go/testdata/script/test_chatty_fail.txt b/src/cmd/go/testdata/script/test_chatty_fail.txt new file mode 100644 index 0000000..a5ef559 --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_fail.txt @@ -0,0 +1,32 @@ +# Run chatty tests. Assert on CONT lines. +! go test chatty_test.go -v + +# Sanity check that output occurs. +stdout -count=2 'this is sub-0' +stdout -count=2 'this is sub-1' +stdout -count=2 'this is sub-2' +stdout -count=1 'error from sub-0' +stdout -count=1 'error from sub-1' +stdout -count=1 'error from sub-2' + +# Non-parallel tests should not print CONT. +! stdout CONT + +-- chatty_test.go -- +package chatty_test + +import ( + "testing" + "fmt" +) + +func TestChatty(t *testing.T) { + for i := 0; i < 3; i++ { + t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { + for j := 0; j < 2; j++ { + t.Logf("this is sub-%d", i) + } + t.Errorf("error from sub-%d", i) + }) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt b/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt new file mode 100644 index 0000000..3f7360b --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt @@ -0,0 +1,58 @@ +# Run parallel chatty tests. Assert on CONT lines. This test makes sure that +# multiple parallel outputs have the appropriate CONT lines between them. +! go test -parallel 3 chatty_parallel_test.go -v + +stdout -count=1 '^=== CONT TestChattyParallel/sub-0\n chatty_parallel_test.go:38: error from sub-0$' +stdout -count=1 '^=== CONT TestChattyParallel/sub-1\n chatty_parallel_test.go:38: error from sub-1$' +stdout -count=1 '^=== CONT TestChattyParallel/sub-2\n chatty_parallel_test.go:38: error from sub-2$' + +# Run parallel chatty tests with -json. Assert on CONT lines as above - make +# sure there are CONT lines before each output line. +! go test -json -parallel 3 chatty_parallel_test.go -v +stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"=== CONT TestChattyParallel/sub-0\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":" chatty_parallel_test.go:38: error from sub-0\\n"}' +stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"=== CONT TestChattyParallel/sub-1\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":" chatty_parallel_test.go:38: error from sub-1\\n"}' +stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":" chatty_parallel_test.go:38: error from sub-2\\n"}' + +-- chatty_parallel_test.go -- +package chatty_paralell_test + +import ( + "testing" + "fmt" + "flag" +) + +// This test ensures the the order of CONT lines in parallel chatty tests. +func TestChattyParallel(t *testing.T) { + t.Parallel() + + // The number of concurrent tests running. This is closely tied to the + // -parallel test flag, so we grab it from the flag rather than setting it + // to some constant. + parallel := flag.Lookup("test.parallel").Value.(flag.Getter).Get().(int) + + // ready is a synchronization mechanism that causes subtests to execute + // round robin. + ready := make([]chan bool, parallel) + for i := range ready { + ready[i] = make(chan bool, 1) + } + ready[0] <- true + + for i := range ready { + i := i + t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { + t.Parallel() + + // Some basic log output to precede the failures. + <-ready[i] + t.Logf("this is sub-%d", i) + ready[(i+1)%len(ready)] <- true + + // The actual failure messages we care about. + <-ready[i] + t.Errorf("error from sub-%d", i) + ready[(i+1)%len(ready)] <- true + }) + } +} diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_success.txt b/src/cmd/go/testdata/script/test_chatty_parallel_success.txt new file mode 100644 index 0000000..4a86d74 --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_parallel_success.txt @@ -0,0 +1,52 @@ +# Run parallel chatty tests. Assert on CONT lines. This test makes sure that +# multiple parallel outputs have the appropriate CONT lines between them. +go test -parallel 3 chatty_parallel_test.go -v +stdout -count=2 '^=== CONT TestChattyParallel/sub-0\n chatty_parallel_test.go:32: this is sub-0$' +stdout -count=2 '^=== CONT TestChattyParallel/sub-1\n chatty_parallel_test.go:32: this is sub-1$' +stdout -count=2 '^=== CONT TestChattyParallel/sub-2\n chatty_parallel_test.go:32: this is sub-2$' + +# Run parallel chatty tests with -json. Assert on CONT lines as above - make +# sure there are CONT lines before each output line. +go test -json -parallel 3 chatty_parallel_test.go -v +stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"=== CONT TestChattyParallel/sub-0\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":" chatty_parallel_test.go:32: this is sub-0\\n"}' +stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"=== CONT TestChattyParallel/sub-1\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":" chatty_parallel_test.go:32: this is sub-1\\n"}' +stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":" chatty_parallel_test.go:32: this is sub-2\\n"}' + +-- chatty_parallel_test.go -- +package chatty_paralell_test + +import ( + "testing" + "fmt" + "flag" +) + +// This test ensures the the order of CONT lines in parallel chatty tests. +func TestChattyParallel(t *testing.T) { + t.Parallel() + + // The number of concurrent tests running. This is closely tied to the + // -parallel test flag, so we grab it from the flag rather than setting it + // to some constant. + parallel := flag.Lookup("test.parallel").Value.(flag.Getter).Get().(int) + + // ready is a synchronization mechanism that causes subtests to execute + // round robin. + ready := make([]chan bool, parallel) + for i := range ready { + ready[i] = make(chan bool, 1) + } + ready[0] <- true + + for i := range ready { + i := i + t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { + t.Parallel() + for j := 0; j < 2; j++ { + <-ready[i] + t.Logf("this is sub-%d", i) + ready[(i+1)%len(ready)] <- true + } + }) + } +} diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt b/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt new file mode 100644 index 0000000..5952a87 --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt @@ -0,0 +1,39 @@ +# Run parallel chatty tests. Assert on CONT lines. This test makes sure that +# multiple parallel outputs have the appropriate CONT lines between them. +go test -parallel 3 chatty_parallel_test.go -v + +stdout '--- PASS: TestFast \([0-9.]{4}s\)\n=== CONT TestSlow\n chatty_parallel_test.go:31: this is the second TestSlow log\n--- PASS: TestSlow \([0-9.]{4}s\)' + +-- chatty_parallel_test.go -- +package chatty_paralell_test + +import ( + "testing" + "time" +) + +var ( + run = make(chan struct{}) + afterFirstLog = make(chan struct{}) + afterPass = make(chan struct{}) +) + +func TestFast(t *testing.T) { + t.Parallel() + + <-afterFirstLog + t.Cleanup(func() { + close(afterPass) + }) +} + +func TestSlow(t *testing.T) { + t.Parallel() + + t.Logf("this is the first TestSlow log") + close(afterFirstLog) + + <-afterPass + time.Sleep(100 * time.Millisecond) + t.Logf("this is the second TestSlow log") +} diff --git a/src/cmd/go/testdata/script/test_chatty_success.txt b/src/cmd/go/testdata/script/test_chatty_success.txt new file mode 100644 index 0000000..8bfa569 --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_success.txt @@ -0,0 +1,27 @@ +# Run chatty tests. Assert on CONT lines. +go test chatty_test.go -v + +# Non-parallel tests should not print CONT. +! stdout CONT + +# The assertion is condensed into one line so that it precisely matches output, +# rather than skipping lines and allow rogue CONT lines. +stdout '=== RUN TestChatty\n=== RUN TestChatty/sub-0\n chatty_test.go:12: this is sub-0\n chatty_test.go:12: this is sub-0\n=== RUN TestChatty/sub-1\n chatty_test.go:12: this is sub-1\n chatty_test.go:12: this is sub-1\n=== RUN TestChatty/sub-2\n chatty_test.go:12: this is sub-2\n chatty_test.go:12: this is sub-2\n--- PASS: TestChatty' + +-- chatty_test.go -- +package chatty_test + +import ( + "testing" + "fmt" +) + +func TestChatty(t *testing.T) { + for i := 0; i < 3; i++ { + t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { + for j := 0; j < 2; j++ { + t.Logf("this is sub-%d", i) + } + }) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_cleanup_failnow.txt b/src/cmd/go/testdata/script/test_cleanup_failnow.txt new file mode 100644 index 0000000..0737a93 --- /dev/null +++ b/src/cmd/go/testdata/script/test_cleanup_failnow.txt @@ -0,0 +1,47 @@ +# For issue 41355 +[short] skip + +# This test could fail if the testing package does not wait until +# a panicking test does the panic. Turn off multithreading, GC, and +# async preemption to increase the probability of such a failure. +env GOMAXPROCS=1 +env GOGC=off +env GODEBUG=asyncpreempt=off + +# If the test exits with 'no tests to run', it means the testing package +# implementation is incorrect and does not wait until a test panic. +# If the test exits with '(?s)panic: die.*panic: die', it means +# the testing package did an extra panic for a panicking test. + +! go test -v cleanup_failnow/panic_nocleanup_test.go +! stdout 'no tests to run' +stdout '(?s)panic: die \[recovered\].*panic: die' +! stdout '(?s)panic: die \[recovered\].*panic: die.*panic: die' + +! go test -v cleanup_failnow/panic_withcleanup_test.go +! stdout 'no tests to run' +stdout '(?s)panic: die \[recovered\].*panic: die' +! stdout '(?s)panic: die \[recovered\].*panic: die.*panic: die' + +-- cleanup_failnow/panic_nocleanup_test.go -- +package panic_nocleanup_test +import "testing" +func TestX(t *testing.T) { + t.Run("x", func(t *testing.T) { + panic("die") + }) +} + +-- cleanup_failnow/panic_withcleanup_test.go -- +package panic_withcleanup_test +import "testing" +func TestCleanupWithFailNow(t *testing.T) { + t.Cleanup(func() { + t.FailNow() + }) + t.Run("x", func(t *testing.T) { + t.Run("y", func(t *testing.T) { + panic("die") + }) + }) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_compile_binary.txt b/src/cmd/go/testdata/script/test_compile_binary.txt new file mode 100644 index 0000000..63bb8ec --- /dev/null +++ b/src/cmd/go/testdata/script/test_compile_binary.txt @@ -0,0 +1,8 @@ +env GO111MODULE=off + +! go test -c compile_binary/... +stderr 'build comment' + +-- compile_binary/foo_test.go -- +// +build foo +package foo diff --git a/src/cmd/go/testdata/script/test_compile_tempfile.txt b/src/cmd/go/testdata/script/test_compile_tempfile.txt new file mode 100644 index 0000000..05f721a --- /dev/null +++ b/src/cmd/go/testdata/script/test_compile_tempfile.txt @@ -0,0 +1,11 @@ +[short] skip + +# Ensure that the target of 'go build -o' can be an existing, empty file so that +# its name can be reserved using os.CreateTemp or the 'mktemp` command. + +go build -o empty-file$GOEXE main.go + +-- main.go -- +package main +func main() {} +-- empty-file$GOEXE -- diff --git a/src/cmd/go/testdata/script/test_deadline.txt b/src/cmd/go/testdata/script/test_deadline.txt new file mode 100644 index 0000000..06ae16f --- /dev/null +++ b/src/cmd/go/testdata/script/test_deadline.txt @@ -0,0 +1,54 @@ +[short] skip + +go test -timeout=0 -run=TestNoDeadline +go test -timeout=1m -run=TestDeadlineWithinMinute +go test -timeout=1m -run=TestSubtestDeadlineWithinMinute + +-- go.mod -- +module m + +go 1.16 +-- deadline_test.go -- +package testing_test + +import ( + "testing" + "time" +) + +func TestNoDeadline(t *testing.T) { + d, ok := t.Deadline() + if ok || !d.IsZero() { + t.Fatalf("t.Deadline() = %v, %v; want 0, false", d, ok) + } +} + +func TestDeadlineWithinMinute(t *testing.T) { + now := time.Now() + d, ok := t.Deadline() + if !ok || d.IsZero() { + t.Fatalf("t.Deadline() = %v, %v; want nonzero deadline", d, ok) + } + if !d.After(now) { + t.Fatalf("t.Deadline() = %v; want after start of test (%v)", d, now) + } + if d.Sub(now) > time.Minute { + t.Fatalf("t.Deadline() = %v; want within one minute of start of test (%v)", d, now) + } +} + +func TestSubtestDeadlineWithinMinute(t *testing.T) { + t.Run("sub", func(t *testing.T) { + now := time.Now() + d, ok := t.Deadline() + if !ok || d.IsZero() { + t.Fatalf("t.Deadline() = %v, %v; want nonzero deadline", d, ok) + } + if !d.After(now) { + t.Fatalf("t.Deadline() = %v; want after start of test (%v)", d, now) + } + if d.Sub(now) > time.Minute { + t.Fatalf("t.Deadline() = %v; want within one minute of start of test (%v)", d, now) + } + }) +} diff --git a/src/cmd/go/testdata/script/test_empty.txt b/src/cmd/go/testdata/script/test_empty.txt new file mode 100644 index 0000000..5ebbecd --- /dev/null +++ b/src/cmd/go/testdata/script/test_empty.txt @@ -0,0 +1,53 @@ +[!race] skip + +cd $GOPATH/src/empty/pkg +go test -cover -coverpkg=. -race + +[short] stop # Only run first case in short mode + +cd $GOPATH/src/empty/test +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/xtest +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/pkgtest +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/pkgxtest +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/pkgtestxtest +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/testxtest +go test -cover -coverpkg=. -race + +-- empty/go.mod -- +module empty + +go 1.16 +-- empty/pkg/pkg.go -- +package p +-- empty/pkgtest/pkg.go -- +package p +-- empty/pkgtest/test_test.go -- +package p +-- empty/pkgtestxtest/pkg.go -- +package p +-- empty/pkgtestxtest/test_test.go -- +package p +-- empty/pkgtestxtest/xtest_test.go -- +package p_test +-- empty/pkgxtest/pkg.go -- +package p +-- empty/pkgxtest/xtest_test.go -- +package p_test +-- empty/test/test_test.go -- +package p +-- empty/testxtest/test_test.go -- +package p +-- empty/testxtest/xtest_test.go -- +package p_test +-- empty/xtest/xtest_test.go -- +package p_test diff --git a/src/cmd/go/testdata/script/test_env_term.txt b/src/cmd/go/testdata/script/test_env_term.txt new file mode 100644 index 0000000..8a5f79a --- /dev/null +++ b/src/cmd/go/testdata/script/test_env_term.txt @@ -0,0 +1,15 @@ +# Tests golang.org/issue/12096 + +env TERM='' +go test test_test.go +! stdout '^ok.*\[no tests to run\]' +stdout '^ok' + +-- test_test.go -- +package main +import ("os"; "testing") +func TestEnv(t *testing.T) { + if os.Getenv("TERM") != "" { + t.Fatal("TERM is set") + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_example_goexit.txt b/src/cmd/go/testdata/script/test_example_goexit.txt new file mode 100644 index 0000000..984f434 --- /dev/null +++ b/src/cmd/go/testdata/script/test_example_goexit.txt @@ -0,0 +1,29 @@ +# For issue golang.org/issue/41084 +[short] skip + +! go test -v examplegoexit +stdout '(?s)--- PASS.*--- FAIL.*' +stdout 'panic: test executed panic\(nil\) or runtime\.Goexit' + +-- go.mod -- +module examplegoexit + +go 1.16 +-- example_test.go -- +package main + +import ( + "fmt" + "runtime" +) + +func ExamplePass() { + fmt.Println("pass") + // Output: + // pass +} + +func ExampleGoexit() { + runtime.Goexit() + // Output: +} diff --git a/src/cmd/go/testdata/script/test_exit.txt b/src/cmd/go/testdata/script/test_exit.txt new file mode 100644 index 0000000..3703ba5 --- /dev/null +++ b/src/cmd/go/testdata/script/test_exit.txt @@ -0,0 +1,131 @@ +# Builds and runs test binaries, so skip in short mode. +[short] skip + +env GO111MODULE=on + +# If a test invoked by 'go test' exits with a zero status code, +# it will panic. +! go test ./zero +! stdout ^ok +! stdout 'exit status' +stdout 'panic' +stdout ^FAIL + +# If a test exits with a non-zero status code, 'go test' fails normally. +! go test ./one +! stdout ^ok +stdout 'exit status' +! stdout 'panic' +stdout ^FAIL + +# Ensure that other flags still do the right thing. +go test -list=. ./zero +stdout ExitZero + +! go test -bench=. ./zero +stdout 'panic' + +# 'go test' with no args streams output without buffering. Ensure that it still +# catches a zero exit with missing output. +cd zero +! go test +stdout 'panic' +cd ../normal +go test +stdout ^ok +cd .. + +# If a TestMain exits with a zero status code, 'go test' shouldn't +# complain about that. It's a common way to skip testing a package +# entirely. +go test ./main_zero +! stdout 'skipping all tests' +stdout ^ok + +# With -v, we'll see the warning from TestMain. +go test -v ./main_zero +stdout 'skipping all tests' +stdout ^ok + +# Listing all tests won't actually give a result if TestMain exits. That's okay, +# because this is how TestMain works. If we decide to support -list even when +# TestMain is used to skip entire packages, we can change this test case. +go test -list=. ./main_zero +stdout 'skipping all tests' +! stdout TestNotListed + +# Running the test directly still fails, if we pass the flag. +go test -c -o ./zero.exe ./zero +! exec ./zero.exe -test.paniconexit0 + +# Using -json doesn't affect the exit status. +! go test -json ./zero +! stdout '"Output":"ok' +! stdout 'exit status' +stdout 'panic' +stdout '"Output":"FAIL' + +# Running the test via test2json also fails. +! go tool test2json ./zero.exe -test.v -test.paniconexit0 +! stdout '"Output":"ok' +! stdout 'exit status' +stdout 'panic' + +-- go.mod -- +module m + +-- ./normal/normal.go -- +package normal +-- ./normal/normal_test.go -- +package normal + +import "testing" + +func TestExitZero(t *testing.T) { +} + +-- ./zero/zero.go -- +package zero +-- ./zero/zero_test.go -- +package zero + +import ( + "os" + "testing" +) + +func TestExitZero(t *testing.T) { + os.Exit(0) +} + +-- ./one/one.go -- +package one +-- ./one/one_test.go -- +package one + +import ( + "os" + "testing" +) + +func TestExitOne(t *testing.T) { + os.Exit(1) +} + +-- ./main_zero/zero.go -- +package zero +-- ./main_zero/zero_test.go -- +package zero + +import ( + "fmt" + "os" + "testing" +) + +func TestMain(m *testing.M) { + fmt.Println("skipping all tests") + os.Exit(0) +} + +func TestNotListed(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/test_fail_fast.txt b/src/cmd/go/testdata/script/test_fail_fast.txt new file mode 100644 index 0000000..132ea70 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fail_fast.txt @@ -0,0 +1,113 @@ +[short] skip + +# test fail fast +! go test ./failfast_test.go -run='TestFailingA' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestFailing[AB]' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestFailing[AB]' -failfast=false +stdout -count=2 'FAIL - ' + +# mix with non-failing tests +! go test ./failfast_test.go -run='TestA|TestFailing[AB]' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestA|TestFailing[AB]' -failfast=false +stdout -count=2 'FAIL - ' + +# mix with parallel tests +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailingA' -failfast=true +stdout -count=2 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailingA' -failfast=false +stdout -count=2 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailing[AB]' -failfast=true +stdout -count=3 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailing[AB]' -failfast=false +stdout -count=3 'FAIL - ' + +# mix with parallel sub-tests +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA' -failfast=true +stdout -count=3 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA' -failfast=false +stdout -count=5 'FAIL - ' +! go test ./failfast_test.go -run='TestParallelFailingSubtestsA' -failfast=true +stdout -count=1 'FAIL - ' + +# only parallels +! go test ./failfast_test.go -run='TestParallelFailing[AB]' -failfast=false +stdout -count=2 'FAIL - ' + +# non-parallel subtests +! go test ./failfast_test.go -run='TestFailingSubtestsA' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingSubtestsA' -failfast=false +stdout -count=2 'FAIL - ' + +# fatal test +! go test ./failfast_test.go -run='TestFatal[CD]' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestFatal[CD]' -failfast=false +stdout -count=2 'FAIL - ' + +-- failfast_test.go -- +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package failfast + +import "testing" + +func TestA(t *testing.T) { + // Edge-case testing, mixing unparallel tests too + t.Logf("LOG: %s", t.Name()) +} + +func TestFailingA(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) +} + +func TestB(t *testing.T) { + // Edge-case testing, mixing unparallel tests too + t.Logf("LOG: %s", t.Name()) +} + +func TestParallelFailingA(t *testing.T) { + t.Parallel() + t.Errorf("FAIL - %s", t.Name()) +} + +func TestParallelFailingB(t *testing.T) { + t.Parallel() + t.Errorf("FAIL - %s", t.Name()) +} + +func TestParallelFailingSubtestsA(t *testing.T) { + t.Parallel() + t.Run("TestFailingSubtestsA1", func(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) + }) + t.Run("TestFailingSubtestsA2", func(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) + }) +} + +func TestFailingSubtestsA(t *testing.T) { + t.Run("TestFailingSubtestsA1", func(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) + }) + t.Run("TestFailingSubtestsA2", func(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) + }) +} + +func TestFailingB(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) +} + +func TestFatalC(t *testing.T) { + t.Fatalf("FAIL - %s", t.Name()) +} + +func TestFatalD(t *testing.T) { + t.Fatalf("FAIL - %s", t.Name()) +} diff --git a/src/cmd/go/testdata/script/test_flag.txt b/src/cmd/go/testdata/script/test_flag.txt new file mode 100644 index 0000000..0142b3f --- /dev/null +++ b/src/cmd/go/testdata/script/test_flag.txt @@ -0,0 +1,40 @@ +[short] skip + +go test flag_test.go -v -args -v=7 # Two distinct -v flags +go test -v flag_test.go -args -v=7 # Two distinct -v flags + +# Using a custom flag mixed with regular 'go test' flags should be OK. +go test -count=1 -custom -args -v=7 + +# However, it should be an error to use custom flags when -i or -c are used, +# since we know for sure that no test binary will run at all. +! go test -i -custom +stderr '^go test: unknown flag -custom cannot be used with -i$' +! go test -c -custom +stderr '^go test: unknown flag -custom cannot be used with -c$' + +# The same should apply even if -c or -i come after a custom flag. +! go test -custom -c +stderr '^go test: unknown flag -custom cannot be used with -c$' + +-- go.mod -- +module m +-- flag_test.go -- +package flag_test + +import ( + "flag" + "log" + "testing" +) + +var v = flag.Int("v", 0, "v flag") + +var custom = flag.Bool("custom", false, "") + +// Run this as go test pkg -v=7 +func TestVFlagIsSet(t *testing.T) { + if *v != 7 { + log.Fatal("v flag not set") + } +} diff --git a/src/cmd/go/testdata/script/test_flags.txt b/src/cmd/go/testdata/script/test_flags.txt new file mode 100644 index 0000000..63385e6 --- /dev/null +++ b/src/cmd/go/testdata/script/test_flags.txt @@ -0,0 +1,132 @@ +env GO111MODULE=on + +[short] skip + +# Arguments after the flag terminator should be ignored. +# If we pass '-- -test.v', we should not get verbose output +# *and* output from the test should not be echoed. +go test ./x -- -test.v +stdout '\Aok\s+example.com/x\s+[0-9.s]+\n\z' +! stderr . + +# For backward-compatibility with previous releases of the 'go' command, +# arguments that appear after unrecognized flags should not be treated +# as packages, even if they are unambiguously not arguments to flags. +# Even though ./x looks like a package path, the real package should be +# the implicit '.'. +! go test --answer=42 ./x +stderr '^no Go files in .+$' +! stderr '/x' + +# However, *flags* that appear after unrecognized flags should still be +# interpreted as flags, under the (possibly-erroneous) assumption that +# unrecognized flags are non-boolean. + +go test -v -x ./x -timeout 24h -boolflag=true foo -timeout 25h +stdout 'args: foo -timeout 25h' +stdout 'timeout: 24h0m0s$' # -timeout is unambiguously not a flag, so the real flag wins. + +go test -v -x ./x -timeout 24h -boolflag foo -timeout 25h +stdout 'args: foo -test\.timeout=25h0m0s' # For legacy reasons, '-timeout ' is erroneously rewritten to -test.timeout; see https://golang.org/issue/40763. +stdout 'timeout: 24h0m0s$' # Actual flag wins. + +go test -v -x ./x -timeout 24h -stringflag foo -timeout 25h +stdout 'args: $' +stdout 'timeout: 25h0m0s$' # Later flag wins. + +# An explicit '-outputdir=' argument should set test.outputdir +# to the 'go' command's working directory, not zero it out +# for the test binary. +go test -x -coverprofile=cover.out '-outputdir=' ./x +stderr '-test.outputdir=[^ ]' +exists ./cover.out +! exists ./x/cover.out + +# Test flags from GOFLAGS should be forwarded to the test binary, +# with the 'test.' prefix in the GOFLAGS entry... +env GOFLAGS='-test.timeout=24h0m0s -count=1' +go test -v -x ./x +stdout 'timeout: 24h0m0s$' +stderr '-test.count=1' + +# ...or without. +env GOFLAGS='-timeout=24h0m0s -count=1' +go test -v -x ./x +stdout 'timeout: 24h0m0s$' +stderr '-test.count=1' + +# Arguments from the command line should override GOFLAGS... +go test -v -x -timeout=25h0m0s ./x +stdout 'timeout: 25h0m0s$' +stderr '-test.count=1' + +# ...even if they use a different flag name. +go test -v -x -test.timeout=26h0m0s ./x +stdout 'timeout: 26h0m0s$' +stderr '-test\.timeout=26h0m0s' +! stderr 'timeout=24h0m0s' +stderr '-test.count=1' + +# Invalid flags should be reported exactly once. +! go test -covermode=walrus ./x +stderr -count=1 'invalid value "walrus" for flag -covermode: valid modes are .*$' +stderr '^usage: go test .*$' +stderr '^Run ''go help test'' and ''go help testflag'' for details.$' + +# Passing -help to the test binary should show flag help. +go test ./x -args -help +stdout 'usage_message' + +# -covermode, -coverpkg, and -coverprofile should imply -cover +go test -covermode=set ./x +stdout '\s+coverage:\s+' + +go test -coverpkg=encoding/binary ./x +stdout '\s+coverage:\s+' + +go test -coverprofile=cover.out ./x +stdout '\s+coverage:\s+' +exists ./cover.out +rm ./cover.out + +# -*profile and -trace flags should force output to the current working directory +# or -outputdir, not the directory containing the test. + +go test -memprofile=mem.out ./x +exists ./mem.out +rm ./mem.out + +go test -trace=trace.out ./x +exists ./trace.out +rm ./trace.out + +# Relative paths with -outputdir should be relative to the go command's working +# directory, not the directory containing the test. +mkdir profiles +go test -memprofile=mem.out -outputdir=./profiles ./x +exists ./profiles/mem.out +rm profiles + +-- go.mod -- +module example.com +go 1.14 +-- x/x_test.go -- +package x + +import ( + "flag" + "strings" + "testing" +) + +var _ = flag.String("usage_message", "", "dummy flag to check usage message") +var boolflag = flag.Bool("boolflag", false, "ignored boolean flag") +var stringflag = flag.String("stringflag", "", "ignored string flag") + +func TestLogTimeout(t *testing.T) { + t.Logf("timeout: %v", flag.Lookup("test.timeout").Value) +} + +func TestLogArgs(t *testing.T) { + t.Logf("args: %s", strings.Join(flag.Args(), " ")) +} diff --git a/src/cmd/go/testdata/script/test_generated_main.txt b/src/cmd/go/testdata/script/test_generated_main.txt new file mode 100644 index 0000000..2e991a5 --- /dev/null +++ b/src/cmd/go/testdata/script/test_generated_main.txt @@ -0,0 +1,34 @@ +# Tests that the generated test main file has a generated code comment. +# This is needed by analyzers that access source files through 'go list'. +# Verifies golang.org/issue/31971. +# TODO(jayconrod): This test is brittle. We should write _testmain.go as +# a build action instead of with an ad-hoc WriteFile call +# in internal/test/test.go. Then we could just grep 'go get -n'. +go test x_test.go + +-- x_test.go -- +package x + +import ( + "os" + "path/filepath" + "regexp" + "testing" +) + +func Test(t *testing.T) { + exePath, err := os.Executable() + if err != nil { + t.Fatal(err) + } + testmainPath := filepath.Join(filepath.Dir(exePath), "_testmain.go") + source, err := os.ReadFile(testmainPath) + if err != nil { + t.Fatal(err) + } + if matched, err := regexp.Match(`(?m)^// Code generated .* DO NOT EDIT\.$`, source); err != nil { + t.Fatal(err) + } else if !matched { + t.Error("_testmain.go does not have generated code comment") + } +} diff --git a/src/cmd/go/testdata/script/test_go111module_cache.txt b/src/cmd/go/testdata/script/test_go111module_cache.txt new file mode 100644 index 0000000..ca1de43 --- /dev/null +++ b/src/cmd/go/testdata/script/test_go111module_cache.txt @@ -0,0 +1,15 @@ +env GO111MODULE=on +go mod init foo +go test +stdout ^ok\s+foo +env GO111MODULE=off +go test +stdout ^ok\s+ +! stdout ^ok\s+(cache)$ + +-- main_test.go -- +package main + +import "testing" + +func TestF(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/test_import_error_stack.txt b/src/cmd/go/testdata/script/test_import_error_stack.txt new file mode 100644 index 0000000..6c60f3d --- /dev/null +++ b/src/cmd/go/testdata/script/test_import_error_stack.txt @@ -0,0 +1,31 @@ +env GO111MODULE=off +! go test testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack +! go vet testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack + +env GO111MODULE=on +cd testdep +! go test testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack +! go vet testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack + +-- testdep/go.mod -- +module testdep + +go 1.16 +-- testdep/p1/p1.go -- +package p1 +-- testdep/p1/p1_test.go -- +package p1 + +import _ "testdep/p2" +-- testdep/p2/p2.go -- +package p2 + +import _ "testdep/p3" +-- testdep/p3/p3.go -- +// +build ignore + +package ignored diff --git a/src/cmd/go/testdata/script/test_json.txt b/src/cmd/go/testdata/script/test_json.txt new file mode 100644 index 0000000..cd5b0b9 --- /dev/null +++ b/src/cmd/go/testdata/script/test_json.txt @@ -0,0 +1,74 @@ +[gccgo] skip # gccgo does not have standard packages +[short] skip + +env GOCACHE=$WORK/tmp + +# Run go test -json on errors m/empty/pkg and m/skipper +# It would be nice to test that the output is interlaced +# but it seems to be impossible to do that in a short test +# that isn't also flaky. Just check that we get JSON output. +go test -json -short -v errors m/empty/pkg m/skipper + +# Check errors for run action +stdout '"Package":"errors"' +stdout '"Action":"run","Package":"errors"' + +# Check m/empty/pkg for output and skip actions +stdout '"Action":"output","Package":"m/empty/pkg","Output":".*no test files' +stdout '"Action":"skip","Package":"m/empty/pkg"' + +# Check skipper for output and skip actions +stdout '"Action":"output","Package":"m/skipper","Test":"Test","Output":"--- SKIP:' +stdout '"Action":"skip","Package":"m/skipper","Test":"Test"' + +# Run go test -json on errors and check it's cached +go test -json -short -v errors +stdout '"Action":"output","Package":"errors","Output":".*\(cached\)' + +go test -json -bench=NONE -short -v errors +stdout '"Package":"errors"' +stdout '"Action":"run"' + +# Test running test2json +go test -o $WORK/tmp/errors.test$GOEXE -c errors +go tool test2json -p errors $WORK/tmp/errors.test$GOEXE -test.v -test.short +stdout '"Package":"errors"' +stdout '"Action":"run"' +stdout '\{"Action":"pass","Package":"errors"\}' + +-- go.mod -- +module m + +go 1.16 +-- skipper/skip_test.go -- +package skipper + +import "testing" + +func Test(t *testing.T) { + t.Skip("skipping") +} +-- empty/pkg/pkg.go -- +package p +-- empty/pkgtest/pkg.go -- +package p +-- empty/pkgtest/test_test.go -- +package p +-- empty/pkgtestxtest/pkg.go -- +package p +-- empty/pkgtestxtest/test_test.go -- +package p +-- empty/pkgtestxtest/xtest_test.go -- +package p_test +-- empty/pkgxtest/pkg.go -- +package p +-- empty/pkgxtest/xtest_test.go -- +package p_test +-- empty/test/test_test.go -- +package p +-- empty/testxtest/test_test.go -- +package p +-- empty/testxtest/xtest_test.go -- +package p_test +-- empty/xtest/xtest_test.go -- +package p_test diff --git a/src/cmd/go/testdata/script/test_json_exit.txt b/src/cmd/go/testdata/script/test_json_exit.txt new file mode 100644 index 0000000..dc7ffb0 --- /dev/null +++ b/src/cmd/go/testdata/script/test_json_exit.txt @@ -0,0 +1,102 @@ +[short] skip + +go test -c -o mainpanic.exe ./mainpanic & +go test -c -o mainexit0.exe ./mainexit0 & +go test -c -o testpanic.exe ./testpanic & +go test -c -o testbgpanic.exe ./testbgpanic & +wait + +# Test binaries that panic in TestMain should be marked as failing. + +! go test -json ./mainpanic +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./mainpanic.exe +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +# Test binaries that exit with status 0 should be marked as passing. + +go test -json ./mainexit0 +stdout '"Action":"pass"' +! stdout '"Action":"fail"' + +go tool test2json ./mainexit0.exe +stdout '"Action":"pass"' +! stdout '"Action":"fail"' + +# Test functions that panic should never be marked as passing +# (https://golang.org/issue/40132). + +! go test -json ./testpanic +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./testpanic.exe -test.v +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./testpanic.exe +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +# Tests that panic in a background goroutine should be marked as failing. + +! go test -json ./testbgpanic +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./testbgpanic.exe -test.v +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./testbgpanic.exe +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +-- go.mod -- +module m +go 1.14 +-- mainpanic/mainpanic_test.go -- +package mainpanic_test + +import "testing" + +func TestMain(m *testing.M) { + panic("haha no") +} +-- mainexit0/mainexit0_test.go -- +package mainexit0_test + +import ( + "fmt" + "os" + "testing" +) + +func TestMain(m *testing.M) { + fmt.Println("nothing to do") + os.Exit(0) +} +-- testpanic/testpanic_test.go -- +package testpanic_test + +import "testing" + +func TestPanic(*testing.T) { + panic("haha no") +} +-- testbgpanic/testbgpanic_test.go -- +package testbgpanic_test + +import "testing" + +func TestPanicInBackground(*testing.T) { + c := make(chan struct{}) + go func() { + panic("haha no") + close(c) + }() + <-c +} diff --git a/src/cmd/go/testdata/script/test_json_interleaved.txt b/src/cmd/go/testdata/script/test_json_interleaved.txt new file mode 100644 index 0000000..e2d349e --- /dev/null +++ b/src/cmd/go/testdata/script/test_json_interleaved.txt @@ -0,0 +1,27 @@ +# Regression test for https://golang.org/issue/40657: output from the main test +# function should be attributed correctly even if interleaved with the PAUSE +# line for a new parallel subtest. + +[short] skip + +go test -json +stdout '"Test":"TestWeirdTiming","Output":"[^"]* logging to outer again\\n"' + +-- go.mod -- +module example.com +go 1.15 +-- main_test.go -- +package main + +import ( + "testing" +) + +func TestWeirdTiming(outer *testing.T) { + outer.Run("pauser", func(pauser *testing.T) { + outer.Logf("logging to outer") + pauser.Parallel() + }) + + outer.Logf("logging to outer again") +} diff --git a/src/cmd/go/testdata/script/test_json_panic_exit.txt b/src/cmd/go/testdata/script/test_json_panic_exit.txt new file mode 100644 index 0000000..d0a7991 --- /dev/null +++ b/src/cmd/go/testdata/script/test_json_panic_exit.txt @@ -0,0 +1,69 @@ +# Verifies golang.org/issue/37555. + +[short] skip + +# 'go test -json' should say a test passes if it says it passes. +go test -json ./pass +stdout '"Action":"pass".*\n\z' +! stdout '"Test":.*\n\z' + +# 'go test -json' should say a test passes if it exits 0 and prints nothing. +# TODO(golang.org/issue/29062): this should fail in the future. +go test -json ./exit0main +stdout '"Action":"pass".*\n\z' +! stdout '"Test":.*\n\z' + +# 'go test -json' should say a test fails if it exits 1 and prints nothing. +! go test -json ./exit1main +stdout '"Action":"fail".*\n\z' +! stdout '"Test":.*\n\z' + +# 'go test -json' should say a test fails if it panics. +! go test -json ./panic +stdout '"Action":"fail".*\n\z' +! stdout '"Test":.*\n\z' + +-- go.mod -- +module example.com/test + +go 1.14 + +-- pass/pass_test.go -- +package pass_test + +import "testing" + +func TestPass(t *testing.T) {} + +-- exit0main/exit0main_test.go -- +package exit0_test + +import ( + "os" + "testing" +) + +func TestMain(m *testing.M) { + os.Exit(0) +} + +-- exit1main/exit1main_test.go -- +package exit1_test + +import ( + "os" + "testing" +) + +func TestMain(m *testing.M) { + os.Exit(1) +} + +-- panic/panic_test.go -- +package panic_test + +import "testing" + +func TestPanic(t *testing.T) { + panic("oh no") +} diff --git a/src/cmd/go/testdata/script/test_main.txt b/src/cmd/go/testdata/script/test_main.txt new file mode 100644 index 0000000..25d02e4 --- /dev/null +++ b/src/cmd/go/testdata/script/test_main.txt @@ -0,0 +1,92 @@ +# Test TestMain +go test standalone_main_normal_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +# Test TestMain sees testing flags +go test standalone_testmain_flag_test.go +stdout '^ok.*\[no tests to run\]' + +# Test TestMain with wrong signature (Issue #22388) +! go test standalone_main_wrong_test.go +stderr 'wrong signature for TestMain, must be: func TestMain\(m \*testing.M\)' + +# Test TestMain does not call os.Exit (Issue #34129) +! go test standalone_testmain_not_call_os_exit_test.go +! stdout '^ok' + +-- standalone_main_normal_test.go -- +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package standalone_main_normal_test + +import "testing" + +func TestMain(t *testing.T) { +} +-- standalone_main_wrong_test.go -- +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package standalone_main_wrong_test + +import "testing" + +func TestMain(m *testing.Main) { +} +-- standalone_testmain_flag_test.go -- +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package standalone_testmain_flag_test + +import ( + "flag" + "fmt" + "os" + "testing" +) + +func TestMain(m *testing.M) { + // A TestMain should be able to access testing flags if it calls + // flag.Parse without needing to use testing.Init. + flag.Parse() + found := false + flag.VisitAll(func(f *flag.Flag) { + if f.Name == "test.count" { + found = true + } + }) + if !found { + fmt.Println("testing flags not registered") + os.Exit(1) + } + os.Exit(m.Run()) +} +-- standalone_testmain_not_call_os_exit_test.go -- +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package standalone_testmain_not_call_os_exit_test + +import ( + "testing" +) + +func TestWillFail(t *testing.T) { + t.Error("this test will fail.") +} + +func TestMain(m *testing.M) { + defer func() { + recover() + }() + exit := m.Run() + panic(exit) +} diff --git a/src/cmd/go/testdata/script/test_main_archive.txt b/src/cmd/go/testdata/script/test_main_archive.txt new file mode 100644 index 0000000..410d923 --- /dev/null +++ b/src/cmd/go/testdata/script/test_main_archive.txt @@ -0,0 +1,32 @@ +env GO111MODULE=off + +# Test that a main_test of 'package main' imports the package, +# not the installed binary. + +[short] skip + +env GOBIN=$WORK/bin +go test main_test +go install main_test + +go list -f '{{.Stale}}' main_test +stdout false + +go test main_test + +-- main_test/m.go -- +package main + +func F() {} +func main() {} +-- main_test/m_test.go -- +package main_test + +import ( + . "main_test" + "testing" +) + +func Test1(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/test_main_panic.txt b/src/cmd/go/testdata/script/test_main_panic.txt new file mode 100644 index 0000000..45887c5 --- /dev/null +++ b/src/cmd/go/testdata/script/test_main_panic.txt @@ -0,0 +1,30 @@ +[short] skip +[!race] skip + +! go test -v -race main_panic/testmain_parallel_sub_panic_test.go +! stdout 'DATA RACE' +-- main_panic/testmain_parallel_sub_panic_test.go -- +package testmain_parallel_sub_panic_test + +import "testing" + +func setup() { println("setup()") } +func teardown() { println("teardown()") } +func TestA(t *testing.T) { + t.Run("1", func(t *testing.T) { + t.Run("1", func(t *testing.T) { + t.Parallel() + panic("A/1/1 panics") + }) + t.Run("2", func(t *testing.T) { + t.Parallel() + println("A/1/2 is ok") + }) + }) +} + +func TestMain(m *testing.M) { + setup() + defer teardown() + m.Run() +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_main_twice.txt b/src/cmd/go/testdata/script/test_main_twice.txt new file mode 100644 index 0000000..f32d4fc --- /dev/null +++ b/src/cmd/go/testdata/script/test_main_twice.txt @@ -0,0 +1,27 @@ +[short] skip + +env GOCACHE=$WORK/tmp +go test -v multimain +stdout -count=2 notwithstanding # check tests ran twice + +-- go.mod -- +module multimain + +go 1.16 +-- multimain_test.go -- +package multimain_test + +import "testing" + +func TestMain(m *testing.M) { + // Some users run m.Run multiple times, changing + // some kind of global state between runs. + // This used to work so I guess now it has to keep working. + // See golang.org/issue/23129. + m.Run() + m.Run() +} + +func Test(t *testing.T) { + t.Log("notwithstanding") +} diff --git a/src/cmd/go/testdata/script/test_match_benchmark_labels.txt b/src/cmd/go/testdata/script/test_match_benchmark_labels.txt new file mode 100644 index 0000000..13c4007 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_benchmark_labels.txt @@ -0,0 +1,18 @@ +# Benchmark labels, file outside gopath +# TODO(matloob): This test was called TestBenchmarkLabelsOutsideGOPATH +# why "OutsideGOPATH"? Does the go command need to be run outside GOPATH? +# Do the files need to exist outside GOPATH? +cp $GOPATH/src/standalone_benchmark_test.go $WORK/tmp/standalone_benchmark_test.go +go test -run '^$' -bench . $WORK/tmp/standalone_benchmark_test.go +stdout '^goos: '$GOOS +stdout '^goarch: '$GOARCH +! stdout '^pkg:' +! stderr '^pkg:' + +-- standalone_benchmark_test.go -- +package standalone_benchmark + +import "testing" + +func Benchmark(b *testing.B) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_benchmarks.txt b/src/cmd/go/testdata/script/test_match_no_benchmarks.txt new file mode 100644 index 0000000..30f4be8 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_benchmarks.txt @@ -0,0 +1,13 @@ +# Matches no benchmarks +go test -run '^$' -bench ThisWillNotMatch standalone_benchmark_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_benchmark_test.go -- +package standalone_benchmark + +import "testing" + +func Benchmark(b *testing.B) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_subtests.txt b/src/cmd/go/testdata/script/test_match_no_subtests.txt new file mode 100644 index 0000000..7abb1eb --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_subtests.txt @@ -0,0 +1,12 @@ +# The subtests don't match +go test -run Test/ThisWillNotMatch standalone_sub_test.go +stdout '^ok.*\[no tests to run\]' + +-- standalone_sub_test.go -- +package standalone_sub_test + +import "testing" + +func Test(t *testing.T) { + t.Run("Sub", func(t *testing.T) {}) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_subtests_failure.txt b/src/cmd/go/testdata/script/test_match_no_subtests_failure.txt new file mode 100644 index 0000000..b3c5b92 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_subtests_failure.txt @@ -0,0 +1,15 @@ +# Matches no subtests, but parent test still fails +! go test -run TestThatFails/ThisWillNotMatch standalone_fail_sub_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout 'FAIL' + +-- standalone_fail_sub_test.go -- +package standalone_fail_sub_test + +import "testing" + +func TestThatFails(t *testing.T) { + t.Run("Sub", func(t *testing.T) {}) + t.Fail() +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_subtests_parallel.txt b/src/cmd/go/testdata/script/test_match_no_subtests_parallel.txt new file mode 100644 index 0000000..11c734c --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_subtests_parallel.txt @@ -0,0 +1,19 @@ +# Matches no subtests, parallel +go test -run Test/Sub/ThisWillNotMatch standalone_parallel_sub_test.go +stdout '^ok.*\[no tests to run\]' + +-- standalone_parallel_sub_test.go -- +package standalone_parallel_sub_test + +import "testing" + +func Test(t *testing.T) { + ch := make(chan bool, 1) + t.Run("Sub", func(t *testing.T) { + t.Parallel() + <-ch + t.Run("Nested", func(t *testing.T) {}) + }) + // Ensures that Sub will finish after its t.Run call already returned. + ch <- true +} diff --git a/src/cmd/go/testdata/script/test_match_no_tests.txt b/src/cmd/go/testdata/script/test_match_no_tests.txt new file mode 100644 index 0000000..1ad2097 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_tests.txt @@ -0,0 +1,11 @@ +# Matches no tests +go test -run ThisWillNotMatch standalone_test.go +stdout '^ok.*\[no tests to run\]' + +-- standalone_test.go -- +package standalone_test + +import "testing" + +func Test(t *testing.T) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt b/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt new file mode 100644 index 0000000..e1c9643 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt @@ -0,0 +1,19 @@ +# Test that when there's a build failure and a -run flag that doesn't match, +# that the error for not matching tests does not override the error for +# the build failure. + +! go test -run ThisWillNotMatch syntaxerror +! stderr '(?m)^ok.*\[no tests to run\]' +stdout 'FAIL' + +-- go.mod -- +module syntaxerror + +go 1.16 +-- x.go -- +package p +-- x_test.go -- +package p + +func f() (x.y, z int) { +} diff --git a/src/cmd/go/testdata/script/test_match_no_tests_with_subtests.txt b/src/cmd/go/testdata/script/test_match_no_tests_with_subtests.txt new file mode 100644 index 0000000..0d94918 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_tests_with_subtests.txt @@ -0,0 +1,12 @@ +# Matches no tests with subtests +go test -run ThisWillNotMatch standalone_sub_test.go +stdout '^ok.*\[no tests to run\]' + +-- standalone_sub_test.go -- +package standalone_sub_test + +import "testing" + +func Test(t *testing.T) { + t.Run("Sub", func(t *testing.T) {}) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_only_benchmarks.txt b/src/cmd/go/testdata/script/test_match_only_benchmarks.txt new file mode 100644 index 0000000..5dfb96e --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_benchmarks.txt @@ -0,0 +1,13 @@ +# Matches only benchmarks +go test -run '^$' -bench . standalone_benchmark_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_benchmark_test.go -- +package standalone_benchmark + +import "testing" + +func Benchmark(b *testing.B) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_only_example.txt b/src/cmd/go/testdata/script/test_match_only_example.txt new file mode 100644 index 0000000..515ccb3 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_example.txt @@ -0,0 +1,31 @@ +[short] skip + +# Check that it's okay for test pattern to match only examples. +go test -run Example example1_test.go +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- example1_test.go -- +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Make sure that go test runs Example_Z before Example_A, preserving source order. + +package p + +import "fmt" + +var n int + +func Example_Z() { + n++ + fmt.Println(n) + // Output: 1 +} + +func Example_A() { + n++ + fmt.Println(n) + // Output: 2 +} diff --git a/src/cmd/go/testdata/script/test_match_only_subtests.txt b/src/cmd/go/testdata/script/test_match_only_subtests.txt new file mode 100644 index 0000000..beea895 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_subtests.txt @@ -0,0 +1,14 @@ +# Matches only subtests +go test -run Test/Sub standalone_sub_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_sub_test.go -- +package standalone_sub_test + +import "testing" + +func Test(t *testing.T) { + t.Run("Sub", func(t *testing.T) {}) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_only_subtests_parallel.txt b/src/cmd/go/testdata/script/test_match_only_subtests_parallel.txt new file mode 100644 index 0000000..11872c2 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_subtests_parallel.txt @@ -0,0 +1,21 @@ +# Matches only subtests, parallel +go test -run Test/Sub/Nested standalone_parallel_sub_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_parallel_sub_test.go -- +package standalone_parallel_sub_test + +import "testing" + +func Test(t *testing.T) { + ch := make(chan bool, 1) + t.Run("Sub", func(t *testing.T) { + t.Parallel() + <-ch + t.Run("Nested", func(t *testing.T) {}) + }) + // Ensures that Sub will finish after its t.Run call already returned. + ch <- true +} diff --git a/src/cmd/go/testdata/script/test_match_only_tests.txt b/src/cmd/go/testdata/script/test_match_only_tests.txt new file mode 100644 index 0000000..9185793 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_tests.txt @@ -0,0 +1,13 @@ +# Matches only tests +go test -run Test standalone_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_test.go -- +package standalone_test + +import "testing" + +func Test(t *testing.T) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_minus_n.txt b/src/cmd/go/testdata/script/test_minus_n.txt new file mode 100644 index 0000000..9900dbc --- /dev/null +++ b/src/cmd/go/testdata/script/test_minus_n.txt @@ -0,0 +1,14 @@ +# The intent here is to verify that 'go test -n' works without crashing. +# Any test will do. + +go test -n x_test.go + +-- x_test.go -- +package x_test + +import ( + "testing" +) + +func TestEmpty(t *testing.T) { +} diff --git a/src/cmd/go/testdata/script/test_no_run_example.txt b/src/cmd/go/testdata/script/test_no_run_example.txt new file mode 100644 index 0000000..53ac755 --- /dev/null +++ b/src/cmd/go/testdata/script/test_no_run_example.txt @@ -0,0 +1,30 @@ +go test -v norunexample +stdout 'File with non-runnable example was built.' + +-- go.mod -- +module norunexample + +go 1.16 +-- example_test.go -- +package pkg_test + +import "os" + +func init() { + os.Stdout.Write([]byte("File with non-runnable example was built.\n")) +} + +func Example_test() { + // This test will not be run, it has no "Output:" comment. +} +-- test_test.go -- +package pkg + +import ( + "os" + "testing" +) + +func TestBuilt(t *testing.T) { + os.Stdout.Write([]byte("A normal test was executed.\n")) +} diff --git a/src/cmd/go/testdata/script/test_no_tests.txt b/src/cmd/go/testdata/script/test_no_tests.txt new file mode 100644 index 0000000..2d624d1 --- /dev/null +++ b/src/cmd/go/testdata/script/test_no_tests.txt @@ -0,0 +1,15 @@ +# Tests issue #26242 + +go test testnorun +stdout 'testnorun\t\[no test files\]' + +-- go.mod -- +module testnorun + +go 1.16 +-- p.go -- +package p + +func init() { + panic("go test must not link and run test binaries without tests") +} diff --git a/src/cmd/go/testdata/script/test_parallel_number.txt b/src/cmd/go/testdata/script/test_parallel_number.txt new file mode 100644 index 0000000..4eb9794 --- /dev/null +++ b/src/cmd/go/testdata/script/test_parallel_number.txt @@ -0,0 +1,25 @@ +[short] skip + +# go test -parallel -1 shouldn't work +! go test -parallel -1 standalone_parallel_sub_test.go +stdout '-parallel can only be given' + +# go test -parallel 0 shouldn't work +! go test -parallel 0 standalone_parallel_sub_test.go +stdout '-parallel can only be given' + +-- standalone_parallel_sub_test.go -- +package standalone_parallel_sub_test + +import "testing" + +func Test(t *testing.T) { + ch := make(chan bool, 1) + t.Run("Sub", func(t *testing.T) { + t.Parallel() + <-ch + t.Run("Nested", func(t *testing.T) {}) + }) + // Ensures that Sub will finish after its t.Run call already returned. + ch <- true +} diff --git a/src/cmd/go/testdata/script/test_profile.txt b/src/cmd/go/testdata/script/test_profile.txt new file mode 100644 index 0000000..4bfa2cc --- /dev/null +++ b/src/cmd/go/testdata/script/test_profile.txt @@ -0,0 +1,19 @@ +[gccgo] skip 'gccgo has no standard packages' +[short] skip + +# Check go test -cpuprofile creates errors.test +go test -cpuprofile errors.prof errors +exists -exec errors.test$GOEXE + +# Check go test -cpuprofile -o myerrors.test creates errors.test +go test -cpuprofile errors.prof -o myerrors.test$GOEXE errors +exists -exec myerrors.test$GOEXE + +# Check go test -mutexprofile creates errors.test +go test -mutexprofile errors.prof errors +exists -exec errors.test$GOEXE + +# Check go test -mutexprofile -o myerrors.test creates errors.test +go test -mutexprofile errors.prof -o myerrors.test$GOEXE errors +exists -exec myerrors.test$GOEXE + diff --git a/src/cmd/go/testdata/script/test_race.txt b/src/cmd/go/testdata/script/test_race.txt new file mode 100644 index 0000000..2ffea46 --- /dev/null +++ b/src/cmd/go/testdata/script/test_race.txt @@ -0,0 +1,51 @@ +[short] skip +[!race] skip + +go test testrace + +! go test -race testrace +stdout 'FAIL: TestRace' +! stdout 'PASS' +! stderr 'PASS' + +! go test -race testrace -run XXX -bench . +stdout 'FAIL: BenchmarkRace' +! stdout 'PASS' +! stderr 'PASS' + +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- +package testrace + +import "testing" + +func TestRace(t *testing.T) { + for i := 0; i < 10; i++ { + c := make(chan int) + x := 1 + go func() { + x = 2 + c <- 1 + }() + x = 3 + <-c + _ = x + } +} + +func BenchmarkRace(b *testing.B) { + for i := 0; i < b.N; i++ { + c := make(chan int) + x := 1 + go func() { + x = 2 + c <- 1 + }() + x = 3 + <-c + _ = x + } +} diff --git a/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt b/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt new file mode 100644 index 0000000..eacc882 --- /dev/null +++ b/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt @@ -0,0 +1,48 @@ +[short] skip +[!race] skip + +# Make sure test is functional. +go test testrace + +# Now, check that -race -covermode=set is not allowed. +! go test -race -covermode=set testrace +stderr '-covermode must be "atomic", not "set", when -race is enabled' +! stdout PASS +! stderr PASS + +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- +package testrace + +import "testing" + +func TestRace(t *testing.T) { + for i := 0; i < 10; i++ { + c := make(chan int) + x := 1 + go func() { + x = 2 + c <- 1 + }() + x = 3 + <-c + _ = x + } +} + +func BenchmarkRace(b *testing.B) { + for i := 0; i < b.N; i++ { + c := make(chan int) + x := 1 + go func() { + x = 2 + c <- 1 + }() + x = 3 + <-c + _ = x + } +} diff --git a/src/cmd/go/testdata/script/test_race_install.txt b/src/cmd/go/testdata/script/test_race_install.txt new file mode 100644 index 0000000..8b1f343 --- /dev/null +++ b/src/cmd/go/testdata/script/test_race_install.txt @@ -0,0 +1,18 @@ +[!race] skip +[short] skip + +mkdir $WORKDIR/tmp/pkg +go install -race -pkgdir=$WORKDIR/tmp/pkg std + +# Make sure go test -i -race doesn't rebuild cached packages +go test -race -pkgdir=$WORKDIR/tmp/pkg -i -v empty/pkg +cmp stderr stderr.txt + +-- go.mod -- +module empty + +go 1.16 +-- pkg/pkg.go -- +package p +-- stderr.txt -- +go test: -i flag is deprecated diff --git a/src/cmd/go/testdata/script/test_race_install_cgo.txt b/src/cmd/go/testdata/script/test_race_install_cgo.txt new file mode 100644 index 0000000..3f4eb90 --- /dev/null +++ b/src/cmd/go/testdata/script/test_race_install_cgo.txt @@ -0,0 +1,93 @@ +# Tests Issue #10500 + +[!race] skip + +[!darwin] ! stale cmd/cgo # The darwin builders are spuriously stale; see #33598. + +env GOBIN=$WORK/bin +go install m/mtime m/sametime + +go tool -n cgo +cp stdout cgopath.txt +exec $GOBIN/mtime cgopath.txt # get the mtime of the file whose name is in cgopath.txt +cp stdout cgotime_before.txt + + # For this test, we don't actually care whether 'go test -race -i' succeeds. + # It may fail if GOROOT is read-only (perhaps it was installed as root). + # We only care that it does not overwrite cmd/cgo regardless. +? go test -race -i runtime/race + +exec $GOBIN/mtime cgopath.txt # get the mtime of the file whose name is in cgopath.txt +cp stdout cgotime_after.txt +exec $GOBIN/sametime cgotime_before.txt cgotime_after.txt + +-- go.mod -- +module m + +go 1.16 +-- mtime/mtime.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" + "strings" +) + +func main() { + b, err := os.ReadFile(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + filename := strings.TrimSpace(string(b)) + info, err := os.Stat(filename) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.NewEncoder(os.Stdout).Encode(info.ModTime()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- sametime/sametime.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" + "time" +) + + +func main() { + var t1 time.Time + b1, err := os.ReadFile(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b1, &t1); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + var t2 time.Time + b2, err := os.ReadFile(os.Args[2]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b2, &t2); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + if !t1.Equal(t2) { + fmt.Fprintf(os.Stderr, "time in %v (%v) is not the same as time in %v (%v)", os.Args[1], t1, os.Args[2], t2) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/test_rebuildall.txt b/src/cmd/go/testdata/script/test_rebuildall.txt new file mode 100644 index 0000000..38233c1 --- /dev/null +++ b/src/cmd/go/testdata/script/test_rebuildall.txt @@ -0,0 +1,14 @@ +env GO111MODULE=off + +# Regression test for golang.org/issue/6844: +# 'go test -a' should force dependencies in the standard library to be rebuilt. + +[short] skip + +go test -x -a -c testdata/dep_test.go +stderr '^.*[/\\]compile'$GOEXE'["]? (.* )?regexp .*[/\\]regexp\.go' + +-- testdata/dep_test.go -- +package deps + +import _ "testing" diff --git a/src/cmd/go/testdata/script/test_regexps.txt b/src/cmd/go/testdata/script/test_regexps.txt new file mode 100644 index 0000000..2f33080 --- /dev/null +++ b/src/cmd/go/testdata/script/test_regexps.txt @@ -0,0 +1,79 @@ +go test -cpu=1 -run=X/Y -bench=X/Y -count=2 -v testregexp + +# Test the following: + +# TestX is run, twice +stdout -count=2 '^=== RUN TestX$' +stdout -count=2 '^ x_test.go:6: LOG: X running$' + +# TestX/Y is run, twice +stdout -count=2 '^=== RUN TestX/Y$' +stdout -count=2 '^ x_test.go:8: LOG: Y running$' + +# TestXX is run, twice +stdout -count=2 '^=== RUN TestXX$' +stdout -count=2 '^ z_test.go:10: LOG: XX running' + +# TestZ is not run +! stdout '^=== RUN TestZ$' + +# BenchmarkX is run with N=1 once, only to discover what sub-benchmarks it has, +# and should not print a final summary line. +stdout -count=1 '^ x_test.go:13: LOG: X running N=1$' +! stdout '^\s+BenchmarkX: x_test.go:13: LOG: X running N=\d\d+' +! stdout 'BenchmarkX\s+\d+' + +# Same for BenchmarkXX. +stdout -count=1 '^ z_test.go:18: LOG: XX running N=1$' +! stdout '^ z_test.go:18: LOG: XX running N=\d\d+' +! stdout 'BenchmarkXX\s+\d+' + +# BenchmarkX/Y is run in full twice due to -count=2. +# "Run in full" means that it runs for approximately the default benchtime, +# but may cap out at N=1e9. +# We don't actually care what the final iteration count is, but it should be +# a large number, and the last iteration count prints right before the results. +stdout -count=2 '^ x_test.go:15: LOG: Y running N=[1-9]\d{4,}\nBenchmarkX/Y\s+\d+' + +-- go.mod -- +module testregexp + +go 1.16 +-- x_test.go -- +package x + +import "testing" + +func TestX(t *testing.T) { + t.Logf("LOG: X running") + t.Run("Y", func(t *testing.T) { + t.Logf("LOG: Y running") + }) +} + +func BenchmarkX(b *testing.B) { + b.Logf("LOG: X running N=%d", b.N) + b.Run("Y", func(b *testing.B) { + b.Logf("LOG: Y running N=%d", b.N) + }) +} +-- z_test.go -- +package x + +import "testing" + +func TestZ(t *testing.T) { + t.Logf("LOG: Z running") +} + +func TestXX(t *testing.T) { + t.Logf("LOG: XX running") +} + +func BenchmarkZ(b *testing.B) { + b.Logf("LOG: Z running N=%d", b.N) +} + +func BenchmarkXX(b *testing.B) { + b.Logf("LOG: XX running N=%d", b.N) +} diff --git a/src/cmd/go/testdata/script/test_relative_cmdline.txt b/src/cmd/go/testdata/script/test_relative_cmdline.txt new file mode 100644 index 0000000..2f9c80f --- /dev/null +++ b/src/cmd/go/testdata/script/test_relative_cmdline.txt @@ -0,0 +1,50 @@ +# Relative imports in command line package + +# Run tests outside GOPATH. +env GOPATH=$WORK/tmp + +go test ./testimport/p.go ./testimport/p_test.go ./testimport/x_test.go +stdout '^ok' + +-- testimport/p.go -- +package p + +func F() int { return 1 } +-- testimport/p1/p1.go -- +package p1 + +func F() int { return 1 } +-- testimport/p2/p2.go -- +package p2 + +func F() int { return 1 } +-- testimport/p_test.go -- +package p + +import ( + "./p1" + + "testing" +) + +func TestF(t *testing.T) { + if F() != p1.F() { + t.Fatal(F()) + } +} +-- testimport/x_test.go -- +package p_test + +import ( + . "../testimport" + + "./p2" + + "testing" +) + +func TestF1(t *testing.T) { + if F() != p2.F() { + t.Fatal(F()) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_relative_import.txt b/src/cmd/go/testdata/script/test_relative_import.txt new file mode 100644 index 0000000..938a875 --- /dev/null +++ b/src/cmd/go/testdata/script/test_relative_import.txt @@ -0,0 +1,31 @@ +# Relative imports in go test +env GO111MODULE=off # relative import not supported in module mode + +# Run tests outside GOPATH. +env GOPATH=$WORK/tmp + +go test ./testimport +stdout '^ok' + +-- testimport/p.go -- +package p + +func F() int { return 1 } +-- testimport/p1/p1.go -- +package p1 + +func F() int { return 1 } +-- testimport/p_test.go -- +package p + +import ( + "./p1" + + "testing" +) + +func TestF(t *testing.T) { + if F() != p1.F() { + t.Fatal(F()) + } +} diff --git a/src/cmd/go/testdata/script/test_relative_import_dash_i.txt b/src/cmd/go/testdata/script/test_relative_import_dash_i.txt new file mode 100644 index 0000000..b2716d8 --- /dev/null +++ b/src/cmd/go/testdata/script/test_relative_import_dash_i.txt @@ -0,0 +1,32 @@ +# Relative imports in go test -i +env GO111MODULE=off # relative import not supported in module mode + +# Run tests outside GOPATH. +env GOPATH=$WORK/tmp + +# Check that it's safe to pass -i (which installs dependencies in $GOPATH/pkg) to go test. +! stale runtime # don't let test -i overwrite runtime +go test -i ./testimport + +-- testimport/p.go -- +package p + +func F() int { return 1 } +-- testimport/p1/p1.go -- +package p1 + +func F() int { return 1 } +-- testimport/p_test.go -- +package p + +import ( + "./p1" + + "testing" +) + +func TestF(t *testing.T) { + if F() != p1.F() { + t.Fatal(F()) + } +} diff --git a/src/cmd/go/testdata/script/test_source_order.txt b/src/cmd/go/testdata/script/test_source_order.txt new file mode 100644 index 0000000..2865276 --- /dev/null +++ b/src/cmd/go/testdata/script/test_source_order.txt @@ -0,0 +1,54 @@ +[short] skip + +# Control +! go test example2_test.go example1_test.go + +# This test only passes if the source order is preserved +go test example1_test.go example2_test.go + +-- example1_test.go -- +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Make sure that go test runs Example_Z before Example_A, preserving source order. + +package p + +import "fmt" + +var n int + +func Example_Z() { + n++ + fmt.Println(n) + // Output: 1 +} + +func Example_A() { + n++ + fmt.Println(n) + // Output: 2 +} +-- example2_test.go -- +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Make sure that go test runs Example_Y before Example_B, preserving source order. + +package p + +import "fmt" + +func Example_Y() { + n++ + fmt.Println(n) + // Output: 3 +} + +func Example_B() { + n++ + fmt.Println(n) + // Output: 4 +} diff --git a/src/cmd/go/testdata/script/test_status.txt b/src/cmd/go/testdata/script/test_status.txt new file mode 100644 index 0000000..aa6ad3c --- /dev/null +++ b/src/cmd/go/testdata/script/test_status.txt @@ -0,0 +1,18 @@ +env GO111MODULE=off + +! go test x y +stdout ^FAIL\s+x +stdout ^ok\s+y +stdout (?-m)FAIL\n$ + +-- x/x_test.go -- +package x + +import "testing" + +func TestNothingJustFail(t *testing.T) { + t.Fail() +} + +-- y/y_test.go -- +package y diff --git a/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt b/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt new file mode 100644 index 0000000..44ff6e2 --- /dev/null +++ b/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt @@ -0,0 +1,25 @@ +# Test that the error message for a syntax error in a test go file +# says FAIL. + +env GO111MODULE=off +! go test syntaxerror +stderr 'x_test.go:' # check that the error is diagnosed +stdout 'FAIL' # check that go test says FAIL + +env GO111MODULE=on +cd syntaxerror +! go test syntaxerror +stderr 'x_test.go:' # check that the error is diagnosed +stdout 'FAIL' # check that go test says FAIL + +-- syntaxerror/go.mod -- +module syntaxerror + +go 1.16 +-- syntaxerror/x.go -- +package p +-- syntaxerror/x_test.go -- +package p + +func f() (x.y, z int) { +} diff --git a/src/cmd/go/testdata/script/test_timeout.txt b/src/cmd/go/testdata/script/test_timeout.txt new file mode 100644 index 0000000..4de4df4 --- /dev/null +++ b/src/cmd/go/testdata/script/test_timeout.txt @@ -0,0 +1,23 @@ +[short] skip +env GO111MODULE=off +cd a + +# If no timeout is set explicitly, 'go test' should set +# -test.timeout to its internal deadline. +go test -v . -- +stdout '10m0s' + +# An explicit -timeout argument should be propagated to -test.timeout. +go test -v -timeout 30m . -- +stdout '30m0s' + +-- a/timeout_test.go -- +package t +import ( + "flag" + "fmt" + "testing" +) +func TestTimeout(t *testing.T) { + fmt.Println(flag.Lookup("test.timeout").Value.String()) +} diff --git a/src/cmd/go/testdata/script/test_vendor.txt b/src/cmd/go/testdata/script/test_vendor.txt new file mode 100644 index 0000000..c6a88b6 --- /dev/null +++ b/src/cmd/go/testdata/script/test_vendor.txt @@ -0,0 +1,57 @@ +# In GOPATH mode, vendored packages can replace std packages. +env GO111MODULE=off +cd vend/hello +go test -v +stdout TestMsgInternal +stdout TestMsgExternal + +# In module mode, they cannot. +env GO111MODULE=on +! go test -mod=vendor +stderr 'undefined: strings.Msg' + +-- vend/hello/go.mod -- +module vend/hello + +go 1.16 +-- vend/hello/hello.go -- +package main + +import ( + "fmt" + "strings" // really ../vendor/strings +) + +func main() { + fmt.Printf("%s\n", strings.Msg) +} +-- vend/hello/hello_test.go -- +package main + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgInternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/hello/hellox_test.go -- +package main_test + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgExternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/vendor/strings/msg.go -- +package strings + +var Msg = "hello, world" diff --git a/src/cmd/go/testdata/script/test_vet.txt b/src/cmd/go/testdata/script/test_vet.txt new file mode 100644 index 0000000..5af26b5 --- /dev/null +++ b/src/cmd/go/testdata/script/test_vet.txt @@ -0,0 +1,92 @@ +[short] skip + +# Test file +! go test p1_test.go +stderr 'Logf format %d' +go test -vet=off +stdout '^ok' + +# Non-test file +! go test p1.go +stderr 'Printf format %d' +go test -x -vet=shift p1.go +stderr '[\\/]vet.*-shift' +stdout '\[no test files\]' +go test -vet=off p1.go +! stderr '[\\/]vet.*-shift' +stdout '\[no test files\]' + +# Test issue #22890 +go test m/vetcycle +stdout 'm/vetcycle.*\[no test files\]' + +# Test with ... +! go test ./vetfail/... +stderr 'Printf format %d' +stdout 'ok\s+m/vetfail/p2' + +# Check there's no diagnosis of a bad build constraint in vetxonly mode. +# Use -a so that we need to recompute the vet-specific export data for +# vetfail/p1. +go test -a m/vetfail/p2 +! stderr 'invalid.*constraint' + +-- go.mod -- +module m + +go 1.16 +-- p1_test.go -- +package p + +import "testing" + +func Test(t *testing.T) { + t.Logf("%d") // oops +} +-- p1.go -- +package p + +import "fmt" + +func F() { + fmt.Printf("%d") // oops +} +-- vetcycle/p.go -- +package p + +type ( + _ interface{ m(B1) } + A1 interface{ a(D1) } + B1 interface{ A1 } + C1 interface { + B1 /* ERROR issue #18395 */ + } + D1 interface{ C1 } +) + +var _ A1 = C1 /* ERROR cannot use C1 */ (nil) +-- vetfail/p1/p1.go -- +// +build !foo-bar + +package p1 + +import "fmt" + +func F() { + fmt.Printf("%d", "hello") // causes vet error +} +-- vetfail/p2/p2.go -- +package p2 + +import _ "m/vetfail/p1" + +func F() { +} +-- vetfail/p2/p2_test.go -- +package p2 + +import "testing" + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt b/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt new file mode 100644 index 0000000..08e67a4 --- /dev/null +++ b/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt @@ -0,0 +1,17 @@ +# Tests issue 19394 + +[short] skip + +! go test -cpuprofile cpu.pprof -memprofile mem.pprof -timeout 1ms +grep . cpu.pprof +grep . mem.pprof + +-- go.mod -- +module profiling + +go 1.16 +-- timeout_test.go -- +package timeouttest_test +import "testing" +import "time" +func TestSleep(t *testing.T) { time.Sleep(time.Second) } diff --git a/src/cmd/go/testdata/script/test_xtestonly_works.txt b/src/cmd/go/testdata/script/test_xtestonly_works.txt new file mode 100644 index 0000000..8e150db --- /dev/null +++ b/src/cmd/go/testdata/script/test_xtestonly_works.txt @@ -0,0 +1,27 @@ +[short] skip + +go test xtestonly +! stdout '^ok.*\[no tests to run\]' +stdout '^ok' + +-- go.mod -- +module xtestonly + +go 1.16 +-- f.go -- +package xtestonly + +func F() int { return 42 } +-- f_test.go -- +package xtestonly_test + +import ( + "testing" + "xtestonly" +) + +func TestF(t *testing.T) { + if x := xtestonly.F(); x != 42 { + t.Errorf("f.F() = %d, want 42", x) + } +} diff --git a/src/cmd/go/testdata/script/testing_issue40908.txt b/src/cmd/go/testdata/script/testing_issue40908.txt new file mode 100644 index 0000000..839320e --- /dev/null +++ b/src/cmd/go/testdata/script/testing_issue40908.txt @@ -0,0 +1,25 @@ +[short] skip +[!race] skip + +go test -race testrace + +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- +package testrace + +import "testing" + +func TestRace(t *testing.T) { + helperDone := make(chan struct{}) + go func() { + t.Logf("Something happened before cleanup.") + close(helperDone) + }() + + t.Cleanup(func() { + <-helperDone + }) +} diff --git a/src/cmd/go/testdata/script/toolexec.txt b/src/cmd/go/testdata/script/toolexec.txt new file mode 100644 index 0000000..5262341 --- /dev/null +++ b/src/cmd/go/testdata/script/toolexec.txt @@ -0,0 +1,85 @@ +[short] skip + +# Build our simple toolexec program. +go build ./cmd/mytool + +# Build the main package with our toolexec program. For each action, it will +# print the tool's name and the TOOLEXEC_IMPORTPATH value. We expect to compile +# each package once, and link the main package once. +# Don't check the entire output at once, because the order in which the tools +# are run is irrelevant here. +# Finally, note that asm and cgo are run twice. + +go build -toolexec=$PWD/mytool +[amd64] stderr -count=2 '^asm'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withasm$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withasm$' +[cgo] stderr -count=2 '^cgo'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withcgo$' +[cgo] stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withcgo$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main$' +stderr -count=1 '^link'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main$' + +-- go.mod -- +module test/main +-- foo.go -- +// Simple package so we can test a program build with -toolexec. +// With a dummy import, to test different TOOLEXEC_IMPORTPATH values. +// Includes dummy uses of cgo and asm, to cover those tools as well. +package main + +import ( + _ "test/main/withasm" + _ "test/main/withcgo" +) + +func main() {} +-- withcgo/withcgo.go -- +package withcgo + +// int fortytwo() +// { +// return 42; +// } +import "C" +-- withcgo/stub.go -- +package withcgo + +// Stub file to ensure we build without cgo too. +-- withasm/withasm.go -- +package withasm + +// Note that we don't need to declare the Add func at all. +-- withasm/withasm_amd64.s -- +TEXT ·Add(SB),$0-24 + MOVQ a+0(FP), AX + ADDQ b+8(FP), AX + MOVQ AX, ret+16(FP) + RET +-- cmd/mytool/main.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" +) + +func main() { + tool, args := os.Args[1], os.Args[2:] + toolName := filepath.Base(tool) + if len(args) > 0 && args[0] == "-V=full" { + // We can't alter the version output. + } else { + // Print which tool we're running, and on what package. + fmt.Fprintf(os.Stdout, "%s TOOLEXEC_IMPORTPATH=%s\n", toolName, os.Getenv("TOOLEXEC_IMPORTPATH")) + } + + // Simply run the tool. + cmd := exec.Command(tool, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/vendor_complex.txt b/src/cmd/go/testdata/script/vendor_complex.txt new file mode 100644 index 0000000..9ca94e7 --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_complex.txt @@ -0,0 +1,75 @@ +env GO111MODULE=off + +# smoke test for complex build configuration +go build -o complex.exe complex +[exec:gccgo] go build -compiler=gccgo -o complex.exe complex + +-- complex/main.go -- +package main + +import ( + _ "complex/nest/sub/test12" + _ "complex/nest/sub/test23" + "complex/w" + "v" +) + +func main() { + println(v.Hello + " " + w.World) +} + +-- complex/nest/sub/test12/p.go -- +package test12 + +// Check that vendor/v1 is used but vendor/v2 is NOT used (sub/vendor/v2 wins). + +import ( + "v1" + "v2" +) + +const x = v1.ComplexNestVendorV1 +const y = v2.ComplexNestSubVendorV2 + +-- complex/nest/sub/test23/p.go -- +package test23 + +// Check that vendor/v3 is used but vendor/v2 is NOT used (sub/vendor/v2 wins). + +import ( + "v2" + "v3" +) + +const x = v3.ComplexNestVendorV3 +const y = v2.ComplexNestSubVendorV2 + +-- complex/nest/sub/vendor/v2/v2.go -- +package v2 + +const ComplexNestSubVendorV2 = true + +-- complex/nest/vendor/v1/v1.go -- +package v1 + +const ComplexNestVendorV1 = true + +-- complex/nest/vendor/v2/v2.go -- +package v2 + +const ComplexNestVendorV2 = true + +-- complex/nest/vendor/v3/v3.go -- +package v3 + +const ComplexNestVendorV3 = true + +-- complex/vendor/v/v.go -- +package v + +const Hello = "hello" + +-- complex/w/w.go -- +package w + +const World = "world" diff --git a/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt b/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt new file mode 100644 index 0000000..da52f9a --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt @@ -0,0 +1,52 @@ +[!windows] [short] stop 'this test only applies to Windows' +env GO111MODULE=off + +go build run_go.go +exec ./run_go$GOEXE $GOPATH $GOPATH/src/vend/hello +stdout 'hello, world' + +-- run_go.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func changeVolume(s string, f func(s string) string) string { + vol := filepath.VolumeName(s) + return f(vol) + s[len(vol):] +} + +func main() { + gopath := changeVolume(os.Args[1], strings.ToLower) + dir := changeVolume(os.Args[2], strings.ToUpper) + cmd := exec.Command("go", "run", "hello.go") + cmd.Dir = dir + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +-- vend/hello/hello.go -- +package main + +import ( + "fmt" + "strings" // really ../vendor/strings +) + +func main() { + fmt.Printf("%s\n", strings.Msg) +} +-- vend/vendor/strings/msg.go -- +package strings + +var Msg = "hello, world" diff --git a/src/cmd/go/testdata/script/vendor_import.txt b/src/cmd/go/testdata/script/vendor_import.txt new file mode 100644 index 0000000..df4c27d --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_import.txt @@ -0,0 +1,104 @@ +# Imports +env GO111MODULE=off +go list -f '{{.ImportPath}} {{.Imports}}' 'vend/...' 'vend/vendor/...' 'vend/x/vendor/...' +cmp stdout want_vendor_imports.txt + +-- want_vendor_imports.txt -- +vend [vend/vendor/p r] +vend/dir1 [] +vend/hello [fmt vend/vendor/strings] +vend/subdir [vend/vendor/p r] +vend/x [vend/x/vendor/p vend/vendor/q vend/x/vendor/r vend/dir1 vend/vendor/vend/dir1/dir2] +vend/x/invalid [vend/x/invalid/vendor/foo] +vend/vendor/p [] +vend/vendor/q [] +vend/vendor/strings [] +vend/vendor/vend/dir1/dir2 [] +vend/x/vendor/p [] +vend/x/vendor/p/p [notfound] +vend/x/vendor/r [] +-- vend/bad.go -- +package vend + +import _ "r" +-- vend/dir1/dir1.go -- +package dir1 +-- vend/good.go -- +package vend + +import _ "p" +-- vend/hello/hello.go -- +package main + +import ( + "fmt" + "strings" // really ../vendor/strings +) + +func main() { + fmt.Printf("%s\n", strings.Msg) +} +-- vend/hello/hello_test.go -- +package main + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgInternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/hello/hellox_test.go -- +package main_test + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgExternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/subdir/bad.go -- +package subdir + +import _ "r" +-- vend/subdir/good.go -- +package subdir + +import _ "p" +-- vend/vendor/p/p.go -- +package p +-- vend/vendor/q/q.go -- +package q +-- vend/vendor/strings/msg.go -- +package strings + +var Msg = "hello, world" +-- vend/vendor/vend/dir1/dir2/dir2.go -- +package dir2 +-- vend/x/invalid/invalid.go -- +package invalid + +import "vend/x/invalid/vendor/foo" +-- vend/x/vendor/p/p/p.go -- +package p + +import _ "notfound" +-- vend/x/vendor/p/p.go -- +package p +-- vend/x/vendor/r/r.go -- +package r +-- vend/x/x.go -- +package x + +import _ "p" +import _ "q" +import _ "r" +import _ "vend/dir1" // not vendored +import _ "vend/dir1/dir2" // vendored diff --git a/src/cmd/go/testdata/script/vendor_import_missing.txt b/src/cmd/go/testdata/script/vendor_import_missing.txt new file mode 100644 index 0000000..8e50dfe --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_import_missing.txt @@ -0,0 +1,7 @@ +# Missing package error message +! go build vend/x/vendor/p/p + +-- vend/x/vendor/p/p/p.go -- +package p + +import _ "notfound" diff --git a/src/cmd/go/testdata/script/vendor_import_wrong.txt b/src/cmd/go/testdata/script/vendor_import_wrong.txt new file mode 100644 index 0000000..73bf595 --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_import_wrong.txt @@ -0,0 +1,20 @@ +# Wrong import path +env GO111MODULE=off +! go build vend/x/invalid +stderr 'must be imported as foo' + +env GO111MODULE= +cd vend/x/invalid +! go build vend/x/invalid +stderr 'must be imported as foo' + +-- vend/x/invalid/go.mod -- +module vend/x/invalid + +go 1.16 + +-- vend/x/invalid/invalid.go -- +package invalid + +import "vend/x/invalid/vendor/foo" + diff --git a/src/cmd/go/testdata/script/vendor_issue12156.txt b/src/cmd/go/testdata/script/vendor_issue12156.txt new file mode 100644 index 0000000..ac95c6d --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_issue12156.txt @@ -0,0 +1,16 @@ +# Tests issue #12156, a former index out of range panic. + +env GO111MODULE=off +env GOPATH=$WORK/gopath/src/testvendor2 # vendor/x is directly in $GOPATH, not in $GOPATH/src +cd $WORK/gopath/src/testvendor2/src/p + +! go build p.go +! stderr panic # Make sure it doesn't panic +stderr 'cannot find package "x"' + +-- testvendor2/src/p/p.go -- +package p + +import "x" +-- testvendor2/vendor/x/x.go -- +package x diff --git a/src/cmd/go/testdata/script/vendor_list_issue11977.txt b/src/cmd/go/testdata/script/vendor_list_issue11977.txt new file mode 100644 index 0000000..ce2e29f --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_list_issue11977.txt @@ -0,0 +1,17 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get -d github.com/rsc/go-get-issue-11864 + +go list -f '{{join .TestImports "\n"}}' github.com/rsc/go-get-issue-11864/t +stdout 'go-get-issue-11864/vendor/vendor.org/p' + +go list -f '{{join .XTestImports "\n"}}' github.com/rsc/go-get-issue-11864/tx +stdout 'go-get-issue-11864/vendor/vendor.org/p' + +go list -f '{{join .XTestImports "\n"}}' github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2 +stdout 'go-get-issue-11864/vendor/vendor.org/tx2' + +go list -f '{{join .XTestImports "\n"}}' github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx3 +stdout 'go-get-issue-11864/vendor/vendor.org/tx3' diff --git a/src/cmd/go/testdata/script/vendor_resolve.txt b/src/cmd/go/testdata/script/vendor_resolve.txt new file mode 100644 index 0000000..bc8cf0a --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_resolve.txt @@ -0,0 +1,21 @@ +env GO111MODULE=off +! go build p +stderr 'must be imported as x' + +-- p/p.go -- +package p + +import ( + _ "q/y" + _ "q/z" +) +-- q/vendor/x/x.go -- +package x +-- q/y/y.go -- +package y + +import _ "x" +-- q/z/z.go -- +package z + +import _ "q/vendor/x" diff --git a/src/cmd/go/testdata/script/vendor_test_issue11864.txt b/src/cmd/go/testdata/script/vendor_test_issue11864.txt new file mode 100644 index 0000000..cfb43bf --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_test_issue11864.txt @@ -0,0 +1,20 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get github.com/rsc/go-get-issue-11864 + +# build -i should work +go build -i github.com/rsc/go-get-issue-11864 +go build -i github.com/rsc/go-get-issue-11864/t + +# test -i should work like build -i (golang.org/issue/11988) +go test -i github.com/rsc/go-get-issue-11864 +go test -i github.com/rsc/go-get-issue-11864/t + +# test should work too +go test github.com/rsc/go-get-issue-11864 +go test github.com/rsc/go-get-issue-11864/t + +# external tests should observe internal test exports (golang.org/issue/11977) +go test github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2 diff --git a/src/cmd/go/testdata/script/vendor_test_issue14613.txt b/src/cmd/go/testdata/script/vendor_test_issue14613.txt new file mode 100644 index 0000000..7801e69 --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_test_issue14613.txt @@ -0,0 +1,22 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +cd $GOPATH + +go get github.com/clsung/go-vendor-issue-14613 +go build -o $WORK/a.out -i github.com/clsung/go-vendor-issue-14613 + +# test folder should work +go test -i github.com/clsung/go-vendor-issue-14613 +go test github.com/clsung/go-vendor-issue-14613 + +# test with specified _test.go should work too +cd $GOPATH/src +go test -i github.com/clsung/go-vendor-issue-14613/vendor_test.go +go test github.com/clsung/go-vendor-issue-14613/vendor_test.go + +# test with imported and not used +go test -i github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go +! go test github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go +stderr 'imported and not used:' diff --git a/src/cmd/go/testdata/script/version.txt b/src/cmd/go/testdata/script/version.txt new file mode 100644 index 0000000..8615a4a --- /dev/null +++ b/src/cmd/go/testdata/script/version.txt @@ -0,0 +1,52 @@ +# Without arguments, we just print Go's own version. +go version +stdout '^go version' + +# Flags without files, or paths to misisng files, should error. +! go version missing.exe +! go version -m +stderr 'with arguments' +! go version -v +stderr 'with arguments' + +# Neither of the two flags above should be an issue via GOFLAGS. +env GOFLAGS='-m -v' +go version +stdout '^go version' +env GOFLAGS= + +env GO111MODULE=on +# Skip the builds below if we are running in short mode. +[short] skip + +# Check that 'go version' and 'go version -m' work on a binary built in module mode. +go get -d rsc.io/fortune +go build -o fortune.exe rsc.io/fortune +go version fortune.exe +stdout '^fortune.exe: .+' +go version -m fortune.exe +stdout '^\tpath\trsc.io/fortune' +stdout '^\tmod\trsc.io/fortune\tv1.0.0' + +# Repeat the test with -buildmode=pie. +[!buildmode:pie] stop +go build -buildmode=pie -o external.exe rsc.io/fortune +go version external.exe +stdout '^external.exe: .+' +go version -m external.exe +stdout '^\tpath\trsc.io/fortune' +stdout '^\tmod\trsc.io/fortune\tv1.0.0' + +# Also test PIE with internal linking. +# currently only supported on linux/amd64, linux/arm64 and windows/amd64. +[!linux] [!windows] stop +[!amd64] [!arm64] stop +go build -buildmode=pie -ldflags=-linkmode=internal -o internal.exe rsc.io/fortune +go version internal.exe +stdout '^internal.exe: .+' +go version -m internal.exe +stdout '^\tpath\trsc.io/fortune' +stdout '^\tmod\trsc.io/fortune\tv1.0.0' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/version_replace.txt b/src/cmd/go/testdata/script/version_replace.txt new file mode 100644 index 0000000..ec98f4e --- /dev/null +++ b/src/cmd/go/testdata/script/version_replace.txt @@ -0,0 +1,33 @@ +[short] skip + +go mod download example.com/printversion@v0.1.0 example.com/printversion@v1.0.0 +go get -d example.com/printversion@v0.1.0 +go install example.com/printversion + +go run example.com/printversion +cmp stdout out.txt + +go version -m $GOPATH/bin/printversion$GOEXE +stdout '^.*[/\\]bin[/\\]printversion'$GOEXE': .*$' +stdout '^ path example.com/printversion$' +stdout '^ mod example.com/printversion v0.1.0$' +stdout '^ => example.com/printversion v1.0.0 h1:.*$' +stdout '^ dep example.com/version v1.0.0$' +stdout '^ => example.com/version v1.0.1 h1:.*$' + +-- go.mod -- +module golang.org/issue/37392 +go 1.14 +require ( + example.com/printversion v0.1.0 +) +replace ( + example.com/printversion => example.com/printversion v1.0.0 + example.com/version v1.0.0 => example.com/version v1.0.1 +) +-- out.txt -- +path is example.com/printversion +main is example.com/printversion v0.1.0 + (replaced by example.com/printversion v1.0.0) +using example.com/version v1.0.0 + (replaced by example.com/version v1.0.1) diff --git a/src/cmd/go/testdata/script/vet.txt b/src/cmd/go/testdata/script/vet.txt new file mode 100644 index 0000000..6573ae3 --- /dev/null +++ b/src/cmd/go/testdata/script/vet.txt @@ -0,0 +1,62 @@ +# Package with external tests +! go vet m/vetpkg +stderr 'Printf' + +# With tags +! go vet -tags tagtest m/vetpkg +stderr 'c\.go.*Printf' + +# With flags on +! go vet -printf m/vetpkg +stderr 'Printf' + +# With flags off +go vet -printf=false m/vetpkg +! stderr . + +# With only test files (tests issue #23395) +go vet m/onlytest +! stderr . + +# With only cgo files (tests issue #24193) +[!cgo] skip +[short] skip +go vet m/onlycgo +! stderr . + +-- go.mod -- +module m + +go 1.16 +-- vetpkg/a_test.go -- +package p_test +-- vetpkg/b.go -- +package p + +import "fmt" + +func f() { + fmt.Printf("%d") +} +-- vetpkg/c.go -- +// +build tagtest + +package p + +import "fmt" + +func g() { + fmt.Printf("%d", 3, 4) +} +-- onlytest/p_test.go -- +package p + +import "testing" + +func TestMe(*testing.T) {} +-- onlycgo/p.go -- +package p + +import "C" + +func F() {} diff --git a/src/cmd/go/testdata/script/vet_asm.txt b/src/cmd/go/testdata/script/vet_asm.txt new file mode 100644 index 0000000..59b35ec --- /dev/null +++ b/src/cmd/go/testdata/script/vet_asm.txt @@ -0,0 +1,32 @@ +env GO111MODULE=off + +# Issue 27665. Verify that "go vet" analyzes non-Go files. + +[!amd64] skip +! go vet -asmdecl a +stderr 'f: invalid MOVW of x' + +# -c flag shows context +! go vet -c=2 -asmdecl a +stderr '...invalid MOVW...' +stderr '1 .*TEXT' +stderr '2 MOVW' +stderr '3 RET' +stderr '4' + +# -json causes success, even with diagnostics and errors. +go vet -json -asmdecl a +stderr '"a": {' +stderr '"asmdecl":' +stderr '"posn": ".*asm.s:2:1",' +stderr '"message": ".*invalid MOVW.*"' + +-- a/a.go -- +package a + +func f(x int8) + +-- a/asm.s -- +TEXT ·f(SB),0,$0-1 + MOVW x+0(FP), AX + RET diff --git a/src/cmd/go/testdata/script/vet_deps.txt b/src/cmd/go/testdata/script/vet_deps.txt new file mode 100644 index 0000000..b2a8f16 --- /dev/null +++ b/src/cmd/go/testdata/script/vet_deps.txt @@ -0,0 +1,34 @@ +env GO111MODULE=off + +# Issue 30296. Verify that "go vet" uses only immediate dependencies. + +# First run fills the cache. +go vet a + +go vet -x a +! stderr 'transitive' + +-- a/a.go -- +package a + +import "b" + +func F() { + b.F() +} + +-- b/b.go -- +package b + +import "transitive" + +func F() { + transitive.F() +} + +-- transitive/c.go -- +package transitive + +func F() { +} + diff --git a/src/cmd/go/testdata/script/vet_flags.txt b/src/cmd/go/testdata/script/vet_flags.txt new file mode 100644 index 0000000..e2e3f5b --- /dev/null +++ b/src/cmd/go/testdata/script/vet_flags.txt @@ -0,0 +1,93 @@ +env GO111MODULE=on + +# Issue 35837: "go vet -<analyzer> <std package>" should use the requested +# analyzers, not the default analyzers for 'go test'. +go vet -n -buildtags=false runtime +stderr '-buildtags=false' +! stderr '-unsafeptr=false' + +# Issue 37030: "go vet <std package>" without other flags should disable the +# unsafeptr check by default. +go vet -n runtime +stderr '-unsafeptr=false' +! stderr '-unreachable=false' + +# However, it should be enabled if requested explicitly. +go vet -n -unsafeptr runtime +stderr '-unsafeptr' +! stderr '-unsafeptr=false' + +# -unreachable is disabled during test but on during plain vet. +go test -n runtime +stderr '-unreachable=false' + +# A flag terminator should be allowed before the package list. +go vet -n -- . + +[short] stop + +# Analyzer flags should be included from GOFLAGS, and should override +# the defaults. +go vet . +env GOFLAGS='-tags=buggy' +! go vet . +stderr 'possible formatting directive' + +# Enabling one analyzer in GOFLAGS should disable the rest implicitly... +env GOFLAGS='-tags=buggy -unsafeptr' +go vet . + +# ...but enabling one on the command line should not disable the analyzers +# enabled via GOFLAGS. +env GOFLAGS='-tags=buggy -printf' +! go vet -unsafeptr +stderr 'possible formatting directive' + +# Analyzer flags don't exist unless we're running 'go vet', +# and we shouldn't run the vet tool to discover them otherwise. +# (Maybe someday we'll hard-code the analyzer flags for the default vet +# tool to make this work, but not right now.) +env GOFLAGS='-unsafeptr' +! go list . +stderr 'go: parsing \$GOFLAGS: unknown flag -unsafeptr' +env GOFLAGS= + +env GOCACHE=$WORK/gocache + +# "go test" on a user package should by default enable an explicit list of analyzers. +go test -x -run=none . +stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# An explicitly-empty -vet argument should imply the default analyzers. +go test -x -vet= -run=none . +stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# "go test" on a standard package should by default disable an explicit list. +go test -x -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +go test -x -vet= -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# Both should allow users to override via the -vet flag. +go test -x -vet=unreachable -run=none . +stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' +go test -x -vet=unreachable -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +-- go.mod -- +module example.com/x +-- x.go -- +package x +-- x_test.go -- +package x +-- x_tagged.go -- +// +build buggy + +package x + +import "fmt" + +func init() { + fmt.Sprint("%s") // oops! +} diff --git a/src/cmd/go/testdata/script/vet_internal.txt b/src/cmd/go/testdata/script/vet_internal.txt new file mode 100644 index 0000000..85f7093 --- /dev/null +++ b/src/cmd/go/testdata/script/vet_internal.txt @@ -0,0 +1,71 @@ +env GO111MODULE=off + +# Issue 36173. Verify that "go vet" prints line numbers on load errors. + +! go vet a/a.go +stderr '^package command-line-arguments\n\ta[/\\]a.go:5:3: use of internal package' + +! go vet a/a_test.go +stderr '^package command-line-arguments \(test\)\n\ta[/\\]a_test.go:4:3: use of internal package' + +! go vet a +stderr '^package a\n\ta[/\\]a.go:5:3: use of internal package' + +go vet b/b.go +! stderr 'use of internal package' + +! go vet b/b_test.go +stderr '^package command-line-arguments \(test\)\n\tb[/\\]b_test.go:4:3: use of internal package' + +! go vet depends-on-a/depends-on-a.go +stderr '^package command-line-arguments\n\timports a\n\ta[/\\]a.go:5:3: use of internal package' + +! go vet depends-on-a/depends-on-a_test.go +stderr '^package command-line-arguments \(test\)\n\timports a\n\ta[/\\]a.go:5:3: use of internal package a/x/internal/y not allowed' + +! go vet depends-on-a +stderr '^package depends-on-a\n\timports a\n\ta[/\\]a.go:5:3: use of internal package' + +-- a/a.go -- +// A package with bad imports in both src and test +package a + +import ( + _ "a/x/internal/y" +) + +-- a/a_test.go -- +package a + +import ( + _ "a/x/internal/y" +) + +-- b/b.go -- +// A package with a bad import in test only +package b + +-- b/b_test.go -- +package b + +import ( + _ "a/x/internal/y" +) + +-- depends-on-a/depends-on-a.go -- +// A package that depends on a package with a bad import +package depends + +import ( + _ "a" +) + +-- depends-on-a/depends-on-a_test.go -- +package depends + +import ( + _ "a" +) + +-- a/x/internal/y/y.go -- +package y |