-
Notifications
You must be signed in to change notification settings - Fork 18.4k
cmd/go: [email protected]+incompatible currently allows Semantic Import Versioning to be optional #32695
Description
This is a spinout from "Factor 2" from #31543 ("cmd/go: creating v2+ modules has lower success rate than it could").
Compared to Go 1.11 and 1.12, current tip / 1.13 might have increased the modes of interaction that work with v2+ modules that have not adopted Semantic Import Versioning.
What version of Go are you using (go version
)?
go 1.12.6
Does this issue reproduce with the latest release?
Yes, including tip as of yesterday (devel +bc27b64d Tue Jun 18 03:41:59 2019 +0000
)
What did you do?
Observe people accidentally creating and using modules that have v2+ semver tags but that have not adopted Semantic Import Versioning.
For example, if there is a module example.com/foo
that:
- has a
go.mod
file (that is, it has adopted modules) - has a v2.0.0 semver tag as its latest tag
- and its
module
line readsmodule example.com/foo
(without the in theory required/v2
)
then this still works for a module-based consumer, even though the module is in a "bad" state:
go get example.com.com/[email protected]+incompatible
This means people can and do create usable v2+ modules that did not adopt Semantic Import Versioning, and consumers can and do consume those "bad" modules.
However, other things such as upgrades or go get example.com.com/foo@latest
do not work as expected, which leads to confusion.
What did you expect to see?
Some type of warning when consuming a v2+ module that has not adopted Semantic Import Versioning (or perhaps an error in the future after the ecosystem has more time to adapt and more tools exist to help prevent or catch mistakes).
What did you see instead?
Here is a concrete example. This uses github.com/pierrec/lz4:
- v2.2.3 has an incorrect go.mod file missing /v2 in the module statement.
- v2.0.6 seems to be when the "bad" go.mod was first introduced.
- v2.0.5 is the tag immediately before the "bad" go.mod was introduced.
First, here is Go 1.12 successfully building a consumer importing the "bad" v2.0.6, as well as this shows a subsequent upgrade not working in 1.12.
cd $(mktemp -d)
export GOPATH=$(mktemp -d)
go mod init tempmod
echo 'require github.com/pierrec/lz4 v2.0.6+incompatible' >> go.mod
cat <<EOF > consumer.go
package consumer
import _ "github.com/pierrec/lz4"
EOF
# build works
go build
go list -m github.com/pierrec/lz4
# outputs:
# github.com/pierrec/lz4 v2.0.6+incompatible
# attempting to upgrade via 'go get -u' does not upgrade lz4
go get -u
go list -m github.com/pierrec/lz4
# outputs:
# github.com/pierrec/lz4 v2.0.6+incompatible
# attempting to upgrade via '@latest' downgrades
go get github.com/pierrec/lz4@latest
go list -m github.com/pierrec/lz4
# outputs:
# github.com/pierrec/lz4 v2.0.5+incompatible
Second, tip is also able to build using the "bad" v2.0.6, but now tip allows upgrading.
cd $(mktemp -d)
export GOPATH=$(mktemp -d)
gotip mod init tempmod
echo 'require github.com/pierrec/lz4 v2.0.6+incompatible' >> go.mod
cat <<EOF > consumer.go
package consumer
import _ "github.com/pierrec/lz4"
EOF
# build works
gotip build
gotip list -m github.com/pierrec/lz4
# outputs:
# github.com/pierrec/lz4 v2.0.6+incompatible
# upgrade now actually does upgrade to a newer "bad" version
gotip get github.com/pierrec/lz4@latest
gotip list -m github.com/pierrec/lz4
# outputs:
# github.com/pierrec/lz4 v2.2.3+incompatible
head -1 $(gotip list -f '{{.Dir}}' github.com/pierrec/lz4)/go.mod
# outputs:
# module github.com/pierrec/lz4