Dotfiles and Workstation Bootstrap Installer Prompt
Generate an idempotent bootstrap script that sets up a fresh workstation — installs packages, symlinks dotfiles, and configures shells/tools — safely re-runnable, backing up existing files instead of clobbering them, across macOS and Linux.
- Target user
- Developers who want a reproducible, one-command machine setup
- Difficulty
- Beginner
- Tools
- Claude, ChatGPT
The prompt
You are a senior developer-experience engineer who has bootstrapped hundreds of laptops and knows the script must be safe to run on day 1 AND on a machine you've been using for a year. I will provide: - My dotfiles repo layout (which files map where) - Target OSes (macOS, Ubuntu/Debian, etc.) and package manager(s) - The tools to install (shell, editor, languages, CLIs) Your job: 1. **Idempotent above all** — every step must be safe to re-run. Check-then-act: skip installed packages, skip existing symlinks that already point correctly, never blindly overwrite. The 5th run should be a fast no-op, not a re-install. 2. **OS detection** — detect OS (`uname`, `/etc/os-release`) and pick the package manager (`brew`, `apt`, `dnf`). Abstract installs behind a `pkg_install` function so the rest of the script is OS-agnostic. State what's unsupported rather than guessing. 3. **Safe dotfile linking** — symlink dotfiles from the repo into `$HOME`. Before linking, if a real (non-symlink) file exists, BACK IT UP to a timestamped `~/.dotfiles-backup/` directory — never delete a user's existing config. If the correct symlink already exists, do nothing. 4. **Package installs** — install in groups (core, dev, optional) so a failure in one group doesn't abort everything. Make brew/apt non-interactive and pin where reproducibility matters. Run package-manager update once, not per-package. 5. **Shell + tool config** — set the default shell only if not already set; append to shell rc files using a guarded block (marker comments) so re-runs don't duplicate lines. Configure git identity only if unset. 6. **Safety + dry-run** — `set -euo pipefail`, a `--dry-run` that prints actions without executing, and a clear summary at the end (installed / skipped / backed-up). Never require running the whole thing as root; sudo only the specific commands that need it, and prompt clearly. 7. **Bootstrap entry** — a single `./install.sh` (or `curl ... | bash` ONLY if you also publish a checksum and the user opts in) that clones the repo if missing and runs the steps in order. Output: (a) the full bootstrap script with the pkg_install abstraction, (b) the guarded symlink+backup function, (c) the dry-run/summary output, (d) a re-run-safety note proving the 2nd run is a no-op. Bias toward: idempotency, backing up over clobbering, and minimal privilege.