Skip to content

Instantly share code, notes, and snippets.

@schoren
Last active March 7, 2026 00:26
Show Gist options
  • Select an option

  • Save schoren/f768bafa4c27c392b1b75e0e343e310a to your computer and use it in GitHub Desktop.

Select an option

Save schoren/f768bafa4c27c392b1b75e0e343e310a to your computer and use it in GitHub Desktop.
hostup bootstrap for nix + private nix-config clone
#!/usr/bin/env bash
set -euo pipefail
REPO_SLUG="${REPO_SLUG:-schoren/nix-config}"
TARGET_DIR="${TARGET_DIR:-$HOME/nix-config}"
NIX_FLAGS=(--extra-experimental-features "nix-command flakes")
NIX_BIN=""
usage() {
cat <<'EOF'
Usage: hostup.sh <host>
Bootstraps a fresh macOS machine by:
1. Installing Nix (if missing)
2. Authenticating to GitHub via web flow (gh)
3. Cloning the private nix-config repository
Environment overrides:
REPO_SLUG GitHub repo slug (default: schoren/nix-config)
TARGET_DIR Clone destination (default: ~/nix-config)
EOF
}
if [[ "${1:-}" == "" ]]; then
usage
exit 1
fi
HOST="$1"
case "$HOST" in
macstudio|mbp-work|mbair) ;;
*)
echo "Unsupported host: $HOST"
echo "Allowed hosts: macstudio, mbp-work, mbair"
exit 1
;;
esac
if [[ "$(uname -s)" != "Darwin" ]]; then
echo "This bootstrap script only supports macOS."
exit 1
fi
if ! command -v curl >/dev/null 2>&1; then
echo "curl is required."
exit 1
fi
if [[ -x /nix/var/nix/profiles/default/bin/nix ]]; then
NIX_BIN="/nix/var/nix/profiles/default/bin/nix"
export PATH="/nix/var/nix/profiles/default/bin:$PATH"
elif command -v nix >/dev/null 2>&1; then
NIX_BIN="$(command -v nix)"
else
echo "Installing Nix..."
sh <(curl -fsSL https://nixos.org/nix/install) --daemon
fi
# Load Nix in the current shell when available.
if [[ -r /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]]; then
# shellcheck source=/dev/null
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
fi
if [[ -z "$NIX_BIN" ]]; then
if command -v nix >/dev/null 2>&1; then
NIX_BIN="$(command -v nix)"
elif [[ -x /nix/var/nix/profiles/default/bin/nix ]]; then
NIX_BIN="/nix/var/nix/profiles/default/bin/nix"
export PATH="/nix/var/nix/profiles/default/bin:$PATH"
else
echo "Nix install appears incomplete: nix binary not found."
exit 1
fi
else
echo "Nix already installed at $NIX_BIN. Skipping install."
fi
if "$NIX_BIN" "${NIX_FLAGS[@]}" shell nixpkgs#gh -c gh auth status --hostname github.com >/dev/null 2>&1; then
echo "GitHub auth already configured. Skipping login."
else
echo "Authenticating to GitHub (browser login)..."
"$NIX_BIN" "${NIX_FLAGS[@]}" shell nixpkgs#gh nixpkgs#git -c gh auth login --hostname github.com --web --git-protocol https
fi
if [[ -d "$TARGET_DIR/.git" ]]; then
CURRENT_DIR="$(pwd -P)"
TARGET_REAL="$(cd "$TARGET_DIR" && pwd -P)"
case "$CURRENT_DIR" in
"$TARGET_REAL"|"$TARGET_REAL"/*)
echo "Current directory is inside $TARGET_DIR. Moving to $HOME first..."
cd "$HOME"
;;
esac
echo "Repository already present at $TARGET_DIR. Checking if it's clean..."
GIT_STATUS="$("$NIX_BIN" "${NIX_FLAGS[@]}" shell nixpkgs#git -c git -C "$TARGET_DIR" status --porcelain)"
if [[ -n "$GIT_STATUS" ]]; then
echo "Repository is dirty at $TARGET_DIR. Refusing to overwrite."
echo "Please commit/stash changes or remove the directory manually."
exit 1
fi
echo "Repository is clean. Removing and cloning fresh..."
rm -rf "$TARGET_DIR"
elif [[ -e "$TARGET_DIR" ]]; then
echo "Target path exists but is not a git repository: $TARGET_DIR"
echo "Remove it manually or set TARGET_DIR to another path."
exit 1
fi
echo "Cloning $REPO_SLUG into $TARGET_DIR..."
"$NIX_BIN" "${NIX_FLAGS[@]}" shell nixpkgs#gh nixpkgs#git -c gh repo clone "$REPO_SLUG" "$TARGET_DIR"
cat <<EOF
Bootstrap complete.
Next step on this machine:
cd "$TARGET_DIR"
./scripts/darwin-switch.sh "$HOST"
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment