Repository navigation
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·168 lines (148 loc) · 6.29 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·168 lines (148 loc) · 6.29 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
#!/usr/bin/env bash
set -euo pipefail
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROFILE_MARKER="$HOME/.dotfiles-profile"
echo "🚀 Bootstrapping machine from dotfiles"
# Machine profile: 'personal' installs everything; any other profile (e.g.
# 'edreams') is a company machine — base Brewfiles plus its own
# Brewfile.<profile> overlay, and no personal keys or identity. Profiles are
# discovered from the overlay files, so onboarding a new company is just
# dropping a Brewfile.<name>. Remembered per machine in ~/.dotfiles-profile
# so reruns and the sync agent agree.
profiles=(personal)
for overlay in "$DOTFILES_DIR"/Brewfile.*; do
name="${overlay##*/Brewfile.}"
if [[ "$name" != "personal" && "$name" != "sudo" && "$name" != *.sudo ]]; then
profiles+=("$name")
fi
done
PROFILE="${1:-}"
PROFILE="${PROFILE#--profile=}"
if [[ -z "$PROFILE" ]]; then
if [[ -f "$PROFILE_MARKER" ]]; then
PROFILE="$(cat "$PROFILE_MARKER")"
elif [[ -t 0 ]]; then
echo "Machine profile:"
select PROFILE in "${profiles[@]}"; do
[[ -n "$PROFILE" ]] && break
done
else
PROFILE="personal"
fi
fi
case " ${profiles[*]} " in
*" $PROFILE "*) ;;
*)
echo "Invalid profile '$PROFILE' (expected one of: ${profiles[*]})" >&2
exit 1
;;
esac
echo "$PROFILE" > "$PROFILE_MARKER"
echo "▶ Machine profile: $PROFILE"
if [[ "$(uname)" != "Darwin" ]]; then
echo "This setup only supports macOS" >&2
exit 1
fi
# Ask for the admin password once and keep the sudo timestamp warm for the
# whole run (it expires after ~5 min by default, causing repeated prompts
# during long installs). Interactive runs only.
if [[ -t 0 ]]; then
sudo -v
while true; do
sudo -n true
sleep 60
kill -0 "$$" 2>/dev/null || exit
done &
SUDO_KEEPALIVE_PID=$!
trap 'kill "$SUDO_KEEPALIVE_PID" 2>/dev/null' EXIT
fi
if [[ ! -x /opt/homebrew/bin/brew ]]; then
echo "▶ Installing Homebrew"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
eval "$(/opt/homebrew/bin/brew shellenv)"
# Compatibility with amd64-only apps
softwareupdate --install-rosetta --agree-to-license 2>/dev/null || true
echo "▶ Installing packages from Brewfile"
# Brew >= 6 refuses formulae from third-party taps unless explicitly trusted
for tap in sdkman/tap grishka/grishka fluxcd/tap; do
brew tap "$tap" 2>/dev/null || true
brew trust "$tap" 2>/dev/null || true
done
# Each profile stacks its overlay on top of the base Brewfile
brewfiles=("$DOTFILES_DIR/Brewfile" "$DOTFILES_DIR/Brewfile.$PROFILE")
sudo_brewfiles=("$DOTFILES_DIR/Brewfile.sudo")
if [[ -f "$DOTFILES_DIR/Brewfile.$PROFILE.sudo" ]]; then
sudo_brewfiles+=("$DOTFILES_DIR/Brewfile.$PROFILE.sudo")
fi
# A single broken cask must not abort the whole bootstrap: report and go on,
# the dotfiles-sync agent retries missing packages later anyway
cat "${brewfiles[@]}" | HOMEBREW_CASK_OPTS="--adopt" brew bundle install --file=- --no-upgrade \
|| echo "⚠️ Some Brewfile entries failed — check output above; sync will retry"
# Casks with privileged install steps; safe here because this run is
# interactive and sudo can prompt in the terminal
cat "${sudo_brewfiles[@]}" | HOMEBREW_CASK_OPTS="--adopt" brew bundle install --file=- --no-upgrade \
|| echo "⚠️ Some Brewfile.sudo entries failed — check output above"
# Colima (where the profile ships it) runs as a launchd service, so docker
# works after reboots without a manual `colima start`. VM specs are fixed on
# first creation (colima persists them per profile and every later start
# reuses them); they go to the default profile on purpose — the brew service
# and DOCKER_HOST both point there, not to a named profile.
if command -v colima >/dev/null 2>&1; then
if [[ ! -f "$HOME/.colima/default/colima.yaml" ]]; then
echo "▶ Creating colima VM (4 CPUs, 8GiB RAM, 60GiB disk, vz + Rosetta)"
colima start --cpu 4 --memory 8 --disk 60 --vm-type=vz --vz-rosetta
colima stop
fi
echo "▶ Starting colima as a service"
brew services start colima || true
fi
# Brew installs docker CLI plugins (compose, ...) under its own prefix;
# expose them so `docker compose` resolves. Left alone if ~/.docker/cli-plugins
# is a real directory owned by some other install.
docker_plugins="$(brew --prefix)/lib/docker/cli-plugins"
if [[ -d "$docker_plugins" && ( ! -e "$HOME/.docker/cli-plugins" || -L "$HOME/.docker/cli-plugins" ) ]]; then
mkdir -p "$HOME/.docker"
ln -sfn "$docker_plugins" "$HOME/.docker/cli-plugins"
fi
echo "▶ Installing npm globals"
if command -v npm >/dev/null 2>&1; then
for pkg in @anthropic-ai/claude-code @openai/codex; do
npm ls -g "$pkg" >/dev/null 2>&1 || npm install -g "$pkg"
done
else
echo "⚠️ npm not available (node install failed?); skipping npm globals"
fi
"$DOTFILES_DIR/link.sh"
"$DOTFILES_DIR/macos/defaults.sh"
if [[ "$PROFILE" == "personal" ]]; then
"$DOTFILES_DIR/setup/setup.sh"
else
echo "⏭️ $PROFILE profile: skipping personal SSH auth keys (gitlab, homelab)."
# Company machines still get git identity (prompted), a GitHub auth key and
# commit signing; identity goes first so the signing key registers under it
"$DOTFILES_DIR/setup/git/setup.sh"
"$DOTFILES_DIR/setup/ssh/00-config.sh"
"$DOTFILES_DIR/setup/ssh/10-github.sh"
"$DOTFILES_DIR/setup/ssh/40-git-signing.sh"
"$DOTFILES_DIR/setup/ssh/90-startup-load.sh"
fi
"$DOTFILES_DIR/agents/install-agents.sh"
# --- Migrations away from the legacy setup ---
OLD_AUTOUPDATE_PLIST="$HOME/Library/LaunchAgents/com.github.domt4.homebrew-autoupdate.plist"
if [[ -f "$OLD_AUTOUPDATE_PLIST" ]]; then
echo "▶ Removing homebrew-autoupdate (replaced by the brew-maintenance agent)"
launchctl bootout "gui/$(id -u)/com.github.domt4.homebrew-autoupdate" 2>/dev/null || true
rm -f "$OLD_AUTOUPDATE_PLIST"
rm -rf "$HOME/Library/Application Support/com.github.domt4.homebrew-autoupdate"
brew untap domt4/autoupdate 2>/dev/null || true
fi
if brew list powerlevel10k >/dev/null 2>&1 && [[ -d "$HOME/powerlevel10k" ]]; then
echo "▶ Removing legacy powerlevel10k clone (now installed via brew)"
rm -rf "$HOME/powerlevel10k"
fi
if brew list zsh-syntax-highlighting >/dev/null 2>&1 && [[ -d "$HOME/zsh-plugins" ]]; then
echo "▶ Removing legacy zsh-plugins clones (now installed via brew)"
rm -rf "$HOME/zsh-plugins"
fi
echo "✅ Done — open a new terminal session"