in language/go/resolve.go [179:231]
func resolveWithIndexGo(c *config.Config, ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
matches := ix.FindRulesByImportWithConfig(c, resolve.ImportSpec{Lang: "go", Imp: imp}, "go")
var bestMatch resolve.FindResult
var bestMatchIsVendored bool
var bestMatchVendorRoot string
var matchError error
for _, m := range matches {
// Apply vendoring logic for Go libraries. A library in a vendor directory
// is only visible in the parent tree. Vendored libraries supercede
// non-vendored libraries, and libraries closer to from.Pkg supercede
// those further up the tree.
isVendored := false
vendorRoot := ""
parts := strings.Split(m.Label.Pkg, "/")
for i := len(parts) - 1; i >= 0; i-- {
if parts[i] == "vendor" {
isVendored = true
vendorRoot = strings.Join(parts[:i], "/")
break
}
}
if isVendored {
}
if isVendored && !label.New(m.Label.Repo, vendorRoot, "").Contains(from) {
// vendor directory not visible
continue
}
if bestMatch.Label.Equal(label.NoLabel) || isVendored && (!bestMatchIsVendored || len(vendorRoot) > len(bestMatchVendorRoot)) {
// Current match is better
bestMatch = m
bestMatchIsVendored = isVendored
bestMatchVendorRoot = vendorRoot
matchError = nil
} else if (!isVendored && bestMatchIsVendored) || (isVendored && len(vendorRoot) < len(bestMatchVendorRoot)) {
// Current match is worse
} else {
// Match is ambiguous
// TODO: consider listing all the ambiguous rules here.
matchError = fmt.Errorf("rule %s imports %q which matches multiple rules: %s and %s. # gazelle:resolve may be used to disambiguate", from, imp, bestMatch.Label, m.Label)
}
}
if matchError != nil {
return label.NoLabel, matchError
}
if bestMatch.Label.Equal(label.NoLabel) {
return label.NoLabel, notFoundError
}
if bestMatch.IsSelfImport(from) {
return label.NoLabel, skipImportError
}
return bestMatch.Label, nil
}