-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap
More file actions
executable file
·117 lines (101 loc) · 4.05 KB
/
bootstrap
File metadata and controls
executable file
·117 lines (101 loc) · 4.05 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
#!/usr/bin/env bash
#
# bootstrap — single-run dotfiles install for fresh macOS machines.
#
# Phases (idempotent; each detects-then-skips):
# 1. Homebrew install/upgrade
# 2. Dropbox cask install
# 3. Launch Dropbox.app
# 4. Wait for sign-in (~/.dropbox/info.json appears)
# 5. Wait for the dotfiles repo to sync (sentinel file appears)
# 6. exec ./install from the synced ~/Dropbox/repos/dotfiles
#
# Re-runs are safe at any time; Ctrl-C aborts cleanly and bootstrap resumes
# at the unfinished phase on the next run. Sign-in is the only human step.
set -Eeuo pipefail
BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/_lib/step.sh
source "${BASEDIR}/scripts/_lib/step.sh"
PHASES_TOTAL=6
DROPBOX_INFO="${HOME}/.dropbox/info.json"
WAIT_TIMEOUT=${BOOTSTRAP_WAIT_TIMEOUT:-1800} # 30 min default
WAIT_INTERVAL=${BOOTSTRAP_WAIT_INTERVAL:-5} # 5 sec default
TICK_EVERY=30 # ~30s elapsed-time ticks during waits
trap '_on_interrupt' INT
_on_interrupt() {
printf '\n⚠️ bootstrap interrupted; re-run ./bootstrap to resume.\n' >&2
exit 130
}
# Poll until the given test command succeeds or WAIT_TIMEOUT elapses.
# Emits an elapsed-time tick every TICK_EVERY seconds so the user sees progress.
# Usage: _wait_for "<human description>" <test command...>
_wait_for() {
local target=$1; shift
local elapsed=0 tick=0
while ! "$@" >/dev/null 2>&1; do
if (( elapsed >= WAIT_TIMEOUT )); then
printf '❌ Timed out after %ds waiting for %s.\n Re-run ./bootstrap to resume once the issue is resolved.\n' \
"$WAIT_TIMEOUT" "$target" >&2
exit 1
fi
sleep "$WAIT_INTERVAL"
elapsed=$(( elapsed + WAIT_INTERVAL ))
tick=$(( tick + WAIT_INTERVAL ))
if (( tick >= TICK_EVERY )); then
step_inner "$elapsed" "$WAIT_TIMEOUT" "still waiting for ${target} (${elapsed}s elapsed)"
tick=0
fi
done
}
# ----- Phase 1: Homebrew -----
if command -v brew >/dev/null 2>&1; then
step_outer 1 "$PHASES_TOTAL" 🍺 "Homebrew already present, skipping"
else
step_outer 1 "$PHASES_TOTAL" 🍺 "Installing Homebrew"
"${BASEDIR}/scripts/setup/setup-upgrade-homebrew"
step_done 🍺 "Homebrew installed"
fi
# ----- Phase 2: Dropbox cask -----
if brew list --cask dropbox >/dev/null 2>&1; then
step_outer 2 "$PHASES_TOTAL" 📦 "Dropbox cask already installed, skipping"
else
step_outer 2 "$PHASES_TOTAL" 📦 "Installing Dropbox cask"
brew install --cask dropbox
step_done 📦 "Dropbox cask installed"
fi
# ----- Phase 3: Launch Dropbox -----
if pgrep -x Dropbox >/dev/null 2>&1; then
step_outer 3 "$PHASES_TOTAL" 🚀 "Dropbox already running, skipping"
else
step_outer 3 "$PHASES_TOTAL" 🚀 "Launching Dropbox"
open -a Dropbox
step_done 🚀 "Dropbox launched"
fi
# ----- Phase 4: Wait for sign-in -----
if [[ -f $DROPBOX_INFO ]]; then
step_outer 4 "$PHASES_TOTAL" 🔑 "Dropbox already signed in, skipping"
else
step_outer 4 "$PHASES_TOTAL" 🔑 "Waiting for Dropbox sign-in"
cat <<'EOF'
>>> Please sign in to Dropbox in the app window that just opened.
>>> This script will resume automatically once sign-in completes.
>>> Press Ctrl-C any time to abort; re-run ./bootstrap to resume.
EOF
_wait_for "Dropbox sign-in (~/.dropbox/info.json)" test -f "$DROPBOX_INFO"
step_done 🔑 "Dropbox sign-in detected"
fi
DROPBOX_ROOT="$("${BASEDIR}/scripts/_lib/dropbox-info.py")"
DOTFILES_PATH="${DROPBOX_ROOT}/repos/dotfiles"
SENTINEL="${DOTFILES_PATH}/install"
# ----- Phase 5: Wait for sync of dotfiles repo -----
if [[ -f $SENTINEL ]]; then
step_outer 5 "$PHASES_TOTAL" 🔄 "Dotfiles repo already synced, skipping"
else
step_outer 5 "$PHASES_TOTAL" 🔄 "Waiting for ${DOTFILES_PATH} to sync"
_wait_for "dotfiles sync (${SENTINEL})" test -f "$SENTINEL"
step_done 🔄 "Dotfiles repo synced"
fi
# ----- Phase 6: Hand-off to ./install -----
step_outer 6 "$PHASES_TOTAL" 🤝 "Handing off to ${DOTFILES_PATH}/install"
cd "$DOTFILES_PATH"
exec ./install "$@"