Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base: f697fb6585
...
compare: d821391ac6
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 7 files changed
  • 0 commit comments
  • 1 contributor
Commits on Mar 24, 2012
@wycats Add docs for ChainedFilter
bbc5e88
@wycats Add #register to ProjectHelper
This feature makes it possible to register that a
file extension should be processed using a
specified filter.

It is implemented by adding a before_filter to all
PipelineDSLs that use the ChainedFilter to
process input files before they are passed to the
rest of the filters.
d821391
View
3  Gemfile
@@ -3,5 +3,6 @@ source "http://rubygems.org"
# Specify your gem's dependencies in rake-pipeline-web-filters.gemspec
gemspec
-gem "rake-pipeline", :git => "git://github.com/livingsocial/rake-pipeline.git"
+gem "rake-pipeline", :path => "~/Code/rake-pipeline"
+#gem "rake-pipeline", :git => "git://github.com/livingsocial/rake-pipeline.git"
gem "pry"
View
1  Rakefile
@@ -1,5 +1,6 @@
#!/usr/bin/env rake
require "bundler/gem_tasks"
+require "bundler/setup"
desc "run the specs"
task :spec do
View
49 lib/rake-pipeline-web-filters/chained_filter.rb
@@ -1,4 +1,8 @@
module Rake::Pipeline::Web::Filters
+ # Implement the FileWrapper API. Because filters are defined
+ # in terms of the FileWrapper API, we can implement an
+ # alternative that doesn't write to disk but still utilizes
+ # the same filter definitions.
class MemoryFileWrapper < Struct.new(:root, :path, :encoding, :body)
def with_encoding(new_encoding)
self.class.new(root, path, new_encoding, body)
@@ -20,7 +24,42 @@ def write(contents)
end
end
+ # The purpose of ChainedFilter is to enable filters to
+ # be applied to files based upon their file extensions.
+ #
+ # Filters are applied repeatedly to files for each
+ # extension.
+ #
+ # @example
+ #
+ # filter ChainedFilter, :types => {
+ # :erb => ErbFilter,
+ # :coffee => CoffeeFilter,
+ # :scss => ScssFilter
+ # }
+ #
+ # In this example, files with the extensions +erb+,
+ # +coffee+, and +scss+ will be processed using the
+ # specified filters. If a file has multiple extensions,
+ # all of the filters will be applied.
+ #
+ # For example, with the above filter specification,
+ # a file like +application.js.coffee.erb+ will first
+ # apply the +ErbFilter+, then the +CoffeeFilter+, and
+ # then output +application.js+.
+ #
+ # This filter is largely designed for use with the
+ # {ProjectHelpers#register register} helper, which
+ # will transparently add a ChainedFilter before each
+ # input block with the registered extensions.
class ChainedFilter < Rake::Pipeline::Filter
+ attr_reader :filters
+
+ # @param [Hash] options
+ # @option options [Hash] :types
+ # A hash of file extensions and their associated
+ # filters. See the class description for more
+ # information.
def initialize(options={}, &block)
@filters = options[:types]
@@ -35,12 +74,19 @@ def initialize(options={}, &block)
super(&block)
end
+ # @private
+ #
+ # Implement +generate_output+
def generate_output(inputs, output)
inputs.each do |input|
output.write process_filters(input)
end
end
+ # @private
+ #
+ # Process an input file by applying the filter for each
+ # extension in the file.
def process_filters(input)
keys = input.path.match(@pattern)[0].scan(/(?<=\.)\w+/)
@@ -55,6 +101,9 @@ def process_filters(input)
input.read
end
+ # @private
+ #
+ # Process an individual file with a filter.
def process_with_filter(input, filter_class)
filter = filter_class.new
View
26 lib/rake-pipeline-web-filters/helpers.rb
@@ -13,7 +13,7 @@ module Rake::Pipeline::Web::Filters
# match("*.scss") do
# sass :syntax => :sass
# end
- module Helpers
+ module PipelineHelpers
# Add a new {MinispadeFilter} to the pipeline.
# @see MinispadeFilter#initialize
def minispade(*args, &block)
@@ -81,6 +81,28 @@ def handlebars(*args, &block)
filter(Rake::Pipeline::Web::Filters::HandlebarsFilter, *args, &block)
end
end
+
+ module ProjectHelpers
+ # Register a filter class for a particular file extension
+ # and add a ChainedFilter as a before filter.
+ #
+ # If this is the first use of +register+, it will set up
+ # the before filter. Subsequent uses will just update the
+ # types hash.
+ #
+ # @see ChainedFilter
+ def register(extension, klass)
+ if @types_hash
+ @types_hash[extension] = klass
+ else
+ @types_hash = { extension => klass }
+ before_filter ChainedFilter, { :types => @types_hash }
+ end
+ end
+ end
end
-Rake::Pipeline::DSL::PipelineDSL.send(:include, Rake::Pipeline::Web::Filters::Helpers)
+require "rake-pipeline/dsl"
+
+Rake::Pipeline::DSL::PipelineDSL.send(:include, Rake::Pipeline::Web::Filters::PipelineHelpers)
+Rake::Pipeline::DSL::ProjectDSL.send(:include, Rake::Pipeline::Web::Filters::ProjectHelpers)
View
10 spec/coffee_script_filter_spec.rb
@@ -40,6 +40,10 @@ def output_file(name)
MemoryFileWrapper.new("/path/to/output", name, "UTF-8")
end
+ def should_match(expected, output)
+ "#{expected}\n".gsub(/\n+/, "\n").should == "#{output}\n".gsub(/\n+/, "\n")
+ end
+
def setup_filter(filter)
filter.file_wrapper_class = MemoryFileWrapper
filter.input_files = [input_file("input.coffee", coffee_input)]
@@ -57,7 +61,7 @@ def setup_filter(filter)
tasks.each(&:invoke)
file = MemoryFileWrapper.files["/path/to/output/input.js"]
- file.body.should == expected_coffee_output
+ should_match file.body, expected_coffee_output
file.encoding.should == "UTF-8"
end
@@ -70,7 +74,7 @@ def setup_filter(filter)
tasks.each(&:invoke)
file = MemoryFileWrapper.files["/path/to/output/input.js"]
- file.body.should == expected_unwrapped_coffee_output
+ should_match file.body, expected_unwrapped_coffee_output
file.encoding.should == "UTF-8"
end
@@ -98,7 +102,7 @@ def setup_filter(filter)
tasks = filter.generate_rake_tasks
lambda {
tasks.each(&:invoke)
- }.should raise_error(ExecJS::RuntimeError, "Error compiling input.coffee. reserved word \"function\" on line 1")
+ }.should raise_error(ExecJS::RuntimeError, /Error compiling input.coffee. reserved word "function" on line 1/i)
end
end
View
32 spec/helpers_spec.rb
@@ -90,3 +90,35 @@ def filter
end
end
end
+
+describe "ProjectHelpers" do
+ def project
+ @project ||= Rake::Pipeline::Project.new
+ end
+
+ def dsl
+ @dsl ||= Rake::Pipeline::DSL::ProjectDSL.new(project)
+ end
+
+ describe "register" do
+ it "registers filters per file name" do
+ dsl.register :coffee, Rake::Pipeline::Web::Filters::CoffeeScriptFilter
+ dsl.register :handlebars, Rake::Pipeline::Web::Filters::HandlebarsFilter
+
+ dsl.input "lib" do
+ concat "lib.js"
+ end
+
+ dsl.input "tests" do
+ concat "tests.js"
+ end
+
+ project.pipelines.size.should == 2
+
+ project.pipelines.each do |pipeline|
+ pipeline.filters.first.should be_kind_of Rake::Pipeline::Web::Filters::ChainedFilter
+ pipeline.filters.first.filters.keys.should == [:coffee, :handlebars]
+ end
+ end
+ end
+end
View
2  spec/spec_helper.rb
@@ -1,6 +1,6 @@
+require "pry"
require "rake-pipeline"
require "rake-pipeline-web-filters"
-require "pry"
class Rake::Pipeline
module SpecHelpers

No commit comments for this range

Something went wrong with that request. Please try again.