Last active
May 26, 2025 08:56
-
-
Save JosephKu/7801bf1b848ae5710e22 to your computer and use it in GitHub Desktop.
$ bash <(curl -s https://gist.githubusercontent.com/JosephKu/7801bf1b848ae5710e22/raw/kickstart-mac.sh) # Run this after installing Xcode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| fancy_echo() { | |
| local fmt="$1"; shift | |
| printf "\n$fmt\n" "$@" | |
| } | |
| append_to_zshrc() { | |
| local text="$1" zshrc | |
| local skip_new_line="${2:-0}" | |
| if [ -w "$HOME/.zshrc.local" ]; then | |
| zshrc="$HOME/.zshrc.local" | |
| else | |
| zshrc="$HOME/.zshrc" | |
| fi | |
| if ! grep -Fqs "$text" "$zshrc"; then | |
| if [ "$skip_new_line" -eq 1 ]; then | |
| printf "%s\n" "$text" >> "$zshrc" | |
| else | |
| printf "\n%s\n" "$text" >> "$zshrc" | |
| fi | |
| fi | |
| } | |
| trap 'ret=$?; test $ret -ne 0 && printf "failed\n\n" >&2; exit $ret' EXIT | |
| set -e | |
| if [ ! -d "$HOME/.bin/" ]; then | |
| mkdir "$HOME/.bin" | |
| fi | |
| if [ ! -f "$HOME/.zshrc" ]; then | |
| touch "$HOME/.zshrc" | |
| fi | |
| append_to_zshrc 'export PATH="$HOME/.bin:$PATH"' | |
| case "$SHELL" in | |
| */zsh) : ;; | |
| *) | |
| fancy_echo "Changing your shell to zsh ..." | |
| chsh -s "$(which zsh)" | |
| ;; | |
| esac | |
| if ! command -v brew >/dev/null; then | |
| fancy_echo "Installing Homebrew ..." | |
| /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
| append_to_zshrc '# recommended by brew doctor' | |
| append_to_zshrc 'export PATH="/usr/local/bin:$PATH"' 1 | |
| export PATH="/usr/local/bin:$PATH" | |
| else | |
| fancy_echo "Homebrew already installed. Skipping ..." | |
| fi | |
| if [[ $(uname -m) == 'arm64' ]]; then | |
| echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> $HOME/.zprofile | |
| eval "$(/opt/homebrew/bin/brew shellenv)" | |
| else | |
| echo 'eval "$(/usr/local/bin/brew shellenv)"' >> $HOME/.zprofile | |
| eval "$(/usr/local/bin/brew shellenv)" | |
| fi | |
| if brew list | grep -Fq brew-cask; then | |
| fancy_echo "Uninstalling old Homebrew-Cask ..." | |
| brew uninstall --force brew-cask | |
| fi | |
| fancy_echo "Updating Homebrew formulae ..." | |
| brew update | |
| brew bundle --file=- <<EOF | |
| # Unix | |
| brew "git" | |
| brew "git-lfs" | |
| brew "tig" | |
| brew "htop" | |
| brew "tree" | |
| brew "tmux" | |
| brew "vim" | |
| # Manage multiple runtime versions | |
| brew "asdf" | |
| # Image manipulation | |
| brew "imagemagick" | |
| # Databases | |
| #brew "postgresql@17", restart_service: :changed | |
| #brew "redis", restart_service: :changed | |
| EOF | |
| fancy_echo "Configuring asdf version manager ..." | |
| if [ -d "/opt/homebrew/opt/asdf/" ]; then | |
| append_to_zshrc "source /opt/homebrew/opt/asdf/libexec/asdf.sh" 1 | |
| fi | |
| add_or_update_asdf_plugin() { | |
| local name="$1" | |
| local url="$2" | |
| if ! asdf plugin list | grep -Fq "$name"; then | |
| asdf plugin add "$name" "$url" | |
| else | |
| asdf plugin update "$name" | |
| fi | |
| } | |
| source /opt/homebrew/opt/asdf/libexec/asdf.sh | |
| add_or_update_asdf_plugin "ruby" "https://github.com/asdf-vm/asdf-ruby.git" | |
| add_or_update_asdf_plugin "nodejs" "https://github.com/asdf-vm/asdf-nodejs.git" | |
| install_asdf_language() { | |
| local language="$1" | |
| local version | |
| version="$(asdf latest "$language")" | |
| if ! asdf list "$language" | grep -Fq "$version"; then | |
| asdf install "$language" "$version" | |
| asdf set -u "$language" "$version" | |
| fi | |
| } | |
| fancy_echo "Installing latest Ruby ..." | |
| install_asdf_language "ruby" | |
| gem update --system | |
| number_of_cores=$(sysctl -n hw.ncpu) | |
| bundle config --global jobs $((number_of_cores - 1)) | |
| fancy_echo "Installing latest Node ..." | |
| install_asdf_language "nodejs" | |
| if [ -f "$HOME/.kickstart.local" ]; then | |
| fancy_echo "Running your customizations from ~/.kickstart.local ..." | |
| . "$HOME/.kickstart.local" | |
| fi | |
| fancy_echo "Cleaning up old Homebrew formulae ..." | |
| brew cleanup | |
| prompt_yes_no() { | |
| while true; do | |
| read -p "$1 (y/n): " yn | |
| case $yn in | |
| [Yy]* ) return 0;; | |
| [Nn]* ) return 1;; | |
| * ) echo "Please answer yes or no.";; | |
| esac | |
| done | |
| } | |
| fancy_echo "Would you like to install recommended packages?" | |
| if prompt_yes_no "Install recommended formulae and casks?"; then | |
| fancy_echo "Installing recommended formulae..." | |
| # Define recommended formulae with comments | |
| recommended_formulae=( | |
| "openssl" # OpenSSL libraries and tools | |
| "knqyf263/pet/pet" # Command-line snippet manager | |
| "gh" # GitHub CLI | |
| "universal-ctags" # Universal Ctags for code indexing | |
| "wget" # Command-line utility for downloading files | |
| "jq" # Command-line JSON processor | |
| "bat" # A cat clone with syntax highlighting and Git integration | |
| "ripgrep" # Fast text search tool | |
| "ripgrep-all" # Search through files, including binary files | |
| "fd" # Simple, fast and user-friendly alternative to 'find' | |
| "fzf" # Command-line fuzzy finder | |
| "watchman" # Watches files and records changes | |
| ) | |
| # Install recommended formulae, skipping any missing or deprecated ones | |
| for formula in "${recommended_formulae[@]}"; do | |
| if brew info "$formula" >/dev/null 2>&1; then | |
| brew install "$formula" | |
| else | |
| fancy_echo "Warning: Formula '$formula' not found. Skipping ..." | |
| fi | |
| done | |
| fancy_echo "Installing recommended applications..." | |
| # Define recommended casks with comments | |
| recommended_casks=( | |
| "iterm2" # Terminal emulator for macOS | |
| "the-unarchiver" # Archive extraction utility | |
| "visual-studio-code" # Source-code editor developed by Microsoft | |
| "gpg-suite" # Tools for GPG encryption and signing | |
| "appcleaner" # Application uninstaller for macOS | |
| "google-chrome" # Web browser by Google | |
| "microsoft-edge" # Web browser by Microsoft | |
| "brave-browser" # Privacy-focused web browser | |
| "arc" # Web browser with a focus on speed and simplicity" | |
| "slack" # Collaboration hub for work | |
| "discord" # Communication platform for gamers | |
| "spotify" # Music streaming service | |
| "vlc" # Media player that plays most multimedia files | |
| ) | |
| # Install recommended casks, skipping any missing or deprecated ones | |
| for cask in "${recommended_casks[@]}"; do | |
| if brew info --cask "$cask" >/dev/null 2>&1; then | |
| brew install --cask "$cask" | |
| else | |
| fancy_echo "Warning: Cask '$cask' not found. Skipping ..." | |
| fi | |
| done | |
| fi | |
| install_oh_my_zsh() { | |
| if [ -d "$HOME/.oh-my-zsh" ]; then | |
| fancy_echo "Oh My Zsh is already installed. Skipping ..." | |
| return | |
| fi | |
| fancy_echo "Installing Oh My Zsh ..." | |
| sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended | |
| # Backup existing .zshrc if it exists and Oh My Zsh created a new one | |
| if [ -f "$HOME/.zshrc.pre-oh-my-zsh" ]; then | |
| fancy_echo "Restoring previous .zshrc configurations ..." | |
| # Append previous configurations to the new .zshrc | |
| cat "$HOME/.zshrc.pre-oh-my-zsh" >> "$HOME/.zshrc" | |
| fi | |
| } | |
| if prompt_yes_no "Would you like to install Oh My Zsh?"; then | |
| install_oh_my_zsh | |
| fi | |
| fancy_echo "Done!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment