mirror of
https://github.com/golang/go
synced 2024-11-26 08:27:56 -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 RecvfromInet4(int, []uint8, int, *SockaddrInet4) (int, error)
|
||||||
pkg syscall (darwin-amd64), func RecvfromInet6(int, []uint8, int, *SockaddrInet6) (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
|
pkg syscall (darwin-amd64), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
pathpkg "path"
|
pathpkg "path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -1921,9 +1922,8 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
|
|||||||
}
|
}
|
||||||
p.Internal.Imports = imports
|
p.Internal.Imports = imports
|
||||||
p.collectDeps()
|
p.collectDeps()
|
||||||
|
if p.Error == nil && p.Name == "main" && len(p.DepsErrors) == 0 {
|
||||||
if cfg.ModulesEnabled && p.Error == nil && p.Name == "main" && len(p.DepsErrors) == 0 {
|
p.setBuildInfo()
|
||||||
p.Internal.BuildInfo = modload.PackageBuildInfo(pkgPath, p.Deps)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsafe is a fake package.
|
// 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,
|
// SafeArg reports whether arg is a "safe" command-line argument,
|
||||||
// meaning that when it appears in a command-line, it probably
|
// meaning that when it appears in a command-line, it probably
|
||||||
// doesn't have some special meaning other than its own name.
|
// doesn't have some special meaning other than its own name.
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
package modload
|
package modload
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
@ -336,53 +335,6 @@ func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode Li
|
|||||||
return info
|
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.
|
// findModule searches for the module that contains the package at path.
|
||||||
// If the package was loaded, its containing module and true are returned.
|
// If the package was loaded, its containing module and true are returned.
|
||||||
// Otherwise, module.Version{} and false are returned.
|
// Otherwise, module.Version{} and false are returned.
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
package debug
|
package debug
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,6 +36,41 @@ type Module struct {
|
|||||||
Replace *Module // replaced by this module
|
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) {
|
func readBuildInfo(data string) (*BuildInfo, bool) {
|
||||||
if len(data) < 32 {
|
if len(data) < 32 {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
Loading…
Reference in New Issue
Block a user