-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap.sh
More file actions
executable file
Β·360 lines (305 loc) Β· 11.7 KB
/
bootstrap.sh
File metadata and controls
executable file
Β·360 lines (305 loc) Β· 11.7 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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#!/bin/bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log_info() { echo -e "${BLUE}βΉοΈ $1${NC}"; }
log_success() { echo -e "${GREEN}β
$1${NC}"; }
log_warning() { echo -e "${YELLOW}β οΈ $1${NC}"; }
log_error() { echo -e "${RED}β $1${NC}"; }
# Run command with timeout across GNU/macOS environments.
run_with_timeout() {
local seconds="$1"
shift
if command -v timeout >/dev/null 2>&1; then
timeout "$seconds" "$@"
return $?
fi
if command -v gtimeout >/dev/null 2>&1; then
gtimeout "$seconds" "$@"
return $?
fi
"$@" &
local cmd_pid=$!
(
sleep "$seconds"
kill "$cmd_pid" >/dev/null 2>&1 || true
) &
local timer_pid=$!
wait "$cmd_pid"
local cmd_status=$?
kill "$timer_pid" >/dev/null 2>&1 || true
wait "$timer_pid" 2>/dev/null || true
return "$cmd_status"
}
# Configuration
REPO_URL="${DOTFILES_REPO_URL:-}" # Set this environment variable or update below
USERNAME="amoselmaliah"
main() {
log_info "Starting macOS Development Environment Setup..."
log_info "Target: Neovim 0.11.1 + LazyVim + Nix/Home Manager"
echo
# Check system requirements
check_requirements
# Install prerequisites
install_xcode_tools
# Install and configure Nix
install_nix
enable_nix_flakes
# Get configuration files
get_configurations
# Activate Home Manager
activate_home_manager
# Bootstrap Neovim
bootstrap_neovim
# Verify installation
verify_installation
# Show completion message
show_completion
}
check_requirements() {
log_info "Checking system requirements..."
# Check macOS version
if ! sw_vers | grep -q "macOS"; then
log_error "This script requires macOS"
exit 1
fi
# Check architecture
if [[ "$(uname -m)" != "arm64" ]]; then
log_warning "This configuration is optimized for Apple Silicon (arm64)"
log_warning "You're running on $(uname -m) - some packages may not be available"
fi
# Check free space (rough estimate)
available_space=$(df -BG "$HOME" | tail -1 | awk '{print $4}' | sed 's/G//')
if [[ $available_space -lt 3 ]]; then
log_warning "Low disk space detected. Nix store and plugins require ~2GB"
fi
log_success "System requirements check completed"
}
install_xcode_tools() {
log_info "Installing Xcode Command Line Tools..."
if xcode-select -p >/dev/null 2>&1; then
log_success "Xcode Command Line Tools already installed"
else
log_info "Installing Xcode Command Line Tools (this may take a while)..."
xcode-select --install
# Wait for installation to complete
log_info "Waiting for Xcode Command Line Tools installation to complete..."
until xcode-select -p >/dev/null 2>&1; do
sleep 5
done
log_success "Xcode Command Line Tools installed successfully"
fi
}
install_nix() {
log_info "Installing Nix package manager..."
if command -v nix >/dev/null 2>&1; then
log_success "Nix already installed ($(nix --version))"
else
log_info "Downloading and installing Nix..."
curl -L https://nixos.org/nix/install | sh
# Source Nix in current shell
if [[ -f /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]]; then
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
fi
# Verify installation
if command -v nix >/dev/null 2>&1; then
log_success "Nix installed successfully ($(nix --version))"
else
log_error "Nix installation failed"
exit 1
fi
fi
}
enable_nix_flakes() {
log_info "Enabling Nix flakes..."
mkdir -p ~/.config/nix
if grep -q "experimental-features.*flakes" ~/.config/nix/nix.conf 2>/dev/null; then
log_success "Nix flakes already enabled"
else
echo 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf
log_success "Nix flakes enabled"
fi
}
get_configurations() {
log_info "Getting configuration files..."
if [[ -n "$REPO_URL" ]]; then
# Clone from repository
if [[ -d ~/.config/home-manager ]]; then
log_info "Configuration directory exists, pulling latest changes..."
cd ~/.config/home-manager
git pull || log_warning "Failed to pull latest changes, continuing with existing config"
else
log_info "Cloning configuration repository..."
git clone "$REPO_URL" ~/.config/home-manager
log_success "Configuration repository cloned"
fi
else
# Check if config already exists
if [[ -d ~/.config/home-manager ]] && [[ -f ~/.config/home-manager/flake.nix ]]; then
log_success "Configuration files already present"
else
log_error "Configuration files not found!"
echo
log_info "Please either:"
log_info "1. Set DOTFILES_REPO_URL environment variable and re-run:"
log_info " export DOTFILES_REPO_URL='https://github.com/yourname/dotfiles.git'"
log_info " ./bootstrap.sh"
echo
log_info "2. Or manually copy configuration files:"
log_info " rsync -avz user@source-machine:~/.config/home-manager/ ~/.config/home-manager/"
log_info " rsync -avz user@source-machine:~/.config/nvim/ ~/.config/nvim/"
exit 1
fi
fi
# Verify essential files
local required_files=(
"~/.config/home-manager/flake.nix"
"~/.config/home-manager/flake.lock"
"~/.config/home-manager/home.nix"
)
for file in "${required_files[@]}"; do
if [[ ! -f ${file/\~/$HOME} ]]; then
log_error "Required file missing: $file"
exit 1
fi
done
log_success "All required configuration files present"
}
activate_home_manager() {
log_info "Activating Home Manager configuration..."
# First time setup may take a while
log_info "This may take several minutes on first run as Nix downloads packages..."
if nix run home-manager/master -- switch --flake ~/.config/home-manager#$USERNAME; then
log_success "Home Manager activated successfully"
# Verify Home Manager is working
if command -v home-manager >/dev/null 2>&1; then
log_success "Home Manager available ($(home-manager --version))"
else
log_warning "Home Manager command not found in PATH, but activation succeeded"
fi
else
log_error "Home Manager activation failed"
log_info "Common fixes:"
log_info "- Ensure flake.nix has the correct username in homeConfigurations"
log_info "- Check that all required files are present"
log_info "- Try running: nix flake check ~/.config/home-manager"
exit 1
fi
}
bootstrap_neovim() {
log_info "Bootstrapping Neovim and LazyVim..."
# Check if nvim config exists, if not copy it
if [[ ! -d ~/.config/nvim ]]; then
if [[ -n "$REPO_URL" ]] && [[ -d ~/.config/home-manager/nvim-config ]]; then
log_info "Copying Neovim configuration from repository..."
cp -r ~/.config/home-manager/nvim-config ~/.config/nvim
else
log_warning "Neovim configuration not found at ~/.config/nvim"
log_info "LazyVim will use default configuration"
fi
fi
# Bootstrap LazyVim (headless installation)
log_info "Installing LazyVim plugins (this may take a few minutes)..."
if run_with_timeout 300 nvim --headless "+Lazy! sync" +qa 2>/dev/null; then
log_success "LazyVim plugins installed successfully"
else
log_warning "LazyVim plugin installation may have failed or timed out"
log_info "You can manually run ':Lazy sync' inside Neovim later"
fi
# Verify plugin installation
if [[ -d ~/.local/share/nvim/lazy ]] && [[ $(ls ~/.local/share/nvim/lazy | wc -l) -gt 20 ]]; then
plugin_count=$(ls ~/.local/share/nvim/lazy | wc -l)
log_success "LazyVim plugins installed: $plugin_count plugins"
else
log_warning "Plugin installation verification failed"
fi
}
verify_installation() {
log_info "Verifying installation..."
echo
# Check core tools
echo "π Core Tools:"
for cmd in nix home-manager nvim; do
if command -v "$cmd" >/dev/null 2>&1; then
version=$($cmd --version 2>/dev/null | head -1 || echo "unknown")
printf " β
%-15s %s\n" "$cmd" "$version"
else
printf " β %-15s %s\n" "$cmd" "not found"
fi
done
echo
# Check LSPs
echo "π§ Language Servers:"
for lsp in gopls pyright typescript-language-server bash-language-server lua-language-server; do
if command -v "$lsp" >/dev/null 2>&1; then
printf " β
%-25s available\n" "$lsp"
else
printf " β οΈ %-25s not found\n" "$lsp"
fi
done
echo
# Check PATH priority
echo "π€οΈ PATH Priority:"
nix_profile_pos=$(echo "$PATH" | tr ':' '\n' | nl | grep nix-profile | head -1 | awk '{print $1}')
if [[ -n "$nix_profile_pos" ]] && [[ "$nix_profile_pos" -le 5 ]]; then
printf " β
~/.nix-profile/bin at position %d (good)\n" "$nix_profile_pos"
else
printf " β οΈ ~/.nix-profile/bin not found in early PATH positions\n"
fi
echo
# Check Neovim setup
echo "β‘ Neovim Setup:"
if [[ "$EDITOR" == "nvim" ]]; then
printf " β
%-20s %s\n" "EDITOR" "$EDITOR"
else
printf " β οΈ %-20s %s (expected: nvim)\n" "EDITOR" "${EDITOR:-not set}"
fi
if [[ -d ~/.local/share/nvim/lazy/LazyVim ]]; then
printf " β
%-20s installed\n" "LazyVim"
else
printf " β %-20s not found\n" "LazyVim"
fi
if [[ -d ~/.local/share/nvim/mason/bin ]] && [[ $(ls ~/.local/share/nvim/mason/bin | wc -l) -gt 0 ]]; then
mason_tools=$(ls ~/.local/share/nvim/mason/bin | wc -l)
printf " β
%-20s %d tools\n" "Mason tools" "$mason_tools"
else
printf " β οΈ %-20s no tools found\n" "Mason tools"
fi
}
show_completion() {
echo
log_success "π Installation completed!"
echo
echo "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
echo
echo "π Your development environment is ready!"
echo
echo "π Quick Start:"
echo " β’ Launch Neovim: nvim"
echo " β’ Edit this config: nvim ~/.config/nvim/init.lua"
echo " β’ Manage plugins: :Lazy (inside Neovim)"
echo " β’ Update packages: home-manager switch"
echo
echo "π Verification commands:"
echo " β’ nix --version"
echo " β’ home-manager --version"
echo " β’ nvim --version"
echo
echo "π Need help?"
echo " β’ Check README.md in ~/.config/home-manager/"
echo " β’ View LazyVim docs: https://lazyvim.github.io/"
echo " β’ Rollback if needed: home-manager switch --rollback"
echo
echo "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
echo
log_info "Enjoy your new development environment! π―"
}
# Run main function if script is executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi