-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathinstall.zsh
executable file
·626 lines (526 loc) · 19 KB
/
install.zsh
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
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
#!/usr/bin/env zsh
# =============================================================================
#
# Dotfiles Installer Script for macOS
#
# Author: AnalogCyan
# License: Unlicense
#
# =============================================================================
set -e # Exit immediately if a command exits with a non-zero status
set -u # Treat unset variables as an error
# =============================================================================
# CONFIGURATION
# =============================================================================
# Homebrew package lists
BREW_TAPS=(
"1password/tap"
"epk/epk"
"gromgit/fuse"
"homebrew-ffmpeg/ffmpeg"
"homebrew/cask"
"homebrew/cask-fonts"
"homebrew/services"
"imxieyi/waifu2x"
"nextfire/tap"
"yt-dlp/taps"
)
BREW_FORMULAE=(
"antidote" # Plugin manager for zsh
"aria2" # High speed download utility with multi-protocol support
"autoconf-archive" # Collection of macros for GNU Autoconf
"automake" # Tool for generating GNU Standards-compliant Makefiles
"bat" # Cat clone with syntax highlighting and Git integration
"btop" # Resource monitor with CPU, memory, disk, and network usage
"ccache" # Compiler cache for faster recompilation
"cmake" # Cross-platform build system generator
"colordiff" # Tool to colorize diff output
"curl" # Command line tool for transferring data with URLs
"docutils" # Text processing system for converting plaintext to various formats
"ffmpeg" # Play, record, convert, and stream audio and video
"findutils" # Collection of GNU find, xargs, and locate
"fortune" # Random quotations program
"fzf" # Command-line fuzzy finder
"gawk" # GNU awk utility
"gh" # GitHub's official command line tool
"git" # Distributed version control system
"glow" # Markdown reader for the terminal
"gnu-sed" # GNU implementation of the sed utility
"grep" # GNU grep, egrep and fgrep
"imagemagick" # Tools and libraries to manipulate images
"zsh" # UNIX shell (Z-Shell)
"lazygit" # Simple terminal UI for git commands
"lolcat" # Rainbow coloring for text output
"make" # Utility for directing compilation
"mas" # Mac App Store command line interface
"mosh" # Mobile shell with roaming and intelligent local echo
"ncdu" # NCurses disk usage viewer
"nerdfetch" # Clean system information tool
"nextfire/tap/apple-music-discord-rpc" # Discord Rich Presence for Apple Music
"ninja" # Small build system with focus on speed
"node" # JavaScript runtime environment
"p7zip" # 7-Zip file archiver with high compression ratio
"pandoc" # Universal document converter
"prettier" # Code formatter for multiple languages
"pv" # Monitor the progress of data through a pipeline
"rclone" # Rsync for cloud storage services
"sherlock" # Hunt down social media accounts by username
"starship" # Cross-shell prompt customization
"thefuck" # Magnificent app which corrects your previous console command
"toilet" # Display large colorful characters
"tokei" # Display statistics about your code
"viu" # Terminal image viewer with Unicode support
"wallpaper" # Manage the desktop wallpaper
"watch" # Executes a program periodically, showing output fullscreen
"wget" # Internet file retriever
"xz" # General-purpose data compression tool
"yt-dlp" # Fork of youtube-dl with additional features
"zoxide" # Smarter cd command with learning abilities
)
BREW_CASKS=(
"1password/tap/1password-cli"
"crunch"
"font-fira-code"
"font-hack-nerd-font"
"font-sf-mono-nerd-font"
"powershell"
"raycast"
"etcher"
)
NPM_PACKAGES=(
"prettier"
"prettier-plugin-sh"
"prettier-plugin-toml"
"prettier-plugin-tailwind"
)
MAS_APPS=(
"1219074514" # Curve (FKA Vectornator)
"1320666476" # Wipr
"1412716242" # Tally
"1432182561" # Cascadea
"1452453066" # Hidden Bar
"1453273600" # Data Jar
"1463298887" # Userscripts
"1474276998" # HP Smart
"1480068668" # Messenger
"1482920575" # DuckDuckGo Privacy for Safari
"1544743900" # Hush
"1568262835" # Super Agent
"1569813296" # 1Password for Safari
"1573461917" # SponsorBlock for YouTube - Skip Sponsorships
"1577761052" # Malwarebytes Browser Guard
"1586435171" # Actions
"1589151155" # Rerouter
"1591303229" # Vinegar
"1591366129" # Convusic
"1592917505" # Noir
"1594183810" # Shortery
"1596706466" # Speediness
"1601151613" # Baking Soda
"409183694" # Keynote
"409201541" # Pages
"409203825" # Numbers
"417375580" # BetterSnapTool
"425424353" # The Unarchiver
"430255202" # Mactracker
"640199958" # Developer
"747648890" # Telegram
"803453959" # Slack
"899247664" # TestFlight
"937984704" # Amphetamine
)
# Git configuration
GIT_USER_NAME="AnalogCyan"
GIT_USER_EMAIL="git@thayn.me"
# Paths
DOTFILES_DIR="$(pwd)"
# =============================================================================
# UTILITY FUNCTIONS
# =============================================================================
# Colors for terminal output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log_info() {
echo -e "${BLUE}INFO:${NC} $1"
}
log_success() {
echo -e "${GREEN}SUCCESS:${NC} $1"
}
log_warning() {
echo -e "${YELLOW}WARNING:${NC} $1"
}
log_error() {
echo -e "${RED}ERROR:${NC} $1"
}
confirm() {
read -r "REPLY?$1 (y/n) "
case "$REPLY" in
[yY][eE][sS] | [yY])
return 0
;;
*)
return 1
;;
esac
}
# =============================================================================
# INSTALLATION FUNCTIONS
# =============================================================================
install_updates() {
log_info "Ensuring system is up-to-date..."
# Update macOS system software
log_info "Checking for macOS system updates..."
sudo softwareupdate -ia --force --verbose || {
log_warning "Some macOS updates may have failed to install."
}
# Update Homebrew and packages if installed
if command -v brew &>/dev/null; then
log_info "Updating Homebrew packages..."
brew update || {
log_warning "Failed to update Homebrew."
}
# Upgrade all packages
brew upgrade || {
log_warning "Some Homebrew packages failed to upgrade."
}
# Clean up old versions
brew cleanup || {
log_warning "Homebrew cleanup failed."
}
fi
log_success "System update process completed."
}
check_system_compatibility() {
log_info "Checking system compatibility..."
if [[ "$(uname)" != "Darwin" ]]; then
log_error "This script is only designed for macOS. Aborting."
exit 1
fi
log_success "System compatibility check passed."
}
install_homebrew() {
log_info "Installing Homebrew..."
# Check if Homebrew is already installed
if command -v brew &>/dev/null; then
log_info "Homebrew is already installed. Updating..."
brew update || {
log_warning "Failed to update Homebrew."
}
else
log_info "🍺 Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || {
log_error "Failed to install Homebrew."
exit 1
}
echo '# Set PATH, MANPATH, etc., for Homebrew.' >>"$HOME/.zprofile"
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >>"$HOME/.zprofile"
eval "$(/opt/homebrew/bin/brew shellenv)"
fi
log_success "Homebrew installed."
}
install_binary_scripts() {
log_info "Installing binary scripts and utilities..."
# Create necessary directories
mkdir -pv ~/bin/apps/pfetch/ || {
log_error "Failed to create bin directories."
return 1
}
# Copy bin scripts
log_info "Copying binary scripts..."
if [ -d "$DOTFILES_DIR/Nix/bin" ]; then
cp "$DOTFILES_DIR/Nix/bin/"* ~/bin/ || {
log_warning "Failed to copy bin scripts."
}
else
log_warning "Bin scripts directory not found."
fi
# Install pfetch
log_info "Installing pfetch..."
if [ ! -d "$HOME/bin/apps/pfetch/.git" ]; then
git clone https://github.com/dylanaraps/pfetch.git ~/bin/apps/pfetch/ || {
log_warning "Failed to clone pfetch repository."
}
else
(cd ~/bin/apps/pfetch && git pull) || {
log_warning "Failed to update pfetch."
}
fi
# Make sure scripts are executable
find ~/bin -type f -exec chmod +x {} \; 2>/dev/null
log_success "Binary scripts and utilities installed."
}
install_config_files() {
log_info "Installing configuration files..."
# Create necessary directories
mkdir -pv ~/.config/zsh/functions ~/.zsh.d || {
log_warning "Failed to create zsh directories."
}
# Backup existing zshrc if it exists
if [ -f "$HOME/.zshrc" ]; then
log_info "Backing up existing .zshrc to .zshrc.dotbak"
mv "$HOME/.zshrc" "$HOME/.zshrc.dotbak" || {
log_warning "Failed to backup .zshrc."
}
fi
# Copy configuration files
if [ -f "$DOTFILES_DIR/Nix/.zshrc" ]; then
cp "$DOTFILES_DIR/Nix/.zshrc" ~/.zshrc || {
log_warning "Failed to copy .zshrc."
}
else
log_error "Could not find .zshrc in the dotfiles repo."
# Create a minimal .zshrc file with proper initialization order
log_info "Creating a minimal .zshrc file..."
cat >"$HOME/.zshrc" <<EOF
# =============================================================================
# Core Configuration
# =============================================================================
# Environment Paths
export PATH=\$HOME/bin:/usr/local/bin:\$PATH
# Session Editor
export EDITOR='vim'
# =============================================================================
# Shell Configuration
# =============================================================================
# Initialize completion system before Antidote
autoload -Uz compinit
compinit -d ~/.zcompdump
# History configuration
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
setopt appendhistory
setopt histignorealldups
setopt histignorespace
# =============================================================================
# Plugin Management (Antidote)
# =============================================================================
# Initialize Antidote
source "\$(brew --prefix)/opt/antidote/share/antidote/antidote.zsh" 2>/dev/null || source "\$HOME/.antidote/antidote.zsh"
antidote load ~/.zsh_plugins.txt
# Set completion options after plugins are loaded
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
# =============================================================================
# Tool Initializations
# =============================================================================
# Initialize modern tools
eval \$(thefuck --alias 2>/dev/null)
eval "\$(zoxide init zsh)"
# Load fzf if it exists
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
# Initialize Starship prompt
eval "\$(starship init zsh)"
EOF
fi
# Copy plugins file with updated configuration
if [ -f "$DOTFILES_DIR/Nix/.zsh_plugins.txt" ]; then
cp "$DOTFILES_DIR/Nix/.zsh_plugins.txt" ~/.zsh_plugins.txt || {
log_warning "Failed to copy .zsh_plugins.txt."
}
log_info "Note: Deprecated plugins have been removed and replaced with maintained alternatives."
log_info " - zpm-zsh/1password replaced with official 1Password CLI"
log_info " - Docker plugins replaced with official completions"
log_info " - Other unmaintained plugins have been removed or replaced"
fi
# Copy custom functions
if [ -d "$DOTFILES_DIR/Nix/functions" ]; then
cp "$DOTFILES_DIR/Nix/functions/"*.zsh ~/.config/zsh/functions/ || {
log_warning "Failed to copy zsh functions."
}
else
log_error "Could not find functions directory in the dotfiles repo."
fi
# Create iCloud & Downloads symlinks
log_info "Creating symbolic links for iCloud and Downloads..."
ln -sf "$HOME/Library/Mobile Documents/com~apple~CloudDocs/iCloud" "$HOME/iCloud" || {
log_warning "Failed to create iCloud symlink."
}
ln -sf "$HOME/Library/Mobile Documents/com~apple~CloudDocs/Downloads" "$HOME/Downloads" || {
log_warning "Failed to create Downloads symlink."
}
# Install and configure Starship prompt
install_starship_prompt
log_success "Configuration files installed."
}
install_starship_prompt() {
log_info "Configuring Starship prompt..."
# Create config directory if it doesn't exist
mkdir -p ~/.config
# Copy starship.toml from dotfiles repo to ~/.config/
if [ -f "$DOTFILES_DIR/starship.toml" ]; then
cp "$DOTFILES_DIR/starship.toml" ~/.config/starship.toml || {
log_warning "Failed to copy starship.toml"
}
log_success "Copied starship.toml to ~/.config/"
else
log_error "starship.toml not found in dotfiles directory"
# Create fallback configuration if file doesn't exist
log_info "Creating default starship.toml configuration..."
curl -sS https://starship.rs/presets/toml/minimal.toml >~/.config/starship.toml
fi
log_success "Starship prompt configured."
}
install_homebrew_packages() {
log_info "Installing Homebrew packages..."
# Install Homebrew taps
log_info "Installing Homebrew taps..."
for tap in "${BREW_TAPS[@]}"; do
log_info "Tapping $tap..."
brew tap "$tap" || {
log_warning "Failed to tap $tap."
}
done
# Install Homebrew formulae
log_info "Installing Homebrew formulae..."
for formula in "${BREW_FORMULAE[@]}"; do
log_info "Installing $formula..."
brew install "$formula" || {
log_warning "Failed to install $formula."
}
done
# Install Homebrew casks
log_info "Installing Homebrew casks..."
for cask in "${BREW_CASKS[@]}"; do
log_info "Installing $cask..."
brew install --cask "$cask" || {
log_warning "Failed to install $cask."
}
done
# Install Nerd Fonts
log_info "Installing Nerd Fonts..."
nfonts=$(brew search "Nerd Font")
for item in ${nfonts}; do
if [[ "$item" == *"nerd-font"* ]]; then
brew install --cask "$item" || {
log_warning "Failed to install $item."
}
fi
done
log_success "Homebrew packages installed."
}
install_npm_packages() {
log_info "Installing NPM packages..."
# Check if npm is installed
if ! command -v npm &>/dev/null; then
log_error "npm is not installed. Skipping NPM packages."
return 1
fi
# Install NPM packages
for package in "${NPM_PACKAGES[@]}"; do
log_info "Installing $package..."
npm i -g "$package" || {
log_warning "Failed to install $package."
}
done
log_success "NPM packages installed."
}
install_mas_apps() {
log_info "Installing Mac App Store applications..."
# Check if mas is installed
if ! command -v mas &>/dev/null; then
log_error "mas is not installed. Skipping Mac App Store applications."
return 1
fi
# Check if user is signed in to the App Store
mas account &>/dev/null
if [ $? -ne 0 ]; then
log_warning "You are not signed in to the App Store. Please sign in and try again."
return 1
fi
# Install Mac App Store applications
for app in "${MAS_APPS[@]}"; do
app_id=$(echo "$app" | awk '{print $1}')
app_name=$(echo "$app" | awk '{for(i=2;i<=NF;++i)print $i}' | sed 's/# //')
log_info "Installing $app_name..."
mas install "$app_id" || {
log_warning "Failed to install $app_name."
}
done
log_success "Mac App Store applications installed."
}
configure_git() {
log_info "Configuring git..."
if ! command -v git &>/dev/null; then
log_error "Git is not installed. Cannot configure git."
return 1
fi
# Choose appropriate editor based on environment
local editor
if command -v code &>/dev/null; then
editor="code --wait"
else
editor="vim" # Default to vim if VSCode is not installed
fi
git config --global core.editor "$editor"
git config --global user.name "$GIT_USER_NAME"
git config --global user.email "$GIT_USER_EMAIL"
log_success "Git configured."
}
configure_zsh() {
log_info "Configuring Homebrew zsh..."
# Get the path to Homebrew's zsh
BREW_ZSH="$(brew --prefix)/bin/zsh"
# Check if Homebrew's zsh is installed
if [ ! -f "$BREW_ZSH" ]; then
log_error "Homebrew zsh not found. Please ensure it's installed."
return 1
fi
# Add Homebrew's zsh to /etc/shells if it's not already there
if ! grep -q "$BREW_ZSH" /etc/shells; then
log_info "Adding Homebrew zsh to /etc/shells..."
echo "$BREW_ZSH" | sudo tee -a /etc/shells >/dev/null || {
log_error "Failed to add Homebrew zsh to /etc/shells."
return 1
}
fi
# Change the default shell to Homebrew's zsh
log_info "Changing default shell to Homebrew zsh..."
chsh -s "$BREW_ZSH" || {
log_error "Failed to change default shell."
return 1
}
log_success "Homebrew zsh configured as default shell."
}
# =============================================================================
# MAIN EXECUTION
# =============================================================================
main() {
# Print banner
echo "====================================="
echo " macOS Dotfiles Installation Script"
echo "====================================="
echo
# Basic system checks
check_system_compatibility
# Update system
install_updates
# Install Homebrew
install_homebrew
# Configure zsh
configure_zsh
# Install binary scripts
install_binary_scripts
# Install configuration files
install_config_files
# Install package managers and packages
install_homebrew_packages
install_npm_packages
install_mas_apps
# Configure git
configure_git
# Completion message
echo
echo "====================================="
log_success "Dotfiles installation complete!"
echo "====================================="
echo "🎉 Please restart your terminal to see the changes!"
if confirm "Would you like to restart your terminal now?"; then
log_info "Please close and reopen your terminal manually."
fi
}
# Execute main function
main "$@"