github.com/gojue/ecapture@v0.8.2/pkg/proc/proc.go (about) 1 package proc 2 3 import ( 4 "debug/buildinfo" 5 "errors" 6 "strconv" 7 "strings" 8 ) 9 10 const ( 11 goVersionPrefix = "Go cmd/compile" 12 ) 13 14 // ErrVersionNotFound is returned when we can't find Go version info from a binary 15 var ErrVersionNotFound = errors.New("version info not found") 16 17 // GoVersion represents Go toolchain version that a binary is built with. 18 type GoVersion struct { 19 major int 20 minor int 21 } 22 23 // After returns true if it is greater than major.minor 24 func (v *GoVersion) After(major, minor int) bool { 25 if v.major > minor { 26 return true 27 } 28 if v.major == major && v.minor > minor { 29 return true 30 } 31 return false 32 } 33 34 // ExtraceGoVersion extracts Go version info from a binary that is built with Go toolchain 35 func ExtraceGoVersion(path string) (*GoVersion, error) { 36 bi, e := buildinfo.ReadFile(path) 37 if e != nil { 38 return nil, ErrVersionNotFound 39 } 40 gv, err := parseGoVersion(bi.GoVersion) 41 if err != nil { 42 return nil, err 43 } 44 return gv, nil 45 } 46 47 func parseGoVersion(r string) (*GoVersion, error) { 48 ver := strings.TrimPrefix(r, goVersionPrefix) 49 50 if strings.HasPrefix(ver, "go") { 51 v := strings.SplitN(ver[2:], ".", 3) 52 var major, minor int 53 var err error 54 55 major, err = strconv.Atoi(v[0]) 56 if err != nil { 57 return nil, err 58 } 59 60 if len(v) >= 2 { 61 minor, err = strconv.Atoi(v[1]) 62 if err != nil { 63 return nil, err 64 } 65 } 66 67 return &GoVersion{ 68 major: major, 69 minor: minor, 70 }, nil 71 } 72 return nil, ErrVersionNotFound 73 }