Setting up a new (OS X) development machine: Part 2 - Global Package Managers

Posted on May 28, 2014 | By Matt Stauffer


Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

In the last post, we synced down our core configuration files and customized our terminal. Next we'll set up global package managers to manage our system-level (and app-level) dependencies, including installing most of our command-line and GUI apps.

Package managers are the best way to simplify the installation process, because they require minimal work from the user's perspective and provide greater flexibility, consistency, and automation of the install process than installing apps manually.

RVM (Ruby Version Manager)

If you're working with Ruby--even if it's just for Sass and Compass--you absolutely want to use a version manager. The old standby, which I'm most familiar with, is RVM, but of you're familiar with Rbenv that'll do fine as well. Either way, a Ruby version manager will make it easy to install, manage, and switch between multiple versions of Ruby on the same system.

Install RVM:

$ \curl -sSL https://get.rvm.io | bash -s stable --ruby

Now you have convenient command-line methods to install, manage, and switch to Ruby versions easily.

Learn more about how to handle your Ruby versions at RVM's site: RVM basics

Install NPM (Node Package Manager) & Node

If you're working with Node--even if it's just for Gulp or Grunt--you already know that you need Node & NPM. You technically can install these with package managers like Homebrew, but I've heard that NPM and Homebrew often battle each other and that it's worth installing it separately.

Thankfully, Node's installer packages are extremely easy to use: Install Node (Note: there is a Node Version Manager, if you need to be able to swap out versions of Node. If you're a NodeJS developer, you'll probably want to look there.)

Homebrew

Homebrew is a package manager like Composer, NPM, or RubyGems, but the apps it installs are OS X system-wide command-line (and, with the addition of cask, system-wide GUI) apps for the Mac. Almost any app you've ever installed and used from the Mac command line--php, mysql, optipng, etc.--can likely be installed and managed via Homebrew.

NOTE: Before you install Homebrew, you'll need the latest version of the Xcode command line tools. Thankfully, recent versions of OS X have started auto-prompting you to download it when you try to do anything relatively complex from the command line, so I'm not going to attempt to provide instructions for that here.

Installing Homebrew

You can visit the Homebrew home page to learn more, or just run the following command to install Homebrew:

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Installing your Homebrew packages

To install a package with Homebrew, you can do one of two things. The classic way of installing a package using Homebrew is to just pass the package (recipe) name as a parameter to the command line app:

$ brew install package_name_here

However, it's still pretty awkward and manual to paste in a massive list of packages to install using this method. So, Homebrew folks created a Brewfile, which is like a Gemfile (or composer.json, or package.json).

NOTE: The syntax and tooling for Brewfiles have changed. I hope to update this post soon, but for now look here: github/homebrew-bundle

A Brewfile is just a text file listing out all of the commands you'd like Homebrew to run in order, one command for each line.

Note: if you ever see brew tap repo_name_here, it's helpful to know that the tap command allows you to add Github repositories to your list of installable Homebrew packages. This way you can install packages that aren't a part of the core Homebrew list of available recipes.

Creating your Brewfile

Of course, since we're talking about automating here, I prefer the Brewfile option. Thoughtbot has written a great article entitled Brewfile: a Gemfile, but for Homebrew that will give you all the details you need. We'll end up with a file looking something like this:

NOTE: This entire section is now a bit out-of-date. I hope to update it very soon (would love help if you want to translate it into modern brewfile-ese for me) but if you're following this, check out the GitHub README for instructions for how it works these days.

# Matt Stauffer's awesome Brewfile
tap josegonzalez/php
tap homebrew/dupes
install openssl
install php54-mcrypt
install josegonzalez/php/composer
install wget
install optipng
install redis
install mysql
install phpunit
install postgresql

As you can tell, Homebrew just runs each line as if you had run brew tap josegonzalez/php, brew tap homebrew/dupes, brew install openssl, etc., one after another.

Now, once I've installed Homebrew, I can just navigate to the directory with my Brewfile and run brew bundle. Done.

Homebrew casks

Up until recently, Homebrew only installed command-line programs. But the homebrew-cask project allows you to manage GUI apps--that is, apps with a graphical interface like Chrome and Skype--via Homebrew as well. Recipes that are for GUI apps are called casks.

First, let's install cask:

$ brew install caskroom/cask/brew-cask

Next, let's try our first install:

$ brew cask install google-chrome

And just like that, you have Google Chrome installed. No navigating to the web site, no downloads, no mounting installers... just run brew cask install app-name and you're ready to go.

NOTE: In order to make your Casks install to sensible and predictable locations, I recommend adding the following line to your ~/.zshrc or ~/.bash_profile. export HOMEBREW_CASK_OPTS="--appdir=/Applications"

But that can still take a while. If only we could have some sort of file that listed out all of our casks. Something like... a Caskfile. Yes! There's a Caskfile! Can our lives get any easier here?

There's actually no difference between a Caskfile and a Brewfile, which means we'll need to preface all of our lines with cask--but, that means we can even install cask within our caskfile!

Check it out:

# Matt's awesome caskfile
# Install Cask
install caskroom/cask/brew-cask

# Install Casks
cask install alfred
cask install caffeine
cask install flux

cask install virtualbox
cask install vagrant

cask install google-chrome
cask install iterm2
cask install phpstorm
cask install sequel-pro
cask install macvim

cask install adium
cask install nvalt
cask install rdio
cask install slack
cask install textexpander
cask install vlc
cask install the-unarchiver

If you want to run brew bundle on a file that's not named Brewfile, just append the file to the end of the command:

$ brew bundle Caskfile

That's it! As you can tell, a Caskfile is really just a Brewfile that we decided to give a different name and a focused set of commands.

Now that I showed you how to create a separate Caskfile, I'm going to flip the script: You could just move your entire Caskfile up into your Brewfile above, run it, and call it a day. Single file installs everything.

Matt's Sample Brewfile

# Matt Stauffer's awesome Brewfile With Casks
tap josegonzalez/php
tap homebrew/dupes
install openssl
install php54-mcrypt
install josegonzalez/php/composer
install wget
install optipng
install redis
install mysql
install phpunit
install postgresql

# Install Cask
install caskroom/cask/brew-cask

# Install Casks
cask install alfred
cask install caffeine
cask install flux

cask install virtualbox
cask install vagrant

cask install google-chrome
cask install iterm2
cask install phpstorm
cask install sequel-pro

cask install adium
cask install nvalt
cask install rdio
cask install slack
cask install textexpander

We now have a single Brewfile that will cover 75% of the apps you need to operate your computer, all with one simple install.

Do you have any favorite casks or essential Homebrew recipes that I missed? Shout out on Twitter.

In my next post I'll talk about creating and syncing dotfiles across your computers, and a Brewfile (or a Caskfile) would be a perfect candidate for that.


Comments? I'm @stauffermatt on Twitter


Tags: homebrew  •  cask  •  osx  •  npm  •  node  •  rvm