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: 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: 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: 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 # 'go mod vendor' should work with an alternative vendor directory if the -o flag is provided. go mod vendor -v -o alternative-vendor-dir exists alternative-vendor-dir/modules.txt exists alternative-vendor-dir/a/foo/LICENSE # 'go mod vendor' should interpret paths relative to the current working directory when the -o flag is provided. mkdir dir1 mkdir dir2 cd dir1 go mod vendor -v -o relative-vendor-dir go mod vendor -v -o ../dir2/relative-vendor-dir cd .. exists dir1/relative-vendor-dir/modules.txt exists dir1/relative-vendor-dir/a/foo/LICENSE exists dir2/relative-vendor-dir/modules.txt exists dir2/relative-vendor-dir/a/foo/LICENSE # 'go mod vendor' should fall back to the default 'vendor' directory when an empty argument is passed to the -o flag # the same behavior should be exhibited both on the module root directory, as well as nested subdirectories go mod vendor -v -o '' exists vendor/modules.txt env GOFLAGS=-o=foo go mod vendor -v -o '' exists vendor/modules.txt env GOFLAGS='' mkdir -p nested/dir cd nested/dir go mod vendor -v -o '' ! exists vendor/ exists ../../vendor/modules.txt cd ../.. # 'go mod vendor' should work with absolute paths as well go mod vendor -v -o $WORK/tmp/absolute-vendor-dir exists $WORK/tmp/absolute-vendor-dir/modules.txt [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