-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·191 lines (170 loc) · 9.04 KB
/
setup.sh
File metadata and controls
executable file
·191 lines (170 loc) · 9.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#!/usr/bin/env bash
# setup.sh — Bootstrap script for the developer environment.
# Installs Homebrew (if needed), taps this repo, runs brew bundle,
# symlinks dotfiles, and sets up credentials.
#
# Usage (fresh machine):
# git clone https://github.com/amcheste/mac-dev-setup ~/Repos/amcheste/mac-dev-setup
# cd ~/Repos/amcheste/mac-dev-setup && bash setup.sh
set -euo pipefail
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ── Constants ────────────────────────────────────────────────────────────────
FAILED=1
SUCCESS=0
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Developer Environment Setup"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# ── Preflight checks ──────────────────────────────────────────────────────────
echo "▶ Preflight checks..."
PREFLIGHT_OK=1
# Must NOT be running as root / sudo
if [[ "$(id -u)" -eq 0 ]]; then
echo ""
echo " ✗ This script must not be run as root or with sudo."
echo ""
echo " Homebrew refuses to run as root. Run setup.sh as your normal"
echo " admin user account — without sudo:"
echo ""
echo " bash setup.sh"
echo ""
echo " If you saw a 'Homebrew prefix is not writable' error, re-run"
echo " setup.sh normally (without sudo) — it will fix the ownership"
echo " automatically by prompting for your password."
echo ""
exit $FAILED
fi
# macOS only
if [[ "$(uname)" != "Darwin" ]]; then
echo " ERROR: This setup script is for macOS only."
exit $FAILED
fi
# Must be an admin account (member of the 'admin' group)
if ! id -Gn | tr ' ' '\n' | grep -q '^admin$'; then
echo ""
echo " ✗ This account is not an administrator."
echo ""
echo " Homebrew and most developer tools require admin (sudo) access."
echo " Please run this script from an admin account, or ask your Mac's"
echo " administrator to run it first."
echo ""
exit $FAILED
fi
echo " Admin account ✓"
# If Homebrew is already installed, make sure it's functional
if command -v brew &>/dev/null; then
BREW_PREFIX="$(brew --prefix 2>/dev/null)" || BREW_PREFIX=""
if [[ -z "$BREW_PREFIX" ]]; then
echo " ✗ Homebrew is installed but not functional."
echo " Try: brew update or reinstall from https://brew.sh"
PREFLIGHT_OK=0
elif [[ ! -w "$BREW_PREFIX" ]]; then
echo " ✗ Homebrew prefix '$BREW_PREFIX' is not writable by this user."
echo " Attempting to fix ownership of Homebrew directories (sudo required)..."
# Only chown the specific subdirs Homebrew uses — not the entire prefix,
# which may contain system-managed files (e.g. /usr/local on Intel Macs).
BREW_SUBDIRS=()
for d in bin Cellar Caskroom etc Frameworks include lib Library opt sbin share var; do
[[ -d "$BREW_PREFIX/$d" ]] && BREW_SUBDIRS+=("$BREW_PREFIX/$d")
done
if [[ ${#BREW_SUBDIRS[@]} -gt 0 ]] && sudo chown -R "$(whoami)" "${BREW_SUBDIRS[@]}" 2>/dev/null; then
echo " Homebrew directory ownership fixed ✓"
else
echo ""
echo " Could not fix automatically. Run this manually, then re-run setup.sh:"
echo ""
echo " sudo chown -R \$(whoami) ${BREW_SUBDIRS[*]:-$BREW_PREFIX}"
echo ""
echo " ⚠ Do NOT re-run setup.sh with sudo — Homebrew refuses to run as root."
PREFLIGHT_OK=0
fi
else
echo " Homebrew writable ✓"
fi
fi
if [[ $PREFLIGHT_OK -eq 0 ]]; then
echo ""
echo " Please fix the issues above and re-run setup.sh."
exit $FAILED
fi
echo ""
# ── Repos directory ──────────────────────────────────────────────────────────
if [[ ! -d "$HOME/Repos" ]]; then
echo "▶ Creating ~/Repos..."
mkdir -p "$HOME/Repos"
fi
# ── Homebrew ─────────────────────────────────────────────────────────────────
echo "▶ Checking Homebrew..."
if ! command -v brew &>/dev/null; then
echo " Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" \
|| { echo "ERROR: Failed to install Homebrew"; exit $FAILED; }
# Add brew to PATH for Apple Silicon
if [[ -f /opt/homebrew/bin/brew ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
# shellcheck disable=SC2016 # single quotes intentional: writing literal string to file
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> "$HOME/.zprofile"
fi
else
echo " Homebrew already installed ✓"
fi
# ── Tap this repo ────────────────────────────────────────────────────────────
echo ""
echo "▶ Tapping amcheste/mac-dev-setup..."
brew tap amcheste/mac-dev-setup https://github.com/amcheste/mac-dev-setup 2>/dev/null || true
# Pre-tap third-party taps so brew bundle can resolve their formulae.
# brew bundle processes taps and formulae together which can cause lookup
# failures if the tap hasn't been added before the formula is fetched.
brew tap cirruslabs/cli 2>/dev/null || true
# ── Brew Bundle ──────────────────────────────────────────────────────────────
echo ""
echo "▶ Installing packages (this may take a few minutes)..."
# BREWFILE env var allows alternate package lists (e.g. Brewfile.vm for VM tests)
BREWFILE_PATH="${BREWFILE:-$REPO_DIR/Brewfile}"
echo " Using: $BREWFILE_PATH"
brew bundle --file="$BREWFILE_PATH" \
|| { echo "ERROR: brew bundle failed"; exit $FAILED; }
# ── Dotfiles ─────────────────────────────────────────────────────────────────
echo ""
echo "▶ Installing dotfiles..."
bash "$REPO_DIR/scripts/install-dotfiles.sh" \
|| { echo "ERROR: Failed to install dotfiles"; exit $FAILED; }
# ── Vim plugins ──────────────────────────────────────────────────────────────
echo ""
echo "▶ Installing Vim plugins..."
if [[ -f "$HOME/.vim/autoload/plug.vim" ]]; then
vim --not-a-term -c "set nomore" +PlugInstall +qall >/dev/null 2>&1 && echo " Vim plugins installed ✓" \
|| echo " Warning: vim +PlugInstall had errors (plugins may still be installed)"
else
echo " vim-plug not found — skipping (run: install-dotfiles.sh first)"
fi
# ── Credentials ──────────────────────────────────────────────────────────────
echo ""
echo "▶ Setting up credentials..."
if [[ ! -f "$HOME/.secrets" ]] || ! grep -q 'ANTHROPIC_API_KEY="..*"' "$HOME/.secrets" 2>/dev/null; then
bash "$REPO_DIR/scripts/setup-credentials.sh"
else
echo " ~/.secrets already configured ✓"
fi
# ── Claude Code MCPs ─────────────────────────────────────────────────────────
echo ""
echo "▶ Configuring Claude Code MCP servers..."
if command -v claude &>/dev/null; then
bash "$REPO_DIR/scripts/setup-mcps.sh"
else
echo " Claude Code not found — skipping MCP setup"
echo " Install Claude Code then run: bash scripts/setup-mcps.sh"
fi
# ── Done ─────────────────────────────────────────────────────────────────────
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Setup complete!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo " Restart your terminal, or run: source ~/.zshrc"
echo ""
echo " Claude Code is configured with:"
echo " • CLAUDE.md — your dev preferences and learned config"
echo " • MCP servers — GitHub, filesystem, memory, PostgreSQL"
echo ""
exit $SUCCESS