ensureStateIsUpToDate ensures the Devbox project state is up to date. Namely: 1. Packages are installed, in nix-profile or runx. Extraneous packages are removed (references purged, not uninstalled). 2. Plugins are installed 3. Files for devbox shellenv are generated 4. The Devbox environment is re-c
(ctx context.Context, mode installMode)
| 299 | // 1. Skipping certain operations that may not apply. |
| 300 | // 2. User messaging to explain what operations are happening, because this function may take time to execute. |
| 301 | func (d *Devbox) ensureStateIsUpToDate(ctx context.Context, mode installMode) error { |
| 302 | defer trace.StartRegion(ctx, "devboxEnsureStateIsUpToDate").End() |
| 303 | defer debug.FunctionTimer().End() |
| 304 | |
| 305 | upToDate, err := d.lockfile.IsUpToDateAndInstalled(isFishShell()) |
| 306 | if err != nil { |
| 307 | return err |
| 308 | } |
| 309 | |
| 310 | // if mode is install or uninstall, then we need to compute some state |
| 311 | // like updating the flake or installing packages locally, so must continue |
| 312 | // below |
| 313 | if mode == ensure { |
| 314 | // if mode is ensure and we are up to date, then we can skip the rest |
| 315 | if upToDate { |
| 316 | return nil |
| 317 | } |
| 318 | ux.Finfof(d.stderr, "Ensuring packages are installed.\n") |
| 319 | } |
| 320 | |
| 321 | if mode != ensure { |
| 322 | // Reload includes because added/removed packages might change plugins. Cases: |
| 323 | // * New package adds built-in plugin. We wanna make sure the plugin is in config. |
| 324 | // * Remove built-in plugin that installs multiple packages (e.g. nginx). We wanna clear them |
| 325 | // up so they get removed from lockfile in updateLockfile |
| 326 | if err = d.cfg.LoadRecursive(d.lockfile); err != nil { |
| 327 | return err |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | if mode == install || mode == update || mode == ensure { |
| 332 | if err := d.installPackages(ctx, mode); err != nil { |
| 333 | return err |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | recomputeState := mode == ensure || d.IsEnvEnabled() |
| 338 | if recomputeState { |
| 339 | if err := d.recomputeState(ctx); err != nil { |
| 340 | return err |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | // If we're in a devbox shell (global or project), then the environment might |
| 345 | // be out of date after the user installs something. If have direnv active |
| 346 | // it should reload automatically so we don't need to refresh. |
| 347 | if d.IsEnvEnabled() && !upToDate && !d.IsDirenvActive() { |
| 348 | ux.FHidableWarning( |
| 349 | ctx, |
| 350 | d.stderr, |
| 351 | StateOutOfDateMessage, |
| 352 | d.RefreshAliasOrCommand(), |
| 353 | ) |
| 354 | } |
| 355 | |
| 356 | return d.updateLockfile(recomputeState) |
| 357 | } |
| 358 |
no test coverage detected