updateLocations initializes LocalSrcPath, RelSrcPath, Location and ImportPath. goroot, localgoroot, localgomod, gomodImportPath and gopaths are expected to be in "/" format even on Windows. They must not have a trailing "/". Returns true if a match was found.
(goroot, localgoroot string, localgomods, gopaths map[string]string)
| 407 | // |
| 408 | // Returns true if a match was found. |
| 409 | func (c *Call) updateLocations(goroot, localgoroot string, localgomods, gopaths map[string]string) bool { |
| 410 | // TODO(maruel): Reduce memory allocations. |
| 411 | if c.RemoteSrcPath == "" { |
| 412 | return false |
| 413 | } |
| 414 | // Check GOROOT first. |
| 415 | if goroot != "" { |
| 416 | if prefix := goroot + "/src/"; strings.HasPrefix(c.RemoteSrcPath, prefix) { |
| 417 | // Replace remote GOROOT with local GOROOT. |
| 418 | c.RelSrcPath = c.RemoteSrcPath[len(prefix):] |
| 419 | c.LocalSrcPath = pathJoin(localgoroot, "src", c.RelSrcPath) |
| 420 | if i := strings.LastIndexByte(c.RelSrcPath, '/'); i != -1 { |
| 421 | c.ImportPath = c.RelSrcPath[:i] |
| 422 | } |
| 423 | if c.Location == LocationUnknown { |
| 424 | c.Location = Stdlib |
| 425 | } |
| 426 | return true |
| 427 | } |
| 428 | } |
| 429 | // Check GOPATH. |
| 430 | // TODO(maruel): Sort for deterministic behavior? |
| 431 | for prefix, dest := range gopaths { |
| 432 | if p := prefix + "/src/"; strings.HasPrefix(c.RemoteSrcPath, p) { |
| 433 | c.RelSrcPath = c.RemoteSrcPath[len(p):] |
| 434 | c.LocalSrcPath = pathJoin(dest, "src", c.RelSrcPath) |
| 435 | if i := strings.LastIndexByte(c.RelSrcPath, '/'); i != -1 { |
| 436 | c.ImportPath = c.RelSrcPath[:i] |
| 437 | } |
| 438 | if c.Location == LocationUnknown { |
| 439 | c.Location = GOPATH |
| 440 | } |
| 441 | return true |
| 442 | } |
| 443 | // For modules, the path has to be altered, as it contains the version. |
| 444 | if p := prefix + "/pkg/mod/"; strings.HasPrefix(c.RemoteSrcPath, p) { |
| 445 | c.RelSrcPath = c.RemoteSrcPath[len(p):] |
| 446 | c.LocalSrcPath = pathJoin(dest, "pkg/mod", c.RelSrcPath) |
| 447 | if i := strings.LastIndexByte(c.RelSrcPath, '/'); i != -1 { |
| 448 | c.ImportPath = c.RelSrcPath[:i] |
| 449 | } |
| 450 | if c.Location == LocationUnknown { |
| 451 | c.Location = GoPkg |
| 452 | } |
| 453 | return true |
| 454 | } |
| 455 | } |
| 456 | // Check Go modules. |
| 457 | // Go module path detection only works with stack traces created on the local |
| 458 | // file system. |
| 459 | for prefix, pkg := range localgomods { |
| 460 | if strings.HasPrefix(c.RemoteSrcPath, prefix+"/") { |
| 461 | c.RelSrcPath = c.RemoteSrcPath[len(prefix)+1:] |
| 462 | c.LocalSrcPath = c.RemoteSrcPath |
| 463 | if i := strings.LastIndexByte(c.RelSrcPath, '/'); i != -1 { |
| 464 | c.ImportPath = pkg + "/" + c.RelSrcPath[:i] |
| 465 | } else { |
| 466 | c.ImportPath = pkg |