Managing Compass Extensions with Bundler

I love hearing about new Compass and Sass tools and am always chomping at the bit to try them out. That can turn into a pain if I, or anyone else, update to the latest, greatest new gem hotness and get out of sync with the rest of the team. Managing versions can turn into a pain, but it doesn't have to.

Often what happens is you need to make a change to an existing project. A simple change. Just change an page title's font size, for example. You clone the repository; update the font size; run compass compile and BAMM! Crazy warnings about such and such being deprecated or errors regarding an "Undefined mixin." Or maybe there are no errors at all, but when you do your pre-commit git diff (you're such a good developer), you see way more line changes than that font-size.

Either way, that simple change is now less straightforward and a more time-consuming problem to sort out. 9 times out of 10, these hiccups come from inconsistencies between your development environment and the one used to compile Sass the last time. It could be a coworker's version. It could be yours from 6 months ago. I'm not pointing fingers.

There's an easy solution. Compile with Bundler. Bundler is a rubygem manager that helps keep track of project gem dependencies.

Install Bundler

First things first. Open your terminal and run this command.

$ gem install bundler

That's it!

Create a Gemfile

Bundler requires a file named Gemfile in your Compass project's root directory (same directory as config.rb.) The Gemfile is project-specific and lists out which versions of which gems this project requires and where to find those gems to install them.

source "https://rubygems.org"
 
gem 'sass', "3.2.9"
gem 'sass-globbing', ">= 1.1.0"
gem 'compass', "0.12.2"
gem 'breakpoint',  "2.0.5"
gem 'singularitygs', "< 2.0.0"

This Gemfile declares the source of our gems to be https://rubygems.org, should you need to fetch them. It then lists all the necessary gem versions for this project.

In the above sample file we are saying we need

When creating a new Gemfile, you can see what gem versions you currently have installed by running:

$ gem list

This will list the gems you have installed on your machine, which is probably more than the project needs. So you'll need to manually determine which ones are needed and write those lines into the Gemfile.

Bundle Exec

Once you have your Gemfile saved in the project root, you simply run compass' compile commands through bundle exec instead of calling them directly. Like so:

$ bundle exec compass watch

or

$ bundle exec compass compile

Before running compass watch or compile, Bundle exec checks your project's gem dependencies and makes sure the gems installed on your machine meet the requirements. If they don't, it won't execute the compass commands.

Bundle Install

If you have gems installed that meet the version requirements declared in your Gemfile, then compass will compile as normal. Otherwise you'll get a warning like

Could not find [name-of-gem]-x.x.x in any of the sources
Run <code>bundle install</code> to install missing gems.

"Thanks for that friendly error message, computer. I will run that command." says you.

$ bundle install

How fun was that!? Bundler install just installed the latest versions of your missing gems that meet your project's requirements.

Bundler also creates a file called Gemfile.lock, which is a cache of sorts that keeps track of dependencies for the project so it doesn't have to go to the source everytime. Which can take a while. For a simple compass project you'll want to commit that file to the project as well. Check out this article If you want to learn more about the Gemfile.lock file.

Bundle Update

Now let's say you have version 1.1.0 of Singularity installed, but the most recent 1.1.2 version has some bug fixes. Version 1.1.0 meets the project requirements of being less than v. 2.0.0 so it's OK as far as Bundler is concerned. However, you want the new hot features. So you run:

$ bundle update singularitygs

Bundle update will update your Singularity gem to the latest available version that meets your Gemfile's requirements and updates Gemfile.lock so the next person to check out this repo and run bundle install will install the updated gems as well.

Bonus Round: Aliases

If you find typing bundle exec compass watch a bit much to type, you can create aliases for it in your shell of choice. Add these lines to your .bash_profile or .zshrc file, depending on if your shell is bash or zsh.

alias bcw='bundle exec compass watch'
alias bcc='bundle exec compass compile'
alias bi='bundle install'
alias bu='bundle update'

Then run one of the following to update your current session with the new aliases.

$ source ~/.zshrc

or

$ source ~/.bash_profile

As you can see, setting up a Compass project with Bundler is super easy and will save you and your team a lot of time and confusion in the long run. But more importantly, it will free you up to use whatever shiny new Compass tool is out there without fear of gems getting out of sync.

Code

Read This Next