Using Brewfile to Share Homebrew Configs across machines

Using Brewfile to Share Homebrew Configs across machines

Table of Contents

Introduction

I am making use of a variation of dotfiles to manage my configuration files. One of the tools I use is Homebrew, a package manager for macOS. I wanted to find a way to share my Homebrew configuration with others. I found that I could use a Brewfile to do this.

What is Brewfile?

Brewfile manages packages installed by Homebrew. It also supports brew-cask and other Homebrew subcommand installers.

What are dotfiles?

Dotfiles are hidden files in your home directory that typically contain configuration settings for applications. They are called dotfiles because their filenames begin with a dot (period). I have been using a version control process to track multiple dotfiles and share them between different machines. Homebrew config isn’t exposed by default in a dotfile and so I have inconsistent Homebrew configurations across my machines.

Install brewfile

Run the following command to install brewfile:

brew install rcmdnk/file/brew-file

Then add the following lines to your .bashrc or .zshrc file (or both):

if [ -f $(brew --prefix)/etc/brew-wrap ];then
  source $(brew --prefix)/etc/brew-wrap
fi

Brew wrap is a wrapper script for Homebrew commands. The idea being that when you run a Homebrew (un)install command, it will also update the Brewfile.

Export the Brewfile

Reload your shell and initialise brewfile:

brew init

This will review the installed packages, then output a brewfile to the default location of ~/.config/brewfile/Brewfile. With my Homebrew config stored as a dotfile, I can now commit it to my dotfiles repository and share with my other machines.

Update a new machine

Assuming machineB has a fresh install of Homebrew, you can use the brewfile to install the same configuration as your original machine (machineA) by running the following command:

brew file install

This will load the config from machineA and install all the packages listed in the brewfile on machineB.

Update an existing machine

Whilst brew file install will install the packages listed in the brewfile it doesn’t take into account consolidating packages that have already been installed on the existing machine (machineC). There are two options here:

  • bring machineC in line with machineA
  • consolidate the config of machineA and machineC

If you want to bring machineC in line with machineA, you can run the following command:

brew file update

This will grab the config of machineA, then install any missing packages and remove any packages that are not listed in the brewfile.

If you want to consolidate configs, it gets a bit more complicated. Assuming that you are using version control, currently the config of machineA will be tracked. By running brew file init on machineC, the config present on machineC will be pushed to the brewfile and will be tracked by git. You can then use git diff to evaluate the differences between the two configs and decide upon your consolidated config.

The screenshot shows a diff of a brewfile in vscode, on the left is the before pane and the right shows the changes that have been applied to it, two entries have been removed on the right hand side representing that the latest change has removed those two lines from the file, this basically means that the current machine does not have those casks installed.

In the screenshot above, the left hand side is the config from machineA and the right hand side is the config from machineC. Having run the brew file init command on machineC, the config of machineC is now being tracked by git and you can see that neither zoom or vlc are installed on machineC. I can then decide whether to bring those changes into the consolidated config or leave them out.

Review the brewfile

If you want to review the brewfile, you can run the following command:

brew file cat

# tap repositories and their packages

tap homebrew/core
brew aom
brew azure-cli
brew brotli
brew c-ares
brew ca-certificates
brew cairo
brew cascadia
brew cask
... ## clipped for brevity

Conclusion

I have found Brewfile to be a useful tool for producing a dotfile, which allows me to share my Homebrew configuration between machines. It is a simple process to export the brewfile and commit it to my dotfiles repository. I can then load the brewfile on my other machines and have a consistent Homebrew configuration across all of them.

References

#mtfbwy



Recent Posts