-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
cmd/go: inconsistent behavior when 'go' directive is missing from 'go.mod' #44976
Comments
Change https://golang.org/cl/302051 mentions this issue: |
Another alternative might be either of the above but defaulting to |
Option 2 seems better to me. I'd expect this to mostly affect a) modules that were converted with Go 1.11 then never upgraded, and b) projects that were never migrated to modules and don't have a real For these projects, it's probably better to default to something older, particularly if the |
…file will be written Then, write the 'go.mod' file with that version before further processing. That way, if the command errors out due to a change in behavior, the reason for the change in behavior will be visible in the file diffs. If the 'go.mod' file cannot be written (due to -mod=readonly or -mod=vendor), assume Go 1.11 instead of the current Go release. (cmd/go has added 'go' directives automatically, including in 'go mod init', since Go 1.12.) For #44976 Change-Id: If9d4af557366f134f40ce4c5638688ba3bab8380 Reviewed-on: https://go-review.googlesource.com/c/go/+/302051 Trust: Bryan C. Mills <[email protected]> Run-TryBot: Bryan C. Mills <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Jay Conrod <[email protected]> Reviewed-by: Michael Matloob <[email protected]>
@jayconrod points out that packages authored today in |
#45109 brings up another interesting complication: If we assume However, if we assume a version lower than I see a few possible solutions. All are unfortunate.
Of these options, I think (2) may be the least-bad. |
Change https://golang.org/cl/303229 mentions this issue: |
If Or, at least, we could error out if the
|
…explicit 'go' directives Fixes #45109 Updates #44976 Updates #36876 Change-Id: Icb00f8b6e0d4e076d82da1697e7058b9e7603916 Reviewed-on: https://go-review.googlesource.com/c/go/+/303229 Trust: Bryan C. Mills <[email protected]> Run-TryBot: Bryan C. Mills <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Jay Conrod <[email protected]>
@bcmills Any update on this issue? Just checking in as it is labeled as a release-blocker. |
It's mostly fixed at head already, although we may need to do some fine-tuning before the final release. We discussed this issue today in a meeting with @rsc, @matloob, @jayconrod, and me, and decided that the differences in behavior from 1.11 to 1.16 are small enough that we may as well assume 1.16 uniformly when either the I'm going to try to implement #45094 as part of lazy loading (in order to provide a migration path), and as part of that we can also evaluate whether |
Change https://golang.org/cl/308509 mentions this issue: |
To close the loop on this: when the When it is not allowed to modify the |
During work on CL 293689, I noticed some issues with the behavior of
cmd/go
when ago.mod
file is present but contains nogo
directive (whichcmd/go
adds by default starting as of Go 1.12).The
go
directive controls two things: the version of the Go language spec that applies for source code compiled within that module, and the assumptions thatcmd/go
makes about the contents and consistency ofgo.mod
andvendor/modules.txt
:go 1.14
,-mod=vendor
is set by default whenvendor/modules.txt
is present. (In prior versions, it always had to be enabled explicitly.)go 1.16
, theall
pattern under-mod=mod
and-mod=readonly
matches the same packages as under-mod=vendor
. (In prior versions, theall
pattern matched additional test dependencies inmod
andreadonly
modes.)go 1.17
,cmd/go
will assume that thego.mod
file satisfies additional invariants, and will prune dependencies and load them lazily instead of eagerly (cmd/go: module graph pruning and lazy module loading #36460).When the
go
directive is missing from the main module'sgo.mod
file,cmd/go
currently adds ago
directive for the latest Go version it supports. It does this regardles of the-mod
setting, but only writes thego
directive back to thego.mod
file if-mod=mod
is set. As of Go 1.16,-mod=mod
is no longer the default behavior.This leads to two problems:
The implicitly-added
go
directive triggers assumptions about the current state of the module that are not necessarily valid, especially for read-only modules found within the module cache. That can cause builds to spuriously fail (such as if the program uses a language feature that was removed in a subsequent version of the language, or if thego
command assumes lazy-loading semantics for a Go 1.11 module).The behavior of builds with
-mod=readonly
is not reproducible. The dependencies in use may vary with changes in the behavior of the module loader from one version to the next, and packages that build successfully in the main module today may fail to build (without any changes in their source code) if features are removed from a future version of the language.In addition, as implemented this behavior contains a (fairly serious) bug: the newly-added
go
version takes effect immediately for the compiler (controlling language versions), but does not take effect in the module loader until thego.mod
file is written back to disk.I can see two possible fixes:
We could change
cmd/go
to only add thego
directive if it intends to write the updatedgo.mod
file back to disk, so that a read-only main module is treated the same as a read-only dependency module.-mod=readonly
and-mod=vendor
), or explicitly modifying thego.mod
file.go.mod
file instead of usinggo mod init
would continue to jump to the latest version.-mod=readonly
to suddenly have very different semantics (and possibly verbose failures) when repeated with-mod=mod
.We could change
cmd/go
to assumego 1.11
(instead of the current language version) when ago
directive is missing, regardless of the-mod
flag.-mod=mod
as under-mod=readonly
and-mod=vendor
.go mod init
to stick at Go 1.11 semantics, instead of incorporating improvements to the language and module-mode semantics made since that time.The text was updated successfully, but these errors were encountered: