Something went wrong. Try again.
Various configuration files from my setup.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378#!/usr/bin/env bash
set -euo pipefail
ROOT=$(cd "$(dirname "$0")" && pwd)
log() { printf "[%s] %s\n" "$(date)" "$@"}
link() { if [ "$#" -ne 2 ]; then echo "usage: link SRC DST" exit 1 fi
SRC="$ROOT/$1" DST="$2" log "Linking '$SRC' to '$DST'..." if [ "$DRY_RUN" -eq 0 ]; then ln -sf "$SRC" "$DST" fi}
load_agent() { if [ "$#" -ne 1 ]; then echo "usage: load_agent NAME" exit 1 fi
AGENT="$1" AGENT_PATH="$HOME/Library/LaunchAgents/$AGENT.plist" log "Loading LaunchAgent '$AGENT'..." if [ "$DRY_RUN" -eq 0 ]; then if launchctl stop "$AGENT"; then launchctl unload "$AGENT_PATH" fi launchctl load "$AGENT_PATH" launchctl start "$AGENT" fi}
render() { if [ "$#" -lt 1 ]; then echo "usage: render NAME [VAR ...]" exit 1 fi
NAME="$1" SRC="$ROOT/$NAME.tpl" DST="$ROOT/$NAME" if [ ! -f "$SRC" ]; then echo "error: $SRC does not exist" exit 1 fi
shift log "Templating '$SRC' to '$DST' with vars '$*'..." if [ "$DRY_RUN" -eq 0 ]; then envsubst "$@" < "$SRC" > "$DST" fi}
install_agent() { if [ "$#" -ne 1 ]; then echo "usage: install_agent NAME" exit 1 fi
mkdir -p "$HOME/Library/LaunchAgents" link "agents/$1.plist" "$HOME/Library/LaunchAgents/" load_agent "$1"}
remove() { if [ "$#" -ne 1 ]; then echo "usage: remove PATH" exit 1 fi
log "Removing '$1'..." if [ "$DRY_RUN" -eq 0 ]; then rm -rf "$1" fi}
DRY_RUN=0
while getopts ":d" arg; do case "$arg" in d) DRY_RUN=1 ;; *) echo "usage: bootstrap [-d]" exit 1 esacdone
if [ "$DRY_RUN" -eq 1 ]; then log "Doing a dry run..."fi
## MacPorts
# The local port overlay in ports/ must be registered before any# packages are installed, otherwise ports it shadows (see# ports/README.md) come from the official tree instead.log "Linking MacPorts sources..."render "etc/macports/sources.conf" '$HOME'if [ "$DRY_RUN" -eq 0 ]; then sudo ln -sf "$ROOT/etc/macports/sources.conf" "/opt/local/etc/macports/sources.conf"fi
# The index is generated, platform-specific and gitignored.log "Indexing the local port overlay..."if [ "$DRY_RUN" -eq 0 ]; then (cd "$ROOT/ports" && portindex >/dev/null)fi
# MacPorts reads Portfiles as the `macports' user, and home directories# are not world-searchable, so grant it traversal of $HOME only.log "Granting the macports user access to the local port overlay..."if [ "$DRY_RUN" -eq 0 ]; then if ! ls -le "$HOME" | grep -q 'user:macports allow search'; then chmod +a "macports allow search" "$HOME" fifi
## Packages
log "Creating workspace..."mkdir -p "$ROOT/workspace"
log "Logging installed pkgs..."port installed > "$ROOT/workspace/installed"
log "Clearing failures..."if [ "$DRY_RUN" -eq 0 ]; then if [ -f "$ROOT/workspace/failures" ]; then echo "" > "$ROOT/workspace/failures" fifi
log "Installing pkgs..."while IFS= read -r PKG_AND_OPTS; do PKG=$(echo "$PKG_AND_OPTS" | cut -d' ' -f1) if ! grep -q "$PKG" "$ROOT/workspace/installed"; then log "Installing $PKG..." if [ "$DRY_RUN" -eq 0 ]; then if ! sudo port install $PKG_AND_OPTS 2>"$ROOT/workspace/errors.$PKG"; then log "Failed to install $PKG, see '$ROOT/workspace/errors.$PKG' for details..." echo "$PKG" >> "$ROOT/workspace/failures" fi fi fidone < "$ROOT/packages"
## Shell and dotfiles
log "Changing shell to Fish..."if [ "$DRY_RUN" -eq 0 ]; then if ! grep -q "/opt/local/bin/fish" "/etc/shells"; then log "Adding /opt/local/bin/fish to /etc/shells..." echo "/opt/local/bin/fish" | sudo tee -a "/etc/shells" fi
sudo chsh -s /opt/local/bin/fish chsh -s /opt/local/bin/fishfi
log "Linking dotfiles..."mkdir -p "$HOME/.config"mkdir -p "$HOME/.gnupg"mkdir -p "$HOME/.local"remove "$HOME/.config/fish"remove "$HOME/.tmux"link "amethyst.yml" "$HOME/.amethyst.yml"link "bashrc" "$HOME/.bashrc"link "fish" "$HOME/.config/fish"link "nix" "$HOME/.config/nix"link "rex" "$HOME/.config/rex"link "gpg.conf" "$HOME/.gnupg/gpg.conf"link "gpg-agent.conf" "$HOME/.gnupg/gpg-agent.conf"link "mbsyncrc" "$HOME/.mbsyncrc"link "msmtprc" "$HOME/.msmtprc"link "psqlrc" "$HOME/.psqlrc"link "tmux" "$HOME/.tmux"link "tmux.conf" "$HOME/.tmux.conf"link "vimrc" "$HOME/.vimrc"
log "Linking utils..."link "bin/envy" "$HOME/bin/envy"
## Key bindings
log "Installing keybindings..."mkdir -p "$HOME/Library/KeyBindings"link "DefaultKeyBinding.dict" "$HOME/Library/KeyBindings/"
## Spaces app assignments
log "Restoring Spaces app assignments..."if [ "$DRY_RUN" -eq 1 ]; then python3 "$ROOT/bin/spaces-app-bindings.py" restore --dry-runelse python3 "$ROOT/bin/spaces-app-bindings.py" restorefi
## Emacs
if [ ! -d "$HOME/.emacs.d" ]; then log "Cloning .emacs.d..." if [ "$DRY_RUN" -eq 0 ]; then git clone https://github.com/Bogdanp/.emacs.d "$HOME/.emacs.d"
log "Loading Emacs submodules..." (cd "$HOME/.emacs.d" && \ git submodule update --init)
log "Fixing up .emacs.d origin repo..." (cd "$HOME/.emacs.d" && \ git remote rm origin && \ git remote add origin git@github.com:Bogdanp/.emacs.d) fifi
if [ ! -f "$HOME/bin/emacsclient" ]; then log "Linking emacslient..." mkdir -p ~/bin ln -sf "/Applications/MacPorts/EmacsMac.app/Contents/MacOS/bin/emacsclient" "$HOME/bin/emacsclient"fi
## Git
log "Linking gitignore and gitconfig..."link gitignore ~/.gitignorelink gitconfig ~/.gitconfig
## Yubikey
log "Installing yubikey-agent launch agent..."mkdir -p ~/.local/var/runrender "agents/io.defn.yubikey-agent.plist" '$HOME'install_agent "io.defn.yubikey-agent"
## Fava
log "Installing fava launch agent..."render "agents/io.defn.fava.plist" '$HOME'install_agent "io.defn.fava"
## Tarsnap
log "Linking tarsnap.conf..."if [ "$DRY_RUN" -eq 0 ]; then sudo ln -sf "$ROOT/tarsnap.conf" "/opt/local/etc/"fi
log "Installing tarsnap scripts..."if [ "$DRY_RUN" -eq 0 ]; then sudo ln -sf "$ROOT/bin/tarsnap-perform-backup" "/opt/local/bin/" sudo ln -sf "$ROOT/bin/tarsnap-prune-backups" "/opt/local/bin/"fi
if ! [ -f ~/.tarsnap.key ]; then log "Creating tarsnap key..." if [ "$DRY_RUN" -eq 0 ]; then tarsnap-keygen \ --keyfile ~/.tarsnap.key \ --machine "$(scutil --get LocalHostName)" \ --user bogdan@defn.io fifi
render "agents/io.defn.tarsnap-backup.plist" '$HOME'install_agent "io.defn.tarsnap-backup"render "agents/io.defn.tarsnap-prune-backups.plist" '$HOME'install_agent "io.defn.tarsnap-prune-backups"
## Notes & accounting agents
log "Installing git-personal launch agent..."render "agents/io.defn.git-personal.plist" '$HOME'install_agent "io.defn.git-personal"
log "Installing git-accounting launch agent..."render "agents/io.defn.git-accounting.plist" '$HOME'install_agent "io.defn.git-accounting"
## Nginx
log "Copying /etc/hosts..."if [ "$DRY_RUN" -eq 0 ]; then sudo cp "$ROOT/etc/hosts" "/etc/hosts"fi
log "Linking Nginx configs..."if [ "$DRY_RUN" -eq 0 ]; then sudo rm -rf "/opt/local/etc/nginx/hosts" sudo ln -sf "$ROOT/etc/nginx/nginx.conf" "/opt/local/etc/nginx/nginx.conf" sudo ln -sf "$ROOT/etc/nginx/hosts" "/opt/local/etc/nginx/hosts"fi
log "Loading Nginx agent..."if [ "$DRY_RUN" -eq 0 ]; then sudo port load nginxfi
## PostgreSQL
if [ ! -d "/opt/local/var/db/postgresql16/defaultdb" ]; then log "Setting up PostgreSQL database..." if [ "$DRY_RUN" -eq 0 ]; then sudo mkdir -p /opt/local/var/db/postgresql16/defaultdb sudo chown postgres:postgres /opt/local/var/db/postgresql16/defaultdb sudo su postgres -c 'cd /opt/local/var/db/postgresql16 && /opt/local/lib/postgresql16/bin/initdb -D /opt/local/var/db/postgresql16/defaultdb' fi
log "Loading PostgreSQL agent..." if [ "$DRY_RUN" -eq 0 ]; then sudo port load postgresql16-server fifi
log "Selecting PostgreSQL version..."if [ "$DRY_RUN" -eq 0 ]; then sudo port select postgresql postgresql16fi
## Python
log "Selecting Python version..."if [ "$DRY_RUN" -eq 0 ]; then sudo port select python python312 sudo port select pip pip312fi
log "Installing pip packages..."while IFS= read -r PKG; do if [ "$DRY_RUN" -eq 0 ]; then if ! grep -q "$PKG" "$ROOT/workspace/installed-pip"; then log "Installing $PKG (pip)..." if ! sudo pip install "$PKG" 2>"$ROOT/workspace/errors.$PKG"; then log "Failed to install $PKG, see '$ROOT/workspace/errors.$PKG' for details..." echo "$PKG" >> "$ROOT/workspace/failures-pip" fi fi fidone < "$ROOT/packages-pip"
## SSL
log "Linking ca-certificates..."if [ "$DRY_RUN" -eq 0 ]; then sudo ln -sf ~/Library/Python/3.12/lib/python/site-packages/certifi/cacert.pem /etc/ssl/certs/ca-certificates.crtfi
## ncurses
log "Adding terminfo for tmux-256color..."/usr/bin/tic -x tmux-256color