github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/runtime/debug/mod.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package debug 6 7 import ( 8 "strings" 9 ) 10 11 // set using cmd/go/internal/modload.ModInfoProg 12 var modinfo string 13 14 // ReadBuildInfo returns the build information embedded 15 // in the running binary. The information is available only 16 // in binaries built with module support. 17 func ReadBuildInfo() (info *BuildInfo, ok bool) { 18 return readBuildInfo(modinfo) 19 } 20 21 // BuildInfo represents the build information read from 22 // the running binary. 23 type BuildInfo struct { 24 Path string // The main package path 25 Main Module // The main module information 26 Deps []*Module // Module dependencies 27 } 28 29 // Module represents a module. 30 type Module struct { 31 Path string // module path 32 Version string // module version 33 Sum string // checksum 34 Replace *Module // replaced by this module 35 } 36 37 func readBuildInfo(data string) (*BuildInfo, bool) { 38 if len(data) < 32 { 39 return nil, false 40 } 41 data = data[16 : len(data)-16] 42 43 const ( 44 pathLine = "path\t" 45 modLine = "mod\t" 46 depLine = "dep\t" 47 repLine = "=>\t" 48 ) 49 50 info := &BuildInfo{} 51 52 var line string 53 // Reverse of cmd/go/internal/modload.PackageBuildInfo 54 for len(data) > 0 { 55 i := strings.IndexByte(data, '\n') 56 if i < 0 { 57 break 58 } 59 line, data = data[:i], data[i+1:] 60 switch { 61 case strings.HasPrefix(line, pathLine): 62 elem := line[len(pathLine):] 63 info.Path = elem 64 case strings.HasPrefix(line, modLine): 65 elem := strings.Split(line[len(modLine):], "\t") 66 if len(elem) != 3 { 67 return nil, false 68 } 69 info.Main = Module{ 70 Path: elem[0], 71 Version: elem[1], 72 Sum: elem[2], 73 } 74 case strings.HasPrefix(line, depLine): 75 elem := strings.Split(line[len(depLine):], "\t") 76 if len(elem) != 2 && len(elem) != 3 { 77 return nil, false 78 } 79 sum := "" 80 if len(elem) == 3 { 81 sum = elem[2] 82 } 83 info.Deps = append(info.Deps, &Module{ 84 Path: elem[0], 85 Version: elem[1], 86 Sum: sum, 87 }) 88 case strings.HasPrefix(line, repLine): 89 elem := strings.Split(line[len(repLine):], "\t") 90 if len(elem) != 3 { 91 return nil, false 92 } 93 last := len(info.Deps) - 1 94 if last < 0 { 95 return nil, false 96 } 97 info.Deps[last].Replace = &Module{ 98 Path: elem[0], 99 Version: elem[1], 100 Sum: elem[2], 101 } 102 } 103 } 104 return info, true 105 }