diff --git a/internal/boxcli/config.go b/internal/boxcli/config.go index 6565444c274..07be1a3693f 100644 --- a/internal/boxcli/config.go +++ b/internal/boxcli/config.go @@ -4,7 +4,11 @@ package boxcli import ( + "os" + "github.com/spf13/cobra" + + "go.jetify.com/devbox/internal/envir" ) // to be composed into xyzCmdFlags structs @@ -34,12 +38,15 @@ type pathFlag struct { func (flags *pathFlag) register(cmd *cobra.Command) { cmd.Flags().StringVarP( - &flags.path, "config", "c", "", "path to directory containing a devbox.json config file", + &flags.path, "config", "c", os.Getenv(envir.DevboxConfig), pathFlagUsage, ) } func (flags *pathFlag) registerPersistent(cmd *cobra.Command) { cmd.PersistentFlags().StringVarP( - &flags.path, "config", "c", "", "path to directory containing a devbox.json config file", + &flags.path, "config", "c", os.Getenv(envir.DevboxConfig), pathFlagUsage, ) } + +const pathFlagUsage = "path to directory containing a devbox.json config file " + + "(defaults to the " + envir.DevboxConfig + " env var, if set)" diff --git a/internal/boxcli/config_test.go b/internal/boxcli/config_test.go new file mode 100644 index 00000000000..11c5af08c06 --- /dev/null +++ b/internal/boxcli/config_test.go @@ -0,0 +1,67 @@ +// Copyright 2024 Jetify Inc. and contributors. All rights reserved. +// Use of this source code is governed by the license in the LICENSE file. + +package boxcli + +import ( + "testing" + + "github.com/spf13/cobra" + + "go.jetify.com/devbox/internal/envir" +) + +// TestConfigFlagDefaultsToEnv verifies that the --config flag defaults to the +// DEVBOX_CONFIG environment variable when the flag is not passed, and that an +// explicit flag value still takes precedence. +func TestConfigFlagDefaultsToEnv(t *testing.T) { + tests := []struct { + name string + envVal string // empty means unset + args []string + want string + }{ + { + name: "unset env and no flag yields empty path", + want: "", + }, + { + name: "env var sets the default config path", + envVal: "/path/from/env", + want: "/path/from/env", + }, + { + name: "explicit flag overrides env var", + envVal: "/path/from/env", + args: []string{"--config", "/path/from/flag"}, + want: "/path/from/flag", + }, + { + name: "explicit flag without env var", + args: []string{"-c", "/path/from/flag"}, + want: "/path/from/flag", + }, + } + + for _, testCase := range tests { + t.Run(testCase.name, func(t *testing.T) { + if testCase.envVal != "" { + t.Setenv(envir.DevboxConfig, testCase.envVal) + } else { + t.Setenv(envir.DevboxConfig, "") + } + + flags := &pathFlag{} + cmd := &cobra.Command{Use: "test", RunE: func(*cobra.Command, []string) error { return nil }} + flags.register(cmd) + cmd.SetArgs(testCase.args) + if err := cmd.Execute(); err != nil { + t.Fatal(err) + } + + if flags.path != testCase.want { + t.Errorf("flags.path = %q, want %q", flags.path, testCase.want) + } + }) + } +} diff --git a/internal/envir/env.go b/internal/envir/env.go index 5cf0c37fe5f..403daa3b12f 100644 --- a/internal/envir/env.go +++ b/internal/envir/env.go @@ -4,7 +4,12 @@ package envir const ( - DevboxCache = "DEVBOX_CACHE" + DevboxCache = "DEVBOX_CACHE" + // DevboxConfig sets the default value for the --config flag, i.e. the path + // to the directory (or devbox.json file) of the devbox project to use. This + // is convenient for setting the config path in environments where passing + // the flag is awkward, such as a Dockerfile. + DevboxConfig = "DEVBOX_CONFIG" DevboxGateway = "DEVBOX_GATEWAY" // DevboxLatestVersion is the latest version available of the devbox CLI binary. // NOTE: it should NOT start with v (like 0.4.8)