A simplified rewrite of Yehuda Katz & Tom Dale's awesome rake-pipeline gem.

...documentation / server / executable / assetfile support / tests etc coming.

A trip through the extruder looks like this:

  1. Define input directories to be processed.
  2. Define output directory for processed files.
  3. Define matches with file globs (ie: *.js) to determine which files from the input directories will be processed.
  4. Define filters within each match block that will process files.
  5. When processing an Extruder instance, the first step is to create a FileSet of eligible files from the input directories.
  6. As each match block is opened, the files that matched the glob are removed from the FileSet and passed in.
  7. As each filter is run, the files created by the previous filter are passed on to the next.
  8. As each match block is closed, the filter-created/modified files are added to the Extruder's FileSet.
  9. After the final match block has run, FileSet.create is called, writing the filtered files to disk.

Extruder layout:

inputs      => {'app/js'=>'*/**','app/css'=>'*/**'},
output_root => 'build',
matches     => [
  { glob: "*.js", filters: [<ConcatFilter>] },
  { glob: "*.txt", filters: [<ClosureFilter>,<CopyFilter>,<CopyFilter>] }
]

New concepts

FileSets contain an array of FileWrappers. A FileSet instance has a glob value (ie: *.js) which is transformed into a regular expression that can be used to determine which files match. An array of matching FileWrappers can be retrieved any time by calling the instance function 'eligible_files'

FileWrappers write to the instance variable @contents until the instance function create is called, at which point @contents is dumped to the output_root+path.

All filtering occurs in memory.

Junky proof of concept trial run:

  1. Build and install gem
  2. Grab the emberjs/todos repo
  3. Load irb in its root
  4. Run this
require 'extruder'
require 'json'
class ClosureFilter < Extruder::Filter
  def generate_output(inputs, output)
    inputs.each do |input|
      output.write "(function() { #{input.read.to_json} })()"
    end
  end
end

extruder = Extruder.build do
  input "app"
  output "output"
  match "*.js" do
    concat "test.txt"
  end
  match "*.txt" do
    filter ClosureFilter
    copy "1.txt"
    copy "2.txt"
  end
end

# show resulting fileset
extruder.result

# save resulting fileset
extruder.result.create