-
Notifications
You must be signed in to change notification settings - Fork 2k
implement module compatibility check #4723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #4723 +/- ##
=======================================
Coverage 55.03% 55.03%
=======================================
Files 361 361
Lines 30140 30140
=======================================
Hits 16588 16588
Misses 12597 12597
Partials 955 955 🚀 New features to boost your workflow:
|
a385e26
to
2fc96b2
Compare
c0a89d6
to
b6a9390
Compare
This is going to get rid of so many headaches in the future! Thanks @thaJeztah :') |
Was still deciding whether we should merge this one as-is (but we don't have a flow yet to run it cleanly, which could be some stage in the Dockerfile), or if we could make this work without that; per moby/moby#46941 (comment)
|
b6a9390
to
5fa9bea
Compare
This package imports all "importable" packages, i.e., packages that: - are not applications ("main") - are not internal - and that have non-test go-files We do this to verify that our code can be consumed as a dependency in "module mode". When using a dependency that does not have a go.mod (i.e.; is not a "module"), go implicitly generates a go.mod. Lacking information from the dependency itself, it assumes "go1.16" language (see [DefaultGoModVersion]). Starting with Go1.21, go downgrades the language version used for such dependencies, which means that any language feature used that is not supported by go1.16 results in a compile error; # github.com/docker/cli/cli/context/store /go/pkg/mod/github.com/docker/cli@v25.0.0-beta.2+incompatible/cli/context/store/storeconfig.go:6:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) /go/pkg/mod/github.com/docker/cli@v25.0.0-beta.2+incompatible/cli/context/store/store.go:74:12: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) These errors do NOT occur when using GOPATH mode, nor do they occur when using "pseudo module mode" (the "-mod=mod -modfile=vendor.mod" approach used in this repository). As a workaround for this situation, we must include "//go:build" comments in any file that uses newer go-language features (such as the "any" type or the "min()", "max()" builtins). From the go toolchain docs (https://go.dev/doc/toolchain): > The go line for each module sets the language version the compiler enforces > when compiling packages in that module. The language version can be changed > on a per-file basis by using a build constraint. > > For example, a module containing code that uses the Go 1.21 language version > should have a go.mod file with a go line such as go 1.21 or go 1.21.3. > If a specific source file should be compiled only when using a newer Go > toolchain, adding //go:build go1.22 to that source file both ensures that > only Go 1.22 and newer toolchains will compile the file and also changes > the language version in that file to Go 1.22. This file is a generated module that imports all packages provided in the repository, which replicates an external consumer using our code as a dependency in go-module mode, and verifies all files in those packages have the correct "//go:build <go language version>" set. To test this package: make shell make -C ./internal/gocompat/ make: Entering directory '/go/src/github.com/docker/cli/internal/gocompat' GO111MODULE=off go generate . GO111MODULE=on go mod tidy GO111MODULE=on go test -v # github.com/docker/cli/templates ../../templates/templates.go:13:17: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) # github.com/docker/cli/cli/compose/template ../../cli/compose/template/template.go:98:45: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/template/template.go:105:27: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/template/template.go:141:28: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) # github.com/docker/cli/cli/compose/types ../../cli/compose/types/types.go:53:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:86:34: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:105:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:137:34: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:211:20: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:343:35: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:442:40: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:469:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:490:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:587:28: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/types/types.go:442:40: too many errors # github.com/docker/cli/cli/context/store ../../cli/context/store/storeconfig.go:6:24: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/context/store/store.go:74:12: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/context/store/store.go:75:23: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/context/store/metadatastore.go:43:58: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/context/store/metadatastore.go:48:22: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/context/store/metadatastore.go:80:30: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) # github.com/docker/cli/cli/command/idresolver ../../cli/command/idresolver/idresolver.go:6:2: "github.com/docker/docker/api/types" imported and not used ../../cli/command/idresolver/idresolver.go:7:2: "github.com/docker/docker/api/types/swarm" imported and not used ../../cli/command/idresolver/idresolver.go:9:2: "github.com/pkg/errors" imported and not used ../../cli/command/idresolver/idresolver.go:28:49: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/command/idresolver/idresolver.go:58:53: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) # github.com/docker/cli/cli/compose/schema ../../cli/compose/schema/schema.go:20:46: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/schema/schema.go:27:53: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/schema/schema.go:45:32: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) ../../cli/compose/schema/schema.go:66:33: predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod) FAIL gocompat [build failed] make: *** [Makefile:3: verify] Error 1 make: Leaving directory '/go/src/github.com/docker/cli/internal/gocompat' [DefaultGoModVersion]: https://github.com/golang/go/blob/58c28ba286dd0e98fe4cca80f5d64bbcb824a685/src/cmd/go/internal/gover/version.go#L15-L24 [2]: https://go.dev/doc/toolchain Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This package imports all "importable" packages, i.e., packages that:
We do this to verify that our code can be consumed as a dependency in "module mode". When using a dependency that does not have a go.mod (i.e.; is not a "module"), go implicitly generates a go.mod. Lacking information from the dependency itself, it assumes "go1.16" language (see DefaultGoModVersion). Starting with Go1.21, go downgrades the language version used for such dependencies, which means that any language feature used that is not supported by go1.16 results in a compile error;
These errors do NOT occur when using GOPATH mode, nor do they occur when using "pseudo module mode" (the "-mod=mod -modfile=vendor.mod" approach used in this repository).
As a workaround for this situation, we must include "//go:build" comments in any file that uses newer go-language features (such as the "any" type or the "min()", "max()" builtins).
From the go toolchain docs (https://go.dev/doc/toolchain):
This file is a generated module that imports all packages provided in the repository, which replicates an external consumer using our code as a dependency in go-module mode, and verifies all files in those packages have the correct "//go:build " set.
To test this package:
- What I did
- How I did it
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)