Bundlerize your SASSy themes!
Nowadays many web-frontend developer use Compass framework to easily manage the CSS side of the currently developed project. We at Cheppers use Compass to compile the SASS files in our custom theme projects. If you do too, and you ever ran into an ugly circular gem file dependency problem, you definitely should use Bundler.
Bundler is a Ruby project environment to use, track and install the exact gems and versions that you need. If you have to make some small changes in a project finished 2 years ago (with many old gem dependencies) and if that one is a bundler-managed Ruby project, it doesn’t matter! You can use either an obsolete beta version of compass in an old project and use the current stable in an another without doing gem install/uninstall every time.
By defining a working collection of the used gems (and their versions) in your Drupal project you can ensure that
- the project will be operable any time
- your co-workers can easily join into a running development process
- you can develop and deploy projects without messing up your development environment’s or the production server’s globally installed gems.
$ gem install bundler
Configure your (currently working) project
To create the Gemfile for your project, run
$ bundle init
in your theme’s root directory (or where the
config.rb file is located). That directory is the root directory of your theme’s Ruby-part. To define gem dependencies, you need
- the newly created
- your theme’s
- a list of your installed gems (
$ gem list)
Add the most recent version of sass and compass in the
# A sample Gemfile
gem 'sass', '~> 3.2.12'
gem 'compass', '~> 0.12.2'
Locate all required compass plugin in your
# Content snippet of config.rb
# Require any additional compass plugins installed on your system.
Check the matching version in your gem list output of the required gems, and add the proper gem dependency in the
# Content of Gemfile
gem 'compass-rgbapng', '~> 0.2.1', :require => 'rgbapng'
gem 'susy', '~> 1.0.9'
gem 'sass-globbing', '~> 1.1.0'
Now you have to build the
Gemfile.lock file, which contains all gem dependencies for your project. After running a
$ bundle install
you should commit the
Gemfile and the
Gemfile.lock file, and you have a properly configured sassy-theme. (We use the pessimistic version constraining method in this post.)
Joining in and work with a “bundlerized” project
The low-footprint way (needed gems will be installed on your system/to your user)
Locate the root of the project, and run
$ bundle check
If you get an error message, you should run
$ bundle install
too to fix unsatisfied dependencies. If the bundle check command reports “The Gemfile's dependencies are satisfied”, you are ready to run compass through Bundler:
$ bundle exec compass compile
$bundle exec compass watch
The bullet-proof way (needed gems will be downloaded to your project)
It’s even more practical to place the needed gems right inside your project. To achieve this run bundle install with the path option.
$ bundle install --path .bundle
Bundler will download all gem-dependencies in the given path inside your project. This way you can avoid having multiple versions of gems on your system.
The self-contained way (needed gems & binaries of that)
This method is more suitable on a live server. If you complete the previous command with the --binstubs option, you can run the Ruby project from binaries (the only dependency will be Ruby itself). With the command
$ bundle install --path .bundle --binstubs
Bundler will create the “binaries” (not real binaries, but wrapper scripts for Ruby executables) for the project, and each time you make a compass compile with bundler, these scripts will be used without any other system-wide dependencies except Ruby. With the
--frozen option (the last one for now) you can ensure that any further changes of the
Gemfile.lock will be ignored in the future. (The
--deployment option does basically the same thing see
$ bundle help install
According to our experience the most usual approach for clients with web development needs is to contact multiple agencies with more or less vague ideas - asking for quotes, and then selecting a choice based on price. This approach is doomed to fail for two reasons.