in language/go/config.go [443:602]
func (*goLang) Configure(c *config.Config, rel string, f *rule.File) {
var gc *goConfig
if raw, ok := c.Exts[goName]; !ok {
gc = newGoConfig()
} else {
gc = raw.(*goConfig).clone()
}
c.Exts[goName] = gc
if rel == "" {
const message = `Gazelle may not be compatible with this version of rules_go.
Update io_bazel_rules_go to a newer version in your WORKSPACE file.`
var err error
gc.rulesGoVersion, err = findRulesGoVersion(c)
if c.ShouldFix {
// Only check the version when "fix" is run. Generated build files
// frequently work with older version of rules_go, and we don't want to
// nag too much since there's no way to disable this warning.
// Also, don't print a warning if the rules_go repo hasn't been fetched,
// since that's a common issue when Gazelle is run as a separate binary.
if err != nil && err != errRulesGoRepoNotFound && c.ShouldFix {
log.Printf("%v\n%s", err, message)
} else if err == nil && gc.rulesGoVersion.Compare(minimumRulesGoVersion) < 0 {
log.Printf("Found RULES_GO_VERSION %s. Minimum compatible version is %s.\n%s", gc.rulesGoVersion, minimumRulesGoVersion, message)
}
}
repoNamingConvention := map[string]namingConvention{}
for _, repo := range c.Repos {
if repo.Kind() == "go_repository" {
if attr := repo.AttrString("build_naming_convention"); attr == "" {
// No naming convention specified.
// go_repsitory uses importAliasNamingConvention by default, so we
// could use whichever name.
// resolveExternal should take that as a signal to follow the current
// naming convention to avoid churn.
repoNamingConvention[repo.Name()] = importAliasNamingConvention
} else if nc, err := namingConventionFromString(attr); err != nil {
log.Printf("in go_repository named %q: %v", repo.Name(), err)
} else {
repoNamingConvention[repo.Name()] = nc
}
}
}
gc.repoNamingConvention = repoNamingConvention
}
if !gc.moduleMode {
st, err := os.Stat(filepath.Join(c.RepoRoot, filepath.FromSlash(rel), "go.mod"))
if err == nil && !st.IsDir() {
gc.moduleMode = true
}
}
if path.Base(rel) == "vendor" {
gc.importMapPrefix = InferImportPath(c, rel)
gc.importMapPrefixRel = rel
gc.prefix = ""
gc.prefixRel = rel
}
if f != nil {
setPrefix := func(prefix string) {
if err := checkPrefix(prefix); err != nil {
log.Print(err)
return
}
gc.prefix = prefix
gc.prefixSet = true
gc.prefixRel = rel
}
for _, d := range f.Directives {
switch d.Key {
case "build_tags":
if err := gc.setBuildTags(d.Value); err != nil {
log.Print(err)
continue
}
gc.preprocessTags()
gc.setBuildTags(d.Value)
case "go_generate_proto":
if goGenerateProto, err := strconv.ParseBool(d.Value); err == nil {
gc.goGenerateProto = goGenerateProto
} else {
log.Printf("parsing go_generate_proto: %v", err)
}
case "go_naming_convention":
if nc, err := namingConventionFromString(d.Value); err == nil {
gc.goNamingConvention = nc
} else {
log.Print(err)
}
case "go_naming_convention_external":
if nc, err := namingConventionFromString(d.Value); err == nil {
gc.goNamingConventionExternal = nc
} else {
log.Print(err)
}
case "go_grpc_compilers":
// Special syntax (empty value) to reset directive.
if d.Value == "" {
gc.goGrpcCompilersSet = false
gc.goGrpcCompilers = defaultGoGrpcCompilers
} else {
gc.goGrpcCompilersSet = true
gc.goGrpcCompilers = splitValue(d.Value)
}
case "go_proto_compilers":
// Special syntax (empty value) to reset directive.
if d.Value == "" {
gc.goProtoCompilersSet = false
gc.goProtoCompilers = defaultGoProtoCompilers
} else {
gc.goProtoCompilersSet = true
gc.goProtoCompilers = splitValue(d.Value)
}
case "go_visibility":
gc.goVisibility = append(gc.goVisibility, strings.TrimSpace(d.Value))
case "importmap_prefix":
gc.importMapPrefix = d.Value
gc.importMapPrefixRel = rel
case "prefix":
setPrefix(d.Value)
}
}
if !gc.prefixSet {
for _, r := range f.Rules {
switch r.Kind() {
case "go_prefix":
args := r.Args()
if len(args) != 1 {
continue
}
s, ok := args[0].(*bzl.StringExpr)
if !ok {
continue
}
setPrefix(s.Value)
case "gazelle":
if prefix := r.AttrString("prefix"); prefix != "" {
setPrefix(prefix)
}
}
}
}
}
if gc.goNamingConvention == unknownNamingConvention {
gc.goNamingConvention = detectNamingConvention(c, f)
}
}