-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: building requires otherwise-unused .mod files to be present #29410
Comments
@stapelberg two quick comments:
edit: sorry, I see you are using the 1.12 beta. |
Setting
Someone else might need to comment if this is a bug, vs. necessary behavior, vs. perhaps a not-yet-implemented feature could avoid this. @stapelberg you mentioned:
I am just looking at this quickly, but is it just meta data about the old version
and:
or:
|
Yes, it’s just the .mod file. Hence my suspicion that this is unintended. |
This is working as designed. Every The good news is, See the go/src/cmd/go/internal/mvs/mvs_test.go Lines 42 to 116 in 006a5e7
|
Can you elaborate on the ways in which these files can impact the version selection? Specifically, are you saying it is not sufficient to synthesize these files?
That’s not my concern, though. In Linux distributions such as Debian, we strive to have precisely one version of a specific module packaged. We can’t keep old packages around just for their .mod files. If this is really working as intended with no wiggle room, we’ll need to work around that and either modify .mod files at package-time (seems more labor-intensive, but haven’t thought it through entirely) or synthesizing .mod files at build-time (ugh). |
Sorry, but Go's version selection algorithm intentionally prioritizes reproducibility over recency: when you build a module-enabled binary, you use the specific versions of the modules it was tested against, not whatever newer version happens to be installed on your system. Now that #27859 is fixed, you can probably make something work using wildcard |
@stapelberg Is this in the context of what I think in the past might have been described as "more or less one giant GOPATH" for Debian packaging of Go libraries, or is this more in the context of trying to use Go modules to break out of that (or perhaps nothing to do with any of that)? I am not sure how much flexibility you have at package time vs. build time, how that changes for a package vs. a binary, the level of control around setting env variables, or your ability to use an auxiliary directory that contains auxiliary data like ...but depending on your constraints, you might be able to do some variety of using https://github.com/go-modules-by-example/index/tree/master/012_modvendor That particular example is showing an alternative to traditional vendoring, and I suspect that is not exactly what you'd want, but it serves as a concrete example of the types of things that are enabled via the flexibility of In any event, good chance |
Debian has its own reproducibility efforts, see https://reproducible-builds.org/. The binaries we build are reproducible, and have been before Go modules :)
Yes. This is the current model and we have no plans to change that.
Changes at packaging-time take a long time to trickle down to all our volunteers. Build-time changes are preferable for this particular situation.
No change.
We can set arbitrary env variables.
We can do that, but every step we need to set up introduces additional complexity, which makes builds slower and harder to understand/debug.
Yeah, we currently already synthesize a GOPATH. From this discussion it seems like we need to synthesize all go.mod files ever referenced by the transitive closure as well. I have not yet looked into how easy or hard this would be to do. |
@stapelberg I am curious what your latest thinking here is, at least briefly? Part of the reason for me bouncing this is curiosity, but also some similar questions are coming up elsewhere. Also, one specific area I do not understand is why you mention synthesizing a large number of Expanding on an earlier point slightly, rather than synthesizing, you might be able use a filesystem-based module cache containing
In other words, that might be an approach to get the actual Note that even though you are setting the GOPROXY environment variable in the steps above, there is no actual proxy process involved, and everything is just being read directly from the local filesystem. An even more detailed example is in the link I had mentioned above. All that said, I don't know if that set of capabilities really helps you or not, and perhaps synthesizing is easier based on your use case. |
Thanks for your reply.
Yes to both questions.
I don’t follow. Where would they come from? Note that Linux distributions generally prohibit internet access during builds, so all files we want to use need to be shipped in other packages (build dependencies) or created by the build infrastructure. |
@bcmills @jayconrod Based on the conversation in #30831 (comment) and #30831 (comment) and related comments, is there some chance that a missing older Any brief thoughts on maybe re-opening this, even if it might not be a near-term change here, and even if it might later end up getting closed again? |
@thepudds I'm not sure if I followed completely, but a missing go.mod file should not be a fatal error. If there is no go.mod file in a dependency, the Go command will synthesize a trivial .mod file with just the module path and no requirements. That will end up in the cache and will be served by the proxy. If a go.mod file is missing in an older version but is present with the wrong module path in a newer version (#30831), that's probably a good sign that we were importing packages with the wrong path. We might not need to know that to suppress the error though. |
The reason why I opened this issue is that I’m seeing the opposite behavior (or I’m misunderstanding you). Can you try to reproduce the steps provided in the initial message please? |
I think there might be two valid but different uses of the word "missing" here. At least as I understood it:
Separately, I had bounced this issue to link it to #30831 (comment). In @stapelberg's case, I suspect the older "missing" |
I talked to @bcmills in person at GopherCon just a few minutes ago, and here are the cliff notes of where we ended up with regards to packaging Go modules in a Linux distribution context (should also apply to NetBSD’s pkgsrc etc.):
Notably, when following step ③, the go tool no longer tries to access the go.mod files, solving this issue. |
@qbit I would be curious if the solution outlined in the above comment (#29410 (comment)) would help in the case of OpenBSD as well. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
As you can see, two versions of
golang.org/x/exp
are involved here: the repro module uses the latest (v0.0.0-20181221233300-b68661188fbf), whereas thegonum.org/v1/gonum
module specifies an older version (v0.0.0-20180321215751-8460e604b9de).In the build itself, the latest version is picked:
However, when preventing internet access by pointing
GOPROXY
to an unused port, I can see that the old version ofgolang.org/x/exp
needs to be present for the build to succeed:This came as a surprise to me, so I wanted to check in and see if this was intentional or an oversight. Given that the .mod file only contains “module golang.org/x/exp”, it seems to me that the file could easily be synthesized?
I discovered this issue because I was experimenting with packaging Go modules in Linux distributions (e.g. Debian). It would be a significant downside if we needed to provide (and therefore maintain!) all versions that a build ever references, instead of just the versions which are selected in the end.
Thanks,
The text was updated successfully, but these errors were encountered: