Full Code of mpereira/macbook-playbook for AI

master 81034c2098b5 cached
265 files
124.2 KB
44.9k tokens
1 requests
Download .txt
Repository: mpereira/macbook-playbook
Branch: master
Commit: 81034c2098b5
Files: 265
Total size: 124.2 KB

Directory structure:
gitextract_g9a7qngr/

├── .gitignore
├── Makefile
├── README.org
├── ansible.cfg
├── bootstrap.yml
├── configure.sh
├── group_vars/
│   └── all
├── hosts
├── main.yml
├── requirements.yml
├── roles/
│   ├── android-file-transfer/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── ansible-download-directory/
│   │   └── tasks/
│   │       └── main.yml
│   ├── awscli/
│   │   └── tasks/
│   │       └── main.yml
│   ├── babashka/
│   │   └── tasks/
│   │       └── main.yml
│   ├── bash/
│   │   └── tasks/
│   │       └── main.yml
│   ├── beets/
│   │   └── tasks/
│   │       └── main.yml
│   ├── better-touch-tool/
│   │   └── tasks/
│   │       └── main.yml
│   ├── black/
│   │   └── tasks/
│   │       └── main.yml
│   ├── bottle/
│   │   └── tasks/
│   │       └── main.yml
│   ├── build-emacs/
│   │   └── tasks/
│   │       └── main.yml
│   ├── bundler/
│   │   └── tasks/
│   │       └── main.yml
│   ├── caps-lock-remapped-to-control/
│   │   ├── files/
│   │   │   └── remap_caps_lock_to_control.scpt
│   │   └── tasks/
│   │       └── main.yml
│   ├── chromedriver/
│   │   └── tasks/
│   │       └── main.yml
│   ├── clojure/
│   │   └── tasks/
│   │       └── main.yml
│   ├── clojure-lsp/
│   │   └── tasks/
│   │       └── main.yml
│   ├── cmake/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── consolas/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ctags/
│   │   └── tasks/
│   │       └── main.yml
│   ├── cursorcerer/
│   │   └── tasks/
│   │       └── main.yml
│   ├── daisydisk/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dash/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── defaultbrowser/
│   │   └── tasks/
│   │       └── main.yml
│   ├── divvy/
│   │   └── tasks/
│   │       └── main.yml
│   ├── docker/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dotemacs/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dotfiles/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dotnet-sdk/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dropbox/
│   │   └── tasks/
│   │       └── main.yml
│   ├── elgato-control-center/
│   │   └── tasks/
│   │       └── main.yml
│   ├── elgato-dock/
│   │   └── tasks/
│   │       └── main.yml
│   ├── emacs-pre-built/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── fd/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ffmpeg/
│   │   └── tasks/
│   │       └── main.yml
│   ├── firefox/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── firefox-adblock-plus/
│   │   └── tasks/
│   │       └── main.yml
│   ├── fish/
│   │   └── tasks/
│   │       └── main.yml
│   ├── fish-foreign-env/
│   │   └── tasks/
│   │       └── main.yml
│   ├── flux/
│   │   └── tasks/
│   │       └── main.yml
│   ├── font-hack/
│   │   └── tasks/
│   │       └── main.yml
│   ├── fontforge/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gcloud/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gh/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gifsicle/
│   │   └── tasks/
│   │       └── main.yml
│   ├── git/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── git-delta/
│   │   └── tasks/
│   │       └── main.yml
│   ├── glances/
│   │   ├── files/
│   │   │   └── com.mpereira.glances.webserver.plist
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── gnu-command-line-tools/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gnupg/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── gnuplot/
│   │   └── tasks/
│   │       └── main.yml
│   ├── go/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── google-chrome/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── google-chrome-as-default-browser/
│   │   ├── meta/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── google-photos/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── graalvm/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── grammarly/
│   │   └── tasks/
│   │       └── main.yml
│   ├── grip/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gron/
│   │   └── tasks/
│   │       └── main.yml
│   ├── hadoop/
│   │   └── tasks/
│   │       └── main.yml
│   ├── haskell/
│   │   └── tasks/
│   │       └── main.yml
│   ├── homebrew/
│   │   └── tasks/
│   │       └── main.yml
│   ├── htop/
│   │   └── tasks/
│   │       └── main.yml
│   ├── hugo/
│   │   └── tasks/
│   │       └── main.yml
│   ├── imagemagick/
│   │   └── tasks/
│   │       └── main.yml
│   ├── istat-menus/
│   │   └── tasks/
│   │       └── main.yml
│   ├── iterm/
│   │   └── tasks/
│   │       └── main.yml
│   ├── java/
│   │   └── tasks/
│   │       └── main.yml
│   ├── jmeter/
│   │   └── tasks/
│   │       └── main.yml
│   ├── jpeg/
│   │   └── tasks/
│   │       └── main.yml
│   ├── jq/
│   │   └── tasks/
│   │       └── main.yml
│   ├── krew/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ktlint/
│   │   └── tasks/
│   │       └── main.yml
│   ├── kubectl/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── kubectl-tree/
│   │   └── tasks/
│   │       └── main.yml
│   ├── leiningen/
│   │   └── tasks/
│   │       └── main.yml
│   ├── licecap/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── llvm/
│   │   └── tasks/
│   │       └── main.yml
│   ├── local-ssl-proxy/
│   │   └── tasks/
│   │       └── main.yml
│   ├── lua/
│   │   └── tasks/
│   │       └── main.yml
│   ├── luajit/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mac-ports/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── maccy/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mactex/
│   │   └── tasks/
│   │       └── main.yml
│   ├── macvim/
│   │   └── tasks/
│   │       └── main.yml
│   ├── make/
│   │   └── tasks/
│   │       └── main.yml
│   ├── markdown/
│   │   └── tasks/
│   │       └── main.yml
│   ├── maven/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mpc/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mpd/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mpdscribble/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mpg123/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mplayer/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mutagen/
│   │   └── tasks/
│   │       └── main.yml
│   ├── neovim/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ngrep/
│   │   └── tasks/
│   │       └── main.yml
│   ├── node/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── node-cljfmt/
│   │   └── tasks/
│   │       └── main.yml
│   ├── octave/
│   │   └── tasks/
│   │       └── main.yml
│   ├── openssl/
│   │   └── tasks/
│   │       └── main.yml
│   ├── openzfs/
│   │   └── tasks/
│   │       └── main.yml
│   ├── orbstack/
│   │   └── tasks/
│   │       └── main.yml
│   ├── p7zip/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pandoc/
│   │   └── tasks/
│   │       └── main.yml
│   ├── parallel/
│   │   └── tasks/
│   │       └── main.yml
│   ├── passwordless-sudo/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pcsv/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pdf-expert/
│   │   └── tasks/
│   │       └── main.yml
│   ├── persephone/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pgsanity/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pngpaste/
│   │   └── tasks/
│   │       └── main.yml
│   ├── prettier/
│   │   └── tasks/
│   │       └── main.yml
│   ├── prey/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── pulp/
│   │   └── tasks/
│   │       └── main.yml
│   ├── purescript/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pyre-check/
│   │   └── tasks/
│   │       └── main.yml
│   ├── python3/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── qt5/
│   │   ├── files/
│   │   │   └── qt-noninteractive.qs
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── r/
│   │   └── tasks/
│   │       └── main.yml
│   ├── rescuetime/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── rider/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ripgrep/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ruby/
│   │   ├── meta/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── rust/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── rust-analyzer/
│   │   └── tasks/
│   │       └── main.yml
│   ├── s3cmd/
│   │   └── tasks/
│   │       └── main.yml
│   ├── scc/
│   │   └── tasks/
│   │       └── main.yml
│   ├── shellcheck/
│   │   └── tasks/
│   │       └── main.yml
│   ├── shfmt/
│   │   └── tasks/
│   │       └── main.yml
│   ├── shpotify/
│   │   └── tasks/
│   │       └── main.yml
│   ├── skype/
│   │   └── tasks/
│   │       └── main.yml
│   ├── slack/
│   │   └── tasks/
│   │       └── main.yml
│   ├── spotify/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── ssh-keys/
│   │   ├── files/
│   │   │   ├── mpereira@argonaut.pub
│   │   │   └── mpereira@pluto.pub
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── steam/
│   │   └── tasks/
│   │       └── main.yml
│   ├── stripe-cli/
│   │   └── tasks/
│   │       └── main.yml
│   ├── taglib/
│   │   └── tasks/
│   │       └── main.yml
│   ├── tealdeer/
│   │   └── tasks/
│   │       └── main.yml
│   ├── teensy-loader/
│   │   └── tasks/
│   │       └── main.yml
│   ├── terminal-notifier/
│   │   └── tasks/
│   │       └── main.yml
│   ├── terraform/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── tmux/
│   │   └── tasks/
│   │       └── main.yml
│   ├── tmuxinator/
│   │   └── tasks/
│   │       └── main.yml
│   ├── toggle-dark-mode/
│   │   ├── files/
│   │   │   └── ToggleDarkMode.app/
│   │   │       └── Contents/
│   │   │           ├── Info.plist
│   │   │           ├── MacOS/
│   │   │           │   └── Application Stub
│   │   │           ├── Resources/
│   │   │           │   ├── AutomatorApplet.icns
│   │   │           │   ├── ar.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ca.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── cs.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── da.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── de.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── el.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── en.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── en_AU.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── en_GB.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── es.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── es_419.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── fi.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── fr.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── fr_CA.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── he.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── hi.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── hr.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── hu.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── id.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── it.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ja.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ko.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ms.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── nl.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── no.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── pl.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── pt.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── pt_PT.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ro.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ru.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── sk.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── sv.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── th.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── tr.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── uk.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── vi.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── zh_CN.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── zh_HK.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   └── zh_TW.lproj/
│   │   │           │       └── InfoPlist.strings
│   │   │           └── document.wflow
│   │   └── tasks/
│   │       └── main.yml
│   ├── tree/
│   │   └── tasks/
│   │       └── main.yml
│   ├── unity/
│   │   └── tasks/
│   │       └── main.yml
│   ├── unity-hub/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── usr-local-src-directory/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vagrant/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vagrant-vbguest/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vault/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vercel/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vim/
│   │   ├── meta/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── virtualbox/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vlc/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── vscode/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vtop/
│   │   └── tasks/
│   │       └── main.yml
│   ├── websocat/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── whatsapp/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wireshark/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wkhtmltopdf/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wordnet/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wrk/
│   │   └── tasks/
│   │       └── main.yml
│   ├── xbar/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── xbar-plugins/
│   │   └── tasks/
│   │       └── main.yml
│   ├── xquartz/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── xz/
│   │   └── tasks/
│   │       └── main.yml
│   ├── yapf/
│   │   └── tasks/
│   │       └── main.yml
│   ├── yarn/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ynab/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── yq/
│   │   └── tasks/
│   │       └── main.yml
│   ├── zoom/
│   │   └── tasks/
│   │       └── main.yml
│   ├── zprint/
│   │   └── tasks/
│   │       └── main.yml
│   ├── zsh/
│   │   └── tasks/
│   │       └── main.yml
│   └── zwift/
│       └── tasks/
│           └── main.yml
└── semver.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
/*.patch
/.ansible_vault_password
/galaxy
/group_vars/localhost/vars.yml
/main.retry


================================================
FILE: Makefile
================================================
# Catalina | 3.7
# Big Sur  | 3.8
# Ventura  | 3.9
SYSTEM_PYTHON                  := /usr/bin/python3
BOOTSTRAP_PYTHON_MAJOR_VERSION := $(shell ./semver.sh "$$($(SYSTEM_PYTHON) --version | cut -d' ' -f2)" | sed -n '1 p')
BOOTSTRAP_PYTHON_MINOR_VERSION := $(shell ./semver.sh "$$($(SYSTEM_PYTHON) --version | cut -d' ' -f2)" | sed -n '2 p')
BOOTSTRAP_PYTHON_VERSION       := $(BOOTSTRAP_PYTHON_MAJOR_VERSION).$(BOOTSTRAP_PYTHON_MINOR_VERSION)
BOOTSTRAP_PYTHON               := /usr/bin/python$(BOOTSTRAP_PYTHON_MAJOR_VERSION)
BOOTSTRAP_PYTHON_BIN_PATH      := ~/Library/Python/$(BOOTSTRAP_PYTHON_VERSION)/bin
BOOTSTRAP_PIP                  := $(BOOTSTRAP_PYTHON) -m pip

# NOTE: this reflects the "python3_version" in the "python" role in main.yml.
PYTHON_VERSION               := 3.11
PYTHON_BIN_PATH              := ~/Library/Python/$(PYTHON_VERSION)/bin
PYTHON                       := /usr/local/bin/python$(PYTHON_VERSION)
PIP                          := $(PYTHON) -m pip

PROJECT_ROOT                 := $(shell pwd)
ANSIBLE_DIRECTORY            := .
ANSIBLE_PLAYBOOKS_DIRECTORY  := $(ANSIBLE_DIRECTORY)
ANSIBLE_ROLES_DIRECTORY      := $(ANSIBLE_DIRECTORY)/roles
ANSIBLE_GROUP_VARS_DIRECTORY := $(ANSIBLE_DIRECTORY)/group_vars
ANSIBLE_INVENTORY            := $(ANSIBLE_DIRECTORY)/hosts
ANSIBLE_VERBOSE              := -v

ANSIBLE_GALAXY := $(PYTHON_BIN_PATH)/ansible-galaxy
ANSIBLE_LOCAL  := \
	$(PYTHON_BIN_PATH)/ansible-playbook $(ANSIBLE_VERBOSE) \
		-i $(ANSIBLE_INVENTORY) \
		--extra-vars "project_root=$(PROJECT_ROOT)" \
		--extra-vars "@$(ANSIBLE_GROUP_VARS_DIRECTORY)/localhost/vars.yml" \
		$(ARGS)

# NOTE: only required for Mojave?
.PHONY: get_bootstrap_pip
get_bootstrap_pip:
	curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
	python get-pip.py --user --force-reinstall
	rm -f get-pip.py

.PHONY: bootstrap
bootstrap:
	$(BOOTSTRAP_PIP) install --user ansible
	$(BOOTSTRAP_PYTHON_BIN_PATH)/ansible-playbook \
		--extra-vars "project_root=$(PROJECT_ROOT)" \
		$(ANSIBLE_PLAYBOOKS_DIRECTORY)/bootstrap.yml \
		--ask-become-pass
	$(PIP) install --user ansible
	$(ANSIBLE_GALAXY) collection install \
		-r $(ANSIBLE_DIRECTORY)/requirements.yml \
		-p $(ANSIBLE_DIRECTORY)/galaxy
	sudo softwareupdate --install-rosetta

# NOTE: this seems to be required for Big Sur. Without it, the 'cryptography'
# pip package (a transitive dependency for the 'ansible' package) fails to
# install.
.PHONY: bootstrap_upgrade_pip
bootstrap_upgrade_pip:
	@sudo $(BOOTSTRAP_PIP) install --upgrade pip

.PHONY: upgrade_pip
upgrade_pip:
	@$(PIP) install --upgrade pip

.PHONY: upgrade_ansible
upgrade_ansible:
	@$(PIP) install --user --upgrade ansible

.PHONY: converge
converge:
	@$(ANSIBLE_LOCAL) $(ANSIBLE_PLAYBOOKS_DIRECTORY)/main.yml


================================================
FILE: README.org
================================================
#+TITLE: macbook-playbook
#+AUTHOR: Murilo Pereira <murilo@murilopereira.com>

:PROPERTIES:
:TOC:      ignore
:END:

Install all your applications and configure everything the way you like it with one command.

** Table of Contents
   :PROPERTIES:
   :TOC:      :include all
   :END:
   :CONTENTS:
- [[#table-of-contents][Table of Contents]]
- [[#tested-on][Tested on]]
- [[#bootstrap-machine-make-bootstrap][Bootstrap machine (make bootstrap)]]
  - [[#install-developer-tools-xcode-select][Install Developer Tools (xcode-select)]]
  - [[#clone-repository][Clone repository]]
  - [[#give-terminaliterm2emacsetc-assistive-access][Give Terminal/iTerm2/Emacs/etc. assistive access]]
  - [[#secrets][Secrets]]
  - [[#prepare-machine-to-run-the-ansible-playbooks][Prepare machine to run the Ansible playbooks]]
- [[#configure-machine-make-converge][Configure machine (make converge)]]
  - [[#provision-machine][Provision machine]]
  - [[#manual-steps-post-make-converge][Manual steps post make converge]]
    - [[#change-keyboard-layout-to-us-international][Change keyboard layout to U.S. international]]
    - [[#istat-menus][iStat Menus]]
    - [[#pdf-expert][PDF Expert]]
    - [[#bettertouchtool][BetterTouchTool]]
    - [[#terminal][Terminal]]
      - [[#preferences--profiles--pro--font][Preferences > Profiles > Pro > Font]]
    - [[#system-preferences--security--privacy--privacy--accessibility][System Preferences > Security & Privacy > Privacy >]]
    - [[#system-preferences--keyboard--shortcuts--mission-control][System Preferences > Keyboard > Shortcuts > Mission Control]]
- [[#roles][Roles]]
  - [[#installs][Installs]]
    - [[#desktop-applications][Desktop Applications]]
    - [[#text-editors][Text Editors]]
    - [[#configuration][Configuration]]
    - [[#programming-languages][Programming Languages]]
    - [[#multimedia][Multimedia]]
    - [[#fonts][Fonts]]
    - [[#browser-plugins][Browser Plugins]]
    - [[#virtualization-provisioning-containers-and-system-tools][Virtualization, Provisioning, Containers and System Tools]]
    - [[#package-managers-and-build-tools][Package Managers and Build Tools]]
    - [[#shell][Shell]]
    - [[#programming-utilities][Programming Utilities]]
    - [[#data-systems][Data Systems]]
    - [[#configuration-monitoring-and-debugging][Configuration, Monitoring and Debugging]]
    - [[#document-processors-and-plotting][Document Processors and Plotting]]
    - [[#markup-tools][Markup Tools]]
    - [[#command-line-tools][Command line tools]]
    - [[#security][Security]]
    - [[#gnu-command-line-tools][GNU Command Line Tools]]
    - [[#miscellaneous][Miscellaneous]]
  - [[#configures][Configures]]
    - [[#makes-google-chrome-the-default-browser][Makes Google Chrome the default browser]]
    - [[#passwordless-sudo][Passwordless sudo]]
    - [[#puts-ssh-keys-in-place][Puts SSH keys in place]]
    - [[#remaps-caps-lock-to-control][Remaps Caps-Lock to Control]]
- [[#author][Author]]
- [[#license][License]]
   :END:

** Tested on
   I've been using =macbook-playbook= since 2013. I've used it on at least eight
   MacBook Pros with different macOS versions. As of May 2023 I use it on my
   personal 16" 2023 Macbook Pro with Ventura installed and on my work 16" 2019
   Macbook Pro with Monterey installed.

   Please open an issue if you're trying this out and bump into anything.

** Bootstrap machine (=make bootstrap=)
   These are one-time steps that need to be done on machines that are running
   =macbook-playbook= for the first time.

*** Install Developer Tools (xcode-select)
    Open the "Terminal" application, type =git= into the shell and follow the
    instructions to install the Apple Developer Tools.

*** Clone repository
    Now your machine should have =git= and =python3= installed.

    #+begin_src bash
    git clone https://github.com/mpereira/macbook-playbook.git
    #+end_src

*** Give Terminal/iTerm2/Emacs/etc. assistive access
    Depending on your macOS version you will be queried or not for assistive
    access while =make converge= runs. This is required for example to remap
    caps lock to control.

    In case that task fails, or if you want to do it beforehand just in case, go
    to "System Preferences > Security & Privacy > Privacy > [[https://www.howtogeek.com/297083/why-do-some-mac-apps-need-to-control-this-computer-using-accessibility-features/][Accessibility]]" and
    add the application running =macbook-playbook= (Terminal/iTerm2/Emacs/etc.)
    to the list.

*** Secrets
    :PROPERTIES:
    :CUSTOM_ID: secrets
    :END:
    I keep secrets encrypted in a file outside of this repository. I have a
    project (also outside of this repository) that will write all secrets
    required by this project's roles to =group_vars/localhost/vars.yml=. This
    file is git-ignored in this project.

    These are the roles that use secrets:
    | Description                       | Secret name                                | Role              |
    | AWS CLI credentials               | =aws_credentials_file_base64=              | awscli            |
    | BetterTouchTool license           | =better_touch_tool_license_file_base64=    | better-touch-tool |
    | DaisyDisk license                 | =daisydisk_registration_key_file_base64=   | daisydisk         |
    | Enviroment variables for [[https://github.com/mpereira/dotfiles][dotfiles]] | =dotfiles_environment_yml_file_base64=     | dotfiles          |
    | iStat Menus settings              | =istat_menus_settings_file_base64=         | istat-menus       |
    | Prey API key                      | =prey_api_key_yaml_file_base64=            | prey              |
    | Private SSH key                   | =mpereira_at_pluto_ssh_private_key_base64= | ssh-keys          |
    | s3cmd configuration               | =s3cmd_cfg_file_base64=                    | s3cmd             |

    If a =group_vars/localhost/vars.yml= file with those secrets is absent
    running these roles will fail.

    You have two choices: skip these roles, or write your
    =group_vars/localhost/vars.yml=.

    To skip them, when you reach the [[#provision-machine][provision machine]] step, make Ansible skip
    roles tagged with =uses-secrets=. You don't need to run this now, the
    command below is just an example.

    #+begin_src bash
    make converge ARGS='--skip-tags uses-secrets'
    #+end_src

*** Prepare machine to run the Ansible playbooks
    This will:
    1. Set up passwordless =sudo=
    2. Install a user Python3
    3. Install Ansible

    #+begin_src bash
    make bootstrap
    #+end_src

    Your machine should now be ready to be provisioned! You won't need to run
    the above steps again.

** Configure machine (=make converge=)
   Now that the machine is bootstrapped, we can provision it.

*** Provision machine
    :PROPERTIES:
    :CUSTOM_ID: provision-machine
    :END:
    This runs all non-disabled roles in [[file:main.yml][=main.yml=]].

    #+begin_src bash
    make converge ARGS='--skip-tags disabled'
    #+end_src

    ~ansible-playbook~ arguments can be passed via the =ARGS= environment variable.
    For example, =--tags= can be passed so that only matching roles are run.

    #+begin_src bash
    make converge ARGS='--tags google-chrome'
    #+end_src

    =--skip-tags= can also be passed to avoid running certain roles.

    #+begin_src bash
    make converge ARGS='--skip-tags disabled,unity'
    #+end_src

    All role tags can be seen in [[file:main.yml][=main.yml=]].

    Tasks may fail due to intermittent reasons like temporary server
    unavailability. When a task fails you can either disable its role via
    =--skip-tags= or use =--start-at-task= with the =name= value of some task to
    cause Ansible to start the playbook exactly there.

    For example, if the "Install Emacs" task from the "build-emacs" role fails
    for what seems to be an intermittent issue, you can pick up provisioning
    from there so that previous tasks don't have to re-run.

    #+begin_src bash
    make converge ARGS='--skip-tags disabled --start-at-task "Install Emacs"'
    #+end_src

    Check the [[https://docs.ansible.com/ansible/latest/user_guide/playbooks_startnstep.html][official Ansible documentation]] for more details.

*** Manual steps post =make converge=
    These are steps that are currently not automated because:
    - it would be difficult
    - it would be impossible
    - or I just didn't have the time

**** Change keyboard layout to U.S. international
     1. System Preferences -> Keyboard -> Input Sources
     2. Click +
     3. Select "English" on left column
     4. Select "U.S. International - PC" on right column
     5. Click "Add"
     6. Remove other keyboard layouts from the left column

**** iStat Menus
     1. Import license from =roles/istat-menus/files/iStat Menus Settings.ismp=

**** PDF Expert
     1. Register license

**** BetterTouchTool
     1. Register license

**** Terminal
***** Preferences > Profiles > Pro > Font
      Set to =Hack Regular 18 pt=.

**** System Preferences > Security & Privacy > Privacy > [[https://www.howtogeek.com/297083/why-do-some-mac-apps-need-to-control-this-computer-using-accessibility-features/][Accessibility]]
     - BetterTouchTool.app
     - Emacs-*.app
     - MacGPT
     - RescueTime
     - Terminal
     - VLC
     - WhatsApp

**** System Preferences > Keyboard > Shortcuts > Mission Control
     Uncheck:
     - Mission Control
     - Move left a space
     - Move right a space
     - Switch to desktop 1

     I use these keybindings on Emacs.

** Roles
*** Installs
**** Desktop Applications
     - [[https://www.android.com/filetransfer/][Android File Transfer]]
     - [[https://getbitbar.com/][BitBar]]
     - [[http://doomlaser.com/cursorcerer-hide-your-cursor-at-will/][Cursorcerer]]
     - [[https://daisydiskapp.com/][DaisyDisk]]
     - [[https://kapeli.com/dash][Dash]]
     - [[http://mizage.com/divvy/][Divvy]]
     - [[https://www.dropbox.com/install][Dropbox]]
     - [[https://www.elgato.com/en/dock/support][Elgato Dock]]
     - [[https://www.elgato.com/en/downloads][Elgato Control Center]]
     - [[https://justgetflux.com/][f.lux]]
     - [[https://www.mozilla.org/en-US/firefox/new][Firefox]]
     - [[https://www.google.com/chrome/index.html][Google Chrome]]
     - [[https://photos.google.com/apps][Google Photos]]
     - [[https://www.grammarly.com/native/mac][Grammarly]]
     - [[https://bjango.com/mac/istatmenus/][iStat Menus]]
     - [[https://www.cockos.com/licecap/][LICEcap]]
     - [[https://maccy.app/][Maccy]]
     - [[https://pdfexpert.com/][PDF Expert]]
     - [[https://persephone.fm/][Persephone]]
     - [[https://www.rescuetime.com/][RescueTime]]
     - [[https://www.skype.com/en/download-skype/skype-for-mac/][Skype]]
     - [[https://slack.com/downloads/osx][Slack]]
     - [[https://www.spotify.com/br/download/other/][Spotify]]
     - [[http://store.steampowered.com/about/][Steam]]
     - [[https://www.pjrc.com/teensy/loader_mac.html][Teensy Loader]]
     - [[https://github.com/mpereira/macbook-playbook/tree/master/roles/toggle-dark-mode/files/ToggleDarkMode.app/Contents][ToggleDarkMode]]
     - [[https://unity3d.com/get-unity/download][Unity]]
     - [[https://docs.unity3d.com/Manual/GettingStartedInstallingHub.html][Unity Hub]]
     - [[https://www.videolan.org/vlc/download-macosx.html][VLC]]
     - [[https://www.whatsapp.com/download][WhatsApp]]
     - [[https://www.wireshark.org/][Wireshark]]
     - [[https://www.xquartz.org/][XQuartz]]
     - [[https://classic.youneedabudget.com/][YNAB]] (disabled by default, I use the online version and the application
       binary isn't available anymore)
     - [[https://zoom.us/][Zoom]]
     - [[https://www.zwift.com/][Zwift]]

**** Text Editors
     - [[https://emacsformacosx.com/][Emacs 28.2]]
     - [[https://github.com/daviderestivo/homebrew-emacs-head][Emacs 29]]
     - [[http://macvim-dev.github.io/macvim/][MacVim]]
     - [[https://github.com/neovim/neovim/wiki/Installing-Neovim][Neovim]]
     - [[https://www.jetbrains.com/rider/][Rider]]
     - [[http://www.vim.org/][Vim]] (disabled by default until I figure out why it isn't compiling on
       macOS Big Sur with LLVM 12)
     - [[https://code.visualstudio.com/][VSCode]]

**** Configuration
     - [[https://github.com/mpereira/.emacs.d][dotemacs]]
     - [[https://github.com/mpereira/dotfiles][dotfiles]]

**** Programming Languages
     - [[https://clojure.org/guides/getting_started][Clojure]]
     - [[https://www.gnu.org/software/octave/download.html][GNU Octave]]
     - [[https://golang.org/][Go]]
     - [[https://docs.haskellstack.org/en/stable/README/][Haskell]]
     - [[https://adoptopenjdk.net/][Java (AdoptOpenJDK)]]
     - [[https://www.lua.org/download.html][Lua]]
     - [[http://luajit.org/download.html][LuaJIT]]
     - [[https://dotnet.microsoft.com/en-us/download/visual-studio-sdks][.NET]]
     - [[https://nodejs.org/en/download/][Node.js]]
     - [[http://www.purescript.org/][PureScript]] (disabled by default until I figure out why =stack install
       purescript= is currently failing)
     - [[https://www.python.org/downloads/mac-osx/][Python 3]]
     - [[https://cran.r-project.org/bin/macosx/][R]]
     - [[https://www.ruby-lang.org][Ruby]]
     - [[https://www.rust-lang.org/][Rust]]

**** Multimedia
     - [[http://beets.io/][Beets]]
     - [[http://www.ffmpegmac.net/][FFmpeg]]
     - [[https://www.lcdf.org/gifsicle/][gifsicle]]
     - [[https://www.imagemagick.org/][ImageMagick]]
     - [[https://www.musicpd.org/clients/mpc/][mpc]]
     - [[https://www.musicpd.org/download.html][mpd]]
     - [[https://www.musicpd.org/clients/mpdscribble/][mpdscribble]]
     - [[https://www.mpg123.de/][mpg123]]
     - [[https://mplayerosx.ch/][mplayer]]
     - [[https://github.com/hnarayanan/shpotify][shpotify]]
     - [[http://taglib.org/][TagLib]]

**** Fonts
     - [[https://docs.microsoft.com/en-us/typography/font-list/consolas][Consolas]]
     - [[https://sourcefoundry.org/hack/][Hack]]

**** Browser Plugins
     - [[https://addons.mozilla.org/en-US/firefox/addon/adblock-plus/][Firefox Adblock Plus]]

**** Virtualization, Provisioning, Containers and System Tools
     - [[https://store.docker.com/editions/community/docker-ce-desktop-mac][Docker]] (using [[https://orbstack.dev/][OrbStack]] instead)
     - [[https://cloud.google.com/sdk/docs/install-sdk][gcloud]]
     - [[https://github.com/kubernetes-sigs/krew][krew]]
     - [[https://kubernetes.io/docs/reference/kubectl/kubectl/][kubectl]]
     - [[https://github.com/ahmetb/kubectl-tree][kubectl-tree]]
     - [[https://openzfsonosx.org/][OpenZFS]] (disabled by default until it works on macOS Big Sur)
     - [[https://orbstack.dev/][OrbStack]]
     - [[https://www.terraform.io/][Terraform]]
     - [[https://www.vagrantup.com/downloads.html][Vagrant]]
     - [[https://github.com/dotless-de/vagrant-vbguest][Vagrant vagrant-vbguest plugin]]
     - [[https://www.virtualbox.org/wiki/Downloads][VirtualBox]]

**** Package Managers and Build Tools
     - [[http://bundler.io/][bundler]]
     - [[https://cmake.org/][CMake]]
     - [[https://www.graalvm.org/][GraalVM]]
     - [[https://brew.sh/][Homebrew]]
     - [[https://leiningen.org/][leiningen]]
     - [[https://www.macports.org/][MacPorts]]
     - [[https://www.gnu.org/software/make/][Make]]
     - [[https://maven.apache.org/][Maven]]
     - [[https://www.npmjs.com/package/pulp][pulp]]
     - [[https://yarnpkg.com/][Yarn]]

**** Shell
     - [[https://github.com/babashka/babashka][Babashka]]
     - [[https://www.gnu.org/software/bash/][Bash]]
     - [[https://fishshell.com/][fish]]
     - [[https://github.com/oh-my-fish/plugin-foreign-env][fish-foreign-env]]
     - [[https://www.iterm2.com/][iTerm]]
     - [[https://github.com/tmux/tmux][tmux]]
     - [[https://github.com/tmuxinator/tmuxinator][tmuxinator]]
     - [[http://www.zsh.org/][Zsh]]

**** Programming Utilities
     - [[https://black.readthedocs.io/en/stable/][Black]]
     - [[https://clojure-lsp.github.io/clojure-lsp/][clojure-lsp]]
     - [[https://ctags.io/][Ctags]]
     - [[https://github.com/google/yapf][YAPF]]
     - [[https://github.com/kkinnear/zprint][zprint]]
     - [[https://github.com/mikefarah/yq][yq]]
     - [[https://github.com/mvdan/sh][shfmt]]
     - [[https://github.com/snoe/node-cljfmt][node-cljfmt]]
     - [[https://github.com/tomnomnom/gron][gron]]
     - [[https://ktlint.github.io/][ktlint]]
     - [[https://prettier.io/][Prettier]]
     - [[https://pyre-check.org/][Pyre]]
     - [[https://rust-analyzer.github.io/][rust-analyzer]]
     - [[https://www.shellcheck.net/][ShellCheck]]

**** Data Systems
     - [[http://hadoop.apache.org/][Apache Hadoop]] (disabled by default, it conflicts with the =yarn=
       JavaScript package manager)

**** Configuration, Monitoring and Debugging
     - [[http://jmeter.apache.org/][Apache JMeter]]
     - [[https://nicolargo.github.io/glances/][Glances]]
     - [[http://hisham.hm/htop/][htop]]
     - [[https://github.com/jpr5/ngrep][ngrep]]
     - [[https://github.com/MrRio/vtop][vtop]]

**** Document Processors and Plotting
     - [[http://www.gnuplot.info/][gnuplot]]
     - [[http://www.tug.org/mactex/][MacTeX]]

**** Markup Tools
     - [[https://github.com/joeyespo/grip][Grip]]
     - [[https://gohugo.io/][Hugo]]
     - [[https://daringfireball.net/projects/markdown/][Markdown]]
     - [[https://pandoc.org/][Pandoc]]
     - [[https://wkhtmltopdf.org/][wkhtmltopdf]]

**** Command line tools
     - [[https://aws.amazon.com/cli/][AWS CLI]]
     - [[https://github.com/kerma/defaultbrowser][defaultbrowser]]
     - [[https://github.com/dandavison/delta][delta]]
     - [[https://github.com/dandavison/delta][delta]]
     - [[https://git-scm.com/download/mac][git]]
     - [[https://cli.github.com/][gh]]
     - [[https://github.com/sharkdp/fd][fd]]
     - [[https://stedolan.github.io/jq/][jq]]
     - [[https://www.npmjs.com/package/local-ssl-proxy][local-ssl-proxy]]
     - [[http://www.7-zip.org/][p7zip]]
     - [[https://www.gnu.org/software/parallel/][parallel]]
     - [[https://pypi.python.org/pypi/pgsanity][pgsanity]]
     - [[https://github.com/jcsalterego/pngpaste][pngpaste]]
     - [[https://github.com/BurntSushi/ripgrep][ripgrep]]
     - [[http://s3tools.org/s3cmd][s3cmd]] (disabled by default, I use the AWS CLI)
     - [[https://github.com/boyter/scc][scc]]
     - [[https://stripe.com/docs/stripe-cli][stripe-cli]]
     - [[https://tldr.sh/][tealdeer]]
     - [[https://github.com/julienXX/terminal-notifier][terminal-notifier]]
     - [[http://brewformulas.org/Tree][tree]]
     - [[https://vercel.com/docs/cli][vercel]]
     - [[https://github.com/vi/websocat][websocat]]
     - [[https://github.com/wg/wrk][wrk]]
     - [[https://tukaani.org/xz/][xz]]

**** Security
     - [[https://www.preyproject.com/download][Prey]]
     - [[https://www.gnupg.org/download/index.html][GnuPG]]
     - [[https://github.com/jcoglan/vault][vault]]

**** GNU Command Line Tools
     - binutils
     - coreutils
     - diffutils
     - ed
     - findutils
     - gawk
     - gnu-indent
     - gnu-sed
     - gnu-tar
     - gnu-which
     - gnutls
     - grep
     - gzip
     - screen
     - watch
     - wdiff
     - wget

**** Miscellaneous
     - [[https://mutagen.io/][Mutagen]]
     - [[https://chromedriver.chromium.org/home][ChromeDriver]]
     - [[http://fontforge.github.io/en-US/downloads/mac-dl/][FontForge]]
     - [[http://download.qt.io/official_releases/qt/5.9/5.9.2/][Qt 5]] (disabled by default)
     - [[https://wordnet.princeton.edu/download][WordNet]]

*** Configures
**** Makes Google Chrome the default browser
**** Passwordless sudo
**** Puts SSH keys in place
**** Remaps Caps-Lock to Control

** Author
   [[http://murilopereira.com][Murilo Pereira]]

** License
   [[http://opensource.org/licenses/MIT][MIT]]

# Local Variables:
# before-save-hook: org-make-toc
# End:


================================================
FILE: ansible.cfg
================================================
[defaults]
stdout_callback = yaml
interpreter_python = python3


================================================
FILE: bootstrap.yml
================================================
---
- hosts: localhost
  connection: local
  gather_facts: no
  roles:
    - ansible-download-directory
    - usr-local-src-directory
    - passwordless-sudo
    - role: python3
      tags: [foundational, programming-languages, bespoke-pkg, python3]
      vars:
        # https://www.python.org/ftp/python/
        python3_version: "3.11.2"
        # 11 is a "Universal 2" binary which works on Apple Silicon.
        # 10.9 does not work on Apple Silicon.
        python3_macos_version: "11" # this is used in the .pkg file name.
        python3_version_major_minor: "{{ python3_version | regex_replace('^([0-9]+)\\.([0-9]+)(?:\\.[0-9]+)?$', '\\1.\\2') }}"


================================================
FILE: configure.sh
================================================
#!/usr/bin/env bash

# Resources:
# - http://www.defaults-write.com
# - https://gist.github.com/MatthewEppelsheimer/2269385
# - https://gist.github.com/vraravam/5e28ca1720c9dddacdc0e6db61e093fe
# - https://github.com/MartinHarding/macOSuckless
# - https://github.com/ddelange/new-mac-setup
# - https://github.com/herrbischoff/awesome-macos-command-line
# - https://github.com/mathiasbynens/dotfiles/blob/master/.macos
# - https://www.cs.rutgers.edu/~pxk/cs/macos-setup.html
# - https://www.learningosx.com/101-ways-to-tweak-os-x-using-terminal/

set -euxo pipefail

email_address="${1}"
hostname="${2}"

# Close open System Preferences panes, to prevent them from overriding settings.
osascript -e 'tell application "System Preferences" to quit'

login_window_text="This computer is attached to an Apple iCloud account \
and is valueless if lost.\nPlease return it by emailing ${email_address}."

# Set computer name.
sudo scutil --set ComputerName "${hostname}"
sudo scutil --set HostName "${hostname}"
sudo scutil --set LocalHostName "${hostname}"
sudo defaults write \
     /Library/Preferences/SystemConfiguration/com.apple.smb.server \
     NetBIOSName \
     -string "${hostname}"

# NOTE: disabled setting a desktop background picture because I haven't figured
# out how to set it to a dynamic background picture.
#
# desktop_picture="/Library/Desktop Pictures/Solid Colors/Solid Gray Pro Ultra Dark.png"
#
# Set desktop background picture.
# desktop_pictures_db="~/Library/Application Support/Dock/desktoppicture.db"
# sqlite3 "${desktop_pictures_db}" "update data set value = '${desktop_picture}'"

sudo defaults write \
     /Library/Preferences/com.apple.loginwindow \
     LoginwindowText \
     "$(echo -e "${login_window_text}")"

# Fade transition between workspaces instead of using movement.
defaults write com.apple.Accessibility ReduceMotionEnabled -bool true

readonly icloud_directory="${HOME}/Library/Mobile Documents/com~apple~CloudDocs"

# Save screenshots to the desktop.
defaults write \
         com.apple.screencapture \
         location \
         -string "${icloud_directory}/Screenshots"

################################################################################
# Dock #########################################################################
################################################################################

# Show only open applications in the Dock.
defaults write com.apple.dock static-only -bool true

# Minimization effect: 'genie', 'scale', 'suck'.
defaults write com.apple.dock mineffect -string 'scale'

# Don't animate opening applications. I don't open applications from the dock
# anyway...
defaults write com.apple.dock launchanim -bool false

# Automatically hide and show the Dock.
defaults write com.apple.dock autohide -bool true

# Make Dock icons of hidden applications translucent.
# NOTE: this doesn't seem to make a difference.
defaults write com.apple.dock showhidden -bool true

# Move dock to the left.
defaults write com.apple.dock orientation left

# Wipe all (default) app icons from the Dock.
defaults write com.apple.dock persistent-apps -array

# Don't rearrange spaces by most recently used.
defaults write com.apple.dock mru-spaces -bool false

# Remove the auto-hiding Dock delay.
# NOTE: this doesn't seem to make a difference.
defaults write com.apple.dock autohide-delay -float 0

# Remove the animation when hiding/showing the Dock.
defaults write com.apple.dock autohide-time-modifier -float 0.5

################################################################################
# Services #####################################################################
################################################################################

# Enable file sharing.
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.smbd.plist

# Disable Notification Center and remove the menu bar icon.
# FIXME: Operation not permitted while System Integrity Protection is engaged
# launchctl \
#   unload -w \
#   /System/Library/LaunchAgents/com.apple.notificationcenterui.plist \
#   2> /dev/null

################################################################################
# Zoom #########################################################################
################################################################################

zoom_plist="${HOME}/Library/Preferences/ZoomChat.plist"

defaults write "${zoom_plist}" ZoomEnterFullscreenWhenViewShare -bool false
defaults write "${zoom_plist}" ZoomEnterMaxWndWhenViewShare -bool false
defaults write "${zoom_plist}" ZMEnableShowUserName -bool true
defaults write "${zoom_plist}" ZoomEnableShow49WallViewKey -bool true
defaults write "${zoom_plist}" ZoomShowIconInMenuBar -bool false

################################################################################
# Finder #######################################################################
################################################################################

# Show hidden files.
defaults write com.apple.finder AppleShowAllFiles true

# Avoid creating .DS_Store files on network or USB volumes.
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true

# Automatically open a new Finder window when a volume is mounted.
defaults write com.apple.frameworks.diskimages auto-open-ro-root -bool true
defaults write com.apple.frameworks.diskimages auto-open-rw-root -bool true
defaults write com.apple.finder OpenWindowForNewRemovableDisk -bool true

# Use list view in all Finder windows by default.
# Icon View:   "icnv"
# List View:   "Nlsv"
# Column View: "clmv"
# Cover Flow:  "Flwv"
defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv"

# Show bar with current directory path at the bottom.
defaults write com.apple.finder ShowPathbar -bool true

# Allow quitting via ⌘ + Q; doing so will also hide desktop icons.
defaults write com.apple.finder QuitMenuItem -bool true

# Disable window animations and Get Info animations.
defaults write com.apple.finder DisableAllAnimations -bool true

# New Finder windows open at $HOME.
# Computer:       "PfCm"
# Volume:         "PfVo"
# $HOME:          "PfHm"
# Desktop:        "PfDe"
# Documents:      "PfDo"
# All My Files:   "PfAF"
# Other:          "PfLo"
defaults write com.apple.finder NewWindowTarget -string "PfHm"
defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}"

# Don't show file icons in the desktop.
defaults write com.apple.finder CreateDesktop -bool false

# When performing a search, search the current folder by default.
# This Mac:       "SCev"
# Current Folder: "SCcf"
# Previous Scope: "SCsp"
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"

# Display full POSIX path as Finder window title.
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true

# Keep folders on top when sorting files by name.
defaults write com.apple.finder _FXSortFoldersFirst -bool true

# Show expanded save panel by default.
# https://www.defaults-write.com/expand-save-panel-default/
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true

# Show file extensions.
defaults write NSGlobalDomain AppleShowAllExtensions -bool true

################################################################################
# Menu bar #####################################################################
################################################################################

defaults write com.apple.menuextra.clock DateFormat -string "EEE d MMM HH:mm"

defaults write com.apple.systemuiserver menuExtras '(
  "/System/Library/CoreServices/Menu Extras/Clock.menu",
  "/System/Library/CoreServices/Menu Extras/Battery.menu",
  "/System/Library/CoreServices/Menu Extras/Volume.menu",
  "/System/Library/CoreServices/Menu Extras/Bluetooth.menu",
  "/System/Library/CoreServices/Menu Extras/VPN.menu"
)'

################################################################################
# Language #####################################################################
################################################################################

# Set language and text formats.
defaults write NSGlobalDomain AppleLanguages -array "en-US" "pt-BR" "de-DE"
defaults write NSGlobalDomain AppleLocale -string "en_DE"
defaults write NSGlobalDomain AppleMeasurementUnits -string "Centimeters"
defaults write NSGlobalDomain AppleMetricUnits -bool true

################################################################################
# Terminal #####################################################################
################################################################################

terminal_theme="Pro"

# Set default theme.
defaults write com.apple.Terminal "Startup Window Settings" -string "${terminal_theme}"

defaults write com.apple.Terminal "Default Window Settings" -string "${terminal_theme}"

# Make bash the default shell in Terminal.
defaults write com.apple.Terminal Shell -string "$(which bash)"

################################################################################
################################################################################
################################################################################

# Disable the sound effects on boot.
sudo nvram SystemAudioVolume=" "

# Disable sound effects: trash emptying, screenshot taking, file moving, etc.
defaults write "Apple Global Domain" com.apple.sound.uiaudio.enabled -int 0

# MacBookPro 2019 16"
# $ sudo pmset -g live
# System-wide power settings:
#  DestroyFVKeyOnStandby		0
# Currently in use:
#  standbydelaylow      10800
#  standby              1
#  halfdim              1
#  hibernatefile        /var/vm/sleepimage
#  proximitywake        0
#  gpuswitch            2
#  powernap             0
#  disksleep            10
#  standbydelayhigh     86400
#  sleep                1 (sleep prevented by coreaudiod)
#  hibernatemode        3
#  ttyskeepawake        1
#  displaysleep         2
#  tcpkeepalive         1
#  highstandbythreshold 50
#  acwake               0
#  lidwake              1

# MacBook Pro 2017 15" on 2021-03
# $ sudo pmset -g live
# System-wide power settings:
# Currently in use:
#  lidwake              1
#  autopoweroff         1
#  standbydelayhigh     86400
#  autopoweroffdelay    28800
#  standbydelaylow      10800
#  standby              1
#  proximitywake        1
#  ttyskeepawake        1
#  hibernatemode        3
#  powernap             0
#  gpuswitch            2
#  hibernatefile        /var/vm/sleepimage
#  highstandbythreshold 50
#  displaysleep         60
#  womp                 1
#  networkoversleep     0
#  sleep                0 (sleep prevented by nfsd, coreaudiod, mds_stores)
#  tcpkeepalive         1
#  halfdim              1
#  acwake               0
#  disksleep            10

# Dark menu bar and dock.
defaults write NSGlobalDomain AppleInterfaceStyle -string "Dark"

# Hide mirroring options in the menu bar.
defaults write com.apple.airplay showInMenuBarIfPresent -bool false

# Enable remote login.
# NOTE: this requires Full Disk Access privileges.
sudo systemsetup -setremotelogin on

# Quit printer app after print jobs complete.
defaults write com.apple.print.PrintingPrefs "Quit When Finished" -bool true

killall Dock > /dev/null 2>&1
killall Finder > /dev/null 2>&1
killall SystemUIServer > /dev/null 2>&1
killall Terminal > /dev/null 2>&1


================================================
FILE: group_vars/all
================================================
# -*-yaml-*-
---
user: "{{ lookup('env', 'USER') }}"
home_directory: "/Users/{{ user }}"
downloads_directory: "{{ home_directory }}/.ansible/downloads"


================================================
FILE: hosts
================================================
0.0.0.0


================================================
FILE: main.yml
================================================
---
- hosts: localhost
  connection: local
  roles:
    #############################################################################
    # Foundational ##############################################################
    #############################################################################

    - role: homebrew
      tags: [foundational, package-and-build, homebrew]

    # Depends on homebrew.
    - role: git
      tags: [foundational, brew-pkg, git]

    # Depends on homebrew.
    - role: gnu-command-line-tools
      tags: [foundational, brew-pkg, gnu-command-line-tools]
    # Depends on homebrew.
    - role: make
      tags: [foundational, package-and-build, brew-pkg, make]

    - role: cmake
      tags: [foundational, package-and-build, bespoke-pkg, cmake]
      vars:
        # https://cmake.org/download/
        cmake_version: "3.22.0"

    - role: llvm
      tags: [foundational, package-and-build, brew-pkg, llvm]

    - role: openssl
      tags: [foundational, package-and-build, brew-pkg, openssl]

    # Depends on homebrew.
    - role: bash
      tags: [foundational, brew-pkg, programming-languages, bash]

    - role: python3
      tags: [foundational, programming-languages, bespoke-pkg, python3]
      vars:
        # NOTE: update PYTHON_VERSION in Makefile when changing this.
        # https://www.python.org/ftp/python/
        python3_version: "3.11.2"
        # 11 is a "Universal 2" binary which works on Apple Silicon.
        # 10.9 does not work on Apple Silicon.
        python3_macos_version: "11" # this is used in the .pkg file name.
        python3_version_major_minor: "{{ python3_version | regex_replace('^([0-9]+)\\.([0-9]+)(?:\\.[0-9]+)?$', '\\1.\\2') }}"

    - role: mac-ports
      tags: [foundational, package-and-build, bespoke-pkg, mac-ports]
      vars:
        # https://www.macports.org/install.php
        macports_version: "2.7.1"
        macports_mac_release: "12-Monterey"

    - role: node
      tags: [foundational, programming-languages, bespoke-pkg, node]
      vars:
        # https://nodejs.org/dist/
        # https://github.com/nodejs/node/releases
        node_version: "21.1.0"

    - role: maven
      tags: [foundational, package-and-build, brew-pkg, maven]

    #############################################################################
    # Fonts #####################################################################
    #############################################################################

    - role: font-hack
      tags: [fonts, brew-cask-pkg, font-hack]

    - role: consolas
      tags: [fonts, bespoke-pkg, consolas]

    #############################################################################
    # Configuration #############################################################
    #############################################################################

    - role: ssh-keys
      tags: [configuration, ssh-keys, uses-secrets]

    - role: better-touch-tool
      tags: [configuration, bespoke-pkg, better-touch-tool, uses-secrets]
      vars:
        # https://folivora.ai/releases
        better_touch_tool_version: "" # using latest

    - role: dotfiles
      tags: [configuration, dotfiles, uses-secrets]

    - role: dotemacs
      tags: [configuration, dotemacs]

    # IMPORTANT #################################################################

    - role: build-emacs
      tags: [text-editors, brew-pkg, build-emacs]

    # NOTE: trying it out with Monterey (should be at least 2.1.0).
    - role: openzfs
      tags: [system-tools, brew-cask-pkg, openzfs]

    #############################################################################
    # Programming languages #####################################################
    #############################################################################

    - role: clojure
      tags: [programming-languages, brew-pkg, clojure]

    - role: java
      tags: [programming-languages, brew-cask-pkg, java]
      vars:
        java_version: adoptopenjdk16

    - role: go
      tags: [programming-languages, bespoke-pkg, go]
      vars:
        # https://go.dev/dl/
        go_version: "1.22.2"

    - role: rust
      tags: [programming-languages, rust]

    - role: ruby
      tags: [programming-languages, ruby]
      vars:
        ruby_version: 3.2.1

    - role: lua
      tags: [programming-languages, brew-pkg, lua]

    - role: luajit
      tags: [programming-languages, brew-pkg, luajit]

    - role: octave
      tags: [programming-languages, brew-pkg, octave]

    - role: r
      tags: [programming-languages, bespoke-pkg, r]
      vars:
        r_version: "4.1.2"

    - role: haskell
      tags: [disabled, programming-languages, brew-pkg, haskell]

    - role: dotnet-sdk
      tags: [programming-languages, brew-cask-pkg, dotnet-sdk]

    # DISABLED: `stack install purescript` is currently failing, disabling until
    # I figure it out.
    # https://gist.github.com/mpereira/a2418c458418cd01a2d18301eaeae85e
    - role: purescript
      tags: [disabled, programming-languages, purescript]

    #############################################################################
    # Text editors ##############################################################
    #############################################################################

    - role: emacs-pre-built
      tags: [text-editors, bespoke-pkg, emacs-pre-built]
      vars:
        emacs_pre_built_version: "28.2"
        emacs_pre_built_patch: ""
        # emacs_pre_built_version: "26.1-rc1"
        # emacs_pre_built_pretest: "yes"

    # DISABLED: Vim isn't compiling with Python 3.10.
    - role: vim
      tags: [disabled, text-editors, bespoke-pkg, vim]
      vars:
        vim_version: "8.2"

    - role: neovim
      tags: [disabled, text-editors, bespoke-pkg, neovim]
      vars:
        # https://github.com/neovim/neovim/releases
        neovim_version: "0.5.1"

    - role: vscode
      tags: [text-editors, brew-pkg, vscode]

    - role: rider
      tags: [text-editors, brew-cask-pkg, rider]

    - role: macvim
      tags: [disabled, text-editors, bespoke-pkg, macvim]
      vars:
        # https://github.com/macvim-dev/macvim/releases
        macvim_version: "snapshot-172"

    #############################################################################
    # Behaviors #################################################################
    #############################################################################

    - role: caps-lock-remapped-to-control
      tags: [behaviors, caps-lock-remapped-to-control]

    #############################################################################
    # Security ##################################################################
    #############################################################################

    # DISABLED: Apple security stuff is good enough.
    - role: prey
      tags: [disabled, security, bespoke-pkg, prey, uses-secrets]
      vars:
        # https://github.com/prey/prey-node-client/releases
        prey_version: "1.9.13"

    - role: vault
      tags: [security, npm-pkg, vault]
      vars:
        # https://www.npmjs.com/package/vault
        vault_version: "0.3.0"

    - role: gnupg
      tags: [security, bespoke-pkg, gnupg]
      vars:
        gnupg_version: "2.3.3"

    ############################################################################
    # Observability ############################################################
    ############################################################################

    - role: glances
      tags: [observability, pip-pkg, glances]

    - role: ngrep
      tags: [observability, brew-pkg, ngrep]

    - role: jmeter
      tags: [observability, brew-pkg, jmeter]

    - role: htop
      tags: [observability, brew-pkg, htop]

    - role: vtop
      tags: [observability, npm-pkg, vtop]

    - role: wireshark
      tags: [observability, brew-cask-pkg, wireshark]

    ############################################################################
    # Data Systems #############################################################
    ############################################################################

    # DISABLED: I'm not using this these days and its `yarn` binary conflicts
    # with the "yarn" JavaScript package manager.
    - role: hadoop
      tags: [disabled, data-systems, brew-pkg, hadoop]

    ############################################################################
    # Document processing and plotting #########################################
    ############################################################################

    - role: mactex
      tags: [mactex, brew-cask-pkg]

    - role: gnuplot
      tags: [gnuplot, brew-pkg]

    ############################################################################
    # Markup tools #############################################################
    ############################################################################

    - role: grip
      tags: [markup-tools, pip-pkg, grip]

    - role: wkhtmltopdf
      tags: [markup-tools, brew-cask-pkg, wkhtmltopdf]

    - role: hugo
      tags: [markup-tools, brew-pkg, hugo]
      vars:
        # NOTE: version is not actually used because homebrew still can't
        # install a versioned package.
        hugo_version: "0.54.0"

    - role: pandoc
      tags: [markup-tools, brew-pkg, pandoc]

    - role: markdown
      tags: [markup-tools, brew-pkg, markdown]

    ############################################################################
    # Desktop applications #####################################################
    ############################################################################

    - role: grammarly
      tags: [desktop-applications, brew-pkg, grammarly]

    - role: zoom
      tags: [desktop-applications, brew-pkg, zoom]

    - role: elgato-dock
      tags: [desktop-applications, bespoke-pkg, elgato-dock]
      vars:
        elgato_dock_version: "1.2.10.131_40"

    - role: istat-menus
      tags: [desktop-applications, brew-cask-pkg, istat-menus, uses-secrets]

    - role: daisydisk
      tags: [desktop-applications, brew-cask-pkg, daisydisk, uses-secrets]

    - role: pdf-expert
      tags: [desktop-applications, brew-cask-pkg, pdf-expert]

    - role: flux
      tags: [desktop-applications, brew-cask-pkg, flux]

    - role: whatsapp
      tags: [desktop-applications, brew-cask-pkg, whatsapp]

    - role: toggle-dark-mode
      tags: [desktop-applications, toggle-dark-mode]

    - role: cursorcerer
      tags: [desktop-applications, brew-cask-pkg, cursorcerer]

    - role: maccy
      tags: [desktop-applications, brew-cask-pkg, maccy]

    - role: licecap
      tags: [desktop-applications, bespoke-pkg, licecap]
      vars:
        licecap_version: "" # not configurable at the moment

    - role: unity-hub
      tags: [desktop-applications, bespoke-pkg, unity-hub]

    - role: unity
      tags: [desktop-applications, bespoke-pkg, unity]
      vars:
        unity_version: "2022.2.9"

    - role: xquartz
      tags: [desktop-applications, bespoke-pkg, xquartz]
      vars:
        # https://www.xquartz.org/
        xquartz_version: "2.8.1"

    - role: rescuetime
      tags: [desktop-applications, bespoke-pkg, rescuetime]

    # TODO: upgrade to xbar: https://github.com/matryer/xbar/issues/607.
    - role: xbar
      tags: [desktop-applications, bespoke-pkg, xbar]
      vars:
        # https://github.com/matryer/xbar/releases
        xbar_version: "v2.1.7-beta"

    - role: xbar-plugins
      tags: [desktop-applications, xbar, xbar-plugins]

    - role: divvy
      tags: [disabled, desktop-applications, bespoke-pkg, divvy]

    - role: android-file-transfer
      tags: [disabled, desktop-applications, bespoke-pkg, android-file-transfer]

    - role: dropbox
      tags: [disabled, desktop-applications, bespoke-pkg, dropbox]

    - role: google-chrome
      tags: [desktop-applications, brew-cask-pkg, google-chrome]

    - role: firefox
      tags: [desktop-applications, bespoke-pkg, firefox]
      vars:
        firefox_version: "latest"

    # - role: google-chrome-as-default-browser
    #   tags: [desktop-applications, google-chrome-as-default-browser]

    - role: skype
      tags: [disabled, desktop-applications, bespoke-pkg, skype]

    - role: slack
      tags: [desktop-applications, brew-cask-pkg, slack]

    - role: spotify
      tags: [desktop-applications, bespoke-pkg, spotify]

    - role: steam
      tags: [desktop-applications, bespoke-pkg, steam]

    - role: teensy-loader
      tags: [desktop-applications, bespoke-pkg, teensy-loader]

    # DISABLED: the YNAB 4 binary isn't available in the YNAB website anymore.
    - role: ynab
      tags: [disabled, desktop-applications, bespoke-pkg, ynab]
      vars:
        ynab_version: "4.3.855"

    - role: google-photos
      tags: [disabled, desktop-applications, bespoke-pkg, google-photos]

    - role: dash
      tags: [desktop-applications, bespoke-pkg, dash]

    - role: persephone
      tags: [desktop-applications, bespoke-pkg, persephone]
      vars:
        persephone_version: 0.18.0-alpha

    - role: vlc
      tags: [desktop-applications, bespoke-pkg, vlc]
      vars:
        # http://download.videolan.org/pub/videolan/vlc/
        vlc_version: "3.0.18"

    - role: elgato-control-center
      tags: [desktop-applications, brew-pkg, elgato-control-center]

    - role: zwift
      tags: [desktop-applications, brew-pkg, zwift]

    #############################################################################
    # Programming utilities #####################################################
    #############################################################################

    - role: rust-analyzer
      tags: [programming-utilities, brew-pkg, rust-analyzer]

    - role: clojure-lsp
      tags: [programming-utilities, bespoke-pkg, clojure-lsp]

    - role: black
      tags: [programming-utilities, pip-pkg, black]

    - role: ktlint
      tags: [programming-utilities, bespoke-pkg, ktlint]

    - role: ctags
      tags: [programming-utilities, brew-pkgm ctags]

    - role: gron
      tags: [programming-utilities, bespoke-pkg, gron]
      vars:
        gron_version: "0.6.1"

    - role: zprint
      tags: [programming-utilities, bespoke-pkg, zprint]
      vars:
        # https://github.com/kkinnear/zprint/releases
        zprint_version: "1.2.7"

    - role: yapf
      tags: [programming-utilities, pip-pkg, yapf]

    - role: pcsv
      tags: [programming-utilities, pip-pkg, pcsv]

    - role: prettier
      tags: [programming-utilities, npm-pkg, prettier]

    - role: node-cljfmt
      tags: [programming-utilities, npm-pkg, node-cljfmt]

    - role: yq
      tags: [programming-utilities, bespoke-pkg, yq]

    - role: shfmt
      tags: [programming-utilities, brew-pkg, shfmt]

    # DISABLED: it fails to install on Monterey because a dependency
    # (pywatchman) isn't building correctly.
    - role: pyre-check
      tags: [disabled, programming-utilities, pip-pkg, pyre-check]

    - role: shellcheck
      tags: [programming-utilities, brew-pkg, shellcheck]

    #############################################################################
    # Shell #####################################################################
    #############################################################################

    - role: babashka
      tags: [shell, bespoke-pkg, babashka]

    - role: zsh
      tags: [shell, brew-pkg, zsh]

    - role: fish
      tags: [shell, brew-pkg, fish]

    - role: fish-foreign-env
      tags: [shell, bespoke-pkg, fish, fish-foreign-env]

    - role: iterm
      tags: [shell, brew-cask-pkg, iterm]

    - role: tmux
      tags: [shell, brew-pkg, tmux]

    - role: tmuxinator
      tags: [shell, gem-pkg, tmux, tmuxinator]

    #############################################################################
    # Package managers and build tools ##########################################
    #############################################################################

    - role: yarn
      tags: [package-and-build, brew-pkg, yarn]

    - role: pulp
      tags: [package-and-build, npm-pkg, pulp]

    - role: bundler
      tags: [package-and-build, gem-pkg, bundler]

    - role: graalvm
      tags: [disabled, package-and-build, bespoke-pkg, graalvm]
      vars:
        graalvm_version: "21.3.0"

    # NOTE: depends on 'java'.
    - role: leiningen
      tags: [package-and-build, brew-pkg, leiningen]

    #############################################################################
    # Virtualization, provisioning, containers and system tools #################
    #############################################################################

    # DISABLED: haven't used VirtualBox in a while.
    - role: virtualbox
      tags: [disabled, system-tools, bespoke-pkg, virtualbox]
      vars:
        # Wait until Vagrant fixes this issue before upgrading to 5.2
        # https://github.com/hashicorp/vagrant/issues/9090
        # virtualbox_version: "5.2.0"
        # virtualbox_build: "118431"
        virtualbox_version: "6.0.2"
        virtualbox_build: "128162"

    # DISABLED: haven't used Vagrant in a while.
    - role: vagrant
      tags: [disabled, system-tools, bespoke-pkg, vagrant]
      vars:
        vagrant_version: "2.2.14"

    # DISABLED: haven't used Vagrant in a while.
    - role: vagrant-vbguest
      tags: [disabled, system-tools, vagrant-pkg, vagrant, vagrant-vbguest]
      vars:
        vagrant_vbguest_version: "0.29.0"

    - role: orbstack
      tags: [system-tools, brew-cask-pkg, orbstack]

    - role: terraform
      tags: [system-tools, bespoke-pkg, terraform]
      vars:
        # https://releases.hashicorp.com/terraform/
        terraform_version: "1.4.0"
        terraform_checksum: "sha256:ec02ccdcc368ce307d03c1e981f3a863d9c07b312635d4aca24159ada7657562"

    - role: kubectl
      tags: [system-tools, bespoke-pkg, kubernetes, kubectl]
      vars:
        kubectl_version: "1.26.2"

    - role: krew
      tags: [system-tools, bespoke-pkg, kubernetes, krew]

    - role: gcloud
      tags: [system-tools, bespoke-pkg, gcloud]
      vars:
        gcloud_version: "472.0.0"

    - role: kubectl-tree
      tags: [system-tools, krew-pkg, kubernetes, kubectl-tree]

    ############################################################################
    # Browser plugins ##########################################################
    ############################################################################

    - role: firefox-adblock-plus
      tags: [bespoke-pkg, firefox-adblock-plus]

    ############################################################################
    # Multimedia ###############################################################
    ############################################################################

    - role: beets
      tags: [multimedia, pip-pkg, beets]

    - role: ffmpeg
      tags: [multimedia, brew-pkg, ffmpeg]

    - role: imagemagick
      tags: [multimedia, brew-pkg, imagemagick]

    - role: gifsicle
      tags: [multimedia, brew-pkg, gifsicle]

    - role: mpg123
      tags: [multimedia, brew-pkg, mpg123]

    - role: mpd
      tags: [multimedia, brew-pkg, mpd]

    - role: mpc
      tags: [multimedia, brew-pkg, mpc]

    - role: mpdscribble
      tags: [multimedia, brew-pkg, mpdscribble]

    - role: shpotify
      tags: [multimedia, brew-pkg, shpotify]

    - role: mplayer
      tags: [multimedia, brew-pkg, mplayer]

    - role: taglib
      tags: [multimedia, brew-pkg, taglib]

    #############################################################################
    # Command line tools ########################################################
    #############################################################################

    - role: pngpaste
      tags: [command-line-tools, brew-pkg, pngpaste]

    - role: git-delta
      tags: [command-line-tools, brew-pkg, git-delta]

    - role: xz
      tags: [command-line-tools, brew-pkg, xz]

    - role: p7zip
      tags: [command-line-tools, brew-pkg, p7zip]

    - role: awscli
      tags: [command-line-tools, pip-pkg, awscli, uses-secrets]

    - role: gh
      tags: [command-line-tools, brew-pkg, gh, contextualize]

    - role: vercel
      tags: [command-line-tools, npm-pkg, vercel, contextualize]

    - role: stripe-cli
      tags: [command-line-tools, npm-pkg, stripe-cli, contextualize]

    - role: local-ssl-proxy
      tags: [command-line-tools, npm-pkg, local-ssl-proxy, contextualize]

    # DISABLED: using awscli instead.
    - role: s3cmd
      tags: [disabled, command-line-tools, s3cmd, uses-secrets]

    - role: defaultbrowser
      tags: [command-line-tools, git-pkg, defaultbrowser]
      vars:
        defaultbrowser_version: "1.1"

    - role: jq
      tags: [command-line-tools, bespoke-pkg, jq]

    - role: tree
      tags: [command-line-tools, brew-pkg, tree]

    - role: scc
      tags: [command-line-tools, brew-pkg, scc]

    - role: pgsanity
      tags: [command-line-tools, pip-pkg, pgsanity]

    - role: ripgrep
      tags: [command-line-tools, brew-pkg, ripgrep]

    - role: fd
      tags: [command-line-tools, brew-pkg, fd]

    - role: parallel
      tags: [command-line-tools, brew-pkg, parallel]

    - role: tealdeer
      tags: [command-line-tools, cargo-pkg, tealdeer]

    - role: wrk
      tags: [command-line-tools, brew-pkg, wrk]

    - role: websocat
      tags: [command-line-tools, bespoke-pkg, websocat]

    - role: terminal-notifier
      tags: [command-line-tools, brew-pkg, terminal-notifier]

    #############################################################################
    # Miscellaneous #############################################################
    #############################################################################

    - role: chromedriver
      tags: [brew-cask-pkg, brew-cask-pkg-versioned, chromedriver]
      vars:
        # Version 116.0.5845.96.
        # https://github.com/Homebrew/homebrew-cask/blob/master/Casks/c/chromedriver.rb
        git_commit_ref: "b9ee893f20b4183f9cf7e204ea408c2b11c42ca2"

    - role: mutagen
      tags: [brew-pkg, mutagen]

    # DISABLED: this was only necessary to build Cantata I think?
    - role: qt5
      tags: [disabled, bespoke-pkg, qt5]
      vars:
        qt_major_minor_version: "5.12"
        qt_version: "{{ qt_major_minor_version }}.0"

    - role: fontforge
      tags: [brew-pkg, fontforge]

    # Depends on xquartz.
    - role: wordnet
      tags: [brew-pkg, wordnet]


================================================
FILE: requirements.yml
================================================
---
collections:
  - name: ansible.posix
    version: 1.3.0


================================================
FILE: roles/android-file-transfer/tasks/main.yml
================================================
---
- name: Download Android File Transfer
  get_url:
    url: "{{ android_file_transfer_image_url }}"
    dest: "{{ android_file_transfer_image_path }}"

- name: Get {{ android_file_transfer_app_directory }} stats
  stat:
    path: "{{ android_file_transfer_app_directory }}"
  register: android_file_transfer_app_directory_stat

- name: Mount Android File Transfer image
  command: >
    hdiutil attach -nobrowse {{ android_file_transfer_image_path }}
    creates="{{ android_file_transfer_volume_path }}"
  when: not android_file_transfer_app_directory_stat.stat.exists

- name: Get {{ android_file_transfer_volume_path }} stats
  stat:
    path: "{{ android_file_transfer_volume_path }}"
  register: android_file_transfer_volume_path_stat

- name: Create {{ android_file_transfer_app_directory }}
  command: >
    cp -R "{{ android_file_transfer_volume_path }}/{{ android_file_transfer_app_name }}" /Applications
    creates="{{ android_file_transfer_app_directory }}"
  become: yes

- name: Unmount Android File Transfer image
  command: hdiutil detach "{{ android_file_transfer_volume_path }}"
  when: android_file_transfer_volume_path_stat.stat.exists


================================================
FILE: roles/android-file-transfer/vars/main.yml
================================================
---
android_file_transfer_image_name: "androidfiletransfer.dmg"
android_file_transfer_image_url: "https://dl.google.com/dl/androidjumper/mtp/current/{{ android_file_transfer_image_name }}"
android_file_transfer_image_path: "{{ downloads_directory }}/{{ android_file_transfer_image_name }}"
android_file_transfer_volume_path: "/Volumes/Android File Transfer"
android_file_transfer_app_name: "Android File Transfer.app"
android_file_transfer_app_directory: "/Applications/{{ android_file_transfer_app_name }}"


================================================
FILE: roles/ansible-download-directory/tasks/main.yml
================================================
---
- name: Ensure that the Ansible downloads directory exists
  file:
    path: "{{ downloads_directory }}"
    state: directory


================================================
FILE: roles/awscli/tasks/main.yml
================================================
- name: Install awscli
  pip:
    name: awscli
    extra_args: --user

- name: Ensure ~/.aws directory exists
  file:
    path: "{{ home_directory }}/.aws"
    state: directory

- name: Install ~/.aws/credentials
  copy:
    content: "{{ aws_credentials_file_base64 | b64decode }}"
    dest: "{{ home_directory }}/.aws/credentials"
    mode: 0644


================================================
FILE: roles/babashka/tasks/main.yml
================================================
---
- name: Download Babashka installer
  get_url:
    url: https://raw.githubusercontent.com/borkdude/babashka/master/install
    dest: "{{ downloads_directory }}/install-babashka"
    mode: u+x

- name: Install Babashka
  command: "{{ downloads_directory }}/install-babashka"
  become: yes


================================================
FILE: roles/bash/tasks/main.yml
================================================
---
- name: Install bash
  homebrew:
    name: bash
    state: latest

- name: Register bash binary path
  register: bin_bash
  shell: >
    echo "$(brew --prefix)/bin/bash"

- name: Add bash to /etc/shells
  lineinfile:
    path: /etc/shells
    line: "{{ bin_bash.stdout }}"
  become: yes

- name: Make bash be the default shell
  shell: >
    chsh -s "{{ bin_bash.stdout }}" "{{ user }}"
  become: yes

- name: Install bash-completion@2
  homebrew:
    name: "bash-completion@2"


================================================
FILE: roles/beets/tasks/main.yml
================================================
---
- name: Install beets
  pip:
    name: beets
    extra_args: --user


================================================
FILE: roles/better-touch-tool/tasks/main.yml
================================================
---
- name: Download BetterTouchTool
  get_url: >
    url="https://folivora.ai/releases/BetterTouchTool.zip"
    dest="{{ downloads_directory }}/BetterTouchTool.zip"

- name: Extract BetterTouchTool zip archive
  command: >
    chdir={{ downloads_directory }}
    unzip "BetterTouchTool.zip" -d "BetterTouchTool"
    creates=BetterTouchTool

- name: Copy BetterTouchTool.app to Applications directory
  command: >
    cp -R "{{ downloads_directory }}/BetterTouchTool/BetterTouchTool.app" /Applications
    creates=/Applications/BetterTouchTool.app
  become: yes

- name: Open BetterTouchTool.app
  command: >
    open /Applications/BetterTouchTool.app


================================================
FILE: roles/black/tasks/main.yml
================================================
---
- name: Install Black
  command:
    python3 -m pip install --user black


================================================
FILE: roles/bottle/tasks/main.yml
================================================
- name: Install bottle
  pip:
    name: bottle
    extra_args: --user


================================================
FILE: roles/build-emacs/tasks/main.yml
================================================
---
- name: Add Homebrew tap
  command: brew tap daviderestivo/emacs-head

- name: Install Emacs
  homebrew:
    name: emacs-head@29
    state: latest
    # https://github.com/daviderestivo/homebrew-emacs-head/blob/master/Formula/emacs-head@29.rb
    install_options:
      - with-cocoa
      - with-crash-debug
      - with-imagemagick
      - with-modern-icon-pen
      - with-native-comp
      - with-no-frame-refocus
      - with-pdumper
      - with-tree-sitter
      - with-xwidgets

# NOTE: spotlight doesn't seem to pick up this symlink?
- name: Create a symbolic link
  ansible.builtin.file:
    src: /opt/homebrew/Cellar/emacs-head@29/29.0.90_1/Emacs.app/
    dest: /Applications/Emacs-29.app
    state: link


================================================
FILE: roles/bundler/tasks/main.yml
================================================
---
- name: Install bundler
  gem:
    name: bundler
    state: latest


================================================
FILE: roles/caps-lock-remapped-to-control/files/remap_caps_lock_to_control.scpt
================================================
tell application "System Preferences"
	activate
	set current pane to pane "com.apple.preference.keyboard"
end tell

delay 1

tell application "System Events"
	tell process "System Preferences"
		get properties

		click button "Modifier Keys…" of tab group 1 of window "Keyboard"
		tell sheet 1 of window "Keyboard"
			click pop up button 2
			click menu item 2 of menu 1 of pop up button 2
			click button "OK"
		end tell
	end tell

	tell application "System Preferences" to quit
end tell


================================================
FILE: roles/caps-lock-remapped-to-control/tasks/main.yml
================================================
---
- name: Remap Caps Lock to Control
  command: osascript roles/caps-lock-remapped-to-control/files/remap_caps_lock_to_control.scpt


================================================
FILE: roles/chromedriver/tasks/main.yml
================================================
---
- name: Create directory for versioned Chromedriver Homebrew recipe
  ansible.builtin.file:
    path: "{{ downloads_directory }}/chromedriver/{{ git_commit_ref }}"
    state: directory

- name: Download the versioned Chromedriver Homebrew recipe
  ansible.builtin.get_url:
    url: "https://raw.githubusercontent.com/Homebrew/homebrew-cask/{{ git_commit_ref }}/Casks/c/chromedriver.rb"
    dest: "{{ downloads_directory }}/chromedriver/{{ git_commit_ref }}/chromedriver.rb"

- name: Install Chromedriver from Homebrew recipe
  homebrew_cask:
    name: "{{ downloads_directory }}/chromedriver/{{ git_commit_ref }}/chromedriver.rb"
    state: latest


================================================
FILE: roles/clojure/tasks/main.yml
================================================
---
- name: Install Clojure
  homebrew:
    name: clojure/tools/clojure
    state: latest


================================================
FILE: roles/clojure-lsp/tasks/main.yml
================================================
---
# NOTE: not using the Homebrew brew because it is hard-coded to depend on
# openjdk@11 from Homebrew.
- name: Install Clojure LSP
  unarchive:
    src: https://github.com/clojure-lsp/clojure-lsp/releases/latest/download/clojure-lsp-native-macos-amd64.zip
    dest: /usr/local/bin
    mode: u+x
    remote_src: yes


================================================
FILE: roles/cmake/tasks/main.yml
================================================
---
- name: Download CMake
  get_url:
    url: "{{ cmake_image_url }}"
    dest: "{{ downloads_directory }}/{{ cmake_image_name }}"

- name: Get current CMake version
  command: /Applications/CMake.app/Contents/bin/cmake --version
  register: cmake_version_output
  ignore_errors: yes

- name: Get current CMake version
  set_fact:
    current_cmake_version: "{{ cmake_version_output.stdout | regex_search('\\d+\\.\\d+\\.\\d+') }}"

- set_fact:
    installed_cmake_version_differs_or_not_installed: "{{ (cmake_version_output.rc != 0 or cmake_version is version(current_cmake_version, '<')) }}"

- name: Convert CMake image to a format that does not require an EULA
  command: >
    chdir={{ downloads_directory }}
    hdiutil convert -quiet {{ cmake_image_name }} -format UDTO -o {{ cmake_image_name }}.cdr
    creates={{ cmake_image_name }}.cdr
  when: installed_cmake_version_differs_or_not_installed | bool

- name: Mount CMake image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse -quiet {{ cmake_image_name }}.cdr
    creates="{{ cmake_volume_path }}"
  when: installed_cmake_version_differs_or_not_installed | bool

- name: Copy CMake application directory to the applications directory
  command: >
    cp -R "{{ cmake_volume_path }}/{{ cmake_app_name }}" /Applications
  when: installed_cmake_version_differs_or_not_installed | bool

- name: Unmount CMake image
  command: hdiutil detach "{{ cmake_volume_path }}"
  when: installed_cmake_version_differs_or_not_installed | bool


================================================
FILE: roles/cmake/vars/main.yml
================================================
---
# https://github.com/Kitware/CMake/releases/download
cmake_image_name_suffix: "macos-universal"
cmake_image_name: "cmake-{{ cmake_version }}-{{ cmake_image_name_suffix }}.dmg"
cmake_image_url: "https://github.com/Kitware/CMake/releases/download/v{{ cmake_version }}/{{ cmake_image_name }}"
cmake_image_path: "{{ downloads_directory }}/{{ cmake_image_name }}"
cmake_volume_path: "/Volumes/cmake-{{ cmake_version }}-{{ cmake_image_name_suffix }}"
cmake_app_name: "CMake.app"
cmake_app_directory: "/Applications/{{ cmake_app_name }}"


================================================
FILE: roles/consolas/tasks/main.yml
================================================
---
- name: Install cabextract
  homebrew: name=cabextract state=present

# Got it originally from here:
# https://download.cnet.com/PowerPoint-Viewer/3001-2075_4-75450958.html
- name: Download PowerPointViewer.exe
  get_url:
    url: https://macbook-playbook.s3.amazonaws.com/artifacts/PowerPointViewer.exe
    dest: "{{ downloads_directory }}/PowerPointViewer.exe"

- name: Make PowerPointViewer directory
  command: mkdir -p "{{ downloads_directory }}/PowerPointViewer"

- name: Extract PowerPointViewer.exe
  command: cabextract "{{ downloads_directory }}/PowerPointViewer.exe" -d "{{ downloads_directory }}/PowerPointViewer"

- name: Make ppviewer directory to extract fonts to
  command: mkdir -p "{{ downloads_directory }}/ppviewer"

- name: Extract ppviewer.cab
  command: cabextract "{{ downloads_directory }}/PowerPointViewer/ppviewer.cab" -d "{{ downloads_directory }}/ppviewer"

- name: Install Consolas
  shell: open {{ downloads_directory }}/ppviewer/CONSOLA*.TTF


================================================
FILE: roles/ctags/tasks/main.yml
================================================
---
- name: Install ctags
  homebrew:
    name: ctags
    state: latest


================================================
FILE: roles/cursorcerer/tasks/main.yml
================================================
---
- name: Install Cursorcerer
  homebrew_cask:
    name: cursorcerer
    state: latest

- name: Open Cursorcerer.prefPane
  command: open /opt/homebrew/Caskroom/cursorcerer/latest/Cursorcerer.prefPane


================================================
FILE: roles/daisydisk/tasks/main.yml
================================================
---
- name: Install DaisyDisk
  homebrew_cask:
    name: daisydisk
    state: latest

- command: open /Applications/DaisyDisk.app

# TODO: open it if it was just installed for the first time?


================================================
FILE: roles/dash/tasks/main.yml
================================================
---
- name: Download Dash
  get_url:
    url: http://newyork.kapeli.com/{{ dash_zip }}
    dest: "{{ downloads_directory }}/{{ dash_zip }}"

- name: Extract {{ dash_zip }} archive
  command: >
    chdir={{ downloads_directory }}
    unzip {{ dash_zip }} -d {{ dash_directory }}
    creates={{ dash_directory }}

- name: Copy {{ dash_app }} to Applications directory
  command: >
    cp -R {{ downloads_directory }}/Dash/{{ dash_app }} /Applications
    creates=/Applications/{{ dash_app }}
  become: yes


================================================
FILE: roles/dash/vars/main.yml
================================================
---
dash_directory: Dash
dash_zip: Dash.zip
dash_app: Dash.app


================================================
FILE: roles/defaultbrowser/tasks/main.yml
================================================
---
- name: Check out the defaultbrowser repository
  git:
    repo: https://github.com/kerma/defaultbrowser.git
    dest: "{{ downloads_directory }}/defaultbrowser"
    version: "{{ defaultbrowser_version }}"

- name: Build defaultbrowser
  command: 
    cmd: make
    chdir: "{{ downloads_directory }}/defaultbrowser"

- name: Install defaultbrowser
  command: 
    cmd: make install
    chdir: "{{ downloads_directory }}/defaultbrowser"


================================================
FILE: roles/divvy/tasks/main.yml
================================================
---
- name: Download Divvy
  get_url:
    url: http://mizage.com/downloads/Divvy.zip
    dest: "{{ downloads_directory }}/Divvy.zip"

- name: Extract Divvy zip archive
  command: >
    chdir={{ downloads_directory }}
    unzip Divvy.zip -d Divvy
    creates=Divvy

- name: Copy Divvy.app to Applications directory
  command: >
    cp -R {{ downloads_directory }}/Divvy/Divvy.app /Applications
    creates=/Applications/Divvy.app
  become: yes


================================================
FILE: roles/docker/tasks/main.yml
================================================
---
- name: Install Docker
  homebrew_cask:
    name: docker
    state: latest

# TODO: open it if it was just installed for the first time?


================================================
FILE: roles/dotemacs/tasks/main.yml
================================================
---
- name: Check out the mpereira/.emacs.d repository
  git:
    repo: git@github.com:mpereira/.emacs.d.git
    dest: "{{ home_directory }}/.emacs.d"
    update: no


================================================
FILE: roles/dotfiles/tasks/main.yml
================================================
---
- name: Check out the mpereira/dotfiles repository
  git:
    repo: git@github.com:mpereira/dotfiles.git
    dest: "{{ home_directory }}/.dotfiles"
    update: no

- name: Install dotfiles
  environment: "{{ dotfiles_environment_yml_file_base64 | b64decode | from_yaml }}"
  shell: rake sync
  args:
    chdir: "{{ home_directory }}/.dotfiles"


================================================
FILE: roles/dotnet-sdk/tasks/main.yml
================================================
---
- name: Install .NET SDK
  homebrew_cask:
    name: dotnet-sdk
    state: latest


================================================
FILE: roles/dropbox/tasks/main.yml
================================================
---
- name: Download Dropbox
  get_url:
    url: https://www.dropbox.com/download?plat=mac
    dest: "{{ downloads_directory }}/DropboxInstaller.dmg"

- name: Mount Dropbox image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse DropboxInstaller.dmg
    creates="/Volumes/Dropbox Installer"

- name: Copy Dropbox application directory to the applications directory
  command: >
    cp -R /Volumes/Dropbox\ Installer/Dropbox.app /Applications
    creates=/Applications/Dropbox.app

- name: Unmount Dropbox image
  command: hdiutil detach /Volumes/Dropbox\ Installer


================================================
FILE: roles/elgato-control-center/tasks/main.yml
================================================
---
- name: Add Homebrew tap
  command: brew tap homebrew/cask-drivers

- name: Install elgato-control-center
  homebrew_cask:
    name: elgato-control-center
    state: latest


================================================
FILE: roles/elgato-dock/tasks/main.yml
================================================
---
- name: Download Elgato Dock software
  get_url:
    url: "https://edge.elgato.com/thunderbolt-dock/Elgato_Thunderbolt_Dock_Software_{{ elgato_dock_version }}.pkg"
    dest: "{{ downloads_directory }}/Elgato_Thunderbolt_Dock_Software_{{ elgato_dock_version }}.pkg"

- name: Install Elgato Dock software
  command: >
    installer -package "{{ downloads_directory}}/Elgato_Thunderbolt_Dock_Software_{{ elgato_dock_version }}.pkg" -target /
  become: yes
  # NOTE: ignoring errors because installing this seems to fail sporadically.
  ignore_errors: yes


================================================
FILE: roles/emacs-pre-built/tasks/main.yml
================================================
---
- name: Download Emacs
  get_url:
    url: https://emacsformacosx.com/emacs-builds/{{ emacs_pre_built_dmg }}
    dest: "{{ downloads_directory }}/{{ emacs_pre_built_dmg }}"
    validate_certs: no

- name: Check existing Emacs version
  shell: "{{ emacs_pre_built_app }}/Contents/MacOS/Emacs --version 2>&1"
  register: emacs_pre_built_version_output
  ignore_errors: yes

- name: Mount the Emacs image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse {{ emacs_pre_built_dmg }}
    creates=/Volumes/Emacs
  when: emacs_pre_built_version_output.stdout.find('GNU Emacs ' ~ emacs_pre_built_version) == -1

- name: Install Emacs
  # `copy` hangs for some reason, using `command` instead.
  command: >
    cp -R /Volumes/Emacs/Emacs.app {{ emacs_pre_built_app }}
  become: yes
  when: emacs_pre_built_version_output.stdout.find('GNU Emacs ' ~ emacs_pre_built_version) == -1

- name: Unmount the Emacs image
  command: hdiutil detach /Volumes/Emacs
  when: emacs_pre_built_version_output.stdout.find('GNU Emacs ' ~ emacs_pre_built_version) == -1

- name: Download Emacs source archive
  get_url:
    url: https://emacsformacosx.com/emacs-sources/{{ emacs_pre_built_src_archive }}
    dest: "{{ downloads_directory }}/{{ emacs_pre_built_src_archive }}"
    timeout: 30
    validate_certs: no

- name: Install Emacs source
  unarchive:
    src: "{{ downloads_directory }}/{{ emacs_pre_built_src_archive }}"
    dest: /usr/local/src


================================================
FILE: roles/emacs-pre-built/vars/main.yml
================================================
---
emacs_pre_built_pretest_prefix: "{{ 'pretest-' if (emacs_pre_built_pretest is defined and emacs_pre_built_pretest) else '' }}"
emacs_pre_built_full_version: "{{ emacs_pre_built_pretest_prefix }}{{ emacs_pre_built_version }}{{ emacs_pre_built_patch }}"
emacs_pre_built_dmg: "Emacs-{{ emacs_pre_built_full_version }}-universal.dmg"
emacs_pre_built_src_archive: "emacs-{{ emacs_pre_built_version }}.tar.xz"
emacs_pre_built_app: "/Applications/Emacs-{{ emacs_pre_built_full_version }}.app"


================================================
FILE: roles/fd/tasks/main.yml
================================================
---
- name: Install fd
  homebrew:
    name: fd
    state: latest


================================================
FILE: roles/ffmpeg/tasks/main.yml
================================================
---
- name: Install ffmpeg
  homebrew:
    name: ffmpeg
    state: latest


================================================
FILE: roles/firefox/tasks/main.yml
================================================
---
- name: Download Firefox
  get_url:
    url: "https://download.mozilla.org/?product=firefox-{{ firefox_version }}&os=osx"
    dest: "{{ downloads_directory }}/Firefox.dmg"

- name: Get current Firefox version
  shell: defaults read "{{ firefox_app }}/Contents/Info.plist" CFBundleShortVersionString
  register: firefox_version_output
  ignore_errors: yes

- name: Maybe clear '{{ firefox_app }}' directory
  file: >
    path="{{ firefox_app }}"
    state=absent
  when: firefox_version_output.rc == 1

- name: Mount Firefox image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse Firefox.dmg
    creates=/Volumes/Firefox
  when: firefox_version_output.rc == 1

- name: Copy Firefox application directory to the applications directory
  command: >
    cp -R /Volumes/Firefox/Firefox.app /Applications
    creates={{ firefox_app }}
  when: firefox_version_output.rc == 1

- name: Unmount Firefox image
  command: hdiutil detach /Volumes/Firefox
  when: firefox_version_output.rc == 1


================================================
FILE: roles/firefox/vars/main.yml
================================================
---
firefox_app: "/Applications/Firefox.app"


================================================
FILE: roles/firefox-adblock-plus/tasks/main.yml
================================================
---
- name: Open Firefox
  shell: >
    "{{ firefox_app }}/Contents/MacOS/firefox-bin" -headless & firefox_pid=$!; sleep 10; kill $firefox_pid

- name: Download Adblock Plus
  get_url: >
    url=https://addons.mozilla.org/firefox/downloads/latest/1865/addon-1865-latest.xpi
    dest={{ downloads_directory }}/addon-1865-latest.xpi

- name: Install Adblock Plus
  shell: >
    cd /Users/{{ user }}/Library/Application\ Support/Firefox/Profiles/*/extensions && unzip -u {{ downloads_directory }}/addon-1865-latest.xpi -d {d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}


================================================
FILE: roles/fish/tasks/main.yml
================================================
---
- name: Install fish
  homebrew:
    name: fish
    state: latest


================================================
FILE: roles/fish-foreign-env/tasks/main.yml
================================================
---
- name: Make sure Fish shell directory exists
  file:
    path: "{{ home_directory }}/.config/fish"
    state: directory
    mode: 0755

- name: Clone foreign-env repository
  git:
    repo: "https://github.com/oh-my-fish/plugin-foreign-env.git"
    dest: "{{ home_directory }}/.config/fish/plugin-foreign-env"


================================================
FILE: roles/flux/tasks/main.yml
================================================
---
- name: Install f.lux
  homebrew_cask:
    name: flux
    state: latest

# TODO: open it if it was just installed for the first time?


================================================
FILE: roles/font-hack/tasks/main.yml
================================================
---
- name: Add cask-fonts tap
  command: brew tap homebrew/cask-fonts

- name: Install Hack font
  homebrew_cask:
    name: font-hack
    state: latest

- name: Install fontconfig
  homebrew:
    name: fontconfig
    state: latest

- name: Reload fonts
  command: fc-cache -vf
  become: yes


================================================
FILE: roles/fontforge/tasks/main.yml
================================================
---
- name: Create /usr/local/Frameworks
  file:
    path: /usr/local/Frameworks
    state: directory
    owner: "{{ user }}"
  become: yes

- name: Install fontforge
  homebrew:
    name: fontforge
    state: latest


================================================
FILE: roles/gcloud/tasks/main.yml
================================================
---
- name: Install gcloud
  shell: >
    set -x; cd ~ &&
      OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
      PROCESSOR="$(uname -p)" &&
      GCLOUD="google-cloud-cli-{{ gcloud_version }}-${OS}-${PROCESSOR}" &&
      curl -fsSLO "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/${GCLOUD}.tar.gz" &&
      tar zxf "${GCLOUD}.tar.gz" &&
      ./google-cloud-sdk/install.sh --rc-path ~/.profile &&
      rm -f "${GCLOUD}.tar.gz"


================================================
FILE: roles/gh/tasks/main.yml
================================================
---
- name: Install gh
  homebrew:
    name: gh
    state: latest


================================================
FILE: roles/gifsicle/tasks/main.yml
================================================
---
- name: Install gifsicle
  homebrew:
    name: gifsicle
    state: present


================================================
FILE: roles/git/tasks/main.yml
================================================
---
- name: Install Git
  homebrew:
    name: git
    state: latest


================================================
FILE: roles/git/vars/main.yml
================================================
---
git_dmg: git-{{ git_version }}-intel-universal-mavericks.dmg
git_volume: Git {{ git_version }} Mavericks Intel Universal
git_pkg: git-{{ git_version }}-intel-universal-mavericks.pkg


================================================
FILE: roles/git-delta/tasks/main.yml
================================================
---
- name: Install delta
  homebrew:
    name: git-delta
    state: latest


================================================
FILE: roles/glances/files/com.mpereira.glances.webserver.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.mpereira.glances.webserver</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/murilo/Library/Python/2.7/bin/glances</string>
        <string>--process-short-name</string>
        <string>--hide-kernel-threads</string>
        <string>--byte</string>
        <string>--webserver</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
</dict>
</plist>


================================================
FILE: roles/glances/tasks/main.yml
================================================
---
- name: Install glances
  pip:
    name: glances
    extra_args: --user

- name: Create glances webserver service plist
  copy:
    src: com.mpereira.glances.webserver.plist
    dest: ~/Library/LaunchAgents/com.mpereira.glances.webserver.plist
    validate: 'plutil %s'

- name: Start glances webserver service
  command: >
    launchctl load -w ~/Library/LaunchAgents/com.mpereira.glances.webserver.plist


================================================
FILE: roles/glances/vars/main.yml
================================================
---
dependencies:
  - bottle


================================================
FILE: roles/gnu-command-line-tools/tasks/main.yml
================================================
---
- name: Install coreutils
  homebrew:
    name: coreutils
    state: latest

- name: Install some GNU tools
  homebrew:
    state: latest
    name:
      - binutils # don't link this so that there's no conflicts with macOS binaries.
      - diffutils
      - ed
      - findutils
      - gawk
      - gnu-indent
      - gnu-sed
      - gnu-tar
      - gnu-which
      - gnutls
      - grep
      - gzip
      - screen
      - watch
      - wdiff
      - wget


================================================
FILE: roles/gnupg/tasks/main.yml
================================================
---
- name: Download GnuPG
  get_url:
    url: https://downloads.sourceforge.net/project/gpgosx/{{ gnupg_dmg }}
    dest: "{{ downloads_directory }}/{{ gnupg_dmg }}"

- name: Mount GnuPG image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse {{ gnupg_dmg }}
    creates="/Volumes/{{ gnupg_volume }}"

- name: Install GnuPG
  command: >
    installer -package "/Volumes/{{ gnupg_volume }}/Install.pkg" -target /
  become: yes

- name: Unmount GnuPG image
  command: hdiutil detach "/Volumes/{{ gnupg_volume }}"


================================================
FILE: roles/gnupg/vars/main.yml
================================================
---
gnupg_dmg: "GnuPG-{{ gnupg_version }}.dmg"
gnupg_volume: "GnuPG {{ gnupg_version }}"


================================================
FILE: roles/gnuplot/tasks/main.yml
================================================
---
- name: Install gnuplot
  homebrew:
    name: gnuplot
    state: latest


================================================
FILE: roles/go/tasks/main.yml
================================================
---
- name: Download Go
  get_url:
    url: "{{ go_pkg_url }}"
    dest: "{{ downloads_directory }}/{{ go_pkg }}"

- name: Install Go
  command: >
    installer -package "{{ downloads_directory }}/{{ go_pkg }}" -target /
  become: yes


================================================
FILE: roles/go/vars/main.yml
================================================
---
go_pkg: "go{{ go_version }}.darwin-amd64.pkg"
go_pkg_url: "https://dl.google.com/go/{{ go_pkg }}"


================================================
FILE: roles/google-chrome/tasks/main.yml
================================================
---
- name: Install Google Chrome
  homebrew_cask:
    name: google-chrome
    state: latest


================================================
FILE: roles/google-chrome/vars/main.yml
================================================
---
google_chrome_image_name: "googlechrome.dmg"
google_chrome_image_url: "https://dl.google.com/chrome/mac/stable/CHFA/{{ google_chrome_image_name }}"
google_chrome_image_path: "{{ downloads_directory }}/{{ google_chrome_image_name }}"
google_chrome_volume_path: "/Volumes/Google Chrome"
google_chrome_app_name: "Google Chrome.app"
google_chrome_app_directory: "/Applications/{{ google_chrome_app_name }}"


================================================
FILE: roles/google-chrome-as-default-browser/meta/main.yml
================================================
---
dependencies:
  - google-chrome
  - defaultbrowser


================================================
FILE: roles/google-chrome-as-default-browser/tasks/main.yml
================================================
---
- name: Make Google Chrome the default browser
  command: defaultbrowser chrome


================================================
FILE: roles/google-photos/tasks/main.yml
================================================
---
- name: Download Google Photos
  get_url:
    url: https://dl.google.com/dl/picasa/{{ google_photos_dmg }}
    dest: "{{ downloads_directory }}/{{ google_photos_dmg }}"

- name: Mount Google Photos image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse {{ google_photos_dmg }}
    creates="/Volumes/{{ google_photos_volume }}"

- name: Copy Google Photos application directory to the applications directory
  command: >
    cp -R "/Volumes/{{ google_photos_volume }}/{{ google_photos_app }}" /Applications
    creates="/Applications/{{ google_photos_app }}"

- name: Unmount Google Photos image
  command: hdiutil detach "/Volumes/{{ google_photos_volume }}"


================================================
FILE: roles/google-photos/vars/main.yml
================================================
---
google_photos_dmg: gpautobackup_setup.dmg
google_photos_volume: Install Google Photos Backup
google_photos_app: Google Photos Backup.app


================================================
FILE: roles/graalvm/tasks/main.yml
================================================
---
- name: Download GraalVM
  get_url:
    url: "https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-{{ graalvm_version }}/{{ graalvm_archive }}"
    dest: "{{ downloads_directory }}/{{ graalvm_archive }}"

- name: Extract GraalVM
  unarchive:
    src="{{ downloads_directory }}/{{ graalvm_archive }}"
    dest="{{ downloads_directory }}"
    creates="{{ downloads_directory }}/{{ graalvm_extracted_directory }}"

- name: Install GraalVM
  command: cp -R "{{ downloads_directory }}/{{ graalvm_extracted_directory }}" "/Applications/GraalVM-{{ graalvm_version }}.app"

- name: Install native-image utility
  command: /Applications/GraalVM-{{ graalvm_version }}.app/Contents/Home/bin/gu install native-image


================================================
FILE: roles/graalvm/vars/main.yml
================================================
---
graalvm_java_version: "java11"
graalvm_directory: "graalvm-ce-{{ graalvm_java_version }}-darwin-amd64-{{ graalvm_version }}"
graalvm_archive: "{{ graalvm_directory }}.tar.gz"
graalvm_extracted_directory: "graalvm-ce-{{ graalvm_java_version }}-{{ graalvm_version }}"


================================================
FILE: roles/grammarly/tasks/main.yml
================================================
---
- name: Install Grammarly
  homebrew_cask:
    name: grammarly
    state: latest


================================================
FILE: roles/grip/tasks/main.yml
================================================
---
- name: Install Grip
  pip:
    name: grip
    extra_args: --user


================================================
FILE: roles/gron/tasks/main.yml
================================================
---
- name: Download and install gron binary
  unarchive:
    src: https://github.com/tomnomnom/gron/releases/download/v{{ gron_version }}/gron-darwin-amd64-{{ gron_version }}.tgz
    dest: /usr/local/bin
    mode: u+x
    remote_src: yes


================================================
FILE: roles/hadoop/tasks/main.yml
================================================
---
- name: Install hadoop
  homebrew:
    name: hadoop
    state: latest


================================================
FILE: roles/haskell/tasks/main.yml
================================================
---
- name: Install haskell-stack
  homebrew:
    name: haskell-stack
    state: latest


================================================
FILE: roles/homebrew/tasks/main.yml
================================================
---
- name: Install Homebrew
  shell: >
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
    creates=/usr/local/bin/brew


================================================
FILE: roles/htop/tasks/main.yml
================================================
---
- name: Install htop
  homebrew:
    name: htop
    state: latest


================================================
FILE: roles/hugo/tasks/main.yml
================================================
---
- name: Install Hugo
  homebrew:
    name: hugo
    # NOTE: I don't want to automatically update Hugo.
    state: present


================================================
FILE: roles/imagemagick/tasks/main.yml
================================================
---
- name: Install imagemagick
  homebrew:
    name: imagemagick
    state: latest


================================================
FILE: roles/istat-menus/tasks/main.yml
================================================
---
- name: Install iStat Menus
  homebrew_cask:
    name: istat-menus
    state: latest

- command: open /Applications/iStat\ Menus.app

# TODO: open it if it was just installed for the first time?


================================================
FILE: roles/iterm/tasks/main.yml
================================================
---
- name: Install iTerm2
  homebrew_cask:
    name: iterm2
    state: latest


================================================
FILE: roles/java/tasks/main.yml
================================================
---
- name: Add Homebrew tap
  command: brew tap AdoptOpenJDK/openjdk

- name: Install OpenJDK
  homebrew_cask:
    name: "{{ java_version }}"
    state: latest


================================================
FILE: roles/jmeter/tasks/main.yml
================================================
---
- name: Install JMeter
  homebrew:
    name: jmeter
    state: latest


================================================
FILE: roles/jpeg/tasks/main.yml
================================================
---
- name: Install jpeg
  homebrew: name=jpeg state=present


================================================
FILE: roles/jq/tasks/main.yml
================================================
---
- name: Download and install jq binary
  get_url:
    url: https://github.com/stedolan/jq/releases/latest/download/jq-osx-amd64
    dest: /usr/local/bin/jq
    mode: u+x


================================================
FILE: roles/krew/tasks/main.yml
================================================
---
- name: Install krew
  shell: >
    set -x; cd "$(mktemp -d)" &&
      OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
      ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
      KREW="krew-${OS}_${ARCH}" &&
      curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
      tar zxvf "${KREW}.tar.gz" &&
      ./"${KREW}" install krew


================================================
FILE: roles/ktlint/tasks/main.yml
================================================
---
- name: Install ktlint
  get_url:
    url: "https://github.com/pinterest/ktlint/releases/latest/download/ktlint"
    mode: 0755
    dest: /usr/local/bin/ktlint


================================================
FILE: roles/kubectl/tasks/main.yml
================================================
---
- name: Download kubectl binary
  get_url:
    url: "{{ kubectl_binary_url }}"
    dest: "{{ downloads_directory }}/{{ kubectl_binary_name }}_{{ kubectl_version }}"
    mode: "755"

- name: Install kubectl
  command: cp "{{ downloads_directory }}/{{ kubectl_binary_name }}_{{ kubectl_version }}" /usr/local/bin/{{ kubectl_binary_name }}


================================================
FILE: roles/kubectl/vars/main.yml
================================================
kubectl_binary_name: "kubectl"
kubectl_binary_url: "https://storage.googleapis.com/kubernetes-release/release/v{{ kubectl_version }}/bin/darwin/amd64/{{ kubectl_binary_name }}"


================================================
FILE: roles/kubectl-tree/tasks/main.yml
================================================
---
- name: Install kubectl-tree
  command: kubectl-krew install tree


================================================
FILE: roles/leiningen/tasks/main.yml
================================================
---
- name: Install leiningen
  homebrew:
    name: leiningen
    state: latest


================================================
FILE: roles/licecap/tasks/main.yml
================================================
---
- name: Download LICEcap
  get_url:
    url: http://www.cockos.com/licecap/{{ licecap_dmg }}
    dest: "{{ downloads_directory }}/{{ licecap_dmg }}"

- name: Convert LICEcap image to a format that does not require an EULA
  command: >
    chdir={{ downloads_directory }}
    hdiutil convert -quiet {{ licecap_dmg }} -format UDTO -o licecap123
    creates={{ licecap_cdr }}

- name: Mount LICEcap image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse -quiet {{ licecap_cdr }}
    creates=/Volumes/{{ licecap_volume }}

- name: Copy {{ licecap_app }}lication directory to the applications directory
  command: >
    cp -R /Volumes/{{ licecap_volume }}/{{ licecap_app }} /Applications
    creates=/Applications/{{ licecap_app }}

- name: Unmount LICEcap image
  command: hdiutil detach /Volumes/{{ licecap_volume }}


================================================
FILE: roles/licecap/vars/main.yml
================================================
---
licecap_name: licecap123
licecap_dmg: "{{ licecap_name }}.dmg"
licecap_cdr: "{{ licecap_name }}.cdr"
licecap_volume: LICECAP_INSTALL
licecap_app: LICEcap.app


================================================
FILE: roles/llvm/tasks/main.yml
================================================
---
- name: Install LLVM
  homebrew:
    name: llvm
    state: latest


================================================
FILE: roles/local-ssl-proxy/tasks/main.yml
================================================
---
- name: Install local-ssl-proxy
  npm:
    name: local-ssl-proxy
    state: latest
    global: yes
  become: yes


================================================
FILE: roles/lua/tasks/main.yml
================================================
---
- name: Install Lua
  homebrew:
    name: lua
    state: latest


================================================
FILE: roles/luajit/tasks/main.yml
================================================
---
- name: Install LuaJIT
  homebrew:
    name: luajit
    state: latest


================================================
FILE: roles/mac-ports/tasks/main.yml
================================================
---
- name: Download MacPorts
  get_url:
    url: https://github.com/macports/macports-base/releases/download/v{{ macports_version }}/{{ macports_pkg }}
    dest: "{{ downloads_directory }}/{{ macports_pkg }}"

- name: Show current MacPorts version
  command: port version
  register: port_version_output
  ignore_errors: yes

- name: Install MacPorts
  command: installer -package {{ downloads_directory }}/{{ macports_pkg }} -target /
  become: yes
  when: port_version_output.stdout.find(macports_version) == -1
  # NOTE: ignore errors because this is currently hard-coded to only work on
  # macOS 12 Monterey.
  ignore_errors: yes


================================================
FILE: roles/mac-ports/vars/main.yml
================================================
---
macports_pkg: MacPorts-{{ macports_version }}-{{ macports_mac_release }}.pkg


================================================
FILE: roles/maccy/tasks/main.yml
================================================
---
- name: Install Maccy
  homebrew_cask:
    name: maccy
    state: latest


================================================
FILE: roles/mactex/tasks/main.yml
================================================
---
- name: Install MacTeX
  homebrew_cask:
    name: mactex-no-gui
    state: latest


================================================
FILE: roles/macvim/tasks/main.yml
================================================
---
- name: Download MacVim
  get_url:
    url: "https://github.com/macvim-dev/macvim/releases/download/{{ macvim_version }}/MacVim.dmg"
    dest: "{{ downloads_directory }}/MacVim-{{ macvim_version }}.dmg"

- name: Get current MacVim version
  shell: defaults read /Applications/MacVim.app/Contents/Info.plist CFBundleVersion
  register: macvim_version_output
  ignore_errors: yes

- name: Mount MacVim image
  command:
    chdir: "{{ downloads_directory }}"
    cmd: "hdiutil attach -nobrowse MacVim-{{ macvim_version }}.dmg"
    creates: /Volumes/MacVim
  when: macvim_version.find(macvim_version_output.stdout) == -1

- name: Install MacVim
  command: >
    cp -R /Volumes/MacVim/MacVim.app /Applications
  become: yes
  when: macvim_version.find(macvim_version_output.stdout) == -1

- name: Unmount MacVim image
  command: hdiutil detach /Volumes/MacVim
  when: macvim_version.find(macvim_version_output.stdout) == -1


================================================
FILE: roles/make/tasks/main.yml
================================================
---
- name: Install make
  community.general.homebrew:
    name: make
    # name: "make@{{ make_version }}"


================================================
FILE: roles/markdown/tasks/main.yml
================================================
---
- name: Install markdown
  homebrew:
    name: markdown
    state: latest


================================================
FILE: roles/maven/tasks/main.yml
================================================
---
- name: Install maven
  homebrew:
    name: maven
    state: latest


================================================
FILE: roles/mpc/tasks/main.yml
================================================
---
- name: Install mpc
  homebrew:
    name: mpc
    state: latest


================================================
FILE: roles/mpd/tasks/main.yml
================================================
---
- name: Install mpd
  homebrew:
    name: mpd
    state: latest

# FIXME: this seems to fail if the service is already started.
- name: Create mpd service and start mpd
  command: brew services restart mpd
  ignore_errors: yes


================================================
FILE: roles/mpdscribble/tasks/main.yml
================================================
---
- name: Install mpdscribble
  homebrew:
    name: mpdscribble
    state: latest

- name: Create mpdscribble service and start mpdscribble
  command: brew services restart mpdscribble
  ignore_errors: yes


================================================
FILE: roles/mpg123/tasks/main.yml
================================================
---
- name: Install mpg123
  homebrew:
    name: mpg123
    state: latest


================================================
FILE: roles/mplayer/tasks/main.yml
================================================
---
- name: Install mplayer
  homebrew:
    name: mplayer
    state: latest


================================================
FILE: roles/mutagen/tasks/main.yml
================================================
---
- name: Install Mutagen
  homebrew:
    name: mutagen-io/mutagen/mutagen
    state: latest


================================================
FILE: roles/neovim/tasks/main.yml
================================================
---
- name: Download Neovim
  get_url:
    url="https://github.com/neovim/neovim/releases/download/v{{ neovim_version }}/nvim-macos.tar.gz"
    dest="{{ downloads_directory }}/nvim-macos.tar.gz"

- name: Extract Neovim
  command: >
    tar -xvf {{ downloads_directory }}/nvim-macos.tar.gz
        -C {{ downloads_directory }}
    creates={{ downloads_directory }}/nvim-osx64

- name: Install nvim binary
  command: >
    cp -R {{ downloads_directory }}/nvim-osx64 /opt/nvim-{{ neovim_version }}
  become: yes


================================================
FILE: roles/ngrep/tasks/main.yml
================================================
---
- name: Install ngrep
  homebrew:
    name: ngrep
    state: latest


================================================
FILE: roles/node/tasks/main.yml
================================================
---
- name: Download Node.js
  get_url:
    url: https://nodejs.org/dist/v{{ node_version }}/{{ node_pkg }}
    dest: "{{ downloads_directory }}/{{ node_pkg }}"

- name: Install Node.js
  command: >
    chdir={{ downloads_directory }}
    installer -package {{ node_pkg }} -target /
  become: yes

- name: Make sure npm installation prefix for global packages is sane
  command: npm config set prefix /usr/local


================================================
FILE: roles/node/vars/main.yml
================================================
---
node_pkg: node-v{{ node_version }}.pkg


================================================
FILE: roles/node-cljfmt/tasks/main.yml
================================================
---
- name: Install node-cljfmt
  npm:
    name: node-cljfmt
    state: latest
    global: yes
  become: yes


================================================
FILE: roles/octave/tasks/main.yml
================================================
---
- name: Install Octave
  homebrew:
    name: octave
    state: latest


================================================
FILE: roles/openssl/tasks/main.yml
================================================
---
- name: Install openssl
  homebrew:
    name: openssl
    state: latest


================================================
FILE: roles/openzfs/tasks/main.yml
================================================
---
- name: Install OpenZFS
  homebrew_cask:
    name: openzfs
    state: latest


================================================
FILE: roles/orbstack/tasks/main.yml
================================================
---
- name: Install OrbStack
  homebrew_cask:
    name: orbstack
    state: latest

# TODO: open it if it was just installed for the first time?


================================================
FILE: roles/p7zip/tasks/main.yml
================================================
---
- name: Install p7zip
  homebrew:
    name: p7zip
    state: latest


================================================
FILE: roles/pandoc/tasks/main.yml
================================================
---
- name: Install Pandoc
  homebrew:
    name: pandoc
    state: latest


================================================
FILE: roles/parallel/tasks/main.yml
================================================
---
- name: Install parallel
  homebrew:
    name: parallel
    state: latest


================================================
FILE: roles/passwordless-sudo/tasks/main.yml
================================================
---
- lineinfile:
    path: "/etc/sudoers.d/{{ user }}"
    line: "{{ user }} ALL=(ALL) NOPASSWD: ALL"
    create: yes
    owner: root
    mode: 0644
    validate: 'visudo -cf %s'
  become: yes


================================================
FILE: roles/pcsv/tasks/main.yml
================================================
---
- name: Install pcsv
  pip:
    name: pcsv
    extra_args: --user


================================================
FILE: roles/pdf-expert/tasks/main.yml
================================================
---
- name: Install PDF Expert
  homebrew_cask:
    name: pdf-expert
    state: latest

# TODO: open it if it was just installed for the first time?


================================================
FILE: roles/persephone/tasks/main.yml
================================================
---
# TODO: Remove "creates" and only run this task when either
# "/Applications/Persephone.app" doesn't exist or "persephone_version" is
# greater than the current.
- name: Install Persephone
  unarchive:
    src: "https://github.com/danbee/persephone/releases/download/{{ persephone_version }}/Persephone-{{ persephone_version }}.zip"
    remote_src: yes
    dest: "/Applications"
    creates: "/Applications/Persephone.app"
  become: yes


================================================
FILE: roles/pgsanity/tasks/main.yml
================================================
---
- name: Install PgSanity
  pip:
    name: pgsanity
    extra_args: --user


================================================
FILE: roles/pngpaste/tasks/main.yml
================================================
---
- name: Install pngpaste
  homebrew:
    name: pngpaste
    state: latest


================================================
FILE: roles/prettier/tasks/main.yml
================================================
---
- name: Install prettier
  npm:
    name: prettier
    state: latest
    global: yes
  become: yes


================================================
FILE: roles/prey/tasks/main.yml
================================================
---
# NOTE: get_url fails to download because of a bug with SSL handling. Using
# command + wget instead. https://github.com/ansible/ansible/issues/23642
- name: Download Prey
  command: >
    chdir={{ downloads_directory }}
    wget -nc -q https://downloads.preyproject.com/prey-client-releases/node-client/{{ prey_version }}/{{ prey_pkg }}

- name: Load API key
  include_vars:
    file: "{{ prey_api_key_yaml_file }}"
    name: api_key
  no_log: yes

- name: Check if Prey is set up
  shell: >
    /usr/local/lib/prey/current/bin/prey config gui
  register: prey_config_gui
  ignore_errors: yes
  become: yes

# TODO: make the "when" condition be if prey_version is different than the
# actual version.
- name: Install Prey
  shell: >
    API_KEY={{ api_key.prey_api_key }} installer -package {{ downloads_directory }}/{{ prey_pkg }} -target /
  become: yes
  when: prey_config_gui.rc != 0


================================================
FILE: roles/prey/vars/main.yml
================================================
---
prey_pkg: prey-mac-{{ prey_version }}-x64.pkg


================================================
FILE: roles/pulp/tasks/main.yml
================================================
---
- name: Install pulp
  npm:
    name: pulp
    state: latest
    global: yes
  become: yes


================================================
FILE: roles/purescript/tasks/main.yml
================================================
---
- name: Install PureScript
  command: stack install purescript


================================================
FILE: roles/pyre-check/tasks/main.yml
================================================
---
- name: Install Pyre-Check
  pip:
    name: pyre-check
    extra_args: --user


================================================
FILE: roles/python3/tasks/main.yml
================================================
---
- name: Download Python 3
  get_url:
    url: https://www.python.org/ftp/python/{{ python3_version }}/{{ python3_pkg }}
    dest: "{{ downloads_directory }}/{{ python3_pkg }}"

- name: Show current Python 3 version
  command: python3 --version
  register: python3_version_output
  ignore_errors: yes

- name: Install Python 3
  command: >
    installer -package {{ downloads_directory }}/{{ python3_pkg }} -target /
  become: yes
  when: python3_version_output.stdout.find(python3_version) == -1

- name: Install Python 3 SSL certificates
  command: >
    "/Applications/Python {{ python3_version_major_minor }}/Install Certificates.command"
  when: python3_version_output.stdout.find(python3_version) == -1


================================================
FILE: roles/python3/vars/main.yml
================================================
---
python3_pkg: python-{{ python3_version }}-macos{{ python3_macos_version }}.pkg


================================================
FILE: roles/qt5/files/qt-noninteractive.qs
================================================
function Controller() {
  installer.autoRejectMessageBoxes();
  installer.installationFinished.connect(function () {
    gui.clickButton(buttons.NextButton);
  })
}

Controller.prototype.WelcomePageCallback = function () {
  gui.clickButton(buttons.NextButton, 3000);
}

Controller.prototype.CredentialsPageCallback = function () {
  gui.clickButton(buttons.NextButton);
}

Controller.prototype.IntroductionPageCallback = function () {
  gui.clickButton(buttons.NextButton);
}

Controller.prototype.TargetDirectoryPageCallback = function ()
{
  gui.currentPageWidget().TargetDirectoryLineEdit.setText("/Applications/Qt5.9.0");
  gui.clickButton(buttons.NextButton);
}

Controller.prototype.ComponentSelectionPageCallback = function () {
  var widget = gui.currentPageWidget();

  widget.deselectAll();

  widget.selectComponent("qt.qt5.5120.clang_64")
  // widget.selectComponent("qt.qt5.5120.doc")
  widget.selectComponent("qt.qt5.5120.examples")
  widget.selectComponent("qt.qt5.5120.qtcharts")
  widget.selectComponent("qt.qt5.5120.qtcharts.gcc_64")
  widget.selectComponent("qt.qt5.5120.qtdatavis3d")
  widget.selectComponent("qt.qt5.5120.qtdatavis3d.gcc_64")
  widget.selectComponent("qt.qt5.5120.qtnetworkauth")
  widget.selectComponent("qt.qt5.5120.qtnetworkauth.gcc_64")
  widget.selectComponent("qt.qt5.5120.qtpurchasing")
  widget.selectComponent("qt.qt5.5120.qtpurchasing.gcc_64")
  widget.selectComponent("qt.qt5.5120.qtremoteobjects")
  widget.selectComponent("qt.qt5.5120.qtremoteobjects.gcc_64")
  widget.selectComponent("qt.qt5.5120.qtscript")
  widget.selectComponent("qt.qt5.5120.qtspeech")
  widget.selectComponent("qt.qt5.5120.qtspeech.gcc_64")
  widget.selectComponent("qt.qt5.5120.qtvirtualkeyboard")
  widget.selectComponent("qt.qt5.5120.qtvirtualkeyboard.gcc_64")
  widget.selectComponent("qt.qt5.5120.qtwebengine")
  widget.selectComponent("qt.qt5.5120.qtwebengine.gcc_64")
  // widget.selectComponent("qt.qt5.5120.src")
  widget.selectComponent("qt.qt5.tools.qtcreator")

  gui.clickButton(buttons.NextButton);
}

Controller.prototype.LicenseAgreementPageCallback = function () {
  gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
  gui.clickButton(buttons.NextButton);
}

Controller.prototype.StartMenuDirectoryPageCallback = function () {
  gui.clickButton(buttons.NextButton);
}

Controller.prototype.ReadyForInstallationPageCallback = function () {
  gui.clickButton(buttons.NextButton);
}

Controller.prototype.FinishedPageCallback = function () {
  var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm
  if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) {
    checkBoxForm.launchQtCreatorCheckBox.checked = false;
  }
  gui.clickButton(buttons.FinishButton);
}


================================================
FILE: roles/qt5/tasks/main.yml
================================================
---
- name: Download {{ qt_image_url }}
  get_url: >
    url="{{ qt_image_url }}"
    dest="{{ qt_image_path }}"
    checksum="md5:3d940877ea3dd22c095463bcdf6aa966"

# 5.12.0:
# checksum="md5:6fe192b2b63bd0f3203266b677510a22"

- name: Get {{ qt_app_directory }} stats
  stat:
    path: "{{ qt_app_directory }}"
  register: qt_app_directory_stat

- name: Mount {{ qt_image_path }}
  command: >
    hdiutil attach -nobrowse -noverify {{ qt_image_path }}
    creates="{{ qt_volume_path }}"
  when: not qt_app_directory_stat.stat.exists

- name: Get {{ qt_volume_path }} stats
  stat:
    path: "{{ qt_volume_path }}"
  register: qt_volume_path_stat

- name: Create {{ qt_app_directory }}
  command: >
    cp -R "{{ qt_volume_path }}/{{ qt_app_name }}" /Applications
    creates="{{ qt_app_directory }}"
  become: yes

- name: Unmount Qt5 image
  command: hdiutil detach "{{ qt_volume_path }}"
  when: qt_volume_path_stat.stat.exists

- name: Install Qt5
  command: >
    {{ qt_app_directory }}/Contents/MacOS/{{ qt_installer_name }} --script roles/qt/files/qt-noninteractive.qs --platform minimal
    creates="/Applications/Qt{{ qt_version }}"
  become: yes


================================================
FILE: roles/qt5/vars/main.yml
================================================
---
qt_image_name: "qt-opensource-mac-x64-{{ qt_version }}.dmg"
qt_image_url: "http://download.qt.io/official_releases/qt/{{qt_major_minor_version}}/{{qt_version}}/{{ qt_image_name }}"
qt_image_path: "{{ downloads_directory }}/{{ qt_image_name }}"
qt_installer_name: "qt-opensource-mac-x64-{{ qt_version }}"
qt_volume_path: "/Volumes/{{ qt_installer_name }}"
qt_app_name: "{{ qt_installer_name }}.app"
qt_app_directory: "/Applications/{{ qt_app_name }}"


================================================
FILE: roles/r/tasks/main.yml
================================================
---
- name: Download R
  get_url: >
    url="https://cran.r-project.org/bin/macosx/base/R-{{ r_version }}.pkg"
    dest="{{ downloads_directory }}/R-{{ r_version }}.pkg"

- name: Get current R version
  shell: defaults read /Applications/R.app/Contents/Info.plist CFBundleShortVersionString
  register: r_version_output
  ignore_errors: yes

- name: Install R
  command: >
    chdir={{ downloads_directory }}
    installer -package "R-{{ r_version }}.pkg" -target /
  become: yes
  when: r_version_output.stdout.find(r_version) == -1


================================================
FILE: roles/rescuetime/tasks/main.yml
================================================
---
- name: Download RescueTime
  get_url:
    url: "{{ rescuetime_image_url }}"
    dest: "{{ rescuetime_image_path }}"

- name: Get {{ rescuetime_app_directory }} stats
  stat:
    path: "{{ rescuetime_app_directory }}"
  register: rescuetime_app_directory_stat

- name: Mount RescueTime image
  command: >
    hdiutil attach -nobrowse {{ rescuetime_image_path }}
    creates="{{ rescuetime_volume_path }}"
  when: not rescuetime_app_directory_stat.stat.exists

- name: Get {{ rescuetime_volume_path }} stats
  stat:
    path: "{{ rescuetime_volume_path }}"
  register: rescuetime_volume_path_stat

- name: Create {{ rescuetime_app_directory }}
  command: >
    cp -R "{{ rescuetime_volume_path }}/{{ rescuetime_app_name }}" /Applications
    creates="{{ rescuetime_app_directory }}"
  become: yes

- name: Unmount RescueTime image
  command: hdiutil detach "{{ rescuetime_volume_path }}"
  when: rescuetime_volume_path_stat.stat.exists

# This will prompt for an email address and also request Accessibility
# permissions for first installs.
- name: Open RescueTime
  command: open /Applications/RescueTime.app


================================================
FILE: roles/rescuetime/vars/main.yml
================================================
---
rescuetime_image_name: "RescueTimeInstaller.dmg"
rescuetime_image_url: "https://www.rescuetime.com/installers/{{ rescuetime_image_name }}"
rescuetime_image_path: "{{ downloads_directory }}/{{ rescuetime_image_name }}"
rescuetime_volume_path: "/Volumes/RescueTime"
rescuetime_app_name: "RescueTime.app"
rescuetime_app_directory: "/Applications/{{ rescuetime_app_name }}"


================================================
FILE: roles/rider/tasks/main.yml
================================================
---
- name: Install Rider
  homebrew_cask:
    name: rider
    state: latest


================================================
FILE: roles/ripgrep/tasks/main.yml
================================================
---
- name: Install ripgrep
  homebrew:
    name: ripgrep
    state: latest


================================================
FILE: roles/ruby/meta/main.yml
================================================
---
dependencies:
  - cmake
  - llvm
  - openssl


================================================
FILE: roles/ruby/tasks/main.yml
================================================
---
- name: Install ruby-build
  homebrew:
    name: ruby-build
    state: latest

- name: List installed Rubies
  command: ruby-build --list
  register: ruby_build_list_output
  ignore_errors: yes

- name: Install Ruby
  shell: >
    RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl)" \
      ruby-build "{{ ruby_version }}" /usr/local
  when: ruby_build_list_output.stdout.find(ruby_version) == -1


================================================
FILE: roles/rust/tasks/main.yml
================================================
---
- name: Install rustup-init
  homebrew:
    name: rustup
    state: latest

- name: Install rustup
  command: rustup-init -y --no-modify-path


================================================
FILE: roles/rust/vars/main.yml
================================================
---
rust_pkg: "rust-{{ rust_version }}i686-apple-darwin.pkg"
rust_pkg_url: "https://static.rust-lang.org/dist/{{ rust_pkg }}"


================================================
FILE: roles/rust-analyzer/tasks/main.yml
================================================
---
- name: Fetch Rust source code
  command: rustup component add rust-src rust-docs

- name: Install rust-analyzer
  homebrew:
    name: rust-analyzer
    state: latest


================================================
FILE: roles/s3cmd/tasks/main.yml
================================================
---
- name: Install s3cmd
  homebrew:
    name: s3cmd
    state: latest

- name: Install ~/.s3cfg
  copy:
    src: "{{ s3cmd_cfg_file }}"
    dest: "{{ home_directory }}/.s3cfg"
    mode: 0644


================================================
FILE: roles/scc/tasks/main.yml
================================================
---
- name: Install scc
  homebrew:
    name: scc
    state: latest


================================================
FILE: roles/shellcheck/tasks/main.yml
================================================
---
- name: Install shellcheck
  homebrew:
    name: shellcheck
    state: latest


================================================
FILE: roles/shfmt/tasks/main.yml
================================================
---
- name: Install shfmt
  homebrew:
    name: shfmt
    state: latest


================================================
FILE: roles/shpotify/tasks/main.yml
================================================
---
- name: Install shpotify
  homebrew:
    name: shpotify
    state: latest


================================================
FILE: roles/skype/tasks/main.yml
================================================
---
- name: Download Skype
  get_url:
    url: http://www.skype.com/go/getskype-macosx.dmg
    dest: "{{ downloads_directory }}/getskype-macosx.dmg"

- name: Mount Skype image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse getskype-macosx.dmg
    creates=/Volumes/Skype

- name: Copy Skype.app to Applications directory
  command: >
    cp -R /Volumes/Skype/Skype.app /Applications
    creates=/Applications/Skype.app
  become: yes

- name: Unmount Skype image
  command: hdiutil detach /Volumes/Skype


================================================
FILE: roles/slack/tasks/main.yml
================================================
---
- name: Install Slack
  homebrew_cask:
    name: slack
    state: latest


================================================
FILE: roles/spotify/tasks/main.yml
================================================
---
- name: Get {{ spotify_installer_path }} stats
  stat:
    path: "{{ spotify_installer_path }}"
  register: spotify_installer_path_stat

- name: Download Spotify installer
  unarchive:
    src: "{{ spotify_installer_archive_url }}"
    dest: "{{ downloads_directory }}"
    remote_src: yes
  when: not spotify_installer_path_stat.stat.exists

- name: Get {{ spotify_app_directory }} stats
  stat:
    path: "{{ spotify_app_directory }}"
  register: spotify_app_directory_stat

- name: Create /Applications/{{ spotify_installer_name }}
  command: >
    cp -R "{{ downloads_directory }}/{{ spotify_installer_name }}" /Applications
    creates="/Applications/{{ spotify_installer_name }}"
  become: yes

- name: Run Spotify installer
  command: >
    open -a "Install Spotify.app"
    creates="{{ spotify_app_directory }}"
  become: yes
  when: not spotify_app_directory_stat.stat.exists


================================================
FILE: roles/spotify/vars/main.yml
================================================
---
spotify_installer_archive_name: "SpotifyInstaller.zip"
spotify_installer_archive_url: "https://download.scdn.co/{{ spotify_installer_archive_name }}"
spotify_installer_name: "Install Spotify.app"
spotify_installer_path: "{{ downloads_directory }}/{{ spotify_installer_name }}"
spotify_app_name: "Spotify.app"
spotify_app_directory: "/Applications/{{ spotify_app_name }}"


================================================
FILE: roles/ssh-keys/files/mpereira@argonaut.pub
================================================
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC9F1D1p7cEyChzhHO5agdMkCKUsAoi3m02LeP0vqrhMzIMsCd4mAlrxUHUmxLI3HnXaidxgpg+R33snSYJrCJG8x3GjKZ1GzTECpW2szIlL/F1wmrx6tvCn+/FCiVFDBbHvr9Xw6sP3jb18WnnGB15OTSfeND/KIulLruc+/1xoThzIXnE4iSYeIws0yxp4sIdb1M7hUvpbOci3jPjwpNwXmH60bWl1vGKhDkVE17k0NXlRPSNlp2FQgTZSqB6IeeaCYdhQLKVqzN71roMcQx8cWZCmxXYBMLxUsPicOElXAe9qX4oVGz8PJnfDKI2yodT+bUwdwEeltWm9jFasZ9fO4xj2YXsONBbt2WoOa3cGefh3JMzeaJ/pXCPk2atMTo0el8tmpDIuy5WS5iDzA3po9W8hG9gFgLpyRwwiiB7RnvDqOsKHFIRewPf9A2PXREaxkSx2DkACtPRMI/4APNhAZ20r2AH4S9/q/iUuEJkN+9GEbaaQvbZQlYskYC/R7i/OAa2HCjaejCmPLqyYFN2a9eTTZMDsTnYfiPKpavi4hQDTJtvrBPLK0zG7ZHnLoWb4+WBi0NMdW7D2tNEc4FOwNDcB9YWYAu9iQDgqSyWbAO+f6LW62131UNqFgkLuNy71s7oWvd57CYx+K/1y/XOt3RqAmE0yRoQ+r55bObQvw== mpereira@argonaut


================================================
FILE: roles/ssh-keys/files/mpereira@pluto.pub
================================================
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC8KkiSw9ADfnyTFgduupwp61FG0GHkuzaio1K3m0tx+tqlea3Xi71hHjKnH1yFx2uryYhnm54MVBR7mv4/jkLRXIdiEkESbvckuD7uYxwi+LI0a0GPUOkNyEBB3QgEeqHxP4iFoGfWtNTUtPeK5Q+QNmEuJgv0iUCuUKfQYi2wUJuEcDh1veRgNr1nAN2jkR/w4v8akXTARGDiUEYT6rugQte19P+MZKCwJNQsB7bP+UnEfQ30R8MXjP8jPzc/PNfiVez5PsONmivx4019BRKcAvEmLNEBYyMGqaRtKoDf4JJ09JT4Du+JxJY49ECaWbR6RcNlcqxBdFOcgcbsc3Rg8+7TlFrxG5FwdPazaMjt2LpG1xTSS9PYAFA0+uuslgea4hGWBycKpfRDN7S2/MJXowIf6ywOW5Cy5qeAGjIlw9d1vtUNhIqtLQtb/kpnrpmFq8J2LXEAfBcwohMQ562wcE+naiAI7vFmbXd3129YxwUob5s8x4XjiMW/GutdYFCd2cjZMCos4Xmo+FixtMyK1Hx1qCy5FtOLNFErBT4fXkXGiP8GgEtbj82NBPwjGgbjU+ofKGCmvCJRGvvcZuDAkWVwWUIE7CM8TGf9mTqrPZjBzzGH+CBhw22sxfzj7MKIcIoEthHmIxZt/H6hYqSZyi9Rgt3Xx3vlXVMNZU6Nrw== mpereira@pluto


================================================
FILE: roles/ssh-keys/tasks/main.yml
================================================
---
- name: Ensure .ssh directory exists.
  file:
    dest: "{{ ssh_directory }}"
    mode: 0700
    owner: "{{ user }}"
    state: directory

- name: Install private SSH key
  copy:
    src: "{{ mpereira_at_pluto_ssh_private_key }}"
    dest: "{{ ssh_directory }}/mpereira@pluto"
    mode: 0600
    owner: "{{ user }}"

- name: Install public SSH keys
  copy:
    src: "{{ item }}"
    dest: "{{ ssh_directory }}/{{ item }}"
    mode: 0644
    owner: "{{ user }}"
  loop:
    - "mpereira@argonaut.pub"
    - "mpereira@pluto.pub"

- name: Add authorized keys
  ansible.posix.authorized_key:
    user: "{{ user }}"
    state: present
    key: "{{ lookup('file', item) }}"
  loop:
    - "mpereira@argonaut.pub"
    - "mpereira@pluto.pub"


================================================
FILE: roles/ssh-keys/vars/main.yml
================================================
---
ssh_directory: "{{ home_directory }}/.ssh"


================================================
FILE: roles/steam/tasks/main.yml
================================================
---
- name: Download Steam
  get_url:
    url: http://media.steampowered.com/client/installer/steam.dmg
    dest: "{{ downloads_directory }}/steam.dmg"

- name: Convert Steam image to a format that does not require an EULA
  command: >
    chdir={{ downloads_directory }}
    hdiutil convert -quiet steam.dmg -format UDTO -o steam
    creates=steam.cdr

- name: Mount Steam image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse -quiet steam.cdr
    creates=/Volumes/Steam

- name: Copy Steam application directory to the applications directory
  command: >
    cp -R /Volumes/Steam/Steam.app /Applications
    creates=/Applications/Steam.app

- name: Unmount Steam image
  command: hdiutil detach /Volumes/Steam

- name: Start Steam
  command: open -a Steam


================================================
FILE: roles/stripe-cli/tasks/main.yml
================================================
---
- name: Install Stripe CLI
  homebrew:
    name: stripe/stripe-cli/stripe
    state: latest


================================================
FILE: roles/taglib/tasks/main.yml
================================================
---
- name: Install taglib
  homebrew:
    name: taglib
    state: present


================================================
FILE: roles/tealdeer/tasks/main.yml
================================================
---
- name: Install tealdeer
  command: >
    cargo install tealdeer --force

- name: Update tldr cache
  command: >
    tldr --update


================================================
FILE: roles/teensy-loader/tasks/main.yml
================================================
---
- name: Download teensy
  get_url:
    url: https://www.pjrc.com/teensy/teensy.dmg
    dest: "{{ downloads_directory }}/teensy.dmg"

- name: Mount teensy image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse teensy.dmg
    creates=/Volumes/teensy

- name: Copy teensy.app to Applications directory
  command: >
    cp -R /Volumes/teensy/teensy.app /Applications
    creates=/Applications/teensy.app
  become: yes

- name: Unmount teensy image
  command: hdiutil detach /Volumes/teensy


================================================
FILE: roles/terminal-notifier/tasks/main.yml
================================================
---
- name: Install terminal-notifier
  homebrew:
    name: terminal-notifier
    state: latest


================================================
FILE: roles/terraform/tasks/main.yml
================================================
---
- name: Download Terraform archive
  get_url:
    url: "{{ terraform_zip_url }}"
    dest: "{{ downloads_directory }}/{{ terraform_zip }}"
    checksum: "{{ terraform_checksum }}"

- name: Extract Terraform archive
  command: >
    chdir={{ downloads_directory }}
    unzip -ou {{ terraform_zip }} -d {{ downloads_directory }}

- name: Install Terraform
  command: cp "{{ downloads_directory }}/{{ terraform_binary_name }}" /usr/local/bin


================================================
FILE: roles/terraform/vars/main.yml
================================================
terraform_binary_name: "terraform"
terraform_binary_arch: "arm64"
terraform_zip: "terraform_{{ terraform_version }}_darwin_{{ terraform_binary_arch }}.zip"
terraform_zip_url: "https://releases.hashicorp.com/terraform/{{ terraform_version }}/{{ terraform_zip }}"


================================================
FILE: roles/tmux/tasks/main.yml
================================================
---
- name: Install tmux
  homebrew:
    name: tmux
    state: latest

- name: Install tmux-switch-session
  get_url:
    url: https://raw.githubusercontent.com/mislav/dotfiles/master/bin/tmux-switch-session
    dest: /usr/local/bin/tmux-switch-session
    mode: 0755


================================================
FILE: roles/tmuxinator/tasks/main.yml
================================================
---
- name: Install tmuxinator gem
  gem:
    name: tmuxinator
    state: latest


================================================
FILE: roles/toggle-dark-mode/files/ToggleDarkMode.app/Contents/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>AMIsApplet</key>
	<true/>
	<key>AMStayOpen</key>
	<false/>
	<key>BuildMachineOSBuild</key>
	<string>18A391024</string>
	<key>CFBundleAllowMixedLocalizations</key>
	<true/>
	<key>CFBundleDevelopmentRegion</key>
	<string>English</string>
	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeExtensions</key>
			<array>
				<string>*</string>
			</array>
			<key>CFBundleTypeName</key>
			<string>Automator workflow file</string>
			<key>CFBundleTypeOSTypes</key>
			<array>
				<string>****</string>
			</array>
			<key>CFBundleTypeRole</key>
			<string>Viewer</string>
		</dict>
	</array>
	<key>CFBundleExecutable</key>
	<string>Application Stub</string>
	<key>CFBundleIconFile</key>
	<string>AutomatorApplet</string>
	<key>CFBundleIdentifier</key>
	<string>com.apple.automator.ToggleDarkMode</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>ToggleDarkMode</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.3</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleSupportedPlatforms</key>
	<array>
		<string>MacOSX</string>
	</array>
	<key>CFBundleURLTypes</key>
	<array/>
	<key>CFBundleVersion</key>
	<string>492</string>
	<key>DTCompiler</key>
	<string>com.apple.compilers.llvm.clang.1_0</string>
	<key>DTPlatformBuild</key>
	<string>11O62d</string>
	<key>DTPlatformName</key>
	<string>macosx</string>
	<key>DTPlatformVersion</key>
	<string>10.15.4</string>
	<key>DTSDKBuild</key>
	<string>19F71</string>
	<key>DTSDKName</key>
	<string>macosx10.15internal</string>
	<key>DTXcode</key>
	<string>1140</string>
	<key>DTXcodeBuild</key>
	<string>11O62d</string>
	<key>LSMinimumSystemVersion</key>
	<string>10.8</string>
	<key>LSUIElement</key>
	<true/>
	<key>NSAppleEventsUsageDescription</key>
	<string>This workflow needs to control other applications to run.</string>
	<key>NSAppleMusicUsageDescription</key>
	<string>This workflow needs access to your music to run.</string>
	<key>NSAppleScriptEnabled</key>
	<string>YES</string>
	<key>NSCalendarsUsageDescription</key>
	<string>This workflow needs access to your calendars to run.</string>
	<key>NSCameraUsageDescription</key>
	<string>This workflow needs access to your camera to run.</string>
	<key>NSContactsUsageDescription</key>
	<string>This workflow needs access to your contacts to run.</string>
	<key>NSHomeKitUsageDescription</key>
	<string>This workflow needs access to your HomeKit Home to run.</string>
	<key>NSMicrophoneUsageDescription</key>
	<string>This workflow needs access to your microphone to run.</string>
	<key>NSPhotoLibraryUsageDescription</key>
	<string>This workflow needs access to your photos to run.</string>
	<key>NSPrincipalClass</key>
	<string>NSApplication</string>
	<key>NSRemindersUsageDescription</key>
	<string>This workflow needs access to your reminders to run.</string>
	<key>NSServices</key>
	<array/>
	<key>NSSiriUsageDescription</key>
	<string>This workflow needs access to Siri to run.</string>
	<key>NSSystemAdministrationUsageDescription</key>
	<string>This workflow needs access to administer this system in order to run.</string>
	<key>UTExportedTypeDeclarations</key>
	<array/>
	<key>UTImportedTypeDeclarations</key>
	<array/>
</dict>
</plist>


================================================
FILE: roles/toggle-dark-mode/files/ToggleDarkMode.app/Contents/document.wflow
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>AMApplicationBuild</key>
	<string>492</string>
	<key>AMApplicationVersion</key>
	<string>2.10</string>
	<key>AMDocumentVersion</key>
	<string>2</string>
	<key>actions</key>
	<array>
		<dict>
			<key>action</key>
			<dict>
				<key>AMAccepts</key>
				<dict>
					<key>Container</key>
					<string>List</string>
					<key>Optional</key>
					<true/>
					<key>Types</key>
					<array/>
				</dict>
				<key>AMActionVersion</key>
				<string>1.0</string>
				<key>AMApplication</key>
				<array>
					<string>System Preferences</string>
				</array>
				<key>AMParameterProperties</key>
				<dict>
					<key>appearanceChangeMode</key>
					<dict/>
				</dict>
				<key>AMProvides</key>
				<dict>
					<key>Container</key>
					<string>List</string>
					<key>Types</key>
					<array/>
				</dict>
				<key>ActionBundlePath</key>
				<string>/System/Library/Automator/Change System Appearance.action</string>
				<key>ActionName</key>
				<string>Change System Appearance</string>
				<key>ActionParameters</key>
				<dict>
					<key>appearanceChangeMode</key>
					<integer>3</integer>
				</dict>
				<key>BundleIdentifier</key>
				<string>com.apple.Automator.ChangeSystemAppearance</string>
				<key>CFBundleVersion</key>
				<string>1.0</string>
				<key>CanShowSelectedItemsWhenRun</key>
				<true/>
				<key>CanShowWhenRun</key>
				<true/>
				<key>Category</key>
				<array>
					<string>AMCategoryUtilities</string>
				</array>
				<key>Class Name</key>
				<string>AMChangeSystemAppearanceAction</string>
				<key>InputUUID</key>
				<string>7133AFCE-A111-4257-805C-58396D8F1877</string>
				<key>Keywords</key>
				<array>
					<string>Light</string>
					<string>Dark</string>
					<string>Theme</string>
				</array>
				<key>OutputUUID</key>
				<string>84D5FE61-D72F-4760-AB2B-C8BE207BCB9B</string>
				<key>UUID</key>
				<string>7A88FD62-959B-4673-B8DD-92E6B5355B43</string>
				<key>UnlocalizedApplications</key>
				<array>
					<string>System Preferences</string>
				</array>
				<key>arguments</key>
				<dict>
					<key>0</key>
					<dict>
						<key>default value</key>
						<integer>3</integer>
						<key>name</key>
						<string>appearanceChangeMode</string>
						<key>required</key>
						<string>0</string>
						<key>type</key>
						<string>0</string>
						<key>uuid</key>
						<string>0</string>
					</dict>
				</dict>
				<key>conversionLabel</key>
				<integer>0</integer>
				<key>isViewVisible</key>
				<true/>
				<key>location</key>
				<string>309.000000:170.000000</string>
				<key>nibPath</key>
				<string>/System/Library/Automator/Change System Appearance.action/Contents/Resources/Base.lproj/main.nib</string>
			</dict>
			<key>isViewVisible</key>
			<true/>
		</dict>
	</array>
	<key>connectors</key>
	<dict/>
	<key>workflowMetaData</key>
	<dict>
		<key>workflowTypeIdentifier</key>
		<string>com.apple.Automator.application</string>
	</dict>
</dict>
</plist>


================================================
FILE: roles/toggle-dark-mode/tasks/main.yml
================================================
---
- name: Install ToggleDarkMode.app
  command: cp -r roles/toggle-dark-mode/files/ToggleDarkMode.app /Applications
  become: yes


================================================
FILE: roles/tree/tasks/main.yml
================================================
---
- name: Install tree
  homebrew:
    name: tree
    state: latest


================================================
FILE: roles/unity/tasks/main.yml
================================================
---
# https://github.com/DragonBox/u3d/releases
- name: Install u3d gem
  gem:
    name: u3d
    state: latest

- name: Install Unity
  command: >
    u3d install {{ unity_version }} -p Unity,WebGL --trace
  become: yes


================================================
FILE: roles/unity-hub/tasks/main.yml
================================================
---
- name: Download Unity Hub image
  get_url: >
    url=https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup.dmg
    dest={{ downloads_directory }}/UnityHubSetup.dmg

- name: Mount Unity Hub image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse {{ downloads_directory }}/UnityHubSetup.dmg

- name: Get mounted Unity Hub image version
  shell: >
    find "/Volumes" -maxdepth 1 -iname "Unity Hub *" 2>/dev/null | sort -nr | head -1
  register: mounted_unity_hub_dmg_output
  ignore_errors: yes

- name: Install Unity Hub
  command: >
    chdir={{ downloads_directory }}
    cp -R "{{ mounted_unity_hub_dmg_output.stdout }}/Unity Hub.app" /Applications
    creates="/Applications/Unity Hub.app"
  become: yes

- name: Unmount Unity Hub image
  command: hdiutil detach "{{ mounted_unity_hub_dmg_output.stdout }}"


================================================
FILE: roles/unity-hub/vars/main.yml
================================================
---
# I get the URL by looking at the web browser "network" tab in the developer
# tools.
unity_download_assistant_dmg: "UnityDownloadAssistant-{{ unity_download_assistant_version }}.dmg"
unity_download_assistant_dmg_url: "https://netstorage.unity3d.com/unity/8e603399ca02/{{ unity_download_assistant_dmg }}"
unity_download_assistant_volume: "/Volumes/Unity Download Assistant"
unity_download_assistant_app: "Unity Download Assistant.app"


================================================
FILE: roles/usr-local-src-directory/tasks/main.yml
================================================
---
- name: Ensure that the /usr/local/src directory exists
  file:
    path: /usr/local/src
    state: directory
    owner: "{{ user }}"
  become: yes

- name: Ensure that the /usr/local/bin directory exists
  file:
    path: /usr/local/bin
    state: directory
    owner: "{{ user }}"
  become: yes


================================================
FILE: roles/vagrant/tasks/main.yml
================================================
---
- name: Download Vagrant
  # get_url fails to download because of a bug with SSL handling.
  # https://github.com/ansible/ansible/issues/23642
  command: >
    chdir={{ downloads_directory }}
    wget -nc -q https://releases.hashicorp.com/vagrant/{{ vagrant_version }}/vagrant_{{ vagrant_version }}_x86_64.dmg

- name: Check existing Vagrant version
  shell: "vagrant --version 2>&1"
  register: vagrant_version_output
  ignore_errors: yes

- name: Mount Vagrant image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse vagrant_{{ vagrant_version }}_x86_64.dmg
    creates=/Volumes/Vagrant
  when: vagrant_version_output.stdout.find('Vagrant ' ~ vagrant_version) == -1

- name: Install Vagrant
  command: >
    installer -package /Volumes/Vagrant/Vagrant.pkg -target /
  become: yes
  when: vagrant_version_output.stdout.find('Vagrant ' ~ vagrant_version) == -1

- name: Unmount Vagrant image
  command: hdiutil detach /Volumes/Vagrant
  when: vagrant_version_output.stdout.find('Vagrant ' ~ vagrant_version) == -1


================================================
FILE: roles/vagrant-vbguest/tasks/main.yml
================================================
- name: Install the vagrant-vbguest Vagrant plugin
  command: >
    vagrant plugin install vagrant-vbguest --plugin-version {{ vagrant_vbguest_version }}


================================================
FILE: roles/vault/tasks/main.yml
================================================
---
- name: Install vault
  npm:
    name: vault
    version: "{{ vault_version }}"
    global: yes
  become: yes


================================================
FILE: roles/vercel/tasks/main.yml
================================================
---
- name: Install vercel
  npm:
    name: vercel
    state: latest
    global: yes
  become: yes


================================================
FILE: roles/vim/meta/main.yml
================================================
---
dependencies:
  - openssl
  - llvm


================================================
FILE: roles/vim/tasks/main.yml
================================================
---
- name: Download Vim
  command: >
    wget "https://ftp.nluug.nl/pub/vim/unix/vim-{{ vim_version }}.tar.bz2"
         -P {{ downloads_directory }}
    creates={{ downloads_directory }}/vim-{{ vim_version }}.tar.bz2

- name: Extract Vim
  command: >
    tar -xjvf {{ downloads_directory }}/vim-{{ vim_version }}.tar.bz2
        -C {{ downloads_directory }}
    creates={{ downloads_directory }}/vim{{ vim_version | regex_replace('\\.', '') }}

- name: Install Vim dependencies
  homebrew: name={{ item }}
  with_items:
    - libtool
    - automake
    - pkg-config
    - gettext

- name: Configure Vim
  shell: >
    chdir="{{ downloads_directory }}/vim{{ vim_version | regex_replace('\\.', '') }}"
    STRIP=/usr/bin/true ./configure \
      --enable-fail-if-missing \
      --enable-luainterp \
      --enable-perlinterp \
      --enable-python3interp \
      --enable-rubyinterp \
      --enable-cscope \
      --enable-gui=auto \
      --disable-netbeans \
      --enable-multibyte \
      --with-lua-prefix=/usr/local/opt/lua \
      --with-features=huge \
      --with-compiledby='Murilo Pereira <murilo@murilopereira.com>'

- name: Build and install Vim
  shell: >
    chdir="{{ downloads_directory }}/vim{{ vim_version | regex_replace('\\.', '') }}"
    make && STRIP=/bin/true sudo make install


================================================
FILE: roles/virtualbox/tasks/main.yml
================================================
---
- name: Download VirtualBox
  get_url:
    url: "http://download.virtualbox.org/virtualbox/{{ virtualbox_version }}/VirtualBox-{{ virtualbox_version }}-{{ virtualbox_build }}-OSX.dmg"
    dest: "{{ downloads_directory }}/VirtualBox-{{ virtualbox_version }}-{{ virtualbox_build }}-OSX.dmg"

- name: Check existing VirtualBox version
  shell: "VirtualBox --help 2>&1"
  register: virtualbox_version_output
  ignore_errors: yes

- name: Mount VirtualBox image
  command:
    chdir: "{{ downloads_directory }}"
    cmd: "hdiutil attach -nobrowse VirtualBox-{{ virtualbox_version }}-{{ virtualbox_build }}-OSX.dmg"
    creates: /Volumes/VirtualBox
  when: virtualbox_version_output.rc != 0 or virtualbox_version_output.stdout.find(virtualbox_version) == -1

- name: Install VirtualBox
  command: >
    installer -package /Volumes/VirtualBox/VirtualBox.pkg -target /
  become: yes
  when: virtualbox_version_output.rc != 0 or virtualbox_version_output.stdout.find(virtualbox_version) == -1

- name: Unmount VirtualBox image
  command: hdiutil detach /Volumes/VirtualBox
  when: virtualbox_version_output.rc != 0 or virtualbox_version_output.stdout.find(virtualbox_version) == -1


================================================
FILE: roles/vlc/tasks/main.yml
================================================
---
- name: Download VLC
  get_url:
    url: "https://get.videolan.org/vlc/{{ vlc_version }}/macosx/{{ vlc_dmg }}"
    dest: "{{ downloads_directory }}/{{ vlc_dmg }}"

- name: Mount VLC image
  command:
    chdir: "{{ downloads_directory }}"
    cmd: hdiutil attach -nobrowse "{{ vlc_dmg }}"
    creates: "/Volumes/{{ vlc_volume }}"

- name: Copy VLC.app to Applications directory
  shell: >
    rm -rf /Applications/VLC.app && cp -R "/Volumes/{{ vlc_volume }}/VLC.app" /Applications
  become: yes

- name: Unmount VLC image
  command: hdiutil detach "/Volumes/{{ vlc_volume }}"


================================================
FILE: roles/vlc/vars/main.yml
================================================
---
vlc_name: vlc-{{ vlc_version }}-intel64
vlc_dmg: "{{ vlc_name }}.dmg"
vlc_volume: "VLC media player"


================================================
FILE: roles/vscode/tasks/main.yml
================================================
---
- name: Install VSCode
  homebrew_cask:
    name: visual-studio-code
    state: latest


================================================
FILE: roles/vtop/tasks/main.yml
================================================
---
- name: Install vtop
  npm:
    name: vtop
    global: yes
  become: yes


================================================
FILE: roles/websocat/tasks/main.yml
================================================
---
- name: Download websocat binary
  get_url:
    url: "{{ websocat_binary_url }}"
    dest: "{{ downloads_directory }}/{{ websocat_binary_name }}"
    mode: "755"

- name: Install websocat
  command: cp "{{ downloads_directory }}/{{ websocat_binary_name }}" "/usr/local/bin/{{ websocat_binary_install_name }}"


================================================
FILE: roles/websocat/vars/main.yml
================================================
websocat_binary_name: "websocat_mac"
websocat_binary_install_name: "websocat"
websocat_binary_url: "https://github.com/vi/websocat/releases/latest/download/{{ websocat_binary_name }}"


================================================
FILE: roles/whatsapp/tasks/main.yml
================================================
---
- name: Install WhatsApp
  homebrew_cask:
    name: whatsapp
    state: latest


================================================
FILE: roles/wireshark/tasks/main.yml
================================================
---
- name: Install Wireshark
  homebrew_cask:
    name: wireshark
    state: latest


================================================
FILE: roles/wkhtmltopdf/tasks/main.yml
================================================
---
- name: Install wkhtmltopdf
  homebrew_cask:
    name: wkhtmltopdf 
    state: latest


================================================
FILE: roles/wordnet/tasks/main.yml
================================================
---
- name: Install WordNet
  homebrew:
    name: wordnet
    state: latest


================================================
FILE: roles/wrk/tasks/main.yml
================================================
---
- name: Install wrk
  homebrew:
    name: wrk
    state: latest


================================================
FILE: roles/xbar/tasks/main.yml
================================================
---
- name: Download xbar
  get_url:
    url: "https://github.com/matryer/xbar/releases/download/{{ xbar_version }}/{{ xbar_name }}.dmg"
    dest: "{{ downloads_directory }}/{{ xbar_name }}.dmg"

- name: Check existing xbar version
  shell: "defaults read /Applications/xbar.app/Contents/Info.plist CFBundleVersion --version 2>&1"
  register: xbar_version_output
  ignore_errors: yes

- name: Mount xbar image
  command:
    cmd: "hdiutil attach -nobrowse {{ downloads_directory }}/{{ xbar_name }}.dmg"
    creates: "/Volumes/Install xbar"
  when: xbar_version.find(xbar_version_output.stdout) == -1

- name: Install xbar
  command: >
    cp -R "/Volumes/Install xbar/xbar.app" /Applications
  become: yes
  when: xbar_version.find(xbar_version_output.stdout) == -1

- name: Unmount xbar image
  command: hdiutil detach "/Volumes/Install xbar"
  when: xbar_version.find(xbar_version_output.stdout) == -1


================================================
FILE: roles/xbar/vars/main.yml
================================================
---
xbar_name: xbar.{{ xbar_version }}


================================================
FILE: roles/xbar-plugins/tasks/main.yml
================================================
---
- name: Ensure the xbar Application Support directory exists
  file: >
    path="{{ home_directory }}/Library/Application Support/xbar/plugins"
    state=directory

- name: Clone xbar plugins repository
  git:
    repo: "git@github.com:mpereira/bitbar-plugins.git"
    dest: "{{ home_directory }}/git/xbar-plugins"

- name: Install xbar plugins
  file:
    src: "{{ home_directory }}/git/xbar-plugins/{{ item.src }}"
    dest: "{{ home_directory }}/Library/Application Support/xbar/plugins/{{ item.dest }}"
    state: link
  with_items:
    - { src: 'Music/mpd-mpereira.5s.sh', dest: 'mpd-mpereira.5s.sh' }
    - { src: 'Music/spotify-mpereira.5s.sh', dest: 'spotify-mpereira.5s.sh' }


================================================
FILE: roles/xquartz/tasks/main.yml
================================================
---
- name: Download XQuartz
  get_url:
    url: "https://github.com/XQuartz/XQuartz/releases/download/XQuartz-{{ xquartz_version }}/{{ xquartz_dmg }}"
    dest: "{{ downloads_directory }}/{{ xquartz_dmg }}"


- name: Mount XQuartz image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse {{ xquartz_dmg }}
    creates=/Volumes/{{ xquartz_volume }}

- name: Install XQuartz
  command: >
    installer -package /Volumes/{{ xquartz_volume }}/XQuartz.pkg -target /
  become: yes

- name: Unmount XQuartz image
  command: hdiutil detach /Volumes/{{ xquartz_volume }}


================================================
FILE: roles/xquartz/vars/main.yml
================================================
---
xquartz_dmg: XQuartz-{{ xquartz_version }}.dmg
xquartz_volume: XQuartz-{{ xquartz_version }}


================================================
FILE: roles/xz/tasks/main.yml
================================================
---
- name: Install xz
  homebrew:
    name: xz
    state: latest


================================================
FILE: roles/yapf/tasks/main.yml
================================================
---
- name: Install Yapf
  pip:
    name: yapf
    extra_args: --user


================================================
FILE: roles/yarn/tasks/main.yml
================================================
---
- name: Install yarn
  homebrew:
    name: yarn
    state: latest


================================================
FILE: roles/ynab/tasks/main.yml
================================================
---
- name: Download YNAB
  get_url:
    url: http://www.youneedabudget.com/CDNOrigin/download/ynab4/liveCaptive/Mac/{{ ynab_dmg }}
    dest: "{{ downloads_directory }}/{{ ynab_dmg }}"

- name: Mount YNAB image
  command: >
    chdir={{ downloads_directory }}
    hdiutil attach -nobrowse {{ ynab_dmg }}
    creates="/Volumes/YNAB 4"

- name: Copy YNAB application directory to the applications directory
  command: >
    cp -R "/Volumes/YNAB 4/YNAB 4.app" /Applications
    creates="/Applications/YNAB 4.app"

- name: Unmount YNAB image
  command: hdiutil detach /Volumes/YNAB\ 4


================================================
FILE: roles/ynab/vars/main.yml
================================================
---
ynab_dmg: YNAB4_LiveCaptive_{{ ynab_version }}.dmg


================================================
FILE: roles/yq/tasks/main.yml
================================================
---
- name: Download and install yq binary
  get_url:
    url: https://github.com/mikefarah/yq/releases/latest/download/yq_darwin_amd64
    dest: /usr/local/bin/yq
    mode: u+x


================================================
FILE: roles/zoom/tasks/main.yml
================================================
---
- name: Install zoom
  homebrew_cask:
    name: zoom
    state: latest


================================================
FILE: roles/zprint/tasks/main.yml
================================================
---
- name: Download and install zprint binary
  get_url:
    url: https://github.com/kkinnear/zprint/releases/download/{{ zprint_version }}/zprintm-{{ zprint_version }}
    dest: /usr/local/bin/zprint
    mode: u+x


================================================
FILE: roles/zsh/tasks/main.yml
================================================
---
- name: Install zsh
  homebrew:
    name: zsh
    state: latest


================================================
FILE: roles/zwift/tasks/main.yml
================================================
---
- name: Install zwift
  homebrew_cask:
    name: zwift
    state: latest


================================================
FILE: semver.sh
================================================
#!/usr/bin/env bash

semver_parse_into () {
  local RE='[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)'
  # MAJOR
  eval "${2}"="$(echo "${1}" | sed -e "s#$RE#\1#")"
  # MINOR
  eval "${3}"="$(echo "${1}" | sed -e "s#$RE#\2#")"
  # MINOR
  eval "${4}"="$(echo "${1}" | sed -e "s#$RE#\3#")"
  # SPECIAL
  eval "${5}"="$(echo "${1}" | sed -e "s#$RE#\4#")"
}

MAJOR=0
MINOR=0
PATCH=0
SPECIAL=""

semver_parse_into "${1}" MAJOR MINOR PATCH SPECIAL
printf "%s\n%s\n%s\n%s" "${MAJOR}" "${MINOR}" "${PATCH}" "${SPECIAL}"
Download .txt
gitextract_g9a7qngr/

