github.com/grafana/pyroscope@v1.18.0/pkg/frontend/vcs/source/golang/golang.go (about) 1 package golang 2 3 import ( 4 "path/filepath" 5 "strings" 6 7 "github.com/grafana/regexp" 8 ) 9 10 const ( 11 vendorPath = "vendor/" 12 stdLocal = "/usr/local/go/src/" 13 stdGoRoot = "$GOROOT/src/" 14 ) 15 16 var ( 17 stdLibRegex = regexp.MustCompile(`.*?\/go\/.*?(?P<version>(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?).*?\/src\/(?P<path>.*)`) 18 toolchainGoVersion = regexp.MustCompile(`-go(?P<version>[0-9]+\.[0-9]+(?:\.[0-9]+)?(?:rc[0-9]+|beta[0-9]+)?)(?:\.|-)`) 19 ) 20 21 // IsStandardLibraryPath returns the cleaned path of the standard library package and a potential version if detected 22 func IsStandardLibraryPath(path string) (string, string, bool) { 23 if len(path) == 0 { 24 return "", "", false 25 } 26 27 // match toolchain go mod paths 28 if modFile, ok := ParseModuleFromPath(path); ok && modFile.Path == "golang.org/toolchain" { 29 // figure out version 30 matches := toolchainGoVersion.FindStringSubmatch(modFile.Version.Version) 31 if len(matches) > 1 { 32 return strings.TrimPrefix(modFile.FilePath, "src/"), matches[1], true 33 } 34 } 35 36 if stdLibRegex.MatchString(path) { 37 matches := stdLibRegex.FindStringSubmatch(path) 38 version := matches[stdLibRegex.SubexpIndex("version")] 39 path = matches[stdLibRegex.SubexpIndex("path")] 40 return path, version, true 41 } 42 43 path = strings.TrimPrefix(path, stdLocal) 44 path = strings.TrimPrefix(path, stdGoRoot) 45 fileName := filepath.Base(path) 46 packageName := strings.TrimSuffix(path, "/"+fileName) 47 isStdVendor := strings.HasPrefix(packageName, vendorPath) 48 49 if _, isStd := StandardPackages[packageName]; !isStdVendor && !isStd { 50 return "", "", false 51 } 52 return path, "", true 53 } 54 55 // VendorRelativePath returns the relative path of the given path 56 // if it is a vendor path. 57 // For example: 58 // /drone/src/vendor/google.golang.org/protobuf/proto/merge.go -> /vendor/google.golang.org/protobuf/proto/merge.go 59 func VendorRelativePath(path string) (string, bool) { 60 idx := strings.Index(path, "/"+vendorPath) 61 if idx < 0 { 62 return "", false 63 } 64 return path[idx:], true 65 }