...

Source file src/edge-infra.dev/pkg/lib/build/bazel/path.go

Documentation: edge-infra.dev/pkg/lib/build/bazel

     1  package bazel
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  )
    10  
    11  // ResolveWd returns the actual working directory if [BuildWorkspaceDir]
    12  // isnt set
    13  func ResolveWd() (string, error) {
    14  	workspaceDir, exists := os.LookupEnv(BuildWorkspaceDir)
    15  
    16  	if exists {
    17  		return workspaceDir, nil
    18  	}
    19  
    20  	// get "actual" working directory
    21  	dir, err := os.Getwd()
    22  	if err != nil {
    23  		return "", err
    24  	}
    25  	return dir, nil
    26  }
    27  
    28  // ResolveWdOrDie is helpful when you need to instantiate initial variables
    29  func ResolveWdOrDie() string {
    30  	workspaceDir, err := ResolveWd()
    31  	if err != nil {
    32  		log.Fatal(err)
    33  	}
    34  	return workspaceDir
    35  }
    36  
    37  // NewTestTmpDir creates a new temporary directory in TestTmpDir()
    38  func NewTestTmpDir(prefix string) (string, error) {
    39  	return os.MkdirTemp(ResolveTestTmpDir(), prefix)
    40  }
    41  
    42  // ResolveTestTmpDir returns the path of the test tmp directory in the Bazel sandbox
    43  // (defined by [TestTmpDir]) if set. Otherwise it returns the OS' default tmp
    44  // directory.
    45  func ResolveTestTmpDir() string {
    46  	if dir, ok := os.LookupEnv(TestTmpDir); ok {
    47  		return dir
    48  	}
    49  	return os.TempDir()
    50  }
    51  
    52  // FindRepoRoot searches from the given dir and up for a directory containing a WORKSPACE file
    53  // returning the directory containing it, or an error if none found in the tree.
    54  func FindRepoRoot(dir string) (string, error) {
    55  	if IsBazelRun() {
    56  		return os.Getenv(BuildWorkspaceDir), nil
    57  	}
    58  
    59  	dir, err := filepath.Abs(dir)
    60  	if err != nil {
    61  		return "", err
    62  	}
    63  
    64  	for {
    65  		for _, workspaceFile := range workspaceFiles {
    66  			filepath := filepath.Join(dir, workspaceFile)
    67  			_, err = os.Stat(filepath)
    68  			if err == nil {
    69  				return dir, nil
    70  			}
    71  			if !os.IsNotExist(err) {
    72  				return "", err
    73  			}
    74  		}
    75  		if strings.HasSuffix(dir, string(os.PathSeparator)) { // stop at root dir
    76  			return "", os.ErrNotExist
    77  		}
    78  		dir = filepath.Dir(dir)
    79  	}
    80  }
    81  
    82  // FindRepoRootOrDie is useful when you need to instantiate initial variables
    83  // or to reduce boilerplate in code that can't recover from not knowing where
    84  // the repo root is
    85  func FindRepoRootOrDie(dir string) string {
    86  	dir, err := FindRepoRoot(dir)
    87  	if err != nil {
    88  		log.Fatal(err)
    89  	}
    90  	return dir
    91  }
    92  
    93  // ChangeDirToRepoRoot correctly navigates to the root of the repository whether
    94  // or not the binary is ran from the Bazel sandbox.
    95  func ChangeDirToRepoRoot() error {
    96  	if IsBazelRun() {
    97  		if err := os.Chdir(os.Getenv(BuildWorkspaceDir)); err != nil {
    98  			return fmt.Errorf("failed to set working directory to %s: %w",
    99  				BuildWorkspaceDir, err)
   100  		}
   101  		return nil
   102  	}
   103  
   104  	cwd, err := os.Getwd()
   105  	if err != nil {
   106  		return fmt.Errorf("failed to determine working directory: %w", err)
   107  	}
   108  	repoRoot, err := FindRepoRoot(cwd)
   109  	if err != nil {
   110  		return fmt.Errorf("failed to determine workspace root: %w", err)
   111  	}
   112  	if err := os.Chdir(repoRoot); err != nil {
   113  		return fmt.Errorf("failed to set working directory to %s: %w",
   114  			repoRoot, err)
   115  	}
   116  	return nil
   117  }
   118  

View as plain text