mirror of
https://github.com/golang/go
synced 2024-11-26 06:38:00 -07:00
cmd/go: move module build info formatting into runtime/debug
Previously, modload.PackageBuildInfo returned a string containing information about modules used to build an executable. This string is embedded in the binary and can be read with debug.ReadBuildInfo or 'go version -m'. With this change, debug.BuildInfo now has a MarshalText method that returns a string in the same format as modload.PackageBuildInfo. Package.load now calls Package.setBuildInfo, which constructs a debug.BuildInfo, formats it with MarshalText, then sets Package.Internal.BuildInfo. This is equivalent to what modload.PackageBuildInfo did. modload.PackageBuildInfo is deleted, since it's no longer used. For #37475 Change-Id: I5875a98cb64737637fec2a450ab2ffa7f1805707 Reviewed-on: https://go-review.googlesource.com/c/go/+/353886 Trust: Jay Conrod <jayconrod@google.com> Run-TryBot: Jay Conrod <jayconrod@google.com> Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
011fd00245
commit
765c9116be
@ -1,3 +1,4 @@
|
||||
pkg runtime/debug, method (*BuildInfo) MarshalText() ([]byte, error)
|
||||
pkg syscall (darwin-amd64), func RecvfromInet4(int, []uint8, int, *SockaddrInet4) (int, error)
|
||||
pkg syscall (darwin-amd64), func RecvfromInet6(int, []uint8, int, *SockaddrInet6) (int, error)
|
||||
pkg syscall (darwin-amd64), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
pathpkg "path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -1921,9 +1922,8 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
|
||||
}
|
||||
p.Internal.Imports = imports
|
||||
p.collectDeps()
|
||||
|
||||
if cfg.ModulesEnabled && p.Error == nil && p.Name == "main" && len(p.DepsErrors) == 0 {
|
||||
p.Internal.BuildInfo = modload.PackageBuildInfo(pkgPath, p.Deps)
|
||||
if p.Error == nil && p.Name == "main" && len(p.DepsErrors) == 0 {
|
||||
p.setBuildInfo()
|
||||
}
|
||||
|
||||
// unsafe is a fake package.
|
||||
@ -2195,6 +2195,83 @@ func (p *Package) collectDeps() {
|
||||
}
|
||||
}
|
||||
|
||||
// setBuildInfo gathers build information, formats it as a string to be
|
||||
// embedded in the binary, then sets p.Internal.BuildInfo to that string.
|
||||
// setBuildInfo should only be called on a main package with no errors.
|
||||
//
|
||||
// This information can be retrieved using debug.ReadBuildInfo.
|
||||
func (p *Package) setBuildInfo() {
|
||||
setPkgErrorf := func(format string, args ...interface{}) {
|
||||
if p.Error == nil {
|
||||
p.Error = &PackageError{Err: fmt.Errorf(format, args...)}
|
||||
}
|
||||
}
|
||||
|
||||
var debugModFromModinfo func(*modinfo.ModulePublic) *debug.Module
|
||||
debugModFromModinfo = func(mi *modinfo.ModulePublic) *debug.Module {
|
||||
dm := &debug.Module{
|
||||
Path: mi.Path,
|
||||
Version: mi.Version,
|
||||
}
|
||||
if mi.Replace != nil {
|
||||
dm.Replace = debugModFromModinfo(mi.Replace)
|
||||
} else {
|
||||
dm.Sum = modfetch.Sum(module.Version{Path: mi.Path, Version: mi.Version})
|
||||
}
|
||||
return dm
|
||||
}
|
||||
|
||||
var main debug.Module
|
||||
if p.Module != nil {
|
||||
main = *debugModFromModinfo(p.Module)
|
||||
}
|
||||
|
||||
visited := make(map[*Package]bool)
|
||||
mdeps := make(map[module.Version]*debug.Module)
|
||||
var q []*Package
|
||||
q = append(q, p.Internal.Imports...)
|
||||
for len(q) > 0 {
|
||||
p1 := q[0]
|
||||
q = q[1:]
|
||||
if visited[p1] {
|
||||
continue
|
||||
}
|
||||
visited[p1] = true
|
||||
if p1.Module != nil {
|
||||
m := module.Version{Path: p1.Module.Path, Version: p1.Module.Version}
|
||||
if p1.Module.Path != main.Path && mdeps[m] == nil {
|
||||
mdeps[m] = debugModFromModinfo(p1.Module)
|
||||
}
|
||||
}
|
||||
q = append(q, p1.Internal.Imports...)
|
||||
}
|
||||
sortedMods := make([]module.Version, 0, len(mdeps))
|
||||
for mod := range mdeps {
|
||||
sortedMods = append(sortedMods, mod)
|
||||
}
|
||||
module.Sort(sortedMods)
|
||||
deps := make([]*debug.Module, len(sortedMods))
|
||||
for i, mod := range sortedMods {
|
||||
deps[i] = mdeps[mod]
|
||||
}
|
||||
|
||||
pkgPath := p.ImportPath
|
||||
if p.Internal.CmdlineFiles {
|
||||
pkgPath = "command-line-arguments"
|
||||
}
|
||||
info := &debug.BuildInfo{
|
||||
Path: pkgPath,
|
||||
Main: main,
|
||||
Deps: deps,
|
||||
}
|
||||
text, err := info.MarshalText()
|
||||
if err != nil {
|
||||
setPkgErrorf("error formatting build info: %v", err)
|
||||
return
|
||||
}
|
||||
p.Internal.BuildInfo = string(text)
|
||||
}
|
||||
|
||||
// SafeArg reports whether arg is a "safe" command-line argument,
|
||||
// meaning that when it appears in a command-line, it probably
|
||||
// doesn't have some special meaning other than its own name.
|
||||
|
@ -5,7 +5,6 @@
|
||||
package modload
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
@ -336,53 +335,6 @@ func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode Li
|
||||
return info
|
||||
}
|
||||
|
||||
// PackageBuildInfo returns a string containing module version information
|
||||
// for modules providing packages named by path and deps. path and deps must
|
||||
// name packages that were resolved successfully with LoadPackages.
|
||||
func PackageBuildInfo(path string, deps []string) string {
|
||||
if !Enabled() {
|
||||
return ""
|
||||
}
|
||||
target, _ := findModule(loaded, path)
|
||||
mdeps := make(map[module.Version]bool)
|
||||
for _, dep := range deps {
|
||||
if m, ok := findModule(loaded, dep); ok {
|
||||
mdeps[m] = true
|
||||
}
|
||||
}
|
||||
var mods []module.Version
|
||||
delete(mdeps, target)
|
||||
for mod := range mdeps {
|
||||
mods = append(mods, mod)
|
||||
}
|
||||
module.Sort(mods)
|
||||
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "path\t%s\n", path)
|
||||
|
||||
writeEntry := func(token string, m module.Version) {
|
||||
mv := m.Version
|
||||
if mv == "" {
|
||||
mv = "(devel)"
|
||||
}
|
||||
fmt.Fprintf(&buf, "%s\t%s\t%s", token, m.Path, mv)
|
||||
if r, _ := Replacement(m); r.Path == "" {
|
||||
fmt.Fprintf(&buf, "\t%s\n", modfetch.Sum(m))
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "\n=>\t%s\t%s\t%s\n", r.Path, r.Version, modfetch.Sum(r))
|
||||
}
|
||||
}
|
||||
|
||||
if target.Path != "" {
|
||||
writeEntry("mod", target)
|
||||
}
|
||||
for _, mod := range mods {
|
||||
writeEntry("dep", mod)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// findModule searches for the module that contains the package at path.
|
||||
// If the package was loaded, its containing module and true are returned.
|
||||
// Otherwise, module.Version{} and false are returned.
|
||||
|
@ -5,6 +5,8 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -34,6 +36,41 @@ type Module struct {
|
||||
Replace *Module // replaced by this module
|
||||
}
|
||||
|
||||
func (bi *BuildInfo) MarshalText() ([]byte, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
if bi.Path != "" {
|
||||
fmt.Fprintf(buf, "path\t%s\n", bi.Path)
|
||||
}
|
||||
var formatMod func(string, Module)
|
||||
formatMod = func(word string, m Module) {
|
||||
buf.WriteString(word)
|
||||
buf.WriteByte('\t')
|
||||
buf.WriteString(m.Path)
|
||||
mv := m.Version
|
||||
if mv == "" {
|
||||
mv = "(devel)"
|
||||
}
|
||||
buf.WriteByte('\t')
|
||||
buf.WriteString(mv)
|
||||
if m.Replace == nil {
|
||||
buf.WriteByte('\t')
|
||||
buf.WriteString(m.Sum)
|
||||
} else {
|
||||
buf.WriteByte('\n')
|
||||
formatMod("=>", *m.Replace)
|
||||
}
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
if bi.Main.Path != "" {
|
||||
formatMod("mod", bi.Main)
|
||||
}
|
||||
for _, dep := range bi.Deps {
|
||||
formatMod("dep", *dep)
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func readBuildInfo(data string) (*BuildInfo, bool) {
|
||||
if len(data) < 32 {
|
||||
return nil, false
|
||||
|
Loading…
Reference in New Issue
Block a user