package bazel import ( "fmt" "log" "os" "path/filepath" "strings" ) // ResolveWd returns the actual working directory if [BuildWorkspaceDir] // isnt set func ResolveWd() (string, error) { workspaceDir, exists := os.LookupEnv(BuildWorkspaceDir) if exists { return workspaceDir, nil } // get "actual" working directory dir, err := os.Getwd() if err != nil { return "", err } return dir, nil } // ResolveWdOrDie is helpful when you need to instantiate initial variables func ResolveWdOrDie() string { workspaceDir, err := ResolveWd() if err != nil { log.Fatal(err) } return workspaceDir } // NewTestTmpDir creates a new temporary directory in TestTmpDir() func NewTestTmpDir(prefix string) (string, error) { return os.MkdirTemp(ResolveTestTmpDir(), prefix) } // ResolveTestTmpDir returns the path of the test tmp directory in the Bazel sandbox // (defined by [TestTmpDir]) if set. Otherwise it returns the OS' default tmp // directory. func ResolveTestTmpDir() string { if dir, ok := os.LookupEnv(TestTmpDir); ok { return dir } return os.TempDir() } // FindRepoRoot searches from the given dir and up for a directory containing a WORKSPACE file // returning the directory containing it, or an error if none found in the tree. func FindRepoRoot(dir string) (string, error) { if IsBazelRun() { return os.Getenv(BuildWorkspaceDir), nil } dir, err := filepath.Abs(dir) if err != nil { return "", err } for { for _, workspaceFile := range workspaceFiles { filepath := filepath.Join(dir, workspaceFile) _, err = os.Stat(filepath) if err == nil { return dir, nil } if !os.IsNotExist(err) { return "", err } } if strings.HasSuffix(dir, string(os.PathSeparator)) { // stop at root dir return "", os.ErrNotExist } dir = filepath.Dir(dir) } } // FindRepoRootOrDie is useful when you need to instantiate initial variables // or to reduce boilerplate in code that can't recover from not knowing where // the repo root is func FindRepoRootOrDie(dir string) string { dir, err := FindRepoRoot(dir) if err != nil { log.Fatal(err) } return dir } // ChangeDirToRepoRoot correctly navigates to the root of the repository whether // or not the binary is ran from the Bazel sandbox. func ChangeDirToRepoRoot() error { if IsBazelRun() { if err := os.Chdir(os.Getenv(BuildWorkspaceDir)); err != nil { return fmt.Errorf("failed to set working directory to %s: %w", BuildWorkspaceDir, err) } return nil } cwd, err := os.Getwd() if err != nil { return fmt.Errorf("failed to determine working directory: %w", err) } repoRoot, err := FindRepoRoot(cwd) if err != nil { return fmt.Errorf("failed to determine workspace root: %w", err) } if err := os.Chdir(repoRoot); err != nil { return fmt.Errorf("failed to set working directory to %s: %w", repoRoot, err) } return nil }