Introduction
To be able to have a consistent experience between my laptop at home, and the one I use at work, I try to have as much
of my configuration as possible under source control. Hence, I have a large repository with different types of
configuration files, and shell scripts for symlinking them.
I also keep scripts for managing my installed applications, and in this post I'll share some parts of the script I
use for installing applications on macOS.
At the beginning of the script, I ensure that Homebrew is installed:
# Install homebrew if it doesn't exist.if test ! $(which brew); then /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/$USER/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)"fi
If you are unfamiliar with Homebrew, it divides programs into two categories. Programs with a GUI are called
casks. Below, I have created two arrays where I list both the casks and the regular packages that I wish to
install:
# Packages we want to have installedWANTED_PACKAGES=(
awscli
btop
coreutils
direnv
dive
dockutil
efm-langserver
flyctl
fzf
git-crypt
git-lfs
gnupg
go
golang-migrate
goreleaser
hey
hugo
jq
mongodb-community
ncdu
neovim
orlangure/tap/gocovsh
pnpm
postgresql
protobuf
ripgrep
rust
starship
tfenv
tig
tldr
tmux
tree
volta
wget
youtube-dl
zsh-autosuggestions
zsh-syntax-highlighting
)
# Casks we want to have installedWANTED_CASKS=(
1password
1password-cli
amethyst
centered
discord
figma
firefox
firefox-developer-edition
goland
google-chrome
insomnia
kap
kitty
mongodb-compass
monodraw
nordvpn
obsidian
postman
raycast
redisinsight
slack
spotify
vlc
)
For subsequent runs of the script, I don't want to add a bunch of noise by trying to install the same application over
and over again. Therefore, I filter out the wanted packages against the ones that I have installed already:
# Already installed packages and casksINSTALLED_PACKAGES=$(brew leaves)
INSTALLED_CASKS=$(brew list --cask)
# Remove the packages that we already have installed from WANTED_PACKAGESfor index in "${!WANTED_PACKAGES[@]}"; do if [[ "${INSTALLED_PACKAGES[*]}" =~ "${WANTED_PACKAGES[$index]}" ]]; then unset -v WANTED_PACKAGES[$index] fidone# Remove the casks that we already have installed from WANTED_CASKSfor index in "${!WANTED_CASKS[@]}"; do if [[ "${INSTALLED_CASKS[*]}" =~ "${WANTED_CASKS[$index]}" ]]; then unset -v WANTED_CASKS[$index] fidone
Most packages are included in the global homebrew formula. However, there are some that require us to add
third-party repositories. To add third-party repositories, we use brew tap <repository>.
# Add third party repositoriesbrew tap mongodb/brew
brew tap homebrew/cask-versions
brew tap homebrew/cask-fonts
At this point we are ready to update homebrew, upgrade any of our existing packages, and install new ones:
# Make sure that homebrew is using the latest formulabrew update
# Upgrade any existing applications# NOTE: If we want to lock a package to a specific version we can use "brew pin"brew upgrade
# Install missing packagesif [ ${#WANTED_PACKAGES[@]} -eq 0 ]; then echo "All packages are already installed"else brew install ${WANTED_PACKAGES[@]}fi# Install missing casksif [ ${#WANTED_CASKS[@]} -eq 0 ]; then echo "All casks are already installed"else brew install ${WANTED_CASKS[@]} --caskfi
If you want to see more of my scripts, you can check out my repository on GitHub. I continuously add new
scripts for things such as setting up folder structures, generating SSH keys, orchestraiting docker containers,
managing my tmux sessions, and so on.
The end
I usually tweet something when I've finished writing a new post. You can find me on Twitter
by clickingÂ