Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find and use Gazelle's repo config in bb fix #8270

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion cli/fix/fix.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fix

import (
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -72,7 +73,11 @@ func runGazelle(repoRoot, baseFile string) error {

os.Args = []string{"gazelle", "update"}
if baseFile == workspace.ModuleFileName {
os.Args = append(os.Args, "-bzlmod", "-repo_root="+repoRoot)
repoConfig, err := findRepoConfig(repoRoot)
if err != nil {
return fmt.Errorf("failed to find repo config: %w", err)
}
os.Args = append(os.Args, "-bzlmod", "-repo_root="+repoRoot, "-repo_config="+repoConfig)
} else {
os.Args = append(os.Args, "-repo_root="+repoRoot, "-go_prefix=")
}
Expand All @@ -85,6 +90,47 @@ func runGazelle(repoRoot, baseFile string) error {
return nil
}

// Finds the "repo config" file generated by gazelle's go_deps module extension
// in its external repository. This file contains the mappings from Go module
// paths to Bazel repository names and is required for correct gazelle behavior
// with Bzlmod enabled.
func findRepoConfig(repoRoot string) (string, error) {
// For the sake of performance and not interfering with the user's build,
// find the repo config file without invoking bazel. This assumes that
// the user has not disabled convenience symlinks.
// TODO: This may operate on stale information, consider forcing the
// go_deps extension to reevaluate before reading the config file.
bazelOutSymlink := filepath.Join(repoRoot, "bazel-out")
bazelOut, err := os.Readlink(bazelOutSymlink)
if errors.Is(err, os.ErrNotExist) {
return "", errors.New("failed to find bazel-out symlink, please run a build first")
} else if err != nil {
return "", fmt.Errorf("failed to read bazel-out symlink: %w", err)
}
// bazel-out has a path of the form <output_base>/execroot/_main/bazel-out.
outputBase := filepath.Dir(filepath.Dir(filepath.Dir(bazelOut)))
externalBase := filepath.Join(outputBase, "external")
// The separator in canonical repo names can be + or ~, depending on the
// Bazel version (>= 8 uses +, < 8 may use either depend on an incompatible
// flag).
gazelleConfigRepoGlob := filepath.Join(externalBase, "gazelle[~+][~+]go_deps[~+]bazel_gazelle_go_repository_config")
matches, err := filepath.Glob(gazelleConfigRepoGlob)
if err != nil {
return "", fmt.Errorf("failed to find repo config file: %w", err)
}
if len(matches) == 0 {
return "", errors.New("failed to find repo config file, please run a build first")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like we are failing at this step in CI.

Perhaps we can materialize the repo by running a quick bazel query?

}
if len(matches) > 2 {
return "", fmt.Errorf("found unexpected number of repo config files: %s", strings.Join(matches, ", "))
}
// If the external directory hasn't been cleaned up since updating to
// Bazel 8, it may contain the repo directory both with ~ and + separators.
// The + separator is the more recent one in that case (assuming that users
// didn't switch back to Bazel 7) and sorts first.
return filepath.Join(matches[0], "WORKSPACE"), nil
}

func walk(moduleOrWorkspaceFile string) error {
languages := getLanguages()
foundLanguages := map[language.Language]bool{}
Expand Down
5 changes: 2 additions & 3 deletions cli/workspace/workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ const (
WorkspaceFileName = "WORKSPACE"
WorkspaceAltFileName = "WORKSPACE.bazel"

ModuleFileName = "MODULE.bazel"
ModuleWorkspaceFileName = "WORKSPACE.bzlmod"
ModuleFileName = "MODULE.bazel"
)

var (
Expand All @@ -25,7 +24,7 @@ var (
pathErr error
basename string

WorkspaceIndicatorFiles = []string{WorkspaceFileName, WorkspaceAltFileName, ModuleFileName}
WorkspaceIndicatorFiles = []string{ModuleFileName, WorkspaceFileName, WorkspaceAltFileName}
)

// Path returns the current Bazel workspace path by traversing upwards until
Expand Down