diff --git a/cmd/cue/cmd/cmd.go b/cmd/cue/cmd/cmd.go index 26a8a0bc1c1..e6432f64740 100644 --- a/cmd/cue/cmd/cmd.go +++ b/cmd/cue/cmd/cmd.go @@ -16,7 +16,6 @@ package cmd import ( "fmt" - "os" "cuelang.org/go/cue/errors" "github.com/spf13/cobra" @@ -164,8 +163,7 @@ Run "cue help commands" for more details on tasks and workflow commands. if !isRootCmd { cmdline += " cmd" } - cwd, _ := os.Getwd() - fmt.Fprint(w, errors.Details(err, &errors.Config{Cwd: cwd})) + fmt.Fprint(w, errors.Details(err, &errors.Config{Cwd: rootWorkingDir})) fmt.Fprintln(w, `Ensure custom commands are defined in a "_tool.cue" file.`) fmt.Fprintln(w, "Run 'cue help cmd' to list available custom commands.") if isRootCmd { diff --git a/cmd/cue/cmd/fix.go b/cmd/cue/cmd/fix.go index e139984185a..8c2147d07b5 100644 --- a/cmd/cue/cmd/fix.go +++ b/cmd/cue/cmd/fix.go @@ -49,11 +49,6 @@ Without any packages, fix applies to all files within a module. } func runFixAll(cmd *Command, args []string) error { - dir, err := os.Getwd() - if err != nil { - return err - } - var opts []fix.Option if flagSimplify.Bool(cmd) { opts = append(opts, fix.Simplify()) @@ -62,6 +57,7 @@ func runFixAll(cmd *Command, args []string) error { if len(args) == 0 { args = []string{"./..."} + dir := rootWorkingDir for { if _, err := os.Stat(filepath.Join(dir, "cue.mod")); err == nil { args = appendDirs(args, filepath.Join(dir, "cue.mod", "gen")) diff --git a/cmd/cue/cmd/fmt.go b/cmd/cue/cmd/fmt.go index a70c240e317..b083e8ac5e3 100644 --- a/cmd/cue/cmd/fmt.go +++ b/cmd/cue/cmd/fmt.go @@ -49,7 +49,6 @@ Directories named "cue.mod" and those beginning with "." and "_" are skipped unl given as explicit arguments. `, RunE: mkRunE(c, func(cmd *Command, args []string) error { - cwd, _ := os.Getwd() check := flagCheck.Bool(cmd) doDiff := flagDiff.Bool(cmd) @@ -86,7 +85,7 @@ given as explicit arguments. continue } - wasModified, err := formatFile(file, formatOpts, cwd, doDiff, check, cmd) + wasModified, err := formatFile(file, formatOpts, doDiff, check, cmd) if err != nil { return err } @@ -121,7 +120,7 @@ given as explicit arguments. file.Source = contents } - wasModified, err := formatFile(file, formatOpts, cwd, doDiff, check, cmd) + wasModified, err := formatFile(file, formatOpts, doDiff, check, cmd) if err != nil { return err } @@ -182,7 +181,7 @@ given as explicit arguments. // formatFile formats a single file. // It returns true if the file was not well formatted. -func formatFile(file *build.File, opts []format.Option, cwd string, doDiff, check bool, cmd *Command) (bool, error) { +func formatFile(file *build.File, opts []format.Option, doDiff, check bool, cmd *Command) (bool, error) { // We buffer the input and output bytes to compare them. // This allows us to determine whether a file is already // formatted, without modifying the file. @@ -216,7 +215,7 @@ func formatFile(file *build.File, opts []format.Option, cwd string, doDiff, chec return false, nil } - path, err := filepath.Rel(cwd, file.Filename) + path, err := filepath.Rel(rootWorkingDir, file.Filename) if err != nil { path = file.Filename } diff --git a/cmd/cue/cmd/modget.go b/cmd/cue/cmd/modget.go index e82df25c3cf..347e6f857f6 100644 --- a/cmd/cue/cmd/modget.go +++ b/cmd/cue/cmd/modget.go @@ -107,10 +107,7 @@ func runModGet(cmd *Command, args []string) error { func findModuleRoot() (string, error) { // TODO this logic is duplicated in multiple places. We should // consider deduplicating it. - dir, err := os.Getwd() - if err != nil { - return "", err - } + dir := rootWorkingDir for { if _, err := os.Stat(filepath.Join(dir, "cue.mod")); err == nil { return dir, nil diff --git a/cmd/cue/cmd/modinit.go b/cmd/cue/cmd/modinit.go index 55096022f00..30a6d20ec97 100644 --- a/cmd/cue/cmd/modinit.go +++ b/cmd/cue/cmd/modinit.go @@ -71,12 +71,7 @@ func runModInit(cmd *Command, args []string) (err error) { } } - cwd, err := os.Getwd() - if err != nil { - return err - } - - mod := filepath.Join(cwd, "cue.mod") + mod := filepath.Join(rootWorkingDir, "cue.mod") if info, err := os.Stat(mod); err == nil { if !info.IsDir() { return fmt.Errorf("cue.mod files are no longer supported; use cue.mod/module.cue") diff --git a/cmd/cue/cmd/root.go b/cmd/cue/cmd/root.go index 104bdb708e9..33c1e907e8b 100644 --- a/cmd/cue/cmd/root.go +++ b/cmd/cue/cmd/root.go @@ -267,14 +267,25 @@ For more information on writing CUE configuration files see cuelang.org.`, var rootContextOptions []cuecontext.Option +// rootWorkingDir avoids repeated calls to [os.Getwd] in cmd/cue. +// If we can't figure out the current directory, something is very wrong, +// and there's no point in continuing to run a command. +var rootWorkingDir = func() string { + wd, err := os.Getwd() + if err != nil { + fmt.Fprintf(os.Stderr, "cannot get current directory: %v\n", err) + os.Exit(1) + } + return wd +}() + // Main runs the cue tool and returns the code for passing to os.Exit. func Main() int { cmd, _ := New(os.Args[1:]) if err := cmd.Run(backgroundContext()); err != nil { if err != ErrPrintedError { - cwd, _ := os.Getwd() errors.Print(os.Stderr, err, &errors.Config{ - Cwd: cwd, + Cwd: rootWorkingDir, ToSlash: testing.Testing(), }) } @@ -350,12 +361,9 @@ func printError(cmd *Command, err error) { format := func(w io.Writer, format string, args ...interface{}) { p.Fprintf(w, format, args...) } - - // TODO(mvdan): call os.Getwd only once at the start of the process. - cwd, _ := os.Getwd() errors.Print(cmd.Stderr(), err, &errors.Config{ Format: format, - Cwd: cwd, + Cwd: rootWorkingDir, ToSlash: testing.Testing(), }) }