Files
andwati 36f0caa66e Add modular dev environment installer, dotfiles, and desnap script
Adds a TUI-driven, rollback-capable installer (install/install.sh +
install/modules/*.sh) covering JS/Python/systems toolchains, dev tooling,
browsers, chat apps, GNOME extras, and misc setup (wakatime key, ssh/gpg
perms, apt mirror benchmarking), all sourced from each vendor's official
install method. bootstrap.sh stows the zsh/git/tmux/vscode dotfiles and
runs the installer; desnap.sh purges snapd and replaces default snaps with
apt/Flatpak equivalents.
2026-07-15 17:02:27 +03:00

140 lines
5.8 KiB
Markdown

# dotfiles
My configuration files, plus a modular installer for the tools I use on a
fresh Ubuntu box (targeting 26.04). Everything installs from each vendor's
official source — apt repos with their real signing keys, or their official
install scripts/tarballs. No PPAs of unclear provenance, no snaps unless the
vendor's own instructions use one (Ubuntu's own default snaps are actively
replaced — see `desnap.sh` below).
## Quick start
On a fresh Ubuntu install:
```sh
git clone <this-repo> ~/dotfiles
cd ~/dotfiles
./bootstrap.sh
```
That will:
1. Install `stow`, `zsh`, `curl`, `git`.
2. Symlink the dotfiles (`zsh/`, `git/`, `tmux/`, `vscode/`) into `$HOME` with
GNU Stow.
3. Prompt once for your git name/email/signing key, saved to
`~/.gitconfig.local` (gitignored — never committed, so this repo stays
shareable).
4. Set zsh as your default shell.
5. Run `install/install.sh`, which shows a checklist (see below) of every
tool to install.
Open a new shell afterwards (or `exec zsh`) to pick up PATH changes.
## Picking what to install
Run interactively with no arguments and `install/install.sh` shows a
`whiptail` checklist — space to toggle, enter to confirm. Everything's
checked by default; uncheck what you don't want. If `whiptail` isn't
available it's installed automatically; if that's not possible either it
falls back to a plain numbered prompt.
Non-interactive options:
```sh
./bootstrap.sh nvm node pnpm docker # only these modules (+ base deps)
./install/install.sh --list # list all module names
./install/install.sh --except discord,slack,spotify
./install/install.sh --all # skip the checklist, install everything
./install/install.sh --dry-run # show what would run without doing it
```
`--dry-run` works with any of the above (`--dry-run --all`,
`--dry-run nvm docker`, ...) and also works on `bootstrap.sh` and
`desnap.sh`.
## Resilience: a failed module doesn't kill the run
Every module runs in its own subshell with `errexit` on. If a command in a
module fails partway through, that module's own changes (packages
installed, repos added, directories created, group memberships granted —
whatever it called `rollback_push` for) are unwound in reverse order, the
failure is recorded, and the **next module still runs**. At the end you get
a summary of what succeeded and what failed, and the script exits nonzero
only if something actually failed. Every module is also idempotent — safe
to re-run individually or all together.
## What gets installed
| Category | Tools |
|---|---|
| System | apt mirror benchmarking, `~/.ssh`/`~/.gnupg` permission fixes, eza/ripgrep |
| JS/TS runtimes | nvm, node (via nvm, LTS), pnpm, deno, bun |
| Python | pyenv, pipx, pipenv, poetry, uv |
| Systems languages | go, rust (rustup), zig + zls |
| Dev tooling | VS Code (+ your extensions/settings, mirrored to Cursor), Cursor, GitHub CLI (`gh`), Docker Engine |
| Apps | Chrome, Firefox, Discord, Slack, Postman, JetBrains Toolbox, mpv, Spotify, Telegram, Signal, ProtonVPN, OneDrive (abraunegg) |
| Desktop | GNOME Tweaks, Extension Manager, AppIndicator support |
| Misc | Wakatime API key setup |
## Layout
```
bootstrap.sh entrypoint: stows dotfiles, then runs install/install.sh
desnap.sh standalone: purges snapd, replaces default snaps with apt/Flatpak
install/
lib.sh shared shell helpers (apt/repo/rollback/profile-line helpers)
install.sh module runner — TUI checklist, dry-run, rollback, summary
modules/*.sh one file per tool, each defines install_<name>()
zsh/ git/ tmux/ vscode/ stow packages — mirror their target layout under $HOME
```
To add a new tool: drop a new `install/modules/<name>.sh` defining
`install_<name>()`, and add `<name>` (+ a description) to `ALL_MODULES` /
`MODULE_DESC` in `install/install.sh`.
## desnap.sh
Purges snapd entirely and pins it out of apt so it can't come back on
upgrade. Before removing anything it works out, per installed snap, whether
there's a real replacement:
- Snaps we already have an official-source module for (Firefox) get that
module.
- Known default-Ubuntu snaps with a plain apt equivalent (Thunderbird,
snap-store → gnome-software) get that apt package.
- GNOME/core runtime snaps (content-only, no user-facing app) are skipped.
- Anything else gets Flatpak + Flathub set up and is listed at the end so
you can `flatpak search`/`install` it yourself, rather than guessing an
app id.
Destructive and asks for confirmation (`-y`/`--yes` to skip the prompt);
supports `--dry-run` to preview the plan first.
```sh
./desnap.sh --dry-run
./desnap.sh
```
## Notes
- `mirrors` benchmarks official Ubuntu mirrors (speed + a freshness check on
`Last-Modified`) and rewrites apt's sources to the fastest one — handles
both the legacy `sources.list` and the 24.04+/26.04 deb822
`ubuntu.sources` format. Runs early so the rest of the install benefits.
`security.ubuntu.com` is left alone on purpose.
- `firefox` removes the transitional apt stub / snap package first and pins
Mozilla's official apt repo, since stock Ubuntu ships Firefox as a snap.
- `docker`, `onedrive` each check whether their upstream repo has packages
for the running Ubuntu codename/version yet and fall back to the most
recent known-supported one if it's too new (relevant right after a fresh
26.04 install).
- `vscode` installs every extension listed in `vscode/extensions.txt`
(exported with `code --list-extensions`) and mirrors `settings.json` to
Cursor via symlink, so both stay in sync from one source of truth.
- `wakatime` prompts once for your API key and writes `~/.wakatime.cfg`
(chmod 600); leave the prompt blank to skip.
- Tool PATH/init lines are appended idempotently to the end of `zsh/.zshrc`
by `profile_add` in `install/lib.sh` — re-running a module never
duplicates a line.