gotest.tools
gotest.tools copied to clipboard
Import aliases break the so-called “minimal module support” in GOPATH mode
For those of us still using GOPATH mode, it's still possible (or at least it should be) to use modern go packages with a go.mod seamlessly.
For a working example : https://github.com/godbus/dbus
$ GOPATH=$(pwd) go get github.com/godbus/dbus
$ echo $?
0
$ head -1 src/github.com/godbus/dbus/go.mod
module github.com/godbus/dbus/v5
However it doesn't work with gotest.tools:
$ GOPATH=$(pwd) go get -v gotest.tools
package gotest.tools: code in directory /tmp/gotestdir/src/gotest.tools expects import "gotest.tools/v3"
$ echo $?
1
$ head -1 src/gotest.tools/go.mod
module gotest.tools/v3
Question one: why does it work with godbus?
Answer: Thanks to the so-called “minimal module support” that was introduced in https://github.com/golang/go/commit/28ae82663a1c57c185312b60a2eae8cf06cc24b4. Basically and as I understand it, Go rewrites the import path on the fly, so we can have godbus installed in the directory $GOPATH/src/github.com/godbus/dbus, despite the fact that ALL the import directives in the code refer to github.com/godbus/dbus/v5. The directory v5 does not need to exist.
Question two: why it doesn't work with gotest.tools then?
Answer: Because of the import aliases. In gotest.tools, all the package lines are of the form package assert // import "gotest.tools/v3/assert". It seems that the // import ... prevents Go from rewriting the import path and dropping the v3 suffix.
Suggestion: drop the import aliases?
I don't know the reason for these import aliases honestly. I tried to remove them all, and it works for me, but I don't know if it might break other configs.
In case you're interested with removing import aliases: https://github.com/gotestyourself/gotest.tools/pull/204
Does go get -v gotest.tools/v3 works though ? :thinking:
As @vdemeester says, I think the right thing to do is go get -v gotest.tools/v3.
But maybe it is appropriate to remove the import aliases now that the module indicates the correct path. I think your theory is likely correct, but I don't see anything about import aliases in that diff. Do you know if there is anything else written about this problem?
I don't know the reason for these import aliases honestly.
They used to be necessary, before modules, to get the custom import path gotest.tools. With modules maybe they are now unnecessary.
@vdemeester So actually, neither gotest.tools neither gotest.tools/v3 work in GOPATH mode. I'm trying in the official golang docker image, latest.
$ go version
go version go1.14.4 linux/amd64
$ GOPATH=$(pwd) go get -v gotest.tools
get "gotest.tools": found meta tag get.metaImport{Prefix:"gotest.tools", VCS:"git", RepoRoot:"https://github.com/gotestyourself/gotest.tools"} at //gotest.tools/?go-get=1
gotest.tools (download)
package gotest.tools: code in directory /go/src/gotest.tools expects import "gotest.tools/v3"
$ GOPATH=$(pwd) go get -v gotest.tools/v3
get "gotest.tools/v3": found meta tag get.metaImport{Prefix:"gotest.tools", VCS:"git", RepoRoot:"https://github.com/gotestyourself/gotest.tools"} at //gotest.tools/v3?go-get=1
get "gotest.tools/v3": verifying non-authoritative meta tag
gotest.tools (download)
package gotest.tools/v3: cannot find package "gotest.tools/v3" in any of:
/usr/local/go/src/gotest.tools/v3 (from $GOROOT)
/go/src/gotest.tools/v3 (from $GOPATH)
@dnephin
I think your theory is likely correct, but I don't see anything about import aliases in that diff.
By "that diff", you mean the diff I propose at https://github.com/gotestyourself/gotest.tools/pull/204/files ?
It's about removing all the // import ... comments after the package declaration. I though it was named "import alias" but I might be mistaken.
In any case, removing those solves the problem for me:
# GOPATH=$(pwd) go get gotest.tools/...
package gotest.tools: code in directory /go/src/gotest.tools expects import "gotest.tools/v3"
package gotest.tools/assert: code in directory /go/src/gotest.tools/assert expects import "gotest.tools/v3/assert"
package gotest.tools/assert/cmp: code in directory /go/src/gotest.tools/assert/cmp expects import "gotest.tools/v3/assert/cmp"
package gotest.tools/assert/opt: code in directory /go/src/gotest.tools/assert/opt expects import "gotest.tools/v3/assert/opt"
package gotest.tools/env: code in directory /go/src/gotest.tools/env expects import "gotest.tools/v3/env"
package gotest.tools/fs: code in directory /go/src/gotest.tools/fs expects import "gotest.tools/v3/fs"
package gotest.tools/golden: code in directory /go/src/gotest.tools/golden expects import "gotest.tools/v3/golden"
package gotest.tools/icmd: code in directory /go/src/gotest.tools/icmd expects import "gotest.tools/v3/icmd"
package gotest.tools/internal/maint: code in directory /go/src/gotest.tools/internal/maint expects import "gotest.tools/v3/internal/maint"
package gotest.tools/poll: code in directory /go/src/gotest.tools/poll expects import "gotest.tools/v3/poll"
package gotest.tools/skip: code in directory /go/src/gotest.tools/skip expects import "gotest.tools/v3/skip"
package gotest.tools/x: code in directory /go/src/gotest.tools/x expects import "gotest.tools/v3/x"
package gotest.tools/x/subtest: code in directory /go/src/gotest.tools/x/subtest expects import "gotest.tools/v3/x/subtest"
$ cd src/gotest.tools/
$ git remote add elboulangero https://github.com/elboulangero/gotest.tools.git
$ git pull elboulangero no-import-aliases
...
16 files changed, 16 insertions(+), 16 deletions(-)
$ cd -
$ GOPATH=$(pwd) go get gotest.tools/...
$ echo $?
0
Thanks for confirming that go get gotest.tools/v3 also does not work.
#204 does look right, and you are correct they are called import aliases. The diff I was talking about was the Go PR you linked (golang/go@28ae826).
Edit; I was wrong, they are called "vanity import paths" not import aliases.
I think most likely your PR is the correct solution, but I'd like to make sure I understand what the recommended approach is before making that change, just in case there is something we have missed. I'll see if I can find any information about import aliases compatibility with modules.