func()

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)
	}
}