Skip to content

Instantly share code, notes, and snippets.

@rachtsingh
Created July 5, 2025 23:51
Show Gist options
  • Save rachtsingh/4eb5aaf7a7dffbb49c0f24cab75702ab to your computer and use it in GitHub Desktop.
Save rachtsingh/4eb5aaf7a7dffbb49c0f24cab75702ab to your computer and use it in GitHub Desktop.
setup macOS
#!/usr/bin/env zsh
set -euo pipefail
# 0. Install uv (fast Python+venv manager) if missing
if ! command -v uv >/dev/null; then
echo "→ Installing uv…"
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.cargo/bin:$PATH" # uv installer puts it here by default
fi
# 1. Run the Python setup (deps resolved ad-hoc)
exec uv run --with click ./setup_computer.py "$@"
#!/usr/bin/env python
from __future__ import annotations
import shutil, subprocess, sys, os, platform
from pathlib import Path
import inspect
def run(cmd: list[str] | str, sudo: bool = False) -> None:
if sudo:
cmd = ["sudo", "-E"] + (cmd if isinstance(cmd, list) else [cmd])
print("·", " ".join(cmd) if isinstance(cmd, list) else cmd)
subprocess.run(cmd, check=True, shell=isinstance(cmd, str))
def ensure_in_path(brew_bin: str) -> None:
incantation = f'eval "$({brew_bin} shellenv)"'
shellrc = Path.home() / ".zshrc"
text = shellrc.read_text() if shellrc.exists() else ""
if incantation not in text.splitlines():
shellrc.write_text(text + f"\n# Homebrew\n{incantation}\n")
def install_homebrew() -> None:
if shutil.which("brew"):
return
run(
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
sudo=False,
)
# apple-silicon vs intel
brew_bin = "/opt/homebrew/bin/brew" if Path("/opt/homebrew/bin").exists() else "/usr/local/bin/brew"
ensure_in_path(brew_bin)
def install_mas() -> None:
run(["brew", "install", "mas"])
def is_mas_installed(app_id: str) -> bool:
out = subprocess.run(["mas", "list"], capture_output=True, text=True, check=True).stdout
return any(line.split()[0] == app_id for line in out.splitlines())
def mas_apps() -> None:
app_id = "1475387142" # Tailscale
if is_mas_installed(app_id):
return # already installed – skip prompt & install
input("Sign in to the Mac App Store now, then press <Enter>...")
run(["mas", "install", app_id])
def brew_casks() -> None:
casks = [
"ghostty", "alt-tab", "zed", "visual-studio-code",
"slack", "1password", "notion-calendar", "obsidian",
"linear-linear", "raycast",
]
run(["brew", "install", "--quiet", "--cask"] + casks)
def brew_cli() -> None:
run(["brew", "install", "starship", "tmux"])
def keyboard_tweaks() -> None:
cmds = [
'defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false',
'defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false',
'defaults write NSGlobalDomain InitialKeyRepeat -int 10',
'defaults write NSGlobalDomain KeyRepeat -int 1',
]
for c in cmds:
run(c, sudo=True)
def setup_starship() -> None:
# need to add this command to ~/.zshrc idempotently if it's not already there
starship_init_command = 'eval "$(starship init zsh)"'
zshrc_path = Path.home() / ".zshrc"
if zshrc_path.exists():
with zshrc_path.open("r") as f:
content = f.read()
if starship_init_command not in content:
with zshrc_path.open("a") as f:
f.write(f"\n{starship_init_command}\n")
else:
with zshrc_path.open("w") as f:
f.write(f"# Zsh configuration file\n{starship_init_command}\n")
command = "starship preset no-nerd-font -o ~/.config/starship.toml"
if not Path("~/.config/starship.toml").expanduser().exists():
# make sure the ~/.config folder exists
config_dir = Path.home() / ".config"
config_dir.mkdir(parents=True, exist_ok=True)
run(command, sudo=False)
def customize_zshrc() -> None:
block = inspect.cleandoc("""
export HISTFILE="$HOME/.zsh_history"
export HISTSIZE=1000000000
export SAVEHIST=1000000000
setopt EXTENDED_HISTORY
""") + "\n"
zshrc = Path.home() / ".zshrc"
content = zshrc.read_text() if zshrc.exists() else ""
if "EXTENDED_HISTORY" not in content:
zshrc.write_text(content + block)
def setup_ghostty() -> None:
"""make a file (and folders) for $HOME/.config/ghostty/config and write to it"""
config_dir = Path.home() / ".config" / "ghostty"
config_dir.mkdir(parents=True, exist_ok=True)
config_file = config_dir / "config"
config_contents = inspect.cleandoc("""
copy-on-select = clipboard
font-family = "SFMono"
theme = "tokyonight"
""").strip() + "\n"
if not config_file.exists():
config_file.write_text(config_contents)
def set_up_ssh_keys_and_github() -> None:
"""
Ensure ~/.ssh/id_ed25519 exists, is loaded into the system agent,
and (optionally) stored in the macOS keychain.
"""
ssh_dir = Path.home() / ".ssh"
ssh_dir.mkdir(mode=0o700, exist_ok=True)
key_path = ssh_dir / "id_ed25519"
pub_path = key_path.with_suffix(".pub")
# 1. Generate a key exactly once
if not key_path.exists():
email = input("Email address for the new SSH key: ").strip()
run(["ssh-keygen", "-t", "ed25519", "-f", str(key_path), "-C", email], sudo=False)
# 2. Check if the key is already in the agent
def key_loaded() -> bool:
res = subprocess.run(["ssh-add", "-l"], capture_output=True, text=True)
return res.returncode == 0 and key_path.name in res.stdout
if not key_loaded():
# macOS runs an ssh-agent under launchd by default; just add the key.
run(["ssh-add", "--apple-use-keychain", str(key_path)], sudo=False)
# 3. Ensure SSH config adds keys automatically (once)
cfg = ssh_dir / "config"
stanza = inspect.cleandoc(f"""
# ~/.ssh/config
# This file is automatically generated by setup_computer.py
# It configures SSH to use the key and add it to the agent.
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
""").strip() + "\n"
if not cfg.exists() or "AddKeysToAgent yes" not in cfg.read_text():
cfg.write_text(cfg.read_text() + stanza if cfg.exists() else stanza, encoding="utf-8")
# 4. Remind the user to register the key with GitHub
print(
f"\n SSH key ready → copy it with:\n"
f" pbcopy < {pub_path}\n"
"Then add it to https://github.com/settings/keys\n"
)
def main() -> None:
if platform.system() != "Darwin":
sys.exit("This script is intended for macOS.")
install_homebrew()
install_mas()
mas_apps()
brew_casks()
brew_cli()
keyboard_tweaks()
setup_starship()
customize_zshrc()
set_up_ssh_keys_and_github()
setup_ghostty()
print("Setup complete. Log out/in (or reboot) for keyboard changes to apply.")
if __name__ == "__main__":
try:
main()
except subprocess.CalledProcessError as exc:
print(f"Command failed with exit code {exc.returncode}", file=sys.stderr)
sys.exit(exc.returncode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment