Skip to content

Instantly share code, notes, and snippets.

@spleenteo
Last active April 20, 2026 19:55
Show Gist options
  • Select an option

  • Save spleenteo/f05f6722f3b34447747b6fc12368061e to your computer and use it in GitHub Desktop.

Select an option

Save spleenteo/f05f6722f3b34447747b6fc12368061e to your computer and use it in GitHub Desktop.
macOS bootstrap — chezmoi dotfiles restore
#!/usr/bin/env bash
# ==============================================================================
# macOS Bootstrap — configura una macchina nuova con chezmoi
#
# Uso:
# curl -fsLS https://gist.githubusercontent.com/spleenteo/f05f6722f3b34447747b6fc12368061e/raw/bootstrap.sh -o /tmp/bootstrap.sh
# bash /tmp/bootstrap.sh
#
# Prerequisiti (da 1Password):
# - GitHub Personal Access Token (per clonare il repo privato)
# - Chiave age identity (per decifrare i file sensibili)
#
# ==============================================================================
set -eo pipefail
# --- Guard: richiede terminale interattivo ---
if [ ! -t 0 ]; then
echo "Errore: questo script richiede input interattivo."
echo ""
echo "Scaricalo prima, poi eseguilo:"
echo " curl -fsLS https://gist.githubusercontent.com/spleenteo/f05f6722f3b34447747b6fc12368061e/raw/bootstrap.sh -o /tmp/bootstrap.sh"
echo " bash /tmp/bootstrap.sh"
exit 1
fi
# --- Colori ---
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
RESET='\033[0m'
step() { printf "\n${CYAN}${BOLD}[%s]${RESET} %s\n" "$1" "$2"; }
ok() { printf "${GREEN} ✔${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW} ⚠${RESET} %s\n" "$1"; }
fail() { printf "${RED} ✖${RESET} %s\n" "$1"; exit 1; }
ask() { printf "${BOLD} → %s${RESET} " "$1"; }
# ==============================================================================
step "1/6" "GitHub Personal Access Token"
# ==============================================================================
echo " Apri 1Password e copia il token con accesso al repo spleenteo/dotfiles."
echo ""
ask "Incolla il GitHub token:"
read -rs GITHUB_TOKEN
echo ""
if [[ -z "$GITHUB_TOKEN" ]]; then
fail "Token vuoto. Riprova."
fi
# Verifica che il token funzioni
if ! curl -sf -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/spleenteo/dotfiles >/dev/null 2>&1; then
fail "Token non valido o senza accesso al repo spleenteo/dotfiles."
fi
ok "Token verificato"
# ==============================================================================
step "2/6" "Chiave age (encryption)"
# ==============================================================================
echo " Apri 1Password e copia la chiave age identity."
echo " (inizia con AGE-SECRET-KEY-...)"
echo ""
ask "Incolla la chiave age (solo la riga AGE-SECRET-KEY-...):"
read -rs AGE_KEY
echo ""
# Accetta anche se l'utente incolla l'intero file identity — estrai solo la chiave
if [[ "$AGE_KEY" != AGE-SECRET-KEY-* ]]; then
AGE_KEY=$(echo "$AGE_KEY" | grep "^AGE-SECRET-KEY-" 2>/dev/null || true)
fi
if [[ -z "$AGE_KEY" || "$AGE_KEY" != AGE-SECRET-KEY-* ]]; then
fail "Chiave age non valida. Deve iniziare con AGE-SECRET-KEY-..."
fi
mkdir -p ~/.config/age
printf '%s\n' "$AGE_KEY" > ~/.config/age/identity.txt
chmod 600 ~/.config/age/identity.txt
ok "Chiave age salvata in ~/.config/age/identity.txt"
# ==============================================================================
step "3/6" "Installazione chezmoi"
# ==============================================================================
export PATH="$HOME/.local/bin:$PATH"
if command -v chezmoi &>/dev/null; then
ok "chezmoi gia installato ($(chezmoi --version 2>/dev/null || echo '?'))"
else
echo " Scaricamento e installazione in ~/.local/bin..."
sh -c "$(curl -fsLS get.chezmoi.io)" -- -b "$HOME/.local/bin"
ok "chezmoi installato"
fi
# ==============================================================================
step "4/6" "Clone e apply del repo dotfiles"
# ==============================================================================
echo " chezmoi clona il repo, deploya i dotfile e lancia il bootstrap automatico."
echo " Questo include: Xcode CLI Tools, Homebrew, formulae, cask, VS Code, macOS defaults."
echo ""
warn "Il processo puo richiedere diversi minuti. Potrebbe chiederti la password di sistema."
echo ""
chezmoi init --apply "https://${GITHUB_TOKEN}@github.com/spleenteo/dotfiles.git"
ok "Dotfiles applicati"
# ==============================================================================
step "5/6" "Claude Code skills da git"
# ==============================================================================
# Aggiungi github.com ai known_hosts (evita prompt interattivo)
mkdir -p ~/.ssh
ssh-keyscan -t ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null
ok "GitHub aggiunto ai known_hosts"
# Avvia ssh-agent e aggiungi la chiave (chezmoi l'ha gia deployata)
eval "$(ssh-agent -s)" >/dev/null 2>&1
ssh-add ~/.ssh/id_rsa 2>/dev/null && ok "Chiave SSH caricata nell'agent" || \
warn "Chiave SSH non caricata — i clone via SSH potrebbero fallire"
REGISTRY="$HOME/Library/Mobile Documents/com~apple~CloudDocs/spleen-backup/claude-skills-registry.yaml"
SKILLS_DIR="$HOME/.claude/skills"
if [[ -f "$REGISTRY" ]]; then
mkdir -p "$SKILLS_DIR"
local_name="" local_restore=""
installed=0
while IFS= read -r line; do
if [[ "$line" == *'- name: "'* ]]; then
local_name="${line#*\"}" ; local_name="${local_name%\"*}"
elif [[ "$line" == *'restore: "'* ]]; then
local_restore="${line#*\"}" ; local_restore="${local_restore%\"*}"
if [[ "$local_restore" != "local" && -n "$local_name" && ! -d "$SKILLS_DIR/$local_name" ]]; then
echo " ⬇ $local_name ← $local_restore"
if ! git clone --quiet "$local_restore" "$SKILLS_DIR/$local_name" 2>/dev/null; then
# Fallback HTTPS con token per repo privati o se SSH fallisce
local_url="$local_restore"
if [[ "$local_url" == git@github.com:* ]]; then
local_url="https://${GITHUB_TOKEN}@github.com/${local_url#git@github.com:}"
fi
git clone --quiet "$local_url" "$SKILLS_DIR/$local_name" 2>/dev/null && \
(( installed++ )) || warn "Clone fallito per $local_name"
else
(( installed++ ))
fi
fi
local_name="" ; local_restore=""
fi
done < <(awk '/^global_skills:/,/^project_skills:/' "$REGISTRY")
ok "$installed skill installate da git"
else
warn "Skills registry non trovato — le skill andranno installate manualmente"
fi
# ==============================================================================
step "6/6" "Riconfigura git remote per SSH"
# ==============================================================================
# Ora che chezmoi ha deployato la chiave SSH, passiamo a SSH per i push futuri
chezmoi git -- remote set-url origin git@github.com:spleenteo/dotfiles.git 2>/dev/null && \
ok "Remote chezmoi impostato su SSH" || \
warn "Non ho potuto cambiare il remote — verificalo manualmente con: chezmoi git -- remote -v"
# ==============================================================================
# Fatto!
# ==============================================================================
printf "\n${GREEN}${BOLD}"
printf " ╔══════════════════════════════════════════╗\n"
printf " ║ Setup completato! ║\n"
printf " ╚══════════════════════════════════════════╝\n"
printf "${RESET}\n"
echo " Passi manuali rimanenti:"
echo " • Login App Store se non fatto durante il bootstrap"
echo " • Login nelle app installate"
echo " • Riavvia il terminale per caricare la nuova shell"
echo ""
echo " Comandi utili:"
echo " :help — lista alias e comandi disponibili"
echo " :backup — esegui un backup completo"
echo " :cmr — sincronizza file modificati con chezmoi"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment