diff --git a/examples/development/go/hello-world/trace.out b/examples/development/go/hello-world/trace.out new file mode 100644 index 00000000000..508fa304ee2 Binary files /dev/null and b/examples/development/go/hello-world/trace.out differ diff --git a/internal/impl/devbox.go b/internal/impl/devbox.go index 7d0089d8e14..a4edbfa3293 100644 --- a/internal/impl/devbox.go +++ b/internal/impl/devbox.go @@ -1172,10 +1172,10 @@ func (d *Devbox) parseEnvAndExcludeSpecialCases(currentEnv []string) (map[string if ignoreCurrentEnvVar[key] { continue } - // handling special cases to for pure shell - // Passing HOME for pure shell to leak through otherwise devbox binary won't work - // We also include PATH to find the nix installation. It is cleaned for pure mode below - // TERM leaking through is to enable colored text in the pure shell + // handling special cases for pure shell + // - HOME required for devbox binary to work + // - PATH to find the nix installation. It is cleaned for pure mode below. + // - TERM to enable colored text in the pure shell if !d.pure || key == "HOME" || key == "PATH" || key == "TERM" { env[key] = val } diff --git a/internal/impl/envvars.go b/internal/impl/envvars.go index 488e9ad0508..2013a05ef1c 100644 --- a/internal/impl/envvars.go +++ b/internal/impl/envvars.go @@ -69,8 +69,8 @@ func markEnvsAsSetByDevbox(envs ...map[string]string) { } } -// IsEnvEnabled checks if the devbox environment is enabled. We use the ogPathKey -// as a proxy for this. This allows us to differentiate between global and +// IsEnvEnabled checks if the devbox environment is enabled. +// This allows us to differentiate between global and // individual project shells. func (d *Devbox) IsEnvEnabled() bool { fakeEnv := map[string]string{} diff --git a/internal/impl/packages.go b/internal/impl/packages.go index 9db082fea7d..2c204d85f83 100644 --- a/internal/impl/packages.go +++ b/internal/impl/packages.go @@ -203,14 +203,22 @@ type installMode string const ( install installMode = "install" uninstall installMode = "uninstall" - ensure installMode = "ensure" + // update is both install new package version and uninstall old package version + update installMode = "update" + ensure installMode = "ensure" ) -// ensurePackagesAreInstalled ensures that the nix profile has the packages specified -// in the config (devbox.json). The `mode` is used for user messaging to explain -// what operations are happening, because this function may take time to execute. -// TODO we should rename this to ensureDevboxEnvironmentIsUpToDate since it does -// much more than ensuring packages are installed. +// ensurePackagesAreInstalled ensures: +// 1. Packages are installed, in nix-profile or runx. +// Extraneous packages are removed (references purged, not uninstalled). +// 2. Files for devbox shellenv are generated +// 3. Env-vars for shellenv are computed +// 4. Lockfile is synced +// +// The `mode` is used for: +// 1. Skipping certain operations that may not apply. +// 2. User messaging to explain what operations are happening, because this function may take time to execute. +// TODO: Rename method since it does more than just ensure packages are installed. func (d *Devbox) ensurePackagesAreInstalled(ctx context.Context, mode installMode) error { defer trace.StartRegion(ctx, "ensurePackages").End() defer debug.FunctionTimer().End() @@ -248,8 +256,10 @@ func (d *Devbox) ensurePackagesAreInstalled(ctx context.Context, mode installMod return err } - // Force print-dev-env cache to be recomputed. - nixEnv, err := d.computeNixEnv(ctx, false /*use cache*/) + // Use the printDevEnvCache if we are adding or removing or updating any package, + // AND we are not in the shellenv-enabled environment of the current devbox-project. + usePrintDevEnvCache := mode != ensure && !d.IsEnvEnabled() + nixEnv, err := d.computeNixEnv(ctx, usePrintDevEnvCache) if err != nil { return err } @@ -291,8 +301,8 @@ func (d *Devbox) profilePath() (string, error) { return absPath, errors.WithStack(os.MkdirAll(filepath.Dir(absPath), 0o755)) } -// syncPackagesToProfile ensures that all packages in devbox.json exist in the nix profile, -// and no more. +// syncPackagesToProfile can ensure that all packages in devbox.json exist in the nix profile, +// and no more. However, it may skip some steps depending on the `mode`. func (d *Devbox) syncPackagesToProfile(ctx context.Context, mode installMode) error { defer debug.FunctionTimer().End() defer trace.StartRegion(ctx, "syncPackagesToProfile").End() @@ -320,9 +330,12 @@ func (d *Devbox) syncPackagesToProfile(ctx context.Context, mode installMode) er } // Second, remove any packages from the nix-profile that are not in the config - itemsToKeep, err := d.removeExtraItemsFromProfile(ctx, profileDir, profileItems, packages) - if err != nil { - return err + itemsToKeep := profileItems + if mode != install { + itemsToKeep, err = d.removeExtraItemsFromProfile(ctx, profileDir, profileItems, packages) + if err != nil { + return err + } } // we are done if mode is uninstall diff --git a/internal/impl/shell_test.go b/internal/impl/shell_test.go index 98255ef2b79..6813f4a443a 100644 --- a/internal/impl/shell_test.go +++ b/internal/impl/shell_test.go @@ -17,8 +17,8 @@ import ( "go.jetpack.io/devbox/internal/shellgen" ) -// update overwrites golden files with the new test results. -var update = flag.Bool("update", false, "update the golden files with the test results") +// updateFlag overwrites golden files with the new test results. +var updateFlag = flag.Bool("update", false, "update the golden files with the test results") func TestWriteDevboxShellrc(t *testing.T) { testdirs, err := filepath.Glob("testdata/shellrc/*") @@ -83,7 +83,7 @@ func testWriteDevboxShellrc(t *testing.T, testdirs []string) { // Overwrite the golden file if the -update flag was // set, and then proceed normally. The test should // always pass in this case. - if *update { + if *updateFlag { err = os.WriteFile(test.goldShellrcPath, gotShellrc, 0o666) if err != nil { t.Error("Error updating golden files:", err) diff --git a/internal/impl/update.go b/internal/impl/update.go index 9679059b7d8..69064e18f97 100644 --- a/internal/impl/update.go +++ b/internal/impl/update.go @@ -62,7 +62,7 @@ func (d *Devbox) Update(ctx context.Context, opts devopt.UpdateOpts) error { } } - if err := d.ensurePackagesAreInstalled(ctx, ensure); err != nil { + if err := d.ensurePackagesAreInstalled(ctx, update); err != nil { return err } diff --git a/trace.out b/trace.out new file mode 100644 index 00000000000..a3a65f653f9 Binary files /dev/null and b/trace.out differ