-
Star
(140)
You must be signed in to star a gist -
Fork
(54)
You must be signed in to fork a gist
-
-
Save somebox/6b00f47451956c1af6b4 to your computer and use it in GitHub Desktop.
| #!/usr/bin/env bash | |
| # Generic macOS workstation setup | |
| # | |
| # A pragmatic, public bootstrap for developer / technical-productivity Macs. | |
| # It installs Homebrew, common CLI utilities, runtimes, terminal/editor/agentic | |
| # coding apps, viewers, media tools, and a curated font set. | |
| # | |
| # Philosophy: | |
| # - Open-source / cross-platform first. | |
| # - Commercial apps only when explicitly useful/common for this workflow. | |
| # - Excludes project/hobby/local-infra apps (games, CAD/3D printing, | |
| # electronics, Home Assistant, OBS, Syncthing, etc.). | |
| # | |
| # Usage: | |
| # bash -c "$(curl -fsSL https://gist.githubusercontent.com/somebox/6b00f47451956c1af6b4/raw/osx-setup.sh)" | |
| # | |
| # Environment flags: | |
| # INSTALL_CASKS=0 # install CLI tools only | |
| # INSTALL_FONTS=0 # skip fonts | |
| # APPLY_DEFAULTS=1 # apply a small set of macOS defaults (off by default) | |
| set -euo pipefail | |
| INSTALL_CASKS="${INSTALL_CASKS:-1}" | |
| INSTALL_FONTS="${INSTALL_FONTS:-1}" | |
| APPLY_DEFAULTS="${APPLY_DEFAULTS:-0}" | |
| bold() { printf '\033[1m%s\033[0m\n' "$*"; } | |
| ok() { printf '\033[1;32m✓ %s\033[0m\n' "$*"; } | |
| warn() { printf '\033[1;33m! %s\033[0m\n' "$*"; } | |
| if [[ "$(uname)" != "Darwin" ]]; then | |
| echo "This script is macOS-only." >&2 | |
| exit 1 | |
| fi | |
| bold "macOS workstation setup" | |
| # --- Xcode command line tools --- | |
| if xcode-select -p >/dev/null 2>&1; then | |
| ok "Xcode Command Line Tools installed" | |
| else | |
| warn "Installing Xcode Command Line Tools (a GUI prompt may appear)..." | |
| xcode-select --install || true | |
| warn "Re-run this script after Command Line Tools finish installing." | |
| exit 0 | |
| fi | |
| # --- Homebrew --- | |
| if command -v brew >/dev/null 2>&1; then | |
| ok "Homebrew installed" | |
| else | |
| warn "Installing Homebrew..." | |
| /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
| fi | |
| # Apple Silicon vs Intel brew shellenv | |
| if [[ -x /opt/homebrew/bin/brew ]]; then | |
| eval "$(/opt/homebrew/bin/brew shellenv)" | |
| elif [[ -x /usr/local/bin/brew ]]; then | |
| eval "$(/usr/local/bin/brew shellenv)" | |
| fi | |
| BREWFILE="$(mktemp)" | |
| trap 'rm -f "$BREWFILE"' EXIT | |
| cat > "$BREWFILE" <<'BREWFILE' | |
| # --- Cross-platform base utilities --- | |
| brew "bat" # cat with syntax highlighting | |
| brew "chezmoi" # dotfile manager | |
| brew "cloc" # count lines of code | |
| brew "d2" # diagrams from text | |
| brew "direnv" # per-directory env vars | |
| brew "eza" # modern ls replacement | |
| brew "fastfetch" # system info summary | |
| brew "fd" # friendly find | |
| brew "fzf" # fuzzy finder | |
| brew "gh" # GitHub CLI | |
| brew "git" # version control | |
| brew "git-filter-repo" # rewrite git history safely | |
| brew "gnupg" # gpg crypto tools | |
| brew "gping" # ping with graph | |
| brew "grc" # colorize command output | |
| brew "htop" # fancy top with color TUI | |
| brew "jq" # JSON processor | |
| brew "just" # command runner | |
| brew "lazygit" # git TUI | |
| brew "lynx" # terminal web browser | |
| brew "most" # pager with colors | |
| brew "nmap" # network scanner | |
| brew "pinentry" # gpg password prompts | |
| brew "pv" # pipe progress viewer | |
| brew "pwgen" # password generator | |
| brew "ripgrep" # fast grep | |
| brew "rsync" # file sync/copy | |
| brew "sevenzip" # 7z archive tool | |
| brew "sqlite" # sqlite database CLI | |
| brew "starship" # fast shell prompt | |
| brew "tig" # git history TUI | |
| brew "tldr" # short command examples | |
| brew "tree" # directory tree view | |
| brew "trippy" # network route TUI | |
| brew "trufflehog" # secret scanner | |
| brew "uv" # fast Python package tool | |
| brew "vim" # terminal editor | |
| brew "watch" # repeat command viewer | |
| brew "wget" # download files | |
| brew "yq" # YAML processor | |
| brew "zoxide" # smarter cd | |
| # --- Shell / terminal niceties --- | |
| brew "asciinema" # terminal recorder | |
| brew "cmatrix" # terminal screensaver | |
| brew "cowsay" # silly text cows | |
| brew "figlet" # ASCII art text | |
| brew "glances" # system monitor TUI | |
| brew "lolcat" # rainbow text output | |
| brew "multitail" # tail many logs | |
| brew "sl" # steam locomotive joke | |
| brew "tty-clock" # terminal clock | |
| brew "wtfutil" # personal dashboard TUI | |
| # --- Runtimes + build basics --- | |
| brew "cmake" # build system generator | |
| brew "deno" # TypeScript runtime | |
| brew "go" # Go compiler/toolchain | |
| brew "ninja" # fast build tool | |
| brew "node" # JavaScript runtime | |
| brew "pipx" # Python CLI app installer | |
| brew "python@3.13" # Python runtime | |
| brew "rustup" # Rust toolchain installer | |
| # --- DevOps / containers --- | |
| brew "docker-compose" # compose CLI plugin/tool | |
| brew "kubernetes-cli" # kubectl | |
| # --- Networking --- | |
| brew "mtr" # traceroute + ping | |
| brew "speedtest-cli" # internet speed test | |
| # --- Media / conversion / viewer support --- | |
| brew "exiftool" # inspect media metadata | |
| brew "ffmpeg" # audio/video Swiss army knife | |
| brew "flac" # FLAC audio tools | |
| brew "imagemagick" # image conversion tools | |
| brew "lame" # MP3 encoder | |
| brew "mp3info" # MP3 metadata tool | |
| brew "mpg123" # MP3 player | |
| brew "mpg321" # MP3 player fallback | |
| brew "vorbis-tools" # Ogg/Vorbis tools | |
| brew "yt-dlp" # video/audio downloader | |
| # --- macOS app management --- | |
| brew "mas" # Mac App Store CLI | |
| # --- Common macOS apps: productivity, dev, terminal, viewers, agentic coding --- | |
| # Open-source / cross-platform first. Commercial exceptions intentionally kept: | |
| # 1Password, Claude/Claude Code, Cursor, VS Code, Obsidian, Docker Desktop, Spotify. | |
| cask "1password" # password manager | |
| cask "1password-cli" # 1Password terminal CLI | |
| cask "audacity" # audio editor | |
| cask "claude" # Claude desktop app | |
| cask "claude-code" # Claude coding agent | |
| cask "cursor" # AI code editor | |
| cask "db-browser-for-sqlite" # SQLite GUI browser | |
| cask "docker-desktop" # Docker Desktop app | |
| cask "firefox" # open-source browser | |
| cask "ghostty" # minimalist powerful terminal | |
| cask "handbrake-app" # video transcoder | |
| cask "inkscape" # vector graphics editor | |
| cask "obsidian" # local markdown notes | |
| cask "opencode-desktop" # agentic coding desktop | |
| cask "qlmarkdown" # QuickLook markdown preview | |
| cask "signal" # secure messaging | |
| cask "spotify" # music streaming | |
| cask "stats" # menu bar system stats | |
| cask "visual-studio-code" # code editor | |
| cask "vlc" # media player | |
| # --- Fonts --- | |
| # Curated favorites for terminal, IDEs, and UI work. Keep this list selective; | |
| # Ghostty bundles JetBrains Mono Nerd Font glyphs, but these are preferred | |
| # across editors, terminals, and design/dev workstations. | |
| cask "font-departure-mono" # retro monospace terminal font | |
| cask "font-maple-mono" # clean coding monospace | |
| cask "font-monaspace" # GitHub coding font family | |
| cask "font-mononoki-nerd-font" # compact nerd font | |
| cask "font-inconsolata" # classic monospace | |
| cask "font-source-code-pro" # Adobe coding font | |
| cask "font-inter" # readable UI sans | |
| cask "font-inter-tight" # compact UI sans | |
| cask "font-lexend" # accessibility-focused sans | |
| cask "font-league-spartan" # bold geometric display font | |
| cask "font-exo" # geometric tech sans | |
| cask "font-grandstander" # playful display font | |
| cask "font-doto" # dotted display font | |
| cask "font-powerline-symbols" # terminal prompt symbols | |
| BREWFILE | |
| if [[ "$INSTALL_CASKS" != "1" ]]; then | |
| warn "INSTALL_CASKS=0 set; removing casks from temporary Brewfile." | |
| sed -i.bak '/^cask /d' "$BREWFILE" | |
| fi | |
| if [[ "$INSTALL_FONTS" != "1" ]]; then | |
| warn "INSTALL_FONTS=0 set; removing font casks from temporary Brewfile." | |
| sed -i.bak '/^cask "font-/d' "$BREWFILE" | |
| fi | |
| warn "Running brew bundle..." | |
| brew bundle --file="$BREWFILE" --no-upgrade || { | |
| warn "brew bundle reported errors. Some GUI casks may require interactive sudo." | |
| warn "Re-run manually with: brew bundle --file=$BREWFILE" | |
| } | |
| # --- Optional macOS defaults --- | |
| if [[ "$APPLY_DEFAULTS" == "1" ]]; then | |
| warn "Applying small set of macOS defaults..." | |
| defaults write NSGlobalDomain AppleShowAllExtensions -bool true | |
| defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false | |
| defaults write NSGlobalDomain KeyRepeat -int 2 | |
| defaults write NSGlobalDomain InitialKeyRepeat -int 15 | |
| defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true | |
| defaults write com.apple.screencapture type png | |
| defaults write com.apple.screencapture disable-shadow -bool true | |
| defaults write com.apple.dock autohide -bool true | |
| killall Dock >/dev/null 2>&1 || true | |
| killall Finder >/dev/null 2>&1 || true | |
| fi | |
| cat <<'NEXT' | |
| Done. | |
| Recommended next steps: | |
| 1. Open a new shell. | |
| 2. Authenticate GitHub CLI: gh auth login | |
| 3. Configure your dotfiles (optional): chezmoi init --apply <your-repo> | |
| 4. If you installed fzf: $(brew --prefix)/opt/fzf/install | |
| This gist is intentionally generic. Personal/project-specific setup belongs in | |
| your private dotfiles repo. | |
| NEXT |
Please note the following issues/concerns/errors upon install:
Pouring qt-5.11.0.high_sierra.bottle.tar.gz ==> Caveats We agreed to the Qt open source license for you. If this is unacceptable you shoulduninstall.`
This formula is keg-only, which means it was not symlinked into /usr/local, because Qt 5 has CMake issues when linked.
If you need to have this software first in your PATH run: _echo 'export PATH="/usr/local/opt/qt/bin:$PATH"' >> ~/.zshrc_
For compilers to find this software you may need to set: LDFLAGS: _-L/usr/local/opt/qt/lib_ CPPFLAGS: _-I/usr/local/opt/qt/include_ For pkg-config to find this software you may need to set: _PKG_CONFIG_PATH: /usr/local/opt/qt/lib/pkgconfig_
Pouring lua-5.3.4_4.high_sierra.bottle.tar.gz ==> Caveats Please be aware due to the way Luarocks is designed any binaries installed via Luarocks-5.3 AND 5.1 will overwrite each other in _/usr/local/bin_.
This is, for now, unavoidable. If this is troublesome for you, you can build rocks with the --tree= command to a special, non-conflicting location and then add that to your **$PATH**.
-
Error: Cask 'font-droid-sans' is unavailable: No Cask with this name exists. Did you mean one of these? **font-droid-sans-mono-for-powerline font-droidsansmono-nerd-font-mono font-droidsansmono-nerd-font** -
Error: Cask **'google-drive'** is unavailable: No Cask with this name exists. Did you mean “google-drive-file-stream”? y -
Error: Cask **'picturelife'** is unavailable: No Cask with this name exists.
Updated with modern dev environment (docker, ghostty, claude, etc.) and removed outdated osx and libs from the old days :)
Error: homebrew/games was deprecated. This tap is now empty as all its formulae were migrated.