Skip to content


Subversion checkout URL

You can clone with
Download ZIP
An extension to Rake for dealing with a directory of inputs, a number of filters, and a directory of outputs
Pull request Compare This branch is 253 commits behind livingsocial:master.

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.



Rake::Pipeline is a system for packaging assets for deployment to the web. It uses Rake under the hood for dependency management and updating output files based on input changes.


The easiest way to use Rake::Pipeline is via a AssetFile file in the root of your project.

A sample AssetFile looks like this:

input "assets"
output "public"

files "**/*.js" do
  filter ClosureWrapper
  filter DataWrapper
  filter Rake::Pipeline::ConcatFilter, "application.js"

file "**/*.{html,css}" do
  filter DataWrapper
  filter Rake::Pipeline::ConcatFilter, "application.assets.js"

files "**/*.{png,jpg}"
files "**/index.html"
file "lib/battlemaster.js"

The available options are:

  • input: the directory containing your input files
  • output: the directory to place your output files
  • file or files: a glob pattern of files you would like to process
    • if you do not specify a block, the files will be copied over directly.
  • inside a file or files block:
    • filter: A filter that should be applied to your input. A filter is a class.
    • An optional second parameter to filter specifies what output file to use for each input. You can also specify a block, which takes the input name and returns an output name.


A filter is a simple class that inherits from Rake::Pipeline::Filter. A filter must implement a single method, called generate_output, which takes two parameters: a list of input files and the output file.

Both the input and output files are FileWrapper objects. The most important methods on a FileWrapper are:

  • path: the path of the file, relative to its input root
  • read: read the contents of the file
  • write(string): write a String to the file

For example, a simple concatenation filter would look like:

class ConcatFilter < Rake::Pipeline::Filter
  def generate_output(inputs, output)
    inputs.each do |input|

If you had a series of input files like:

  • app/javascripts/one.js
  • app/javascripts/two.js
  • app/javascripts/three.js

and you specified the ConcatFilter in your AssetFile like:

filter ConcatFilter, "application.js"

The filter would receive a single call to generate_output with an Array of FileWrappers representing each of the three files, and a FileWrapper representing application.js.

Binary Data

If your filter is operating on binary data, like images, rather than textual data, like source code, you can specify that in your filter:

class ConcatFilter < Rake::Pipeline::Filter

  def generate_output(inputs, output)
    inputs.each do |input|

This will stop Rake::Pipeline from trying to interpret the input files as UTF-8, which obviously will not work on binary data.

Built-In Filters

At the current time, Rake::Pipeline comes with a single built-in filter: Rake::Pipeline::ConcatFilter. Its implementation is the same as the ConcatFilter shown above.

You will usually use it to specify the output file for the files specified by a file or files block.

Preview Server

To start up the preview server, run rakep. This will start up a server that automatically recompiles files for you on the fly and serves up the files you need.

This should allow you to have a single index.html file pointing at the same files in both development and production.

Compiling Assets

To compile all assets before deployment, simply run:

$ rakep build


If a filter does not specify that it processes binary files, Rake::Pipeline will open all inputs and outputs as UTF-8.

This means that if you have files encoded in other encodings, like Latin-1, Rake::Pipeline will raise an exception. In this situation, you need to open the offending file in your text editor and re-save it as UTF-8.

Public Release Requirement

Before publicly releasing this code, we need to properly support encodings other than UTF-8. That means using the default_external instead of hardcoding to UTF-8 and providing a mechanism for specifying the encoding of a file using a magic comment.

Something went wrong with that request. Please try again.