Skip to content

Commit be9f114

Browse files
committed
[Devbox] introduce devopt.EnvOptions
1 parent 8b2b47b commit be9f114

File tree

7 files changed

+80
-60
lines changed

7 files changed

+80
-60
lines changed

internal/boxcli/run.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ func listScripts(cmd *cobra.Command, flags runCmdFlags) []string {
7373
Dir: flags.config.path,
7474
Environment: flags.config.environment,
7575
Stderr: cmd.ErrOrStderr(),
76-
Pure: flags.pure,
7776
IgnoreWarnings: true,
7877
})
7978
if err != nil {
@@ -114,15 +113,17 @@ func runScriptCmd(cmd *cobra.Command, args []string, flags runCmdFlags) error {
114113
Dir: path,
115114
Environment: flags.config.environment,
116115
Stderr: cmd.ErrOrStderr(),
117-
OmitNixEnv: flags.omitNixEnv,
118-
Pure: flags.pure,
119116
Env: env,
120117
})
121118
if err != nil {
122119
return redact.Errorf("error reading devbox.json: %w", err)
123120
}
124121

125-
if err := box.RunScript(cmd.Context(), script, scriptArgs); err != nil {
122+
envOpts := devopt.EnvOptions{
123+
OmitNixEnv: flags.omitNixEnv,
124+
Pure: flags.pure,
125+
}
126+
if err := box.RunScript(cmd.Context(), envOpts, script, scriptArgs); err != nil {
126127
return redact.Errorf("error running script %q in Devbox: %w", script, err)
127128
}
128129
return nil

internal/boxcli/shell.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ func runShellCmd(cmd *cobra.Command, flags shellCmdFlags) error {
6969
Dir: flags.config.path,
7070
Env: env,
7171
Environment: flags.config.environment,
72-
OmitNixEnv: flags.omitNixEnv,
73-
Pure: flags.pure,
7472
Stderr: cmd.ErrOrStderr(),
7573
})
7674
if err != nil {
@@ -93,7 +91,10 @@ func runShellCmd(cmd *cobra.Command, flags shellCmdFlags) error {
9391
return shellInceptionErrorMsg("devbox shell")
9492
}
9593

96-
return box.Shell(cmd.Context())
94+
return box.Shell(cmd.Context(), devopt.EnvOptions{
95+
OmitNixEnv: flags.omitNixEnv,
96+
Pure: flags.pure,
97+
})
9798
}
9899

99100
func shellInceptionErrorMsg(cmdPath string) error {

internal/boxcli/shellenv.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ type shellenvFlagDefaults struct {
3333
}
3434

3535
func shellEnvCmd(defaults shellenvFlagDefaults) *cobra.Command {
36-
3736
flags := shellEnvCmdFlags{}
3837
command := &cobra.Command{
3938
Use: "shellenv",
@@ -96,13 +95,10 @@ func shellEnvFunc(
9695
return "", err
9796
}
9897
box, err := devbox.Open(&devopt.Opts{
99-
Dir: flags.config.path,
100-
Environment: flags.config.environment,
101-
OmitNixEnv: flags.omitNixEnv,
102-
Stderr: cmd.ErrOrStderr(),
103-
PreservePathStack: flags.preservePathStack,
104-
Pure: flags.pure,
105-
Env: env,
98+
Dir: flags.config.path,
99+
Environment: flags.config.environment,
100+
Stderr: cmd.ErrOrStderr(),
101+
Env: env,
106102
})
107103
if err != nil {
108104
return "", err
@@ -116,8 +112,13 @@ func shellEnvFunc(
116112

117113
envStr, err := box.EnvExports(cmd.Context(), devopt.EnvExportsOpts{
118114
DontRecomputeEnvironment: !flags.recomputeEnv,
119-
NoRefreshAlias: flags.noRefreshAlias,
120-
RunHooks: flags.runInitHook,
115+
EnvOptions: devopt.EnvOptions{
116+
OmitNixEnv: flags.omitNixEnv,
117+
PreservePathStack: flags.preservePathStack,
118+
Pure: flags.pure,
119+
},
120+
NoRefreshAlias: flags.noRefreshAlias,
121+
RunHooks: flags.runInitHook,
121122
})
122123
if err != nil {
123124
return "", err

internal/devbox/devbox.go

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,11 @@ const (
5959
type Devbox struct {
6060
cfg *devconfig.Config
6161
env map[string]string
62-
envForPackageBins bool
6362
environment string
6463
lockfile *lock.File
6564
nix nix.Nixer
6665
projectDir string
6766
pluginManager *plugin.Manager
68-
preservePathStack bool
69-
pure bool
7067
customProcessComposeFile string
7168

7269
// This is needed because of the --quiet flag.
@@ -98,14 +95,11 @@ func Open(opts *devopt.Opts) (*Devbox, error) {
9895
box := &Devbox{
9996
cfg: cfg,
10097
env: opts.Env,
101-
envForPackageBins: opts.OmitNixEnv,
10298
environment: environment,
10399
nix: &nix.Nix{},
104100
projectDir: projectDir,
105101
pluginManager: plugin.NewManager(),
106102
stderr: opts.Stderr,
107-
preservePathStack: opts.PreservePathStack,
108-
pure: opts.Pure,
109103
customProcessComposeFile: opts.CustomProcessComposeFile,
110104
}
111105

@@ -200,11 +194,11 @@ func (d *Devbox) Generate(ctx context.Context) error {
200194
return errors.WithStack(shellgen.GenerateForPrintEnv(ctx, d))
201195
}
202196

203-
func (d *Devbox) Shell(ctx context.Context) error {
197+
func (d *Devbox) Shell(ctx context.Context, envOpts devopt.EnvOptions) error {
204198
ctx, task := trace.NewTask(ctx, "devboxShell")
205199
defer task.End()
206200

207-
envs, err := d.ensureStateIsUpToDateAndComputeEnv(ctx)
201+
envs, err := d.ensureStateIsUpToDateAndComputeEnv(ctx, envOpts)
208202
if err != nil {
209203
return err
210204
}
@@ -228,15 +222,22 @@ func (d *Devbox) Shell(ctx context.Context) error {
228222
WithShellStartTime(telemetry.ShellStart()),
229223
}
230224

231-
shell, err := NewDevboxShell(d, opts...)
225+
shell, err := NewDevboxShell(d, envOpts, opts...)
232226
if err != nil {
233227
return err
234228
}
235229

236230
return shell.Run()
237231
}
238232

239-
func (d *Devbox) RunScript(ctx context.Context, cmdName string, cmdArgs []string) error {
233+
// runDevboxServicesScript invokes RunScript with the envOptions set to the appropriate
234+
// defaults for the `devbox services` scenario.
235+
// TODO: move to services.go
236+
func (d *Devbox) runDevboxServicesScript(ctx context.Context, cmdArgs []string) error {
237+
return d.RunScript(ctx, devopt.EnvOptions{}, "devbox", cmdArgs)
238+
}
239+
240+
func (d *Devbox) RunScript(ctx context.Context, envOpts devopt.EnvOptions, cmdName string, cmdArgs []string) error {
240241
ctx, task := trace.NewTask(ctx, "devboxRun")
241242
defer task.End()
242243

@@ -245,7 +246,7 @@ func (d *Devbox) RunScript(ctx context.Context, cmdName string, cmdArgs []string
245246
}
246247

247248
lock.SetIgnoreShellMismatch(true)
248-
env, err := d.ensureStateIsUpToDateAndComputeEnv(ctx)
249+
env, err := d.ensureStateIsUpToDateAndComputeEnv(ctx, envOpts)
249250
if err != nil {
250251
return err
251252
}
@@ -329,9 +330,9 @@ func (d *Devbox) EnvExports(ctx context.Context, opts devopt.EnvExportsOpts) (st
329330
)
330331
}
331332

332-
envs, err = d.computeEnv(ctx, true /*usePrintDevEnvCache*/)
333+
envs, err = d.computeEnv(ctx, true /*usePrintDevEnvCache*/, opts.EnvOptions)
333334
} else {
334-
envs, err = d.ensureStateIsUpToDateAndComputeEnv(ctx)
335+
envs, err = d.ensureStateIsUpToDateAndComputeEnv(ctx, opts.EnvOptions)
335336
}
336337

337338
if err != nil {
@@ -356,7 +357,7 @@ func (d *Devbox) EnvVars(ctx context.Context) ([]string, error) {
356357
ctx, task := trace.NewTask(ctx, "devboxEnvVars")
357358
defer task.End()
358359
// this only returns env variables for the shell environment excluding hooks
359-
envs, err := d.ensureStateIsUpToDateAndComputeEnv(ctx)
360+
envs, err := d.ensureStateIsUpToDateAndComputeEnv(ctx, devopt.EnvOptions{})
360361
if err != nil {
361362
return nil, err
362363
}
@@ -566,11 +567,12 @@ func (d *Devbox) Services() (services.Services, error) {
566567
return result, nil
567568
}
568569

570+
// TODO: move to services.go
569571
func (d *Devbox) StartServices(
570572
ctx context.Context, runInCurrentShell bool, serviceNames ...string,
571573
) error {
572574
if !runInCurrentShell {
573-
return d.RunScript(ctx, "devbox",
575+
return d.runDevboxServicesScript(ctx,
574576
append(
575577
[]string{"services", "start", "--run-in-current-shell"},
576578
serviceNames...,
@@ -610,14 +612,15 @@ func (d *Devbox) StartServices(
610612
return nil
611613
}
612614

615+
// TODO: move to services.go
613616
func (d *Devbox) StopServices(ctx context.Context, runInCurrentShell, allProjects bool, serviceNames ...string) error {
614617
if !runInCurrentShell {
615618
args := []string{"services", "stop", "--run-in-current-shell"}
616619
args = append(args, serviceNames...)
617620
if allProjects {
618621
args = append(args, "--all-projects")
619622
}
620-
return d.RunScript(ctx, "devbox", args)
623+
return d.runDevboxServicesScript(ctx, args)
621624
}
622625

623626
if allProjects {
@@ -649,10 +652,10 @@ func (d *Devbox) StopServices(ctx context.Context, runInCurrentShell, allProject
649652
return nil
650653
}
651654

655+
// TODO: move to services.go
652656
func (d *Devbox) ListServices(ctx context.Context, runInCurrentShell bool) error {
653657
if !runInCurrentShell {
654-
return d.RunScript(ctx,
655-
"devbox", []string{"services", "ls", "--run-in-current-shell"})
658+
return d.runDevboxServicesScript(ctx, []string{"services", "ls", "--run-in-current-shell"})
656659
}
657660

658661
svcSet, err := d.Services()
@@ -688,11 +691,12 @@ func (d *Devbox) ListServices(ctx context.Context, runInCurrentShell bool) error
688691
return nil
689692
}
690693

694+
// TODO: move to services.go
691695
func (d *Devbox) RestartServices(
692696
ctx context.Context, runInCurrentShell bool, serviceNames ...string,
693697
) error {
694698
if !runInCurrentShell {
695-
return d.RunScript(ctx, "devbox",
699+
return d.runDevboxServicesScript(ctx,
696700
append(
697701
[]string{"services", "restart", "--run-in-current-shell"},
698702
serviceNames...,
@@ -727,6 +731,7 @@ func (d *Devbox) RestartServices(
727731
return nil
728732
}
729733

734+
// TODO: move to services.go
730735
func (d *Devbox) StartProcessManager(
731736
ctx context.Context,
732737
runInCurrentShell bool,
@@ -750,7 +755,7 @@ func (d *Devbox) StartProcessManager(
750755
args = append(args, "--pcflags", flag)
751756
}
752757

753-
return d.RunScript(ctx, "devbox", args)
758+
return d.runDevboxServicesScript(ctx, args)
754759
}
755760

756761
svcs, err := d.Services()
@@ -874,13 +879,17 @@ func (d *Devbox) execPrintDevEnv(ctx context.Context, usePrintDevEnvCache bool)
874879
// Note that the shellrc.tmpl template (which sources this environment) does
875880
// some additional processing. The computeEnv environment won't necessarily
876881
// represent the final "devbox run" or "devbox shell" environments.
877-
func (d *Devbox) computeEnv(ctx context.Context, usePrintDevEnvCache bool) (map[string]string, error) {
882+
func (d *Devbox) computeEnv(
883+
ctx context.Context,
884+
usePrintDevEnvCache bool,
885+
envOpts devopt.EnvOptions,
886+
) (map[string]string, error) {
878887
defer debug.FunctionTimer().End()
879888
defer trace.StartRegion(ctx, "devboxComputeEnv").End()
880889

881890
// Append variables from current env if --pure is not passed
882891
currentEnv := os.Environ()
883-
env, err := d.parseEnvAndExcludeSpecialCases(currentEnv)
892+
env, err := d.parseEnvAndExcludeSpecialCases(currentEnv, envOpts.Pure)
884893
if err != nil {
885894
return nil, err
886895
}
@@ -900,7 +909,7 @@ func (d *Devbox) computeEnv(ctx context.Context, usePrintDevEnvCache bool) (map[
900909

901910
// TODO: look up callers of computeEnv to ensure we properly cache print-dev-env
902911
// when needed in the product flows
903-
if !d.envForPackageBins {
912+
if !envOpts.OmitNixEnv {
904913
nixEnv, err := d.execPrintDevEnv(ctx, usePrintDevEnvCache)
905914
if err != nil {
906915
return nil, err
@@ -979,13 +988,13 @@ func (d *Devbox) computeEnv(ctx context.Context, usePrintDevEnvCache bool) (map[
979988
devboxEnvPath = envpath.JoinPathLists(devboxEnvPath, runXPaths)
980989

981990
pathStack := envpath.Stack(env, originalEnv)
982-
pathStack.Push(env, d.ProjectDirHash(), devboxEnvPath, d.preservePathStack)
991+
pathStack.Push(env, d.ProjectDirHash(), devboxEnvPath, envOpts.PreservePathStack)
983992
env["PATH"] = pathStack.Path(env)
984993
slog.Debug("new path stack is", "path_stack", pathStack)
985994

986995
slog.Debug("computed environment PATH", "path", env["PATH"])
987996

988-
if !d.pure {
997+
if !envOpts.Pure {
989998
// preserve the original XDG_DATA_DIRS by prepending to it
990999
env["XDG_DATA_DIRS"] = envpath.JoinPathLists(env["XDG_DATA_DIRS"], os.Getenv("XDG_DATA_DIRS"))
9911000
}
@@ -1001,6 +1010,7 @@ func (d *Devbox) computeEnv(ctx context.Context, usePrintDevEnvCache bool) (map[
10011010
// while ensuring these reflect the current (up to date) state of the project.
10021011
func (d *Devbox) ensureStateIsUpToDateAndComputeEnv(
10031012
ctx context.Context,
1013+
envOpts devopt.EnvOptions,
10041014
) (map[string]string, error) {
10051015
defer debug.FunctionTimer().End()
10061016

@@ -1027,7 +1037,7 @@ func (d *Devbox) ensureStateIsUpToDateAndComputeEnv(
10271037
// it's ok to use usePrintDevEnvCache=true here always. This does end up
10281038
// doing some non-nix work twice if lockfile is not up to date.
10291039
// TODO: Improve this to avoid extra work.
1030-
return d.computeEnv(ctx, true /*usePrintDevEnvCache*/)
1040+
return d.computeEnv(ctx, true /*usePrintDevEnvCache*/, envOpts)
10311041
}
10321042

10331043
func (d *Devbox) nixPrintDevEnvCachePath() string {
@@ -1246,7 +1256,7 @@ func (d *Devbox) addHashToEnv(env map[string]string) error {
12461256

12471257
// parseEnvAndExcludeSpecialCases converts env as []string to map[string]string
12481258
// In case of pure shell, it leaks HOME and it leaks PATH with some modifications
1249-
func (d *Devbox) parseEnvAndExcludeSpecialCases(currentEnv []string) (map[string]string, error) {
1259+
func (d *Devbox) parseEnvAndExcludeSpecialCases(currentEnv []string, pure bool) (map[string]string, error) {
12501260
env := make(map[string]string, len(currentEnv))
12511261
for _, kv := range currentEnv {
12521262
key, val, found := strings.Cut(kv, "=")
@@ -1260,13 +1270,13 @@ func (d *Devbox) parseEnvAndExcludeSpecialCases(currentEnv []string) (map[string
12601270
// - HOME required for devbox binary to work
12611271
// - PATH to find the nix installation. It is cleaned for pure mode below.
12621272
// - TERM to enable colored text in the pure shell
1263-
if !d.pure || key == "HOME" || key == "PATH" || key == "TERM" {
1273+
if !pure || key == "HOME" || key == "PATH" || key == "TERM" {
12641274
env[key] = val
12651275
}
12661276
}
12671277

12681278
// handling special case for PATH
1269-
if d.pure {
1279+
if pure {
12701280
// Setting a custom env variable to differentiate pure and regular shell
12711281
env["DEVBOX_PURE_SHELL"] = "1"
12721282
// Finding nix executables in path and passing it through

0 commit comments

Comments
 (0)