Skip to content

Skip already-installed packages (verify-first fast path) to speed up subsequent setup runs #54

Description

@ulises-c

Problem

Re-running setup.sh after a package set has mostly been installed still walks
through every selected package and asks its manager to install it. Even when the
manager is a no-op for already-present packages (e.g. brew install on an
installed formula), the per-package invocation overhead adds up and makes
subsequent runs slow — especially noticeable when adding just one or two new
packages to an existing machine.

Idea

verify.sh already knows how to probe whether each selected package is present,
using the same selection logic as setup.sh. We could leverage that to skip the
install step for packages that are already installed, so that adding new packages
to an already-provisioned machine only does work for the genuinely-missing ones.

Rough shape:

  • Run the verify probes first (or fold the probe into the install loop) to build
    a "what's already installed" set.
  • In setup.sh's install loop, skip packages that the probe reports as present,
    installing only the missing ones.
  • Keep this opt-in or fast-path-only so a full clean install is unaffected, and
    so --dry-run semantics (print every command) still hold.

Open questions

  • Probe cost vs. install cost: is probing every package actually cheaper than
    letting the manager no-op? Probably yes for slow managers (cask, app-store,
    pipx, custom install_commands) but maybe not for fast ones — may want this
    scoped per manager.
  • macOS probe asymmetry: lib/verify.sh has no command -v fallback for casks,
    pipx, or app-store (platform-faithful per UNIFICATION.md), so a skip
    decision must not rely on probes that can't actually confirm presence.
  • Where to share code so setup.sh and verify.sh don't drift — the probe
    logic lives in lib/verify.sh today.

Goal

Faster subsequent setup.sh runs when adding new packages to a machine that's
already mostly provisioned, without changing clean-install or --dry-run
behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions