@@ -255,13 +255,12 @@ func (d *Devbox) ensureStateIsUpToDate(ctx context.Context, mode installMode) er
255
255
defer trace .StartRegion (ctx , "devboxEnsureStateIsUpToDate" ).End ()
256
256
defer debug .FunctionTimer ().End ()
257
257
258
- // if mode is install or uninstall, then we need to update the nix-profile
259
- // and lockfile, so we must continue below.
260
258
upToDate , err := d .lockfile .IsUpToDateAndInstalled ()
261
259
if err != nil {
262
260
return err
263
261
}
264
-
262
+ // if mode is install or uninstall, then we need to update the nix-profile
263
+ // and lockfile, so we must continue below.
265
264
if mode == ensure {
266
265
// if mode is ensure and we are up to date, then we can skip the rest
267
266
if upToDate {
@@ -270,6 +269,47 @@ func (d *Devbox) ensureStateIsUpToDate(ctx context.Context, mode installMode) er
270
269
fmt .Fprintln (d .stderr , "Ensuring packages are installed." )
271
270
}
272
271
272
+ recomputeState := mode == ensure || d .IsEnvEnabled ()
273
+ if recomputeState {
274
+ if err := d .recomputeState (ctx , mode ); err != nil {
275
+ return err
276
+ }
277
+ } else {
278
+ // TODO: in the next PR, we will only `nix build` the packages that are being
279
+ // added or updated. For now, we continue to call recomputeState here.
280
+ if err := d .recomputeState (ctx , mode ); err != nil {
281
+ return err
282
+ }
283
+ }
284
+
285
+ // If we're in a devbox shell (global or project), then the environment might
286
+ // be out of date after the user installs something. If have direnv active
287
+ // it should reload automatically so we don't need to refresh.
288
+ if d .IsEnvEnabled () && ! upToDate && ! d .IsDirenvActive () {
289
+ ux .Fwarning (
290
+ d .stderr ,
291
+ "Your shell environment may be out of date. Run `%s` to update it.\n " ,
292
+ d .refreshAliasOrCommand (),
293
+ )
294
+ }
295
+
296
+ if recomputeState {
297
+ if err := d .lockfile .Save (); err != nil {
298
+ return err
299
+ }
300
+ return d .lockfile .UpdateAndSaveLocalLock ()
301
+ }
302
+ // if we are not recomputing state, then we are only updating the lockfile
303
+ // and we do not update the local.lock file
304
+ return d .lockfile .Save ()
305
+ }
306
+
307
+ // recomputeState updates the local state comprising of:
308
+ // - plugins directories
309
+ // - devbox.lock file
310
+ // - the generated flake
311
+ // - the nix-profile
312
+ func (d * Devbox ) recomputeState (ctx context.Context , mode installMode ) error {
273
313
// Create plugin directories first because packages might need them
274
314
for _ , pkg := range d .InstallablePackages () {
275
315
if err := d .PluginManager ().Create (pkg ); err != nil {
@@ -310,18 +350,7 @@ func (d *Devbox) ensureStateIsUpToDate(ctx context.Context, mode installMode) er
310
350
}
311
351
}
312
352
313
- // If we're in a devbox shell (global or project), then the environment might
314
- // be out of date after the user installs something. If have direnv active
315
- // it should reload automatically so we don't need to refresh.
316
- if d .IsEnvEnabled () && ! upToDate && ! d .IsDirenvActive () {
317
- ux .Fwarning (
318
- d .stderr ,
319
- "Your shell environment may be out of date. Run `%s` to update it.\n " ,
320
- d .refreshAliasOrCommand (),
321
- )
322
- }
323
-
324
- return d .lockfile .Save ()
353
+ return nil
325
354
}
326
355
327
356
func (d * Devbox ) profilePath () (string , error ) {
0 commit comments