Last active
July 1, 2026 15:12
-
-
Save shedali/38c78cbf3d42855a83a44f54bc1cc2ab to your computer and use it in GitHub Desktop.
bootstrap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Run this on a new Mac: | |
| # curl -fsSL https://gist.githubusercontent.com/shedali/38c78cbf3d42855a83a44f54bc1cc2ab/raw/bootstrap.sh | bash | |
| set -e | |
| # Ensure Xcode Command Line Tools are installed AND usable before anything that | |
| # needs a compiler/git (Homebrew, nix-darwin casks). A bare `xcode-select -p` can | |
| # succeed even when the tools are missing/broken, so also verify `clang` resolves. | |
| if ! xcode-select -p &>/dev/null || ! /usr/bin/xcrun --find clang &>/dev/null; then | |
| echo "Installing Xcode Command Line Tools (required before Homebrew)..." | |
| # Prefer a headless install via softwareupdate (no GUI dialog to babysit). | |
| # The placeholder file makes the CLT package show up in `softwareupdate -l`. | |
| CLT_PLACEHOLDER="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress" | |
| touch "$CLT_PLACEHOLDER" | |
| CLT_LABEL=$(softwareupdate -l 2>/dev/null \ | |
| | grep -E 'Command Line Tools' \ | |
| | awk -F'Label: ' '/Label:/ {print $2}' \ | |
| | sort -V | tail -n1) | |
| if [ -n "$CLT_LABEL" ]; then | |
| echo "Installing '$CLT_LABEL' via softwareupdate..." | |
| softwareupdate -i "$CLT_LABEL" --verbose || true | |
| else | |
| # Fall back to the GUI installer if the package label can't be found. | |
| xcode-select --install &>/dev/null || true | |
| echo "Complete the Xcode Command Line Tools dialog if it appears; waiting for it to finish..." | |
| fi | |
| rm -f "$CLT_PLACEHOLDER" | |
| # Block until the tools are actually usable (survives GUI-driven installs too). | |
| until xcode-select -p &>/dev/null && /usr/bin/xcrun --find clang &>/dev/null; do | |
| echo "Waiting for Command Line Tools to finish installing..." | |
| sleep 15 | |
| done | |
| echo "✓ Xcode Command Line Tools installed" | |
| fi | |
| NIX_BIN="/nix/var/nix/profiles/default/bin/nix" | |
| if ! "$NIX_BIN" --version &>/dev/null 2>&1; then | |
| # Before installing, check if an APFS Nix Store volume already exists. | |
| # If it does, the volume is likely locked/unmounted (daemon not running) rather | |
| # than truly absent. Attempting to reinstall in this state triggers a broken | |
| # uninstall flow. Abort and let the user fix the daemon instead. | |
| if /usr/sbin/diskutil list 2>/dev/null | grep -q "Nix Store"; then | |
| echo "" | |
| echo "ERROR: A Nix Store APFS volume already exists but Nix is not accessible." >&2 | |
| echo "The volume is likely encrypted and not mounted (daemon not running)." >&2 | |
| echo "" >&2 | |
| echo "To fix, try one of:" >&2 | |
| echo " 1. Load the Nix daemon LaunchDaemon:" >&2 | |
| echo " sudo launchctl load /Library/LaunchDaemons/systems.determinate-nix-installer.nix-hook.plist" >&2 | |
| echo " 2. If the daemon plist is missing, delete the volume and reinstall:" >&2 | |
| echo " VOLUME=\$(/usr/sbin/diskutil list | awk '/Nix Store/{print \$NF}')" >&2 | |
| echo " sudo /usr/sbin/diskutil apfs deleteVolume \"\$VOLUME\"" >&2 | |
| echo " curl -fsSL https://install.determinate.systems/nix | sh -s -- install --determinate" >&2 | |
| echo "" >&2 | |
| exit 1 | |
| fi | |
| echo "Nix not found, installing..." | |
| curl -fsSL https://install.determinate.systems/nix | sh -s -- install --determinate | |
| echo "Nix installed, sourcing environment..." | |
| # Source Nix to make it available in current shell | |
| if [ -e "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" ]; then | |
| . "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" | |
| fi | |
| fi | |
| echo "Nix is available, continuing setup..." | |
| # Ask if user wants full setup or minimal (nix-darwin only) | |
| echo "" | |
| echo "Setup options:" | |
| echo " Full: Clone repos (home-manager, nvim, etc.) + nix-darwin (requires GitHub auth)" | |
| echo " Minimal: Just apply nix-darwin configuration (no GitHub auth needed)" | |
| echo "" | |
| set +e | |
| setup_mode=$("$NIX_BIN" shell nixpkgs#gum --command gum choose "Full setup" "Minimal (nix-darwin only)" </dev/tty 2>/dev/tty) | |
| gum_mode_exit=$? | |
| set -e | |
| if [ $gum_mode_exit -ne 0 ] || [ -z "$setup_mode" ]; then | |
| echo " 1) Full setup" | |
| echo " 2) Minimal (nix-darwin only)" | |
| read -p "Enter choice (1 or 2): " mode_choice </dev/tty | |
| case "$mode_choice" in | |
| 1) setup_mode="Full setup" ;; | |
| 2) setup_mode="Minimal (nix-darwin only)" ;; | |
| *) | |
| echo "ERROR: Invalid choice" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
| fi | |
| # If minimal, skip to nix-darwin setup | |
| if [ "$setup_mode" = "Minimal (nix-darwin only)" ]; then | |
| echo "" | |
| echo "Skipping GitHub auth and repo cloning..." | |
| echo "" | |
| # Jump to profile selection | |
| set +e | |
| setup_type=$("$NIX_BIN" shell nixpkgs#gum --command gum choose "Personal" "Work" "Air" "Mini" </dev/tty 2>/dev/tty) | |
| gum_exit_code=$? | |
| set -e | |
| if [ $gum_exit_code -ne 0 ] || [ -z "$setup_type" ]; then | |
| echo "Select setup type:" | |
| echo " 1) Personal" | |
| echo " 2) Work" | |
| echo " 3) Air" | |
| echo " 4) Mini" | |
| read -p "Enter choice (1-4): " choice </dev/tty | |
| case "$choice" in | |
| 1) setup_type="Personal" ;; | |
| 2) setup_type="Work" ;; | |
| 3) setup_type="Air" ;; | |
| 4) setup_type="Mini" ;; | |
| *) | |
| echo "ERROR: Invalid choice" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
| fi | |
| profile_name=$(echo "$setup_type" | tr '[:upper:]' '[:lower:]') | |
| # Map friendly names to actual flake attribute names | |
| case "$profile_name" in | |
| work) profile_name="chasevm" ;; | |
| esac | |
| echo "Applying $setup_type nix-darwin configuration..." | |
| echo "You will be prompted for your sudo password..." | |
| # Back up existing /etc files that nix-darwin needs to manage | |
| if [ -f /etc/zshrc ] && [ ! -f /etc/zshrc.before-nix-darwin ]; then | |
| echo "Backing up /etc/zshrc to /etc/zshrc.before-nix-darwin..." | |
| sudo mv /etc/zshrc /etc/zshrc.before-nix-darwin | |
| fi | |
| if [ -f /etc/zprofile ] && [ ! -f /etc/zprofile.before-nix-darwin ]; then | |
| echo "Backing up /etc/zprofile to /etc/zprofile.before-nix-darwin..." | |
| sudo mv /etc/zprofile /etc/zprofile.before-nix-darwin | |
| fi | |
| if [ -f /etc/zshenv ] && [ ! -f /etc/zshenv.before-nix-darwin ]; then | |
| echo "Backing up /etc/zshenv to /etc/zshenv.before-nix-darwin..." | |
| sudo mv /etc/zshenv /etc/zshenv.before-nix-darwin | |
| fi | |
| sudo "$NIX_BIN" run nix-darwin -- switch --flake "github:shedali/nix-darwin#${profile_name}" --refresh | |
| echo "$setup_type setup complete!" | |
| # Chase profiles need the imperative Chase/fincloud setup (GitHub Enterprise | |
| # login, MDM, fincloud-config sync) which isn't part of nix-darwin. Offer it in | |
| # Minimal mode too so a Work/chasevm machine isn't left half-configured. | |
| if [[ "$profile_name" == "chasevm" || "$profile_name" == "chasehost" ]]; then | |
| echo "" | |
| if "$NIX_BIN" shell nixpkgs#gum --command gum confirm "Chase profile selected — run Chase-specific setup (chase-setup.sh) now?" </dev/tty; then | |
| if [ -f ~/.config/home-manager/chase-setup.sh ]; then | |
| cs=~/.config/home-manager/chase-setup.sh | |
| else | |
| curl -fsSL https://gist.githubusercontent.com/shedali/7f96ef92ead665e7cfc2f7652cb0b179/raw/chase-setup.sh -o /tmp/chase-setup.sh && chmod +x /tmp/chase-setup.sh && cs=/tmp/chase-setup.sh | |
| fi | |
| [ -n "${cs:-}" ] && bash "$cs" </dev/tty | |
| else | |
| echo "Skipping Chase setup. Run it later: bash ~/.config/home-manager/chase-setup.sh" | |
| fi | |
| fi | |
| exit 0 | |
| fi | |
| echo "Proceeding with full setup..." | |
| # Check if already authenticated with GitHub before entering nix shell | |
| export GH_AUTHENTICATED=false | |
| if [ -f ~/.config/gh/hosts.yml ] && grep -q "github.com" ~/.config/gh/hosts.yml 2>/dev/null; then | |
| echo "✓ Found existing GitHub authentication" | |
| export GH_AUTHENTICATED=true | |
| fi | |
| # Write sync_or_clone_repo to temp file for reuse across nix shell subshells | |
| _SYNC_FUNC=/tmp/bootstrap-sync-func.sh | |
| cat > "$_SYNC_FUNC" << 'SYNC_FUNC_EOF' | |
| sync_or_clone_repo() { | |
| local repo=$1 | |
| local target_dir=$2 | |
| if [ -d "$target_dir/.git" ]; then | |
| echo "Repository exists at $target_dir, syncing..." | |
| cd "$target_dir" | |
| # Check for unmerged paths (merge conflicts) | |
| if ! git diff --check &>/dev/null && git ls-files -u | grep -q .; then | |
| echo "ERROR: Repository has unmerged files (merge conflicts)" | |
| echo "Please resolve conflicts manually in $target_dir" | |
| cd - >/dev/null | |
| return 1 | |
| fi | |
| # Check for any changes (tracked, untracked, or modified) | |
| local has_changes=false | |
| if ! git diff-index --quiet HEAD -- 2>/dev/null || [ -n "$(git ls-files --others --exclude-standard)" ]; then | |
| echo "Stashing local changes (including untracked files)..." | |
| git stash push -u -m "bootstrap.sh auto-stash $(date +%Y-%m-%d_%H-%M-%S)" | |
| has_changes=true | |
| fi | |
| # Sync with remote | |
| echo "Pulling latest changes..." | |
| git pull --rebase || { | |
| echo "WARNING: Failed to pull changes, repository may have conflicts" | |
| if [ "$has_changes" = true ]; then | |
| echo "Attempting to pop stash..." | |
| git stash pop || echo "WARNING: Could not auto-pop stash, run 'git stash pop' manually later" | |
| fi | |
| cd - >/dev/null | |
| return 1 | |
| } | |
| # Pop stash if we created one | |
| if [ "$has_changes" = true ]; then | |
| echo "Restoring stashed changes..." | |
| git stash pop || echo "WARNING: Could not auto-pop stash, changes are still in stash. Run 'git stash list' to see them." | |
| fi | |
| cd - >/dev/null | |
| else | |
| echo "Cloning $repo to $target_dir..." | |
| if [ -d "$target_dir" ]; then | |
| echo "WARNING: Directory exists but is not a git repo, removing..." | |
| /bin/rm -rf "$target_dir" | |
| fi | |
| gh repo clone "$repo" "$target_dir" | |
| fi | |
| } | |
| SYNC_FUNC_EOF | |
| # Use nix shell to temporarily get gh for authentication and repo management | |
| "$NIX_BIN" shell nixpkgs#gh nixpkgs#git --command bash -c ' | |
| source /tmp/bootstrap-sync-func.sh | |
| # Only authenticate if not already logged in | |
| mkdir -p ~/.config/gh | |
| if [ -f ~/.config/gh/hosts.yml ] && grep -q "github.com" ~/.config/gh/hosts.yml 2>/dev/null; then | |
| echo "Using existing GitHub authentication..." | |
| elif ! gh auth status &>/dev/null; then | |
| gh auth login | |
| fi | |
| # Inject token directly into git URL config so git never prompts for credentials | |
| GH_TOKEN=$(gh auth token 2>/dev/null) | |
| if [ -n "$GH_TOKEN" ]; then | |
| git config --global url."https://oauth2:${GH_TOKEN}@github.com/".insteadOf "https://github.com/" | |
| echo "✓ GitHub token configured for git" | |
| else | |
| echo "WARNING: Could not get GitHub token, git operations may prompt for credentials" | |
| fi | |
| sync_or_clone_repo shedali/home-manager ~/.config/home-manager | |
| sync_or_clone_repo shedali/nvim ~/.config/nvim | |
| ' | |
| # Use a unique backup extension per run so a retried bootstrap never fails on a | |
| # pre-existing *.backup (home-manager refuses "would be clobbered by backup"). | |
| # gh (and HM's own gh activation) rewrites ~/.config/gh/config.yml as a real file, | |
| # so this backup is expected on every run. | |
| cd ~/.config/home-manager && nix run home-manager/master -- switch -b "backup-$(date +%Y%m%d%H%M%S)" | |
| # Clone additional personal repos after home-manager creates directory structure | |
| echo "Cloning additional personal repositories..." | |
| "$NIX_BIN" shell nixpkgs#gh nixpkgs#git --command bash -c ' | |
| source /tmp/bootstrap-sync-func.sh | |
| sync_or_clone_repo shedali/blog ~/dev/shedali/writing/blog | |
| sync_or_clone_repo shedali/text-blog ~/dev/shedali/writing/text-blog | |
| sync_or_clone_repo shedali/citations ~/dev/shedali/writing/citations | |
| sync_or_clone_repo shedali/cv ~/dev/shedali/cv | |
| ' | |
| rm -f /tmp/bootstrap-sync-func.sh | |
| # Source the new profile to make newly installed packages available | |
| if [ -f ~/.nix-profile/etc/profile.d/hm-session-vars.sh ]; then | |
| . ~/.nix-profile/etc/profile.d/hm-session-vars.sh | |
| fi | |
| echo "Installing neovim plugins..." | |
| nvim --headless +'lua require("lazy").sync({wait=true})' +qall | |
| echo "Setup complete! Opening new terminal for verification..." | |
| osascript -e 'tell application "Terminal" to do script ""' | |
| # Ask which profile to use (now available after home-manager switch) | |
| echo "" | |
| echo "Select nix-darwin profile to apply..." | |
| # Available profiles | |
| PROFILES="personal | |
| mini | |
| chasehost | |
| air | |
| chasevm" | |
| # Try gum first, fall back to read if it fails | |
| set +e | |
| selected_profile=$(echo "$PROFILES" | gum choose --header "Select nix-darwin profile:" </dev/tty 2>/dev/tty) | |
| gum_exit_code=$? | |
| set -e | |
| if [ $gum_exit_code -eq 0 ] && [ -n "$selected_profile" ]; then | |
| echo "Profile selected: $selected_profile" | |
| else | |
| echo "Select profile:" | |
| echo " 1) personal - Full personal setup" | |
| echo " 2) mini - Mac mini server" | |
| echo " 3) chasehost - Chase work host machine" | |
| echo " 4) air - MacBook Air portable" | |
| echo " 5) chasevm - Chase virtual machines" | |
| read -p "Enter choice (1-5): " choice </dev/tty | |
| case "$choice" in | |
| 1) selected_profile="personal" ;; | |
| 2) selected_profile="mini" ;; | |
| 3) selected_profile="chasehost" ;; | |
| 4) selected_profile="air" ;; | |
| 5) selected_profile="chasevm" ;; | |
| *) | |
| echo "ERROR: Invalid choice" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
| echo "Profile selected: $selected_profile" | |
| fi | |
| # Back up existing /etc files that nix-darwin needs to manage | |
| if [ -f /etc/zshrc ] && [ ! -f /etc/zshrc.before-nix-darwin ]; then | |
| echo "Backing up /etc/zshrc to /etc/zshrc.before-nix-darwin..." | |
| sudo mv /etc/zshrc /etc/zshrc.before-nix-darwin | |
| fi | |
| if [ -f /etc/zprofile ] && [ ! -f /etc/zprofile.before-nix-darwin ]; then | |
| echo "Backing up /etc/zprofile to /etc/zprofile.before-nix-darwin..." | |
| sudo mv /etc/zprofile /etc/zprofile.before-nix-darwin | |
| fi | |
| if [ -f /etc/zshenv ] && [ ! -f /etc/zshenv.before-nix-darwin ]; then | |
| echo "Backing up /etc/zshenv to /etc/zshenv.before-nix-darwin..." | |
| sudo mv /etc/zshenv /etc/zshenv.before-nix-darwin | |
| fi | |
| # Apply the selected nix-darwin configuration | |
| echo "" | |
| echo "Applying nix-darwin configuration: $selected_profile" | |
| echo "You will be prompted for your sudo password..." | |
| if ! sudo "$NIX_BIN" run nix-darwin -- switch --flake "github:shedali/nix-darwin#${selected_profile}" --refresh; then | |
| echo "" | |
| echo "ERROR: Failed to apply nix-darwin configuration" >&2 | |
| echo "You may need to run this manually later:" | |
| echo " sudo $NIX_BIN run nix-darwin -- switch --flake github:shedali/nix-darwin#${selected_profile} --refresh" | |
| exit 1 | |
| fi | |
| echo "✓ nix-darwin $selected_profile configuration applied successfully" | |
| # Run Chase-specific setup for chase profiles | |
| if [[ "$selected_profile" == "chasevm" || "$selected_profile" == "chasehost" ]]; then | |
| echo "" | |
| echo "========================================" | |
| echo "Starting Chase work environment setup..." | |
| echo "========================================" | |
| echo "" | |
| # Setup 1Password | |
| echo "Step 1/3: Setting up 1Password..." | |
| echo "1Password app should be installed via nix-darwin configuration" | |
| echo "Now you need to sign in to 1Password and authenticate the CLI" | |
| # Check if user wants to setup 1Password | |
| setup_1password=false | |
| set +e | |
| if gum confirm "Open 1Password app to sign in?" </dev/tty 2>/dev/tty; then | |
| setup_1password=true | |
| else | |
| gum_exit=$? | |
| if [ $gum_exit -ne 0 ]; then | |
| # gum failed, fall back to read | |
| read -p "Open 1Password app to sign in? (y/n): " answer </dev/tty | |
| if [[ "$answer" =~ ^[Yy] ]]; then | |
| setup_1password=true | |
| fi | |
| fi | |
| fi | |
| set -e | |
| if [ "$setup_1password" = "true" ]; then | |
| # Check if 1Password app exists | |
| if [ ! -e "/Applications/1Password.app" ]; then | |
| echo "ERROR: 1Password app not found!" | |
| echo "Ensure 1Password is included in your nix-darwin configuration" | |
| if ! { gum confirm "Continue without 1Password setup?" </dev/tty 2>/dev/tty || { read -p "Continue without 1Password setup? (y/n): " answer </dev/tty && [[ "$answer" =~ ^[Yy] ]]; }; }; then | |
| exit 1 | |
| fi | |
| fi | |
| if [ -e "/Applications/1Password.app" ]; then | |
| open -a "1Password" | |
| echo "Please sign in to 1Password with your Chase account" | |
| if gum confirm "1Password sign-in complete?" </dev/tty 2>/dev/tty || { read -p "1Password sign-in complete? (y/n): " answer </dev/tty && [[ "$answer" =~ ^[Yy] ]]; }; then | |
| echo "1Password app setup confirmed" | |
| # Authenticate op CLI with the 1Password app | |
| echo "Now authenticating 1Password CLI (op)..." | |
| echo "The op CLI will connect to the 1Password app you just signed into" | |
| if op account list &>/dev/null; then | |
| echo "op CLI already authenticated" | |
| else | |
| # The op CLI should automatically connect to the 1Password app | |
| if op account get &>/dev/null 2>&1; then | |
| echo "op CLI connected to 1Password app successfully" | |
| else | |
| echo "op CLI authentication may need manual setup" | |
| echo "If prompted, follow the op CLI authentication flow" | |
| eval $(op signin) || echo "op signin had issues, but continuing..." | |
| fi | |
| fi | |
| fi | |
| fi | |
| fi | |
| # Setup sudo password caching | |
| echo "" | |
| echo "Step 2/3: Setting up sudo password caching with 1Password..." | |
| echo "" | |
| # Select which password to use | |
| echo "Which password should be used for sudo commands throughout this setup?" | |
| set +e | |
| password_choice=$(gum choose \ | |
| "Default Password (before MDM/Jamf Connect setup)" \ | |
| "System Password (after MDM/Jamf Connect setup)" </dev/tty 2>/dev/tty) | |
| gum_pwd_exit=$? | |
| set -e | |
| if [ $gum_pwd_exit -eq 0 ] && [ -n "$password_choice" ]; then | |
| echo "Password selected: $password_choice" | |
| else | |
| echo "Select password:" | |
| echo " 1) Default Password (before MDM/Jamf Connect setup)" | |
| echo " 2) System Password (after MDM/Jamf Connect setup)" | |
| read -p "Enter choice (1 or 2): " choice </dev/tty | |
| case "$choice" in | |
| 1) password_choice="Default Password (before MDM/Jamf Connect setup)" ;; | |
| 2) password_choice="System Password (after MDM/Jamf Connect setup)" ;; | |
| *) | |
| echo "WARNING: Invalid choice, skipping sudo caching" | |
| password_choice="" | |
| ;; | |
| esac | |
| fi | |
| if [ -n "$password_choice" ]; then | |
| case "$password_choice" in | |
| "Default Password (before MDM/Jamf Connect setup)") | |
| SUDO_PASSWORD_REF="op://Chase/JPMorgan Chase/Bootstrapping/default password" | |
| ;; | |
| "System Password (after MDM/Jamf Connect setup)") | |
| SUDO_PASSWORD_REF="op://Chase/JPMorgan Chase/Bootstrapping/system password" | |
| ;; | |
| esac | |
| fi | |
| # Cache the sudo password | |
| if [ -n "$SUDO_PASSWORD_REF" ] && command -v op &>/dev/null && op account get &>/dev/null; then | |
| echo "Retrieving sudo password from 1Password..." | |
| echo "Using: ${SUDO_PASSWORD_REF}" | |
| if op read "$SUDO_PASSWORD_REF" | sudo -S -v 2>/dev/null; then | |
| echo "✓ Sudo credentials cached successfully" | |
| echo "All subsequent sudo commands will use this cached password" | |
| # Keep sudo session alive in background | |
| ( | |
| while true; do | |
| sleep 50 | |
| sudo -n true 2>/dev/null || break | |
| done | |
| ) & | |
| SUDO_REFRESH_PID=$! | |
| # Setup trap to kill background process on exit | |
| trap "kill $SUDO_REFRESH_PID 2>/dev/null || true" EXIT | |
| else | |
| echo "WARNING: Failed to authenticate with 1Password password" | |
| echo "You may need to enter your password manually for sudo commands" | |
| fi | |
| else | |
| if [ -z "$SUDO_PASSWORD_REF" ]; then | |
| echo "WARNING: No password selected, sudo will prompt for password normally" | |
| else | |
| echo "WARNING: 1Password CLI not available, sudo will prompt for password normally" | |
| fi | |
| fi | |
| # Now run chase-setup.sh for Chase-specific configuration | |
| echo "" | |
| echo "Step 3/3: Running Chase-specific setup (chase-setup.sh)..." | |
| # Check if local copy exists (for development), otherwise download from gist | |
| if [ -f ~/.config/home-manager/chase-setup.sh ]; then | |
| echo "Using local chase-setup.sh from ~/.config/home-manager/" | |
| chase_setup_script=~/.config/home-manager/chase-setup.sh | |
| else | |
| echo "Downloading chase-setup.sh from gist..." | |
| if curl -fsSL https://gist.githubusercontent.com/shedali/7f96ef92ead665e7cfc2f7652cb0b179/raw/chase-setup.sh -o /tmp/chase-setup.sh; then | |
| echo "chase-setup.sh downloaded successfully" | |
| chmod +x /tmp/chase-setup.sh | |
| chase_setup_script=/tmp/chase-setup.sh | |
| else | |
| echo "ERROR: Failed to download chase-setup.sh" >&2 | |
| exit 1 | |
| fi | |
| fi | |
| echo "Running chase-setup.sh..." | |
| bash "$chase_setup_script" | |
| exit_code=$? | |
| if [ $exit_code -eq 0 ]; then | |
| echo "Chase setup completed successfully!" | |
| elif [ $exit_code -eq 130 ]; then | |
| echo "Chase setup was cancelled by user" | |
| exit 0 | |
| else | |
| echo "ERROR: chase-setup.sh failed with exit code $exit_code" >&2 | |
| echo "You can try running it manually: bash $chase_setup_script" | |
| exit $exit_code | |
| fi | |
| else | |
| echo "" | |
| echo "$selected_profile setup complete!" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment