diff --git a/devbox.json b/devbox.json index 48f4240cbb0..0253af59b7f 100644 --- a/devbox.json +++ b/devbox.json @@ -5,6 +5,8 @@ "go": "latest", "runx:golangci/golangci-lint": "latest", "runx:mvdan/gofumpt": "latest", + + "hello": "latest", }, "env": { "GOENV": "off", diff --git a/devbox.lock b/devbox.lock index 6237e47e5f3..86908fc1282 100644 --- a/devbox.lock +++ b/devbox.lock @@ -49,6 +49,54 @@ } } }, + "hello@latest": { + "last_modified": "2024-10-13T23:44:06Z", + "resolved": "github:NixOS/nixpkgs/d4f247e89f6e10120f911e2e2d2254a050d0f732#hello", + "source": "devbox-search", + "version": "2.12.1", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8fpvkfwr8fm91xlzznsgh3g1fcw0hfnh-hello-2.12.1", + "default": true + } + ], + "store_path": "/nix/store/8fpvkfwr8fm91xlzznsgh3g1fcw0hfnh-hello-2.12.1" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/9i2ay9whhyswa2cc30azxiyqrjb795xj-hello-2.12.1", + "default": true + } + ], + "store_path": "/nix/store/9i2ay9whhyswa2cc30azxiyqrjb795xj-hello-2.12.1" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/h6lx6hmccksq64nsa4h3c8p9gl1vzqcf-hello-2.12.1", + "default": true + } + ], + "store_path": "/nix/store/h6lx6hmccksq64nsa4h3c8p9gl1vzqcf-hello-2.12.1" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/26xbg1ndr7hbcncrlf9nhx5is2b25d13-hello-2.12.1", + "default": true + } + ], + "store_path": "/nix/store/26xbg1ndr7hbcncrlf9nhx5is2b25d13-hello-2.12.1" + } + } + }, "runx:golangci/golangci-lint@latest": { "resolved": "golangci/golangci-lint@v1.60.2", "version": "v1.60.2" diff --git a/internal/boxcli/run.go b/internal/boxcli/run.go index 123288b5039..2372142304e 100644 --- a/internal/boxcli/run.go +++ b/internal/boxcli/run.go @@ -17,6 +17,7 @@ import ( "go.jetpack.io/devbox/internal/devbox" "go.jetpack.io/devbox/internal/devbox/devopt" "go.jetpack.io/devbox/internal/redact" + "go.jetpack.io/devbox/internal/ux" ) type runCmdFlags struct { @@ -122,13 +123,22 @@ func runScriptCmd(cmd *cobra.Command, args []string, flags runCmdFlags) error { return redact.Errorf("error reading devbox.json: %w", err) } + onStaleState := func() { + ux.FHidableWarning( + ctx, + cmd.ErrOrStderr(), + devbox.StateOutOfDateMessage, + "with --recompute=true", + ) + } + envOpts := devopt.EnvOptions{ - OmitNixEnv: flags.omitNixEnv, - Pure: flags.pure, - RecomputeEnv: &devopt.RecomputeEnvOpts{ - Disabled: !flags.recomputeEnv, - StateOutOfDateMessage: fmt.Sprintf(devbox.StateOutOfDateMessage, "with --recompute=true"), + Hooks: devopt.EnvLifecycleHooks{ + OnSkipRecomputeDespiteStaleState: onStaleState, }, + OmitNixEnv: flags.omitNixEnv, + Pure: flags.pure, + SkipRecomputeEnv: !flags.recomputeEnv, } if err := box.RunScript(ctx, envOpts, script, scriptArgs); err != nil { return redact.Errorf("error running script %q in Devbox: %w", script, err) diff --git a/internal/boxcli/shell.go b/internal/boxcli/shell.go index 60575549f9f..91f9ca9a362 100644 --- a/internal/boxcli/shell.go +++ b/internal/boxcli/shell.go @@ -13,6 +13,7 @@ import ( "go.jetpack.io/devbox/internal/devbox" "go.jetpack.io/devbox/internal/devbox/devopt" "go.jetpack.io/devbox/internal/envir" + "go.jetpack.io/devbox/internal/ux" ) type shellCmdFlags struct { @@ -95,13 +96,22 @@ func runShellCmd(cmd *cobra.Command, flags shellCmdFlags) error { return shellInceptionErrorMsg("devbox shell") } + onStaleState := func() { + ux.FHidableWarning( + ctx, + cmd.ErrOrStderr(), + devbox.StateOutOfDateMessage, + "with --recompute=true", + ) + } + return box.Shell(ctx, devopt.EnvOptions{ - OmitNixEnv: flags.omitNixEnv, - Pure: flags.pure, - RecomputeEnv: &devopt.RecomputeEnvOpts{ - Disabled: !flags.recomputeEnv, - StateOutOfDateMessage: fmt.Sprintf(devbox.StateOutOfDateMessage, "with --recompute=true"), + Hooks: devopt.EnvLifecycleHooks{ + OnSkipRecomputeDespiteStaleState: onStaleState, }, + OmitNixEnv: flags.omitNixEnv, + Pure: flags.pure, + SkipRecomputeEnv: !flags.recomputeEnv, }) } diff --git a/internal/boxcli/shellenv.go b/internal/boxcli/shellenv.go index a783e091306..7742a3fffed 100644 --- a/internal/boxcli/shellenv.go +++ b/internal/boxcli/shellenv.go @@ -115,15 +115,24 @@ func shellEnvFunc( } } + onStaleState := func() { + ux.FHidableWarning( + ctx, + cmd.ErrOrStderr(), + devbox.StateOutOfDateMessage, + "devbox install", + ) + } + envStr, err := box.EnvExports(ctx, devopt.EnvExportsOpts{ EnvOptions: devopt.EnvOptions{ + Hooks: devopt.EnvLifecycleHooks{ + OnSkipRecomputeDespiteStaleState: onStaleState, + }, OmitNixEnv: flags.omitNixEnv, PreservePathStack: flags.preservePathStack, Pure: flags.pure, - RecomputeEnv: &devopt.RecomputeEnvOpts{ - Disabled: !flags.recomputeEnv, - StateOutOfDateMessage: fmt.Sprintf(devbox.StateOutOfDateMessage, box.RefreshAliasOrCommand()), - }, + SkipRecomputeEnv: !flags.recomputeEnv, }, NoRefreshAlias: flags.noRefreshAlias, RunHooks: flags.runInitHook, diff --git a/internal/devbox/devbox.go b/internal/devbox/devbox.go index 2083e363ab0..5919a56f6e8 100644 --- a/internal/devbox/devbox.go +++ b/internal/devbox/devbox.go @@ -804,14 +804,12 @@ func (d *Devbox) ensureStateIsUpToDateAndComputeEnv( ) (map[string]string, error) { defer debug.FunctionTimer().End() - if envOpts.RecomputeEnv.Disabled { + if envOpts.SkipRecomputeEnv { upToDate, _ := d.lockfile.IsUpToDateAndInstalled(isFishShell()) if !upToDate { - ux.FHidableWarning( - ctx, - d.stderr, - envOpts.RecomputeEnv.StateOutOfDateMessage, //nolint:govet - ) + if envOpts.Hooks.OnSkipRecomputeDespiteStaleState != nil { + envOpts.Hooks.OnSkipRecomputeDespiteStaleState() + } } } else { // When ensureStateIsUpToDate is called with ensure=true, it always diff --git a/internal/devbox/devopt/devboxopts.go b/internal/devbox/devopt/devboxopts.go index 4ee64f9dd40..e7e7871b43e 100644 --- a/internal/devbox/devopt/devboxopts.go +++ b/internal/devbox/devopt/devboxopts.go @@ -72,13 +72,14 @@ type EnvExportsOpts struct { // like `shellenv`, `shell` and `run`. // - The struct is designed for the "common case" to be zero-initialized as `EnvOptions{}`. type EnvOptions struct { + Hooks EnvLifecycleHooks OmitNixEnv bool PreservePathStack bool Pure bool - RecomputeEnv *RecomputeEnvOpts + SkipRecomputeEnv bool } -type RecomputeEnvOpts struct { - Disabled bool // Disabled instead of Enabled, because zero-value is false - StateOutOfDateMessage string +type EnvLifecycleHooks struct { + // OnSkipRecomputeDespiteStaleState is called when the Devbox state is out of date, AND it is not being recomputed. + OnSkipRecomputeDespiteStaleState func() }