├── .gitignore
├── Makefile
├── README.org
├── ansible.cfg
├── bootstrap.yml
├── configure.sh
├── group_vars/
│   └── all
├── hosts
├── main.yml
├── requirements.yml
├── roles/
│   ├── android-file-transfer/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── ansible-download-directory/
│   │   └── tasks/
│   │       └── main.yml
│   ├── awscli/
│   │   └── tasks/
│   │       └── main.yml
│   ├── babashka/
│   │   └── tasks/
│   │       └── main.yml
│   ├── bash/
│   │   └── tasks/
│   │       └── main.yml
│   ├── beets/
│   │   └── tasks/
│   │       └── main.yml
│   ├── better-touch-tool/
│   │   └── tasks/
│   │       └── main.yml
│   ├── black/
│   │   └── tasks/
│   │       └── main.yml
│   ├── bottle/
│   │   └── tasks/
│   │       └── main.yml
│   ├── build-emacs/
│   │   └── tasks/
│   │       └── main.yml
│   ├── bundler/
│   │   └── tasks/
│   │       └── main.yml
│   ├── caps-lock-remapped-to-control/
│   │   ├── files/
│   │   │   └── remap_caps_lock_to_control.scpt
│   │   └── tasks/
│   │       └── main.yml
│   ├── chromedriver/
│   │   └── tasks/
│   │       └── main.yml
│   ├── clojure/
│   │   └── tasks/
│   │       └── main.yml
│   ├── clojure-lsp/
│   │   └── tasks/
│   │       └── main.yml
│   ├── cmake/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── consolas/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ctags/
│   │   └── tasks/
│   │       └── main.yml
│   ├── cursorcerer/
│   │   └── tasks/
│   │       └── main.yml
│   ├── daisydisk/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dash/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── defaultbrowser/
│   │   └── tasks/
│   │       └── main.yml
│   ├── divvy/
│   │   └── tasks/
│   │       └── main.yml
│   ├── docker/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dotemacs/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dotfiles/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dotnet-sdk/
│   │   └── tasks/
│   │       └── main.yml
│   ├── dropbox/
│   │   └── tasks/
│   │       └── main.yml
│   ├── elgato-control-center/
│   │   └── tasks/
│   │       └── main.yml
│   ├── elgato-dock/
│   │   └── tasks/
│   │       └── main.yml
│   ├── emacs-pre-built/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── fd/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ffmpeg/
│   │   └── tasks/
│   │       └── main.yml
│   ├── firefox/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── firefox-adblock-plus/
│   │   └── tasks/
│   │       └── main.yml
│   ├── fish/
│   │   └── tasks/
│   │       └── main.yml
│   ├── fish-foreign-env/
│   │   └── tasks/
│   │       └── main.yml
│   ├── flux/
│   │   └── tasks/
│   │       └── main.yml
│   ├── font-hack/
│   │   └── tasks/
│   │       └── main.yml
│   ├── fontforge/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gcloud/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gh/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gifsicle/
│   │   └── tasks/
│   │       └── main.yml
│   ├── git/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── git-delta/
│   │   └── tasks/
│   │       └── main.yml
│   ├── glances/
│   │   ├── files/
│   │   │   └── com.mpereira.glances.webserver.plist
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── gnu-command-line-tools/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gnupg/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── gnuplot/
│   │   └── tasks/
│   │       └── main.yml
│   ├── go/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── google-chrome/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── google-chrome-as-default-browser/
│   │   ├── meta/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── google-photos/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── graalvm/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── grammarly/
│   │   └── tasks/
│   │       └── main.yml
│   ├── grip/
│   │   └── tasks/
│   │       └── main.yml
│   ├── gron/
│   │   └── tasks/
│   │       └── main.yml
│   ├── hadoop/
│   │   └── tasks/
│   │       └── main.yml
│   ├── haskell/
│   │   └── tasks/
│   │       └── main.yml
│   ├── homebrew/
│   │   └── tasks/
│   │       └── main.yml
│   ├── htop/
│   │   └── tasks/
│   │       └── main.yml
│   ├── hugo/
│   │   └── tasks/
│   │       └── main.yml
│   ├── imagemagick/
│   │   └── tasks/
│   │       └── main.yml
│   ├── istat-menus/
│   │   └── tasks/
│   │       └── main.yml
│   ├── iterm/
│   │   └── tasks/
│   │       └── main.yml
│   ├── java/
│   │   └── tasks/
│   │       └── main.yml
│   ├── jmeter/
│   │   └── tasks/
│   │       └── main.yml
│   ├── jpeg/
│   │   └── tasks/
│   │       └── main.yml
│   ├── jq/
│   │   └── tasks/
│   │       └── main.yml
│   ├── krew/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ktlint/
│   │   └── tasks/
│   │       └── main.yml
│   ├── kubectl/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── kubectl-tree/
│   │   └── tasks/
│   │       └── main.yml
│   ├── leiningen/
│   │   └── tasks/
│   │       └── main.yml
│   ├── licecap/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── llvm/
│   │   └── tasks/
│   │       └── main.yml
│   ├── local-ssl-proxy/
│   │   └── tasks/
│   │       └── main.yml
│   ├── lua/
│   │   └── tasks/
│   │       └── main.yml
│   ├── luajit/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mac-ports/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── maccy/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mactex/
│   │   └── tasks/
│   │       └── main.yml
│   ├── macvim/
│   │   └── tasks/
│   │       └── main.yml
│   ├── make/
│   │   └── tasks/
│   │       └── main.yml
│   ├── markdown/
│   │   └── tasks/
│   │       └── main.yml
│   ├── maven/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mpc/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mpd/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mpdscribble/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mpg123/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mplayer/
│   │   └── tasks/
│   │       └── main.yml
│   ├── mutagen/
│   │   └── tasks/
│   │       └── main.yml
│   ├── neovim/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ngrep/
│   │   └── tasks/
│   │       └── main.yml
│   ├── node/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── node-cljfmt/
│   │   └── tasks/
│   │       └── main.yml
│   ├── octave/
│   │   └── tasks/
│   │       └── main.yml
│   ├── openssl/
│   │   └── tasks/
│   │       └── main.yml
│   ├── openzfs/
│   │   └── tasks/
│   │       └── main.yml
│   ├── orbstack/
│   │   └── tasks/
│   │       └── main.yml
│   ├── p7zip/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pandoc/
│   │   └── tasks/
│   │       └── main.yml
│   ├── parallel/
│   │   └── tasks/
│   │       └── main.yml
│   ├── passwordless-sudo/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pcsv/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pdf-expert/
│   │   └── tasks/
│   │       └── main.yml
│   ├── persephone/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pgsanity/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pngpaste/
│   │   └── tasks/
│   │       └── main.yml
│   ├── prettier/
│   │   └── tasks/
│   │       └── main.yml
│   ├── prey/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── pulp/
│   │   └── tasks/
│   │       └── main.yml
│   ├── purescript/
│   │   └── tasks/
│   │       └── main.yml
│   ├── pyre-check/
│   │   └── tasks/
│   │       └── main.yml
│   ├── python3/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── qt5/
│   │   ├── files/
│   │   │   └── qt-noninteractive.qs
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── r/
│   │   └── tasks/
│   │       └── main.yml
│   ├── rescuetime/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── rider/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ripgrep/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ruby/
│   │   ├── meta/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── rust/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── rust-analyzer/
│   │   └── tasks/
│   │       └── main.yml
│   ├── s3cmd/
│   │   └── tasks/
│   │       └── main.yml
│   ├── scc/
│   │   └── tasks/
│   │       └── main.yml
│   ├── shellcheck/
│   │   └── tasks/
│   │       └── main.yml
│   ├── shfmt/
│   │   └── tasks/
│   │       └── main.yml
│   ├── shpotify/
│   │   └── tasks/
│   │       └── main.yml
│   ├── skype/
│   │   └── tasks/
│   │       └── main.yml
│   ├── slack/
│   │   └── tasks/
│   │       └── main.yml
│   ├── spotify/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── ssh-keys/
│   │   ├── files/
│   │   │   ├── mpereira@argonaut.pub
│   │   │   └── mpereira@pluto.pub
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── steam/
│   │   └── tasks/
│   │       └── main.yml
│   ├── stripe-cli/
│   │   └── tasks/
│   │       └── main.yml
│   ├── taglib/
│   │   └── tasks/
│   │       └── main.yml
│   ├── tealdeer/
│   │   └── tasks/
│   │       └── main.yml
│   ├── teensy-loader/
│   │   └── tasks/
│   │       └── main.yml
│   ├── terminal-notifier/
│   │   └── tasks/
│   │       └── main.yml
│   ├── terraform/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── tmux/
│   │   └── tasks/
│   │       └── main.yml
│   ├── tmuxinator/
│   │   └── tasks/
│   │       └── main.yml
│   ├── toggle-dark-mode/
│   │   ├── files/
│   │   │   └── ToggleDarkMode.app/
│   │   │       └── Contents/
│   │   │           ├── Info.plist
│   │   │           ├── MacOS/
│   │   │           │   └── Application Stub
│   │   │           ├── Resources/
│   │   │           │   ├── AutomatorApplet.icns
│   │   │           │   ├── ar.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ca.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── cs.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── da.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── de.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── el.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── en.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── en_AU.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── en_GB.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── es.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── es_419.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── fi.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── fr.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── fr_CA.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── he.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── hi.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── hr.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── hu.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── id.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── it.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ja.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ko.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ms.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── nl.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── no.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── pl.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── pt.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── pt_PT.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ro.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── ru.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── sk.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── sv.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── th.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── tr.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── uk.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── vi.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── zh_CN.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   ├── zh_HK.lproj/
│   │   │           │   │   └── InfoPlist.strings
│   │   │           │   └── zh_TW.lproj/
│   │   │           │       └── InfoPlist.strings
│   │   │           └── document.wflow
│   │   └── tasks/
│   │       └── main.yml
│   ├── tree/
│   │   └── tasks/
│   │       └── main.yml
│   ├── unity/
│   │   └── tasks/
│   │       └── main.yml
│   ├── unity-hub/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── usr-local-src-directory/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vagrant/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vagrant-vbguest/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vault/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vercel/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vim/
│   │   ├── meta/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── virtualbox/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vlc/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── vscode/
│   │   └── tasks/
│   │       └── main.yml
│   ├── vtop/
│   │   └── tasks/
│   │       └── main.yml
│   ├── websocat/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── whatsapp/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wireshark/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wkhtmltopdf/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wordnet/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wrk/
│   │   └── tasks/
│   │       └── main.yml
│   ├── xbar/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── xbar-plugins/
│   │   └── tasks/
│   │       └── main.yml
│   ├── xquartz/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── xz/
│   │   └── tasks/
│   │       └── main.yml
│   ├── yapf/
│   │   └── tasks/
│   │       └── main.yml
│   ├── yarn/
│   │   └── tasks/
│   │       └── main.yml
│   ├── ynab/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── vars/
│   │       └── main.yml
│   ├── yq/
│   │   └── tasks/
│   │       └── main.yml
│   ├── zoom/
│   │   └── tasks/
│   │       └── main.yml
│   ├── zprint/
│   │   └── tasks/
│   │       └── main.yml
│   ├── zsh/
│   │   └── tasks/
│   │       └── main.yml
│   └── zwift/
│       └── tasks/
│           └── main.yml
└── semver.sh
Condensed preview — 265 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (146K chars).
[
  {
    "path": ".gitignore",
    "chars": 85,
    "preview": "/*.patch\n/.ansible_vault_password\n/galaxy\n/group_vars/localhost/vars.yml\n/main.retry\n"
  },
  {
    "path": "Makefile",
    "chars": 2738,
    "preview": "# Catalina | 3.7\n# Big Sur  | 3.8\n# Ventura  | 3.9\nSYSTEM_PYTHON                  := /usr/bin/python3\nBOOTSTRAP_PYTHON_M"
  },
  {
    "path": "README.org",
    "chars": 19894,
    "preview": "#+TITLE: macbook-playbook\n#+AUTHOR: Murilo Pereira <murilo@murilopereira.com>\n\n:PROPERTIES:\n:TOC:      ignore\n:END:\n\nIns"
  },
  {
    "path": "ansible.cfg",
    "chars": 63,
    "preview": "[defaults]\nstdout_callback = yaml\ninterpreter_python = python3\n"
  },
  {
    "path": "bootstrap.yml",
    "chars": 658,
    "preview": "---\n- hosts: localhost\n  connection: local\n  gather_facts: no\n  roles:\n    - ansible-download-directory\n    - usr-local-"
  },
  {
    "path": "configure.sh",
    "chars": 11550,
    "preview": "#!/usr/bin/env bash\n\n# Resources:\n# - http://www.defaults-write.com\n# - https://gist.github.com/MatthewEppelsheimer/2269"
  },
  {
    "path": "group_vars/all",
    "chars": 152,
    "preview": "# -*-yaml-*-\n---\nuser: \"{{ lookup('env', 'USER') }}\"\nhome_directory: \"/Users/{{ user }}\"\ndownloads_directory: \"{{ home_d"
  },
  {
    "path": "hosts",
    "chars": 8,
    "preview": "0.0.0.0\n"
  },
  {
    "path": "main.yml",
    "chars": 22633,
    "preview": "---\n- hosts: localhost\n  connection: local\n  roles:\n    ################################################################"
  },
  {
    "path": "requirements.yml",
    "chars": 60,
    "preview": "---\ncollections:\n  - name: ansible.posix\n    version: 1.3.0\n"
  },
  {
    "path": "roles/android-file-transfer/tasks/main.yml",
    "chars": 1159,
    "preview": "---\n- name: Download Android File Transfer\n  get_url:\n    url: \"{{ android_file_transfer_image_url }}\"\n    dest: \"{{ and"
  },
  {
    "path": "roles/android-file-transfer/vars/main.yml",
    "chars": 508,
    "preview": "---\nandroid_file_transfer_image_name: \"androidfiletransfer.dmg\"\nandroid_file_transfer_image_url: \"https://dl.google.com/"
  },
  {
    "path": "roles/ansible-download-directory/tasks/main.yml",
    "chars": 130,
    "preview": "---\n- name: Ensure that the Ansible downloads directory exists\n  file:\n    path: \"{{ downloads_directory }}\"\n    state: "
  },
  {
    "path": "roles/awscli/tasks/main.yml",
    "chars": 347,
    "preview": "- name: Install awscli\n  pip:\n    name: awscli\n    extra_args: --user\n\n- name: Ensure ~/.aws directory exists\n  file:\n  "
  },
  {
    "path": "roles/babashka/tasks/main.yml",
    "chars": 292,
    "preview": "---\n- name: Download Babashka installer\n  get_url:\n    url: https://raw.githubusercontent.com/borkdude/babashka/master/i"
  },
  {
    "path": "roles/bash/tasks/main.yml",
    "chars": 482,
    "preview": "---\n- name: Install bash\n  homebrew:\n    name: bash\n    state: latest\n\n- name: Register bash binary path\n  register: bin"
  },
  {
    "path": "roles/beets/tasks/main.yml",
    "chars": 72,
    "preview": "---\n- name: Install beets\n  pip:\n    name: beets\n    extra_args: --user\n"
  },
  {
    "path": "roles/better-touch-tool/tasks/main.yml",
    "chars": 652,
    "preview": "---\n- name: Download BetterTouchTool\n  get_url: >\n    url=\"https://folivora.ai/releases/BetterTouchTool.zip\"\n    dest=\"{"
  },
  {
    "path": "roles/black/tasks/main.yml",
    "chars": 77,
    "preview": "---\n- name: Install Black\n  command:\n    python3 -m pip install --user black\n"
  },
  {
    "path": "roles/bottle/tasks/main.yml",
    "chars": 70,
    "preview": "- name: Install bottle\n  pip:\n    name: bottle\n    extra_args: --user\n"
  },
  {
    "path": "roles/build-emacs/tasks/main.yml",
    "chars": 719,
    "preview": "---\n- name: Add Homebrew tap\n  command: brew tap daviderestivo/emacs-head\n\n- name: Install Emacs\n  homebrew:\n    name: e"
  },
  {
    "path": "roles/bundler/tasks/main.yml",
    "chars": 71,
    "preview": "---\n- name: Install bundler\n  gem:\n    name: bundler\n    state: latest\n"
  },
  {
    "path": "roles/caps-lock-remapped-to-control/files/remap_caps_lock_to_control.scpt",
    "chars": 489,
    "preview": "tell application \"System Preferences\"\n\tactivate\n\tset current pane to pane \"com.apple.preference.keyboard\"\nend tell\n\ndela"
  },
  {
    "path": "roles/caps-lock-remapped-to-control/tasks/main.yml",
    "chars": 134,
    "preview": "---\n- name: Remap Caps Lock to Control\n  command: osascript roles/caps-lock-remapped-to-control/files/remap_caps_lock_to"
  },
  {
    "path": "roles/chromedriver/tasks/main.yml",
    "chars": 652,
    "preview": "---\n- name: Create directory for versioned Chromedriver Homebrew recipe\n  ansible.builtin.file:\n    path: \"{{ downloads_"
  },
  {
    "path": "roles/clojure/tasks/main.yml",
    "chars": 90,
    "preview": "---\n- name: Install Clojure\n  homebrew:\n    name: clojure/tools/clojure\n    state: latest\n"
  },
  {
    "path": "roles/clojure-lsp/tasks/main.yml",
    "chars": 318,
    "preview": "---\n# NOTE: not using the Homebrew brew because it is hard-coded to depend on\n# openjdk@11 from Homebrew.\n- name: Instal"
  },
  {
    "path": "roles/cmake/tasks/main.yml",
    "chars": 1516,
    "preview": "---\n- name: Download CMake\n  get_url:\n    url: \"{{ cmake_image_url }}\"\n    dest: \"{{ downloads_directory }}/{{ cmake_ima"
  },
  {
    "path": "roles/cmake/vars/main.yml",
    "chars": 535,
    "preview": "---\n# https://github.com/Kitware/CMake/releases/download\ncmake_image_name_suffix: \"macos-universal\"\ncmake_image_name: \"c"
  },
  {
    "path": "roles/consolas/tasks/main.yml",
    "chars": 978,
    "preview": "---\n- name: Install cabextract\n  homebrew: name=cabextract state=present\n\n# Got it originally from here:\n# https://downl"
  },
  {
    "path": "roles/ctags/tasks/main.yml",
    "chars": 72,
    "preview": "---\n- name: Install ctags\n  homebrew:\n    name: ctags\n    state: latest\n"
  },
  {
    "path": "roles/cursorcerer/tasks/main.yml",
    "chars": 203,
    "preview": "---\n- name: Install Cursorcerer\n  homebrew_cask:\n    name: cursorcerer\n    state: latest\n\n- name: Open Cursorcerer.prefP"
  },
  {
    "path": "roles/daisydisk/tasks/main.yml",
    "chars": 192,
    "preview": "---\n- name: Install DaisyDisk\n  homebrew_cask:\n    name: daisydisk\n    state: latest\n\n- command: open /Applications/Dais"
  },
  {
    "path": "roles/dash/tasks/main.yml",
    "chars": 504,
    "preview": "---\n- name: Download Dash\n  get_url:\n    url: http://newyork.kapeli.com/{{ dash_zip }}\n    dest: \"{{ downloads_directory"
  },
  {
    "path": "roles/dash/vars/main.yml",
    "chars": 63,
    "preview": "---\ndash_directory: Dash\ndash_zip: Dash.zip\ndash_app: Dash.app\n"
  },
  {
    "path": "roles/defaultbrowser/tasks/main.yml",
    "chars": 440,
    "preview": "---\n- name: Check out the defaultbrowser repository\n  git:\n    repo: https://github.com/kerma/defaultbrowser.git\n    des"
  },
  {
    "path": "roles/divvy/tasks/main.yml",
    "chars": 443,
    "preview": "---\n- name: Download Divvy\n  get_url:\n    url: http://mizage.com/downloads/Divvy.zip\n    dest: \"{{ downloads_directory }"
  },
  {
    "path": "roles/docker/tasks/main.yml",
    "chars": 141,
    "preview": "---\n- name: Install Docker\n  homebrew_cask:\n    name: docker\n    state: latest\n\n# TODO: open it if it was just installed"
  },
  {
    "path": "roles/dotemacs/tasks/main.yml",
    "chars": 166,
    "preview": "---\n- name: Check out the mpereira/.emacs.d repository\n  git:\n    repo: git@github.com:mpereira/.emacs.d.git\n    dest: \""
  },
  {
    "path": "roles/dotfiles/tasks/main.yml",
    "chars": 348,
    "preview": "---\n- name: Check out the mpereira/dotfiles repository\n  git:\n    repo: git@github.com:mpereira/dotfiles.git\n    dest: \""
  },
  {
    "path": "roles/dotnet-sdk/tasks/main.yml",
    "chars": 85,
    "preview": "---\n- name: Install .NET SDK\n  homebrew_cask:\n    name: dotnet-sdk\n    state: latest\n"
  },
  {
    "path": "roles/dropbox/tasks/main.yml",
    "chars": 593,
    "preview": "---\n- name: Download Dropbox\n  get_url:\n    url: https://www.dropbox.com/download?plat=mac\n    dest: \"{{ downloads_direc"
  },
  {
    "path": "roles/elgato-control-center/tasks/main.yml",
    "chars": 177,
    "preview": "---\n- name: Add Homebrew tap\n  command: brew tap homebrew/cask-drivers\n\n- name: Install elgato-control-center\n  homebrew"
  },
  {
    "path": "roles/elgato-dock/tasks/main.yml",
    "chars": 556,
    "preview": "---\n- name: Download Elgato Dock software\n  get_url:\n    url: \"https://edge.elgato.com/thunderbolt-dock/Elgato_Thunderbo"
  },
  {
    "path": "roles/emacs-pre-built/tasks/main.yml",
    "chars": 1456,
    "preview": "---\n- name: Download Emacs\n  get_url:\n    url: https://emacsformacosx.com/emacs-builds/{{ emacs_pre_built_dmg }}\n    des"
  },
  {
    "path": "roles/emacs-pre-built/vars/main.yml",
    "chars": 490,
    "preview": "---\nemacs_pre_built_pretest_prefix: \"{{ 'pretest-' if (emacs_pre_built_pretest is defined and emacs_pre_built_pretest) e"
  },
  {
    "path": "roles/fd/tasks/main.yml",
    "chars": 66,
    "preview": "---\n- name: Install fd\n  homebrew:\n    name: fd\n    state: latest\n"
  },
  {
    "path": "roles/ffmpeg/tasks/main.yml",
    "chars": 74,
    "preview": "---\n- name: Install ffmpeg\n  homebrew:\n    name: ffmpeg\n    state: latest\n"
  },
  {
    "path": "roles/firefox/tasks/main.yml",
    "chars": 1014,
    "preview": "---\n- name: Download Firefox\n  get_url:\n    url: \"https://download.mozilla.org/?product=firefox-{{ firefox_version }}&os"
  },
  {
    "path": "roles/firefox/vars/main.yml",
    "chars": 45,
    "preview": "---\nfirefox_app: \"/Applications/Firefox.app\"\n"
  },
  {
    "path": "roles/firefox-adblock-plus/tasks/main.yml",
    "chars": 558,
    "preview": "---\n- name: Open Firefox\n  shell: >\n    \"{{ firefox_app }}/Contents/MacOS/firefox-bin\" -headless & firefox_pid=$!; sleep"
  },
  {
    "path": "roles/fish/tasks/main.yml",
    "chars": 70,
    "preview": "---\n- name: Install fish\n  homebrew:\n    name: fish\n    state: latest\n"
  },
  {
    "path": "roles/fish-foreign-env/tasks/main.yml",
    "chars": 315,
    "preview": "---\n- name: Make sure Fish shell directory exists\n  file:\n    path: \"{{ home_directory }}/.config/fish\"\n    state: direc"
  },
  {
    "path": "roles/flux/tasks/main.yml",
    "chars": 138,
    "preview": "---\n- name: Install f.lux\n  homebrew_cask:\n    name: flux\n    state: latest\n\n# TODO: open it if it was just installed fo"
  },
  {
    "path": "roles/font-hack/tasks/main.yml",
    "chars": 292,
    "preview": "---\n- name: Add cask-fonts tap\n  command: brew tap homebrew/cask-fonts\n\n- name: Install Hack font\n  homebrew_cask:\n    n"
  },
  {
    "path": "roles/fontforge/tasks/main.yml",
    "chars": 217,
    "preview": "---\n- name: Create /usr/local/Frameworks\n  file:\n    path: /usr/local/Frameworks\n    state: directory\n    owner: \"{{ use"
  },
  {
    "path": "roles/gcloud/tasks/main.yml",
    "chars": 444,
    "preview": "---\n- name: Install gcloud\n  shell: >\n    set -x; cd ~ &&\n      OS=\"$(uname | tr '[:upper:]' '[:lower:]')\" &&\n      PROC"
  },
  {
    "path": "roles/gh/tasks/main.yml",
    "chars": 66,
    "preview": "---\n- name: Install gh\n  homebrew:\n    name: gh\n    state: latest\n"
  },
  {
    "path": "roles/gifsicle/tasks/main.yml",
    "chars": 79,
    "preview": "---\n- name: Install gifsicle\n  homebrew:\n    name: gifsicle\n    state: present\n"
  },
  {
    "path": "roles/git/tasks/main.yml",
    "chars": 68,
    "preview": "---\n- name: Install Git\n  homebrew:\n    name: git\n    state: latest\n"
  },
  {
    "path": "roles/git/vars/main.yml",
    "chars": 186,
    "preview": "---\ngit_dmg: git-{{ git_version }}-intel-universal-mavericks.dmg\ngit_volume: Git {{ git_version }} Mavericks Intel Unive"
  },
  {
    "path": "roles/git-delta/tasks/main.yml",
    "chars": 76,
    "preview": "---\n- name: Install delta\n  homebrew:\n    name: git-delta\n    state: latest\n"
  },
  {
    "path": "roles/glances/files/com.mpereira.glances.webserver.plist",
    "chars": 624,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "roles/glances/tasks/main.yml",
    "chars": 410,
    "preview": "---\n- name: Install glances\n  pip:\n    name: glances\n    extra_args: --user\n\n- name: Create glances webserver service pl"
  },
  {
    "path": "roles/glances/vars/main.yml",
    "chars": 29,
    "preview": "---\ndependencies:\n  - bottle\n"
  },
  {
    "path": "roles/gnu-command-line-tools/tasks/main.yml",
    "chars": 463,
    "preview": "---\n- name: Install coreutils\n  homebrew:\n    name: coreutils\n    state: latest\n\n- name: Install some GNU tools\n  homebr"
  },
  {
    "path": "roles/gnupg/tasks/main.yml",
    "chars": 539,
    "preview": "---\n- name: Download GnuPG\n  get_url:\n    url: https://downloads.sourceforge.net/project/gpgosx/{{ gnupg_dmg }}\n    dest"
  },
  {
    "path": "roles/gnupg/vars/main.yml",
    "chars": 89,
    "preview": "---\ngnupg_dmg: \"GnuPG-{{ gnupg_version }}.dmg\"\ngnupg_volume: \"GnuPG {{ gnupg_version }}\"\n"
  },
  {
    "path": "roles/gnuplot/tasks/main.yml",
    "chars": 76,
    "preview": "---\n- name: Install gnuplot\n  homebrew:\n    name: gnuplot\n    state: latest\n"
  },
  {
    "path": "roles/go/tasks/main.yml",
    "chars": 235,
    "preview": "---\n- name: Download Go\n  get_url:\n    url: \"{{ go_pkg_url }}\"\n    dest: \"{{ downloads_directory }}/{{ go_pkg }}\"\n\n- nam"
  },
  {
    "path": "roles/go/vars/main.yml",
    "chars": 102,
    "preview": "---\ngo_pkg: \"go{{ go_version }}.darwin-amd64.pkg\"\ngo_pkg_url: \"https://dl.google.com/go/{{ go_pkg }}\"\n"
  },
  {
    "path": "roles/google-chrome/tasks/main.yml",
    "chars": 93,
    "preview": "---\n- name: Install Google Chrome\n  homebrew_cask:\n    name: google-chrome\n    state: latest\n"
  },
  {
    "path": "roles/google-chrome/vars/main.yml",
    "chars": 407,
    "preview": "---\ngoogle_chrome_image_name: \"googlechrome.dmg\"\ngoogle_chrome_image_url: \"https://dl.google.com/chrome/mac/stable/CHFA/"
  },
  {
    "path": "roles/google-chrome-as-default-browser/meta/main.yml",
    "chars": 55,
    "preview": "---\ndependencies:\n  - google-chrome\n  - defaultbrowser\n"
  },
  {
    "path": "roles/google-chrome-as-default-browser/tasks/main.yml",
    "chars": 84,
    "preview": "---\n- name: Make Google Chrome the default browser\n  command: defaultbrowser chrome\n"
  },
  {
    "path": "roles/google-photos/tasks/main.yml",
    "chars": 692,
    "preview": "---\n- name: Download Google Photos\n  get_url:\n    url: https://dl.google.com/dl/picasa/{{ google_photos_dmg }}\n    dest:"
  },
  {
    "path": "roles/google-photos/vars/main.yml",
    "chars": 141,
    "preview": "---\ngoogle_photos_dmg: gpautobackup_setup.dmg\ngoogle_photos_volume: Install Google Photos Backup\ngoogle_photos_app: Goog"
  },
  {
    "path": "roles/graalvm/tasks/main.yml",
    "chars": 721,
    "preview": "---\n- name: Download GraalVM\n  get_url:\n    url: \"https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-{{ g"
  },
  {
    "path": "roles/graalvm/vars/main.yml",
    "chars": 270,
    "preview": "---\ngraalvm_java_version: \"java11\"\ngraalvm_directory: \"graalvm-ce-{{ graalvm_java_version }}-darwin-amd64-{{ graalvm_ver"
  },
  {
    "path": "roles/grammarly/tasks/main.yml",
    "chars": 85,
    "preview": "---\n- name: Install Grammarly\n  homebrew_cask:\n    name: grammarly\n    state: latest\n"
  },
  {
    "path": "roles/grip/tasks/main.yml",
    "chars": 70,
    "preview": "---\n- name: Install Grip\n  pip:\n    name: grip\n    extra_args: --user\n"
  },
  {
    "path": "roles/gron/tasks/main.yml",
    "chars": 239,
    "preview": "---\n- name: Download and install gron binary\n  unarchive:\n    src: https://github.com/tomnomnom/gron/releases/download/v"
  },
  {
    "path": "roles/hadoop/tasks/main.yml",
    "chars": 74,
    "preview": "---\n- name: Install hadoop\n  homebrew:\n    name: hadoop\n    state: latest\n"
  },
  {
    "path": "roles/haskell/tasks/main.yml",
    "chars": 88,
    "preview": "---\n- name: Install haskell-stack\n  homebrew:\n    name: haskell-stack\n    state: latest\n"
  },
  {
    "path": "roles/homebrew/tasks/main.yml",
    "chars": 174,
    "preview": "---\n- name: Install Homebrew\n  shell: >\n    /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/instal"
  },
  {
    "path": "roles/htop/tasks/main.yml",
    "chars": 70,
    "preview": "---\n- name: Install htop\n  homebrew:\n    name: htop\n    state: latest\n"
  },
  {
    "path": "roles/hugo/tasks/main.yml",
    "chars": 126,
    "preview": "---\n- name: Install Hugo\n  homebrew:\n    name: hugo\n    # NOTE: I don't want to automatically update Hugo.\n    state: pr"
  },
  {
    "path": "roles/imagemagick/tasks/main.yml",
    "chars": 84,
    "preview": "---\n- name: Install imagemagick\n  homebrew:\n    name: imagemagick\n    state: latest\n"
  },
  {
    "path": "roles/istat-menus/tasks/main.yml",
    "chars": 199,
    "preview": "---\n- name: Install iStat Menus\n  homebrew_cask:\n    name: istat-menus\n    state: latest\n\n- command: open /Applications/"
  },
  {
    "path": "roles/iterm/tasks/main.yml",
    "chars": 79,
    "preview": "---\n- name: Install iTerm2\n  homebrew_cask:\n    name: iterm2\n    state: latest\n"
  },
  {
    "path": "roles/java/tasks/main.yml",
    "chars": 161,
    "preview": "---\n- name: Add Homebrew tap\n  command: brew tap AdoptOpenJDK/openjdk\n\n- name: Install OpenJDK\n  homebrew_cask:\n    name"
  },
  {
    "path": "roles/jmeter/tasks/main.yml",
    "chars": 74,
    "preview": "---\n- name: Install JMeter\n  homebrew:\n    name: jmeter\n    state: latest\n"
  },
  {
    "path": "roles/jpeg/tasks/main.yml",
    "chars": 61,
    "preview": "---\n- name: Install jpeg\n  homebrew: name=jpeg state=present\n"
  },
  {
    "path": "roles/jq/tasks/main.yml",
    "chars": 174,
    "preview": "---\n- name: Download and install jq binary\n  get_url:\n    url: https://github.com/stedolan/jq/releases/latest/download/j"
  },
  {
    "path": "roles/krew/tasks/main.yml",
    "chars": 434,
    "preview": "---\n- name: Install krew\n  shell: >\n    set -x; cd \"$(mktemp -d)\" &&\n      OS=\"$(uname | tr '[:upper:]' '[:lower:]')\" &&"
  },
  {
    "path": "roles/ktlint/tasks/main.yml",
    "chars": 164,
    "preview": "---\n- name: Install ktlint\n  get_url:\n    url: \"https://github.com/pinterest/ktlint/releases/latest/download/ktlint\"\n   "
  },
  {
    "path": "roles/kubectl/tasks/main.yml",
    "chars": 341,
    "preview": "---\n- name: Download kubectl binary\n  get_url:\n    url: \"{{ kubectl_binary_url }}\"\n    dest: \"{{ downloads_directory }}/"
  },
  {
    "path": "roles/kubectl/vars/main.yml",
    "chars": 177,
    "preview": "kubectl_binary_name: \"kubectl\"\nkubectl_binary_url: \"https://storage.googleapis.com/kubernetes-release/release/v{{ kubect"
  },
  {
    "path": "roles/kubectl-tree/tasks/main.yml",
    "chars": 70,
    "preview": "---\n- name: Install kubectl-tree\n  command: kubectl-krew install tree\n"
  },
  {
    "path": "roles/leiningen/tasks/main.yml",
    "chars": 80,
    "preview": "---\n- name: Install leiningen\n  homebrew:\n    name: leiningen\n    state: latest\n"
  },
  {
    "path": "roles/licecap/tasks/main.yml",
    "chars": 847,
    "preview": "---\n- name: Download LICEcap\n  get_url:\n    url: http://www.cockos.com/licecap/{{ licecap_dmg }}\n    dest: \"{{ downloads"
  },
  {
    "path": "roles/licecap/vars/main.yml",
    "chars": 162,
    "preview": "---\nlicecap_name: licecap123\nlicecap_dmg: \"{{ licecap_name }}.dmg\"\nlicecap_cdr: \"{{ licecap_name }}.cdr\"\nlicecap_volume:"
  },
  {
    "path": "roles/llvm/tasks/main.yml",
    "chars": 70,
    "preview": "---\n- name: Install LLVM\n  homebrew:\n    name: llvm\n    state: latest\n"
  },
  {
    "path": "roles/local-ssl-proxy/tasks/main.yml",
    "chars": 117,
    "preview": "---\n- name: Install local-ssl-proxy\n  npm:\n    name: local-ssl-proxy\n    state: latest\n    global: yes\n  become: yes\n"
  },
  {
    "path": "roles/lua/tasks/main.yml",
    "chars": 68,
    "preview": "---\n- name: Install Lua\n  homebrew:\n    name: lua\n    state: latest\n"
  },
  {
    "path": "roles/luajit/tasks/main.yml",
    "chars": 74,
    "preview": "---\n- name: Install LuaJIT\n  homebrew:\n    name: luajit\n    state: latest\n"
  },
  {
    "path": "roles/mac-ports/tasks/main.yml",
    "chars": 636,
    "preview": "---\n- name: Download MacPorts\n  get_url:\n    url: https://github.com/macports/macports-base/releases/download/v{{ macpor"
  },
  {
    "path": "roles/mac-ports/vars/main.yml",
    "chars": 81,
    "preview": "---\nmacports_pkg: MacPorts-{{ macports_version }}-{{ macports_mac_release }}.pkg\n"
  },
  {
    "path": "roles/maccy/tasks/main.yml",
    "chars": 77,
    "preview": "---\n- name: Install Maccy\n  homebrew_cask:\n    name: maccy\n    state: latest\n"
  },
  {
    "path": "roles/mactex/tasks/main.yml",
    "chars": 86,
    "preview": "---\n- name: Install MacTeX\n  homebrew_cask:\n    name: mactex-no-gui\n    state: latest\n"
  },
  {
    "path": "roles/macvim/tasks/main.yml",
    "chars": 923,
    "preview": "---\n- name: Download MacVim\n  get_url:\n    url: \"https://github.com/macvim-dev/macvim/releases/download/{{ macvim_versio"
  },
  {
    "path": "roles/make/tasks/main.yml",
    "chars": 108,
    "preview": "---\n- name: Install make\n  community.general.homebrew:\n    name: make\n    # name: \"make@{{ make_version }}\"\n"
  },
  {
    "path": "roles/markdown/tasks/main.yml",
    "chars": 78,
    "preview": "---\n- name: Install markdown\n  homebrew:\n    name: markdown\n    state: latest\n"
  },
  {
    "path": "roles/maven/tasks/main.yml",
    "chars": 72,
    "preview": "---\n- name: Install maven\n  homebrew:\n    name: maven\n    state: latest\n"
  },
  {
    "path": "roles/mpc/tasks/main.yml",
    "chars": 68,
    "preview": "---\n- name: Install mpc\n  homebrew:\n    name: mpc\n    state: latest\n"
  },
  {
    "path": "roles/mpd/tasks/main.yml",
    "chars": 231,
    "preview": "---\n- name: Install mpd\n  homebrew:\n    name: mpd\n    state: latest\n\n# FIXME: this seems to fail if the service is alrea"
  },
  {
    "path": "roles/mpdscribble/tasks/main.yml",
    "chars": 208,
    "preview": "---\n- name: Install mpdscribble\n  homebrew:\n    name: mpdscribble\n    state: latest\n\n- name: Create mpdscribble service "
  },
  {
    "path": "roles/mpg123/tasks/main.yml",
    "chars": 74,
    "preview": "---\n- name: Install mpg123\n  homebrew:\n    name: mpg123\n    state: latest\n"
  },
  {
    "path": "roles/mplayer/tasks/main.yml",
    "chars": 76,
    "preview": "---\n- name: Install mplayer\n  homebrew:\n    name: mplayer\n    state: latest\n"
  },
  {
    "path": "roles/mutagen/tasks/main.yml",
    "chars": 95,
    "preview": "---\n- name: Install Mutagen\n  homebrew:\n    name: mutagen-io/mutagen/mutagen\n    state: latest\n"
  },
  {
    "path": "roles/neovim/tasks/main.yml",
    "chars": 509,
    "preview": "---\n- name: Download Neovim\n  get_url:\n    url=\"https://github.com/neovim/neovim/releases/download/v{{ neovim_version }}"
  },
  {
    "path": "roles/ngrep/tasks/main.yml",
    "chars": 72,
    "preview": "---\n- name: Install ngrep\n  homebrew:\n    name: ngrep\n    state: latest\n"
  },
  {
    "path": "roles/node/tasks/main.yml",
    "chars": 412,
    "preview": "---\n- name: Download Node.js\n  get_url:\n    url: https://nodejs.org/dist/v{{ node_version }}/{{ node_pkg }}\n    dest: \"{"
  },
  {
    "path": "roles/node/vars/main.yml",
    "chars": 43,
    "preview": "---\nnode_pkg: node-v{{ node_version }}.pkg\n"
  },
  {
    "path": "roles/node-cljfmt/tasks/main.yml",
    "chars": 109,
    "preview": "---\n- name: Install node-cljfmt\n  npm:\n    name: node-cljfmt\n    state: latest\n    global: yes\n  become: yes\n"
  },
  {
    "path": "roles/octave/tasks/main.yml",
    "chars": 74,
    "preview": "---\n- name: Install Octave\n  homebrew:\n    name: octave\n    state: latest\n"
  },
  {
    "path": "roles/openssl/tasks/main.yml",
    "chars": 76,
    "preview": "---\n- name: Install openssl\n  homebrew:\n    name: openssl\n    state: latest\n"
  },
  {
    "path": "roles/openzfs/tasks/main.yml",
    "chars": 81,
    "preview": "---\n- name: Install OpenZFS\n  homebrew_cask:\n    name: openzfs\n    state: latest\n"
  },
  {
    "path": "roles/orbstack/tasks/main.yml",
    "chars": 145,
    "preview": "---\n- name: Install OrbStack\n  homebrew_cask:\n    name: orbstack\n    state: latest\n\n# TODO: open it if it was just insta"
  },
  {
    "path": "roles/p7zip/tasks/main.yml",
    "chars": 72,
    "preview": "---\n- name: Install p7zip\n  homebrew:\n    name: p7zip\n    state: latest\n"
  },
  {
    "path": "roles/pandoc/tasks/main.yml",
    "chars": 74,
    "preview": "---\n- name: Install Pandoc\n  homebrew:\n    name: pandoc\n    state: latest\n"
  },
  {
    "path": "roles/parallel/tasks/main.yml",
    "chars": 78,
    "preview": "---\n- name: Install parallel\n  homebrew:\n    name: parallel\n    state: latest\n"
  },
  {
    "path": "roles/passwordless-sudo/tasks/main.yml",
    "chars": 194,
    "preview": "---\n- lineinfile:\n    path: \"/etc/sudoers.d/{{ user }}\"\n    line: \"{{ user }} ALL=(ALL) NOPASSWD: ALL\"\n    create: yes\n "
  },
  {
    "path": "roles/pcsv/tasks/main.yml",
    "chars": 70,
    "preview": "---\n- name: Install pcsv\n  pip:\n    name: pcsv\n    extra_args: --user\n"
  },
  {
    "path": "roles/pdf-expert/tasks/main.yml",
    "chars": 149,
    "preview": "---\n- name: Install PDF Expert\n  homebrew_cask:\n    name: pdf-expert\n    state: latest\n\n# TODO: open it if it was just i"
  },
  {
    "path": "roles/persephone/tasks/main.yml",
    "chars": 441,
    "preview": "---\n# TODO: Remove \"creates\" and only run this task when either\n# \"/Applications/Persephone.app\" doesn't exist or \"perse"
  },
  {
    "path": "roles/pgsanity/tasks/main.yml",
    "chars": 78,
    "preview": "---\n- name: Install PgSanity\n  pip:\n    name: pgsanity\n    extra_args: --user\n"
  },
  {
    "path": "roles/pngpaste/tasks/main.yml",
    "chars": 78,
    "preview": "---\n- name: Install pngpaste\n  homebrew:\n    name: pngpaste\n    state: latest\n"
  },
  {
    "path": "roles/prettier/tasks/main.yml",
    "chars": 103,
    "preview": "---\n- name: Install prettier\n  npm:\n    name: prettier\n    state: latest\n    global: yes\n  become: yes\n"
  },
  {
    "path": "roles/prey/tasks/main.yml",
    "chars": 893,
    "preview": "---\n# NOTE: get_url fails to download because of a bug with SSL handling. Using\n# command + wget instead. https://github"
  },
  {
    "path": "roles/prey/vars/main.yml",
    "chars": 50,
    "preview": "---\nprey_pkg: prey-mac-{{ prey_version }}-x64.pkg\n"
  },
  {
    "path": "roles/pulp/tasks/main.yml",
    "chars": 95,
    "preview": "---\n- name: Install pulp\n  npm:\n    name: pulp\n    state: latest\n    global: yes\n  become: yes\n"
  },
  {
    "path": "roles/purescript/tasks/main.yml",
    "chars": 67,
    "preview": "---\n- name: Install PureScript\n  command: stack install purescript\n"
  },
  {
    "path": "roles/pyre-check/tasks/main.yml",
    "chars": 82,
    "preview": "---\n- name: Install Pyre-Check\n  pip:\n    name: pyre-check\n    extra_args: --user\n"
  },
  {
    "path": "roles/python3/tasks/main.yml",
    "chars": 712,
    "preview": "---\n- name: Download Python 3\n  get_url:\n    url: https://www.python.org/ftp/python/{{ python3_version }}/{{ python3_pkg"
  },
  {
    "path": "roles/python3/vars/main.yml",
    "chars": 83,
    "preview": "---\npython3_pkg: python-{{ python3_version }}-macos{{ python3_macos_version }}.pkg\n"
  },
  {
    "path": "roles/qt5/files/qt-noninteractive.qs",
    "chars": 2737,
    "preview": "function Controller() {\n  installer.autoRejectMessageBoxes();\n  installer.installationFinished.connect(function () {\n   "
  },
  {
    "path": "roles/qt5/tasks/main.yml",
    "chars": 1155,
    "preview": "---\n- name: Download {{ qt_image_url }}\n  get_url: >\n    url=\"{{ qt_image_url }}\"\n    dest=\"{{ qt_image_path }}\"\n    che"
  },
  {
    "path": "roles/qt5/vars/main.yml",
    "chars": 454,
    "preview": "---\nqt_image_name: \"qt-opensource-mac-x64-{{ qt_version }}.dmg\"\nqt_image_url: \"http://download.qt.io/official_releases/q"
  },
  {
    "path": "roles/r/tasks/main.yml",
    "chars": 534,
    "preview": "---\n- name: Download R\n  get_url: >\n    url=\"https://cran.r-project.org/bin/macosx/base/R-{{ r_version }}.pkg\"\n    dest="
  },
  {
    "path": "roles/rescuetime/tasks/main.yml",
    "chars": 1114,
    "preview": "---\n- name: Download RescueTime\n  get_url:\n    url: \"{{ rescuetime_image_url }}\"\n    dest: \"{{ rescuetime_image_path }}\""
  },
  {
    "path": "roles/rescuetime/vars/main.yml",
    "chars": 374,
    "preview": "---\nrescuetime_image_name: \"RescueTimeInstaller.dmg\"\nrescuetime_image_url: \"https://www.rescuetime.com/installers/{{ res"
  },
  {
    "path": "roles/rider/tasks/main.yml",
    "chars": 77,
    "preview": "---\n- name: Install Rider\n  homebrew_cask:\n    name: rider\n    state: latest\n"
  },
  {
    "path": "roles/ripgrep/tasks/main.yml",
    "chars": 76,
    "preview": "---\n- name: Install ripgrep\n  homebrew:\n    name: ripgrep\n    state: latest\n"
  },
  {
    "path": "roles/ruby/meta/main.yml",
    "chars": 49,
    "preview": "---\ndependencies:\n  - cmake\n  - llvm\n  - openssl\n"
  },
  {
    "path": "roles/ruby/tasks/main.yml",
    "chars": 415,
    "preview": "---\n- name: Install ruby-build\n  homebrew:\n    name: ruby-build\n    state: latest\n\n- name: List installed Rubies\n  comma"
  },
  {
    "path": "roles/rust/tasks/main.yml",
    "chars": 146,
    "preview": "---\n- name: Install rustup-init\n  homebrew:\n    name: rustup\n    state: latest\n\n- name: Install rustup\n  command: rustup"
  },
  {
    "path": "roles/rust/vars/main.yml",
    "chars": 126,
    "preview": "---\nrust_pkg: \"rust-{{ rust_version }}i686-apple-darwin.pkg\"\nrust_pkg_url: \"https://static.rust-lang.org/dist/{{ rust_pk"
  },
  {
    "path": "roles/rust-analyzer/tasks/main.yml",
    "chars": 171,
    "preview": "---\n- name: Fetch Rust source code\n  command: rustup component add rust-src rust-docs\n\n- name: Install rust-analyzer\n  h"
  },
  {
    "path": "roles/s3cmd/tasks/main.yml",
    "chars": 193,
    "preview": "---\n- name: Install s3cmd\n  homebrew:\n    name: s3cmd\n    state: latest\n\n- name: Install ~/.s3cfg\n  copy:\n    src: \"{{ s"
  },
  {
    "path": "roles/scc/tasks/main.yml",
    "chars": 68,
    "preview": "---\n- name: Install scc\n  homebrew:\n    name: scc\n    state: latest\n"
  },
  {
    "path": "roles/shellcheck/tasks/main.yml",
    "chars": 82,
    "preview": "---\n- name: Install shellcheck\n  homebrew:\n    name: shellcheck\n    state: latest\n"
  },
  {
    "path": "roles/shfmt/tasks/main.yml",
    "chars": 72,
    "preview": "---\n- name: Install shfmt\n  homebrew:\n    name: shfmt\n    state: latest\n"
  },
  {
    "path": "roles/shpotify/tasks/main.yml",
    "chars": 78,
    "preview": "---\n- name: Install shpotify\n  homebrew:\n    name: shpotify\n    state: latest\n"
  },
  {
    "path": "roles/skype/tasks/main.yml",
    "chars": 533,
    "preview": "---\n- name: Download Skype\n  get_url:\n    url: http://www.skype.com/go/getskype-macosx.dmg\n    dest: \"{{ downloads_direc"
  },
  {
    "path": "roles/slack/tasks/main.yml",
    "chars": 77,
    "preview": "---\n- name: Install Slack\n  homebrew_cask:\n    name: slack\n    state: latest\n"
  },
  {
    "path": "roles/spotify/tasks/main.yml",
    "chars": 889,
    "preview": "---\n- name: Get {{ spotify_installer_path }} stats\n  stat:\n    path: \"{{ spotify_installer_path }}\"\n  register: spotify_"
  },
  {
    "path": "roles/spotify/vars/main.yml",
    "chars": 375,
    "preview": "---\nspotify_installer_archive_name: \"SpotifyInstaller.zip\"\nspotify_installer_archive_url: \"https://download.scdn.co/{{ s"
  },
  {
    "path": "roles/ssh-keys/files/mpereira@argonaut.pub",
    "chars": 743,
    "preview": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC9F1D1p7cEyChzhHO5agdMkCKUsAoi3m02LeP0vqrhMzIMsCd4mAlrxUHUmxLI3HnXaidxgpg+R33snSYJ"
  },
  {
    "path": "roles/ssh-keys/files/mpereira@pluto.pub",
    "chars": 740,
    "preview": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC8KkiSw9ADfnyTFgduupwp61FG0GHkuzaio1K3m0tx+tqlea3Xi71hHjKnH1yFx2uryYhnm54MVBR7mv4/"
  },
  {
    "path": "roles/ssh-keys/tasks/main.yml",
    "chars": 736,
    "preview": "---\n- name: Ensure .ssh directory exists.\n  file:\n    dest: \"{{ ssh_directory }}\"\n    mode: 0700\n    owner: \"{{ user }}\""
  },
  {
    "path": "roles/ssh-keys/vars/main.yml",
    "chars": 47,
    "preview": "---\nssh_directory: \"{{ home_directory }}/.ssh\"\n"
  },
  {
    "path": "roles/steam/tasks/main.yml",
    "chars": 788,
    "preview": "---\n- name: Download Steam\n  get_url:\n    url: http://media.steampowered.com/client/installer/steam.dmg\n    dest: \"{{ do"
  },
  {
    "path": "roles/stripe-cli/tasks/main.yml",
    "chars": 96,
    "preview": "---\n- name: Install Stripe CLI\n  homebrew:\n    name: stripe/stripe-cli/stripe\n    state: latest\n"
  },
  {
    "path": "roles/taglib/tasks/main.yml",
    "chars": 75,
    "preview": "---\n- name: Install taglib\n  homebrew:\n    name: taglib\n    state: present\n"
  },
  {
    "path": "roles/tealdeer/tasks/main.yml",
    "chars": 135,
    "preview": "---\n- name: Install tealdeer\n  command: >\n    cargo install tealdeer --force\n\n- name: Update tldr cache\n  command: >\n   "
  },
  {
    "path": "roles/teensy-loader/tasks/main.yml",
    "chars": 519,
    "preview": "---\n- name: Download teensy\n  get_url:\n    url: https://www.pjrc.com/teensy/teensy.dmg\n    dest: \"{{ downloads_directory"
  },
  {
    "path": "roles/terminal-notifier/tasks/main.yml",
    "chars": 96,
    "preview": "---\n- name: Install terminal-notifier\n  homebrew:\n    name: terminal-notifier\n    state: latest\n"
  },
  {
    "path": "roles/terraform/tasks/main.yml",
    "chars": 443,
    "preview": "---\n- name: Download Terraform archive\n  get_url:\n    url: \"{{ terraform_zip_url }}\"\n    dest: \"{{ downloads_directory }"
  },
  {
    "path": "roles/terraform/vars/main.yml",
    "chars": 262,
    "preview": "terraform_binary_name: \"terraform\"\nterraform_binary_arch: \"arm64\"\nterraform_zip: \"terraform_{{ terraform_version }}_darw"
  },
  {
    "path": "roles/tmux/tasks/main.yml",
    "chars": 268,
    "preview": "---\n- name: Install tmux\n  homebrew:\n    name: tmux\n    state: latest\n\n- name: Install tmux-switch-session\n  get_url:\n  "
  },
  {
    "path": "roles/tmuxinator/tasks/main.yml",
    "chars": 81,
    "preview": "---\n- name: Install tmuxinator gem\n  gem:\n    name: tmuxinator\n    state: latest\n"
  },
  {
    "path": "roles/toggle-dark-mode/files/ToggleDarkMode.app/Contents/Info.plist",
    "chars": 3486,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "roles/toggle-dark-mode/files/ToggleDarkMode.app/Contents/document.wflow",
    "chars": 3091,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "roles/toggle-dark-mode/tasks/main.yml",
    "chars": 132,
    "preview": "---\n- name: Install ToggleDarkMode.app\n  command: cp -r roles/toggle-dark-mode/files/ToggleDarkMode.app /Applications\n  "
  },
  {
    "path": "roles/tree/tasks/main.yml",
    "chars": 70,
    "preview": "---\n- name: Install tree\n  homebrew:\n    name: tree\n    state: latest\n"
  },
  {
    "path": "roles/unity/tasks/main.yml",
    "chars": 220,
    "preview": "---\n# https://github.com/DragonBox/u3d/releases\n- name: Install u3d gem\n  gem:\n    name: u3d\n    state: latest\n\n- name: "
  },
  {
    "path": "roles/unity-hub/tasks/main.yml",
    "chars": 849,
    "preview": "---\n- name: Download Unity Hub image\n  get_url: >\n    url=https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup.dm"
  },
  {
    "path": "roles/unity-hub/vars/main.yml",
    "chars": 439,
    "preview": "---\n# I get the URL by looking at the web browser \"network\" tab in the developer\n# tools.\nunity_download_assistant_dmg: "
  },
  {
    "path": "roles/usr-local-src-directory/tasks/main.yml",
    "chars": 301,
    "preview": "---\n- name: Ensure that the /usr/local/src directory exists\n  file:\n    path: /usr/local/src\n    state: directory\n    ow"
  },
  {
    "path": "roles/vagrant/tasks/main.yml",
    "chars": 1046,
    "preview": "---\n- name: Download Vagrant\n  # get_url fails to download because of a bug with SSL handling.\n  # https://github.com/an"
  },
  {
    "path": "roles/vagrant-vbguest/tasks/main.yml",
    "chars": 154,
    "preview": "- name: Install the vagrant-vbguest Vagrant plugin\n  command: >\n    vagrant plugin install vagrant-vbguest --plugin-vers"
  },
  {
    "path": "roles/vault/tasks/main.yml",
    "chars": 114,
    "preview": "---\n- name: Install vault\n  npm:\n    name: vault\n    version: \"{{ vault_version }}\"\n    global: yes\n  become: yes\n"
  },
  {
    "path": "roles/vercel/tasks/main.yml",
    "chars": 99,
    "preview": "---\n- name: Install vercel\n  npm:\n    name: vercel\n    state: latest\n    global: yes\n  become: yes\n"
  },
  {
    "path": "roles/vim/meta/main.yml",
    "chars": 39,
    "preview": "---\ndependencies:\n  - openssl\n  - llvm\n"
  },
  {
    "path": "roles/vim/tasks/main.yml",
    "chars": 1307,
    "preview": "---\n- name: Download Vim\n  command: >\n    wget \"https://ftp.nluug.nl/pub/vim/unix/vim-{{ vim_version }}.tar.bz2\"\n       "
  },
  {
    "path": "roles/virtualbox/tasks/main.yml",
    "chars": 1177,
    "preview": "---\n- name: Download VirtualBox\n  get_url:\n    url: \"http://download.virtualbox.org/virtualbox/{{ virtualbox_version }}/"
  },
  {
    "path": "roles/vlc/tasks/main.yml",
    "chars": 579,
    "preview": "---\n- name: Download VLC\n  get_url:\n    url: \"https://get.videolan.org/vlc/{{ vlc_version }}/macosx/{{ vlc_dmg }}\"\n    d"
  },
  {
    "path": "roles/vlc/vars/main.yml",
    "chars": 105,
    "preview": "---\nvlc_name: vlc-{{ vlc_version }}-intel64\nvlc_dmg: \"{{ vlc_name }}.dmg\"\nvlc_volume: \"VLC media player\"\n"
  },
  {
    "path": "roles/vscode/tasks/main.yml",
    "chars": 91,
    "preview": "---\n- name: Install VSCode\n  homebrew_cask:\n    name: visual-studio-code\n    state: latest\n"
  }
]

// ... and 65 more files (download for full content)

About this extraction

This page contains the full source code of the mpereira/macbook-playbook GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 265 files (124.2 KB), approximately 44.9k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!