From 250baaaba1f35539abd5c3ca2e71431a60ecb0dc Mon Sep 17 00:00:00 2001 From: Trevi Awater Date: Mon, 7 Sep 2026 19:11:26 +0200 Subject: [PATCH] Add setup.sh bootstrap script for fresh machines Runs the whole README runbook in one go: relocates the repo off the USB stick, installs CLT + Homebrew, brew bundle, symlinks, copied configs, fish as default shell, and the .NET SDK, then prints the remaining manual steps. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01MN5eka2MuNJP9uCMdTda75 --- README.md | 20 ++++++++++- setup.sh | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) create mode 100755 setup.sh diff --git a/README.md b/README.md index 2b65822..7ab06ae 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,25 @@ Two kinds of files live here: - **Copied** — files that can't be symlinked (`/etc/hosts`, Claude/Serena settings, the brewfile). Refresh them from the machine with `./update.fish`. -## Fresh machine setup +## Fresh machine setup — the fast way + +Get this repo onto the machine (USB stick copy or a clone) and run: + +```bash +/bin/bash setup.sh +``` + +The script is idempotent and does steps 1–9 below automatically: it copies the +repo to `~/Repositories/personal/macos-configuration` (so it works straight off +a USB stick), installs Command Line Tools and Homebrew, runs the brew bundle, +creates all symlinks, restores the copied configs, sets fish as the default +shell, and installs the .NET SDK. At the end it prints the manual steps that +remain (1Password/SSH keys, iTerm2 profile import, `gh auth login` + repo +cloning, WireGuard, app sign-ins). + +The sections below document what the script does, for reference or manual runs. + +## Fresh machine setup — step by step ### 1. Install Command Line Tools and clone this repo diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..977beb3 --- /dev/null +++ b/setup.sh @@ -0,0 +1,101 @@ +#!/bin/bash + +# Bootstrap a fresh Mac from this repo. Idempotent — safe to re-run. +# +# /bin/bash setup.sh +# +# Works when run straight from a USB stick or a fresh clone: it first copies +# the repo to ~/Repositories/personal/macos-configuration (so symlinks never +# point at removable media) and continues from there. + +set -uo pipefail + +REPO_HOME="$HOME/Repositories/personal/macos-configuration" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +step() { printf '\n\033[1;34m==> %s\033[0m\n' "$*"; } + +# --- 0. Relocate off removable media / into the canonical path ------------- +if [ "$SCRIPT_DIR" != "$REPO_HOME" ]; then + step "Copying repo from $SCRIPT_DIR to $REPO_HOME" + mkdir -p "$REPO_HOME" + cp -R "$SCRIPT_DIR/." "$REPO_HOME/" + exec /bin/bash "$REPO_HOME/setup.sh" +fi +cd "$REPO_HOME" + +# --- 1. Xcode Command Line Tools ------------------------------------------- +if ! xcode-select -p >/dev/null 2>&1; then + step "Installing Xcode Command Line Tools (accept the GUI prompt)" + xcode-select --install + until xcode-select -p >/dev/null 2>&1; do + sleep 10 + done +else + step "Xcode Command Line Tools already installed" +fi + +# --- 2. Homebrew ------------------------------------------------------------ +if [ ! -x /opt/homebrew/bin/brew ]; then + step "Installing Homebrew" + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +else + step "Homebrew already installed" +fi +eval "$(/opt/homebrew/bin/brew shellenv)" + +# --- 3. Packages, casks, VS Code extensions -------------------------------- +step "Installing brewfile bundle (this takes a while)" +brew bundle --file="$REPO_HOME/brewfile" || true + +# --- 4. Symlink configs ------------------------------------------------------ +step "Symlinking configuration files" +mkdir -p ~/.config/fish ~/.kube ~/.nuget/NuGet ~/.ssh +ln -sf "$REPO_HOME/fish-config.fish" ~/.config/fish/config.fish +ln -sf "$REPO_HOME/starship.toml" ~/.config/starship.toml +ln -sf "$REPO_HOME/ssh-config" ~/.ssh/config +ln -sf "$REPO_HOME/kube-config" ~/.kube/config +ln -sf "$REPO_HOME/.npmrc" ~/.npmrc +ln -sf "$REPO_HOME/NuGet.Config" ~/.nuget/NuGet/NuGet.Config + +# --- 5. Copied configs ------------------------------------------------------- +step "Restoring copied configs" +mkdir -p ~/.claude ~/.serena +cp "$REPO_HOME/claude-settings.json" ~/.claude/settings.json +cp "$REPO_HOME/serena_config.yml" ~/.serena/serena_config.yml +echo "Updating /etc/hosts (sudo)" +sudo cp "$REPO_HOME/hosts" /etc/hosts + +# --- 6. Fish as default shell ------------------------------------------------ +if ! grep -q /opt/homebrew/bin/fish /etc/shells; then + step "Registering fish as a shell (sudo)" + echo /opt/homebrew/bin/fish | sudo tee -a /etc/shells +fi +if [ "$(dscl . -read "/Users/$USER" UserShell | awk '{print $2}')" != "/opt/homebrew/bin/fish" ]; then + step "Setting fish as default shell" + chsh -s /opt/homebrew/bin/fish +fi + +# --- 7. .NET 10 SDK ---------------------------------------------------------- +if [ ! -x "$HOME/.dotnet/dotnet" ]; then + step "Installing .NET 10 SDK" + /opt/homebrew/bin/fish "$REPO_HOME/install-dotnet10.fish" +else + step ".NET SDK already installed" +fi + +# --- 8. Point git remote at SSH --------------------------------------------- +if [ -d "$REPO_HOME/.git" ]; then + git -C "$REPO_HOME" remote set-url origin git@github.com:awatertrevi/macos-configuration.git 2>/dev/null || true +fi + +step "Done. Remaining manual steps:" +cat <<'EOF' + 1. Open 1Password, sign in, enable Settings > Developer > SSH Agent, + and put the *.pub files referenced in ssh-config into ~/.ssh/. + 2. iTerm2 > Settings > Profiles > Import JSON Profiles > iterm-profile.json. + 3. gh auth login, then: fish clone-resoftware-repos.fish + 4. Optional: import meerkoet-proxy.conf into the WireGuard app. + 5. Sign in to iCloud, browsers, Slack, Spark, Google Drive, Docker, + Todoist, JetBrains Toolbox; restore Alfred/BTT licenses. +EOF