Skip to content

Instantly share code, notes, and snippets.

@anschmieg
Last active June 2, 2025 10:07
Show Gist options
  • Save anschmieg/59f8bca8527c7745aa3781f49c8bb313 to your computer and use it in GitHub Desktop.
Save anschmieg/59f8bca8527c7745aa3781f49c8bb313 to your computer and use it in GitHub Desktop.
πŸš€ One-Command Dotfiles Deployment Script
#!/bin/bash
# πŸš€ One-Command Dotfiles Deployment Script
#
# Quick deployment: curl -sfL https://nothing.pink/zsh | bash
# Or for interactivity: bash <(curl -sfL https://nothing.pink/zsh) < /dev/tty
#
# What this script does:
# 1. Installs chezmoi if needed
# 2. Helps you set up your age encryption key
# 3. Deploys your complete dotfiles setup
# 4. Runs all automated configuration scripts
# 5. Validates the installation (37 checks)
#
# Prerequisites: Your age encryption key from ~/.config/age/chezmoi.txt
set -euo pipefail
echo "πŸš€ Starting automated dotfiles deployment..."
echo "πŸ“ Repository: https://github.com/anschmieg/dotfiles.git"
echo ""
# Ensure ~/.local/bin is in PATH first
export PATH="$HOME/.local/bin:$PATH"
# Install chezmoi if not present
if ! command -v chezmoi &>/dev/null; then
echo "πŸ“₯ Installing chezmoi..."
# Force installation to ~/.local/bin directory
mkdir -p ~/.local/bin
if curl -sfL https://get.chezmoi.io | sh -s -- -b ~/.local/bin; then
echo "βœ… chezmoi installation completed"
else
echo "❌ Failed to install chezmoi!"
echo "πŸ’‘ Please install chezmoi manually:"
echo " curl -sfL https://get.chezmoi.io | sh -s -- -b ~/.local/bin"
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
exit 1
fi
fi
# Verify chezmoi is available and set the command
CHEZMOI_CMD=""
if command -v chezmoi &>/dev/null; then
CHEZMOI_CMD="chezmoi"
echo "βœ… chezmoi found in PATH: $(command -v chezmoi)"
elif [[ -x "$HOME/.local/bin/chezmoi" ]]; then
CHEZMOI_CMD="$HOME/.local/bin/chezmoi"
echo "βœ… chezmoi found at ~/.local/bin/chezmoi"
elif [[ -x "./bin/chezmoi" ]]; then
CHEZMOI_CMD="./bin/chezmoi"
echo "βœ… chezmoi found at ./bin/chezmoi"
else
echo "❌ chezmoi not found! Checking installation directory..."
echo "πŸ“‚ Current directory: $(pwd)"
echo "πŸ“‚ Contents of ~/.local/bin/:"
ls -la "$HOME/.local/bin/" 2>/dev/null || echo " Directory ~/.local/bin/ does not exist"
echo "πŸ“‚ Contents of ./bin/:"
ls -la "./bin/" 2>/dev/null || echo " Directory ./bin/ does not exist"
echo ""
echo "πŸ’‘ Manual installation required:"
echo " curl -sfL https://get.chezmoi.io | sh -s -- -b ~/.local/bin"
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
exit 1
fi
# Check for age key
if [[ ! -f ~/.config/age/chezmoi.txt ]]; then
echo "πŸ”‘ Age encryption key not found at ~/.config/age/chezmoi.txt"
echo ""
# Check for environment variable first
if [[ -n "${CHEZMOI_AGE_KEY:-}" ]]; then
echo "πŸ”‘ Found age key in CHEZMOI_AGE_KEY environment variable"
mkdir -p ~/.config/age
echo "$CHEZMOI_AGE_KEY" >~/.config/age/chezmoi.txt
chmod 600 ~/.config/age/chezmoi.txt
echo "βœ… Age key saved from environment variable!"
# Check if we're running interactively
elif [[ -t 0 ]]; then
# Interactive mode - show menu
echo "Choose an option to provide your age key:"
echo " 1) Paste the key content (I'll create the file)"
echo " 2) I'll copy the file manually"
echo ""
read -p "Enter choice (1 or 2): " choice
else
# Non-interactive mode (piped script) - default to paste option
echo "πŸ€– Running in non-interactive mode. Starting age key paste mode..."
echo ""
echo "πŸ“‹ Please paste your age key content now and press Ctrl+D when finished:"
echo " (Age key format: AGE-SECRET-KEY-1...)"
echo ""
choice="1"
fi
case $choice in
1)
echo ""
echo "πŸ“‹ Please paste your age key content (from ~/.config/age/chezmoi.txt):"
echo " (Press Ctrl+D when finished)"
echo ""
# Create the directory
mkdir -p ~/.config/age
# Read the key content with timeout in non-interactive mode
if [[ ! -t 0 ]]; then
echo "⏳ Waiting for age key input... (timeout in 30 seconds)"
if ! key_content=$(timeout 30s cat); then
echo ""
echo "❌ No key input received or timeout reached."
echo "πŸ’‘ Alternative: Run the script interactively instead:"
echo " 1. Download: curl -sL https://nothing.pink/zsh > deploy.sh"
echo " 2. Run: bash deploy.sh"
echo " 3. Or manually setup:"
echo " mkdir -p ~/.config/age"
echo " # Copy your age key to ~/.config/age/chezmoi.txt"
echo " chezmoi init --apply https://github.com/anschmieg/dotfiles.git"
exit 1
fi
else
# Interactive mode
if ! key_content=$(cat); then
echo "❌ Failed to read key content"
exit 1
fi
fi
if [[ -n "$key_content" ]]; then
echo "$key_content" >~/.config/age/chezmoi.txt
chmod 600 ~/.config/age/chezmoi.txt
echo "βœ… Age key saved successfully!"
else
echo "❌ No key content provided"
exit 1
fi
;;
2)
echo ""
echo "πŸ“ Please manually copy your age key file:"
echo " Source: ~/.config/age/chezmoi.txt (from your existing machine)"
echo " Target: ~/.config/age/chezmoi.txt (on this machine)"
echo ""
echo "πŸ’‘ Run these commands:"
echo " mkdir -p ~/.config/age"
echo " # Copy chezmoi.txt from your existing machine to ~/.config/age/"
echo ""
read -p "Press Enter when you've copied the file..."
# Verify the file exists
if [[ ! -f ~/.config/age/chezmoi.txt ]]; then
echo "❌ Age key file still not found. Please copy it and run this script again."
exit 1
fi
echo "βœ… Age key file found!"
;;
*)
echo "❌ Invalid choice. Please run the script again and choose 1 or 2."
exit 1
;;
esac
fi
# Deploy dotfiles
echo "πŸ”„ Deploying dotfiles..."
echo " This will run all setup scripts automatically:"
echo " β€’ Install dependencies and tools"
echo " β€’ Configure package managers"
echo " β€’ Set up Zsh with plugins"
echo " β€’ Run validation checks"
echo ""
if $CHEZMOI_CMD init --apply https://github.com/anschmieg/dotfiles.git; then
echo ""
echo "βœ… Deployment completed successfully!"
echo ""
echo "πŸ“‹ What was set up:"
echo " β€’ App package manager with auto-detection"
echo " β€’ Zsh with Antidote plugin manager"
echo " β€’ Git configuration"
echo " β€’ SSH configuration"
echo " β€’ Development tools and utilities"
echo ""
echo "πŸ” Validation results should appear above ☝️"
echo "πŸ’‘ If any validations failed, run: chezmoi cd && ./scripts/troubleshoot.sh"
else
echo "❌ Deployment failed! Check the output above for errors."
echo "πŸ†˜ For troubleshooting, visit: https://github.com/anschmieg/dotfiles"
exit 1
fi
echo ""
echo "🐚 Starting new shell session with your configuration..."
exec zsh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment