runtime/debug: populate BuildInfo so ReadBuildInfo works - #5592
Conversation
|
This PR updates all submodules - unintentionally I guess? |
debug.ReadBuildInfo() returns ok=false under TinyGo, so anything that
reports its own version — a --version flag, a crash handler, a metric —
has nothing to read.
The information already exists: `go list` reports module paths and
versions for the loaded packages, and the standard toolchain stamps the
same data into runtime/debug.modinfo, a plain string global that
runtime/debug parses back into a *BuildInfo. This fills that global the
same way.
Four pieces, because the data has to travel:
- loader: keep the module Version that `go list` already returns and
the struct was discarding.
- builder: assemble the modinfo string and set the global, unless
-ldflags="-X runtime/debug.modinfo=..." already did.
- src/runtime/debug: parse it, which is where ReadBuildInfo reads from.
- go.mod: golang.org/x/mod, for module.Check and semver validation of
what goes into the string.
Skipped in GOPATH mode and when the main package is not in a module,
where there is nothing to report.
Verified: a module built with this prints its own path and version from
ReadBuildInfo, where it previously reported nothing available.
|
Correct, entirely unintentional — thanks for catching it. The branch had picked up submodule pointer bumps for All seven are gone; the diff is now only Also rebased on dev, which merged cleanly with c33682c apart from an import that both sides added to; |
86d1329 to
e053e7f
Compare
|
This needs a test. |
Adds testdata/buildinfo.go to the compiler test list. The output has to be identical on every machine, so nothing here prints a version, a module path or a checksum the build happens to have. What is checked is either derived — that ReadBuildInfo always succeeds, that it reports a toolchain version even with no module information embedded, and that the version names the compiler — or comes from a fixed module string parsed in the test. That string covers the four line kinds and a replacement, so the parse, the round trip back through BuildInfo.String, and the shapes that must be rejected are all exercised. The distinction the last group draws is the one worth having: a line whose prefix is not a known kind is skipped, which is what upstream does and what lets an older parser read a newer module string, while a known kind with the wrong number of columns is an error — ReadBuildInfo falls back to reporting just the toolchain version when that happens.
|
Added The constraint is that the golden output has to be identical on every machine, so nothing printed is a version, a module path or a checksum the build happens to have. What is asserted is either derived — ReadBuildInfo always succeeds, it reports a toolchain version even with no module info embedded, and that version names the compiler — or comes from a fixed module string the test parses, covering the four line kinds plus a replacement, the round trip back through One distinction in there is worth calling out, because writing the test is what settled it: a line whose prefix is not a known kind is skipped rather than rejected — matching upstream, and what lets an older parser read a newer module string — while a known kind with the wrong column count is an error, which is when I could not run the full |
debug.ReadBuildInfo()returnsok=falseunder TinyGo, so anything that reports its own version — a--versionflag, a crash handler, a metric — has nothing to read.The information already exists.
go listreports module paths and versions for the loaded packages, and the standard toolchain stamps the same data intoruntime/debug.modinfo, a plain string global thatruntime/debugparses back into a*BuildInfo. This fills that global the same way, so the existing parsing path does the rest.Four pieces, because the data has to travel:
Versionthatgo listalready returns and the struct was discarding-ldflags="-X runtime/debug.modinfo=..."already didReadBuildInforeads fromgolang.org/x/mod, formodule.Checkand semver validation of what goes into the stringSkipped in GOPATH mode and when the main package isn't in a module, where there's nothing to report.
Verified: a module built with this prints its own path and version from
ReadBuildInfo(path: bitest,main: bitest (devel)), where it previously reported nothing available.