rake-pipeline-web-filters 0.5.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +1 -0
- data/Rakefile +8 -0
- data/lib/rake-pipeline-web-filters.rb +17 -3
- data/lib/rake-pipeline-web-filters/cache_buster_filter.rb +42 -0
- data/lib/rake-pipeline-web-filters/chained_filter.rb +116 -0
- data/lib/rake-pipeline-web-filters/coffee_script_filter.rb +41 -0
- data/lib/rake-pipeline-web-filters/filter_with_dependencies.rb +27 -0
- data/lib/rake-pipeline-web-filters/gzip_filter.rb +59 -0
- data/lib/rake-pipeline-web-filters/handlebars_filter.rb +62 -0
- data/lib/rake-pipeline-web-filters/helpers.rb +100 -18
- data/lib/rake-pipeline-web-filters/iife_filter.rb +38 -0
- data/lib/rake-pipeline-web-filters/less_filter.rb +55 -0
- data/lib/rake-pipeline-web-filters/markdown_filter.rb +70 -0
- data/lib/rake-pipeline-web-filters/minispade_filter.rb +21 -5
- data/lib/rake-pipeline-web-filters/neuter_filter.rb +110 -0
- data/lib/rake-pipeline-web-filters/sass_filter.rb +87 -0
- data/lib/rake-pipeline-web-filters/stylus_filter.rb +59 -0
- data/lib/rake-pipeline-web-filters/tilt_filter.rb +16 -3
- data/lib/rake-pipeline-web-filters/uglify_filter.rb +66 -0
- data/lib/rake-pipeline-web-filters/version.rb +1 -1
- data/lib/rake-pipeline-web-filters/yui_css_filter.rb +70 -0
- data/lib/rake-pipeline-web-filters/yui_javascript_filter.rb +59 -0
- data/rake-pipeline-web-filters.gemspec +10 -1
- data/spec/cache_buster_filter_spec.rb +105 -0
- data/spec/chained_filter_spec.rb +76 -0
- data/spec/coffee_script_filter_spec.rb +110 -0
- data/spec/gzip_filter_spec.rb +49 -0
- data/spec/handlebars_filter_spec.rb +70 -0
- data/spec/helpers_spec.rb +112 -18
- data/spec/iife_filter_spec.rb +55 -0
- data/spec/less_filter_spec.rb +59 -0
- data/spec/markdown_filter_spec.rb +86 -0
- data/spec/minispade_filter_spec.rb +47 -15
- data/spec/neuter_filter_spec.rb +204 -0
- data/spec/sass_filter_spec.rb +147 -0
- data/spec/spec_helper.rb +10 -1
- data/spec/stylus_filter_spec.rb +69 -0
- data/spec/tilt_filter_spec.rb +25 -1
- data/spec/uglify_filter_spec.rb +82 -0
- data/spec/yui_css_filter_spec.rb +88 -0
- data/spec/yui_javascript_filter_spec.rb +68 -0
- metadata +225 -19
- data/lib/rake-pipeline-web-filters/ordering_concat_filter.rb +0 -38
- data/lib/rake-pipeline-web-filters/sass_compiler.rb +0 -53
- data/spec/ordering_concat_filter_spec.rb +0 -39
- data/spec/sass_compiler_spec.rb +0 -89
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'rake-pipeline-web-filters/filter_with_dependencies'
|
2
2
|
|
3
3
|
module Rake::Pipeline::Web::Filters
|
4
4
|
# A filter that accepts a series of inputs and translates
|
@@ -6,6 +6,8 @@ module Rake::Pipeline::Web::Filters
|
|
6
6
|
# to guess which template language to use based on the input
|
7
7
|
# file extension.
|
8
8
|
#
|
9
|
+
# Requires {http://rubygems.org/gems/tilt/ tilt}
|
10
|
+
#
|
9
11
|
# @example
|
10
12
|
# !!!ruby
|
11
13
|
# Rake::Pipeline.build do
|
@@ -19,17 +21,24 @@ module Rake::Pipeline::Web::Filters
|
|
19
21
|
# end
|
20
22
|
# end
|
21
23
|
class TiltFilter < Rake::Pipeline::Filter
|
24
|
+
include Rake::Pipeline::Web::Filters::FilterWithDependencies
|
25
|
+
|
22
26
|
# @return [Hash] a hash of options to pass to Tilt
|
23
27
|
# when rendering.
|
24
28
|
attr_reader :options
|
25
29
|
|
30
|
+
# @return [Object] an object to use as the rendering
|
31
|
+
# context.
|
32
|
+
attr_reader :context
|
33
|
+
|
26
34
|
# @param [Hash] options options to pass to the Tilt
|
27
35
|
# template class constructor.
|
28
36
|
# @param [Proc] block a block to use as the Filter's
|
29
37
|
# {#output_name_generator}.
|
30
|
-
def initialize(options={}, &block)
|
38
|
+
def initialize(options={}, context = nil, &block)
|
31
39
|
super(&block)
|
32
40
|
@options = options
|
41
|
+
@context = context || Object.new
|
33
42
|
end
|
34
43
|
|
35
44
|
# Implement the {#generate_output} method required by
|
@@ -45,7 +54,7 @@ module Rake::Pipeline::Web::Filters
|
|
45
54
|
def generate_output(inputs, output)
|
46
55
|
inputs.each do |input|
|
47
56
|
out = if (template_class = Tilt[input.path])
|
48
|
-
template_class.new(nil, 1, options) { |t| input.read }.render
|
57
|
+
template_class.new(nil, 1, options) { |t| input.read }.render(context)
|
49
58
|
else
|
50
59
|
input.read
|
51
60
|
end
|
@@ -53,5 +62,9 @@ module Rake::Pipeline::Web::Filters
|
|
53
62
|
output.write out
|
54
63
|
end
|
55
64
|
end
|
65
|
+
|
66
|
+
def external_dependencies
|
67
|
+
[ 'tilt' ]
|
68
|
+
end
|
56
69
|
end
|
57
70
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'rake-pipeline-web-filters/filter_with_dependencies'
|
2
|
+
|
3
|
+
module Rake::Pipeline::Web::Filters
|
4
|
+
# A filter that uses the Uglify JS compressor to compress
|
5
|
+
# JavaScript input files.
|
6
|
+
#
|
7
|
+
# Requires {http://rubygems.org/gems/uglifier uglifier}.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# !!!ruby
|
11
|
+
# Rake::Pipeline.build do
|
12
|
+
# input "app/assets", "**/*.js"
|
13
|
+
# output "public"
|
14
|
+
#
|
15
|
+
# # Compile each JS file under the app/assets
|
16
|
+
# # directory.
|
17
|
+
# filter Rake::Pipeline::Web::Filters::UglifyFilter
|
18
|
+
# end
|
19
|
+
class UglifyFilter < Rake::Pipeline::Filter
|
20
|
+
include Rake::Pipeline::Web::Filters::FilterWithDependencies
|
21
|
+
|
22
|
+
# @return [Hash] a hash of options to pass to Uglify
|
23
|
+
# when compiling.
|
24
|
+
attr_reader :options
|
25
|
+
|
26
|
+
# @param [Hash] options options to pass to Uglify
|
27
|
+
# @param [Proc] block a block to use as the Filter's
|
28
|
+
# {#output_name_generator}.
|
29
|
+
def initialize(options={}, &block)
|
30
|
+
block ||= proc { |input|
|
31
|
+
if input =~ %r{min.js$}
|
32
|
+
input
|
33
|
+
else
|
34
|
+
input.sub(/\.js$/, '.min.js')
|
35
|
+
end
|
36
|
+
}
|
37
|
+
|
38
|
+
super(&block)
|
39
|
+
@options = options
|
40
|
+
end
|
41
|
+
|
42
|
+
# Implement the {#generate_output} method required by
|
43
|
+
# the {Filter} API. Compiles each input file with Uglify.
|
44
|
+
#
|
45
|
+
# @param [Array<FileWrapper>] inputs an Array of
|
46
|
+
# {FileWrapper} objects representing the inputs to
|
47
|
+
# this filter.
|
48
|
+
# @param [FileWrapper] output a single {FileWrapper}
|
49
|
+
# object representing the output.
|
50
|
+
def generate_output(inputs, output)
|
51
|
+
inputs.each do |input|
|
52
|
+
if input.path =~ %r{min.js$}
|
53
|
+
output.write input.read
|
54
|
+
else
|
55
|
+
output.write Uglifier.compile(input.read, options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def external_dependencies
|
63
|
+
[ 'uglifier' ]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rake-pipeline-web-filters/filter_with_dependencies'
|
2
|
+
|
3
|
+
module Rake::Pipeline::Web::Filters
|
4
|
+
# A filter that compresses CSS input files using
|
5
|
+
# the YUI CSS compressor.
|
6
|
+
#
|
7
|
+
# Requires {https://rubygems.org/gems/yui-compressor yui-compressor}
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# !!!ruby
|
11
|
+
# Rake::Pipeline.build do
|
12
|
+
# input "app/assets", "**/*.js"
|
13
|
+
# output "public"
|
14
|
+
#
|
15
|
+
# # Compress each CSS file under the app/assets
|
16
|
+
# # directory.
|
17
|
+
# filter Rake::Pipeline::Web::Filters::YUICssFilter
|
18
|
+
# end
|
19
|
+
class YUICssFilter < Rake::Pipeline::Filter
|
20
|
+
include Rake::Pipeline::Web::Filters::FilterWithDependencies
|
21
|
+
|
22
|
+
# @return [Hash] a hash of options to pass to the
|
23
|
+
# YUI compressor when compressing.
|
24
|
+
attr_reader :options
|
25
|
+
|
26
|
+
# @param [Hash] options options to pass to the YUI
|
27
|
+
# CSS compressor.
|
28
|
+
# @param [Proc] block a block to use as the Filter's
|
29
|
+
# {#output_name_generator}.
|
30
|
+
def initialize(options={}, &block)
|
31
|
+
block ||= proc { |input|
|
32
|
+
if input =~ %r{min.css$}
|
33
|
+
input
|
34
|
+
else
|
35
|
+
input.sub /\.css$/, '.min.css'
|
36
|
+
end
|
37
|
+
}
|
38
|
+
|
39
|
+
super(&block)
|
40
|
+
@options = options
|
41
|
+
end
|
42
|
+
|
43
|
+
# Implement the {#generate_output} method required by
|
44
|
+
# the {Filter} API. Compresses each input file with
|
45
|
+
# the YUI CSS compressor.
|
46
|
+
#
|
47
|
+
# @param [Array<FileWrapper>] inputs an Array of
|
48
|
+
# {FileWrapper} objects representing the inputs to
|
49
|
+
# this filter.
|
50
|
+
# @param [FileWrapper] output a single {FileWrapper}
|
51
|
+
# object representing the output.
|
52
|
+
def generate_output(inputs, output)
|
53
|
+
compressor = YUI::CssCompressor.new(options)
|
54
|
+
inputs.each do |input|
|
55
|
+
if input.path !~ /min\.css/
|
56
|
+
output.write compressor.compress(input.read)
|
57
|
+
else
|
58
|
+
output.write input.read
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def external_dependencies
|
66
|
+
[ 'yui/compressor' ]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rake-pipeline-web-filters/filter_with_dependencies'
|
2
|
+
|
3
|
+
module Rake::Pipeline::Web::Filters
|
4
|
+
# A filter that compresses JavaScript input files using
|
5
|
+
# the YUI JavaScript compressor.
|
6
|
+
#
|
7
|
+
# Requires {https://rubygems.org/gems/yui-compressor yui-compressor}
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# !!!ruby
|
11
|
+
# Rake::Pipeline.build do
|
12
|
+
# input "app/assets", "**/*.js"
|
13
|
+
# output "public"
|
14
|
+
#
|
15
|
+
# # Compress each JS file under the app/assets
|
16
|
+
# # directory.
|
17
|
+
# filter Rake::Pipeline::Web::Filters::YUIJavaScriptFilter
|
18
|
+
# end
|
19
|
+
class YUIJavaScriptFilter < Rake::Pipeline::Filter
|
20
|
+
include Rake::Pipeline::Web::Filters::FilterWithDependencies
|
21
|
+
|
22
|
+
# @return [Hash] a hash of options to pass to the
|
23
|
+
# YUI compressor when compressing.
|
24
|
+
attr_reader :options
|
25
|
+
|
26
|
+
# @param [Hash] options options to pass to the YUI
|
27
|
+
# JavaScript compressor.
|
28
|
+
# @param [Proc] block a block to use as the Filter's
|
29
|
+
# {#output_name_generator}.
|
30
|
+
def initialize(options={}, &block)
|
31
|
+
block ||= proc { |input| input.sub(/\.js$/, '.min.js') }
|
32
|
+
super(&block)
|
33
|
+
@options = options
|
34
|
+
end
|
35
|
+
|
36
|
+
# Implement the {#generate_output} method required by
|
37
|
+
# the {Filter} API. Compresses each input file with
|
38
|
+
# the YUI JavaScript compressor.
|
39
|
+
#
|
40
|
+
# @param [Array<FileWrapper>] inputs an Array of
|
41
|
+
# {FileWrapper} objects representing the inputs to
|
42
|
+
# this filter.
|
43
|
+
# @param [FileWrapper] output a single {FileWrapper}
|
44
|
+
# object representing the output.
|
45
|
+
def generate_output(inputs, output)
|
46
|
+
compressor = YUI::JavaScriptCompressor.new(options)
|
47
|
+
inputs.each do |input|
|
48
|
+
output.write compressor.compress(input.read)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def external_dependencies
|
55
|
+
[ 'yui/compressor' ]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -15,10 +15,19 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Rake::Pipeline::Web::Filters::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency "rake-pipeline"
|
18
|
+
gem.add_dependency "rake-pipeline", "~> 0.6"
|
19
|
+
gem.add_dependency "rack"
|
19
20
|
|
20
21
|
gem.add_development_dependency "rspec"
|
21
22
|
gem.add_development_dependency "tilt"
|
22
23
|
gem.add_development_dependency "sass"
|
23
24
|
gem.add_development_dependency "compass"
|
25
|
+
gem.add_development_dependency "coffee-script"
|
26
|
+
gem.add_development_dependency "redcarpet", '~> 2.0'
|
27
|
+
gem.add_development_dependency "yui-compressor"
|
28
|
+
gem.add_development_dependency "uglifier"
|
29
|
+
gem.add_development_dependency "less"
|
30
|
+
gem.add_development_dependency "json"
|
31
|
+
gem.add_development_dependency "therubyracer"
|
32
|
+
gem.add_development_dependency "stylus"
|
24
33
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
describe "CacheBusterFilter" do
|
2
|
+
MemoryFileWrapper ||= Rake::Pipeline::SpecHelpers::MemoryFileWrapper
|
3
|
+
CacheBusterFilter ||= Rake::Pipeline::Web::Filters::CacheBusterFilter
|
4
|
+
|
5
|
+
let(:content) { "it doesn't matter" }
|
6
|
+
|
7
|
+
let(:input_file) {
|
8
|
+
MemoryFileWrapper.new '/path/to/input', 'file.txt', 'UTF-8', content
|
9
|
+
}
|
10
|
+
|
11
|
+
let(:output_root) {
|
12
|
+
'/path/to/output'
|
13
|
+
}
|
14
|
+
|
15
|
+
def setup_filter(filter)
|
16
|
+
filter.file_wrapper_class = MemoryFileWrapper
|
17
|
+
filter.input_files = [ input_file ]
|
18
|
+
filter.output_root = output_root
|
19
|
+
filter.rake_application = Rake::Application.new
|
20
|
+
filter
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'DEFAULT_KEY_GENERATOR' do
|
24
|
+
|
25
|
+
subject { CacheBusterFilter::DEFAULT_KEY_GENERATOR }
|
26
|
+
|
27
|
+
it "returns the MD5 hash of the input's file name and contents" do
|
28
|
+
expected = Digest::MD5.new << input_file.path << content
|
29
|
+
subject.call(input_file).should == expected
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'with the default cache key strategy' do
|
35
|
+
|
36
|
+
let(:output_file) {
|
37
|
+
key = CacheBusterFilter::DEFAULT_KEY_GENERATOR.call(input_file)
|
38
|
+
MemoryFileWrapper.new output_root, "file-#{key}.txt", 'UTF-8'
|
39
|
+
}
|
40
|
+
|
41
|
+
subject { setup_filter CacheBusterFilter.new }
|
42
|
+
|
43
|
+
it 'outputs to the MD5 hash of the file name and contents' do
|
44
|
+
subject.output_files.should == [ output_file ]
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'passes file contents through unchanged' do
|
48
|
+
tasks = subject.generate_rake_tasks
|
49
|
+
tasks.each(&:invoke)
|
50
|
+
file = MemoryFileWrapper.files[ output_file.fullpath ]
|
51
|
+
file.body.should == content
|
52
|
+
file.encoding.should == 'UTF-8'
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'with a custom key strategy' do
|
58
|
+
|
59
|
+
let(:output_file) {
|
60
|
+
MemoryFileWrapper.new output_root, 'file-foo.txt', 'UTF-8'
|
61
|
+
}
|
62
|
+
|
63
|
+
subject do
|
64
|
+
setup_filter(CacheBusterFilter.new() { 'foo' })
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'uses the custom key strategy' do
|
68
|
+
subject.output_files.should == [ output_file ]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'for an input file with multiple dots' do
|
74
|
+
let(:input_file) {
|
75
|
+
MemoryFileWrapper.new '/path/to/input', 'my.text.file.txt', 'UTF-8', content
|
76
|
+
}
|
77
|
+
|
78
|
+
let(:output_file) {
|
79
|
+
MemoryFileWrapper.new output_root, "my.text.file-foo.txt", 'UTF-8'
|
80
|
+
}
|
81
|
+
|
82
|
+
subject { setup_filter(CacheBusterFilter.new() { 'foo' }) }
|
83
|
+
|
84
|
+
it 'appends the busting key to the penultimate part' do
|
85
|
+
subject.output_files.should == [ output_file ]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'for an input file with no dots' do
|
90
|
+
let(:input_file) {
|
91
|
+
MemoryFileWrapper.new '/path/to/input', 'my_text_file', 'UTF-8', content
|
92
|
+
}
|
93
|
+
|
94
|
+
let(:output_file) {
|
95
|
+
MemoryFileWrapper.new output_root, "my_text_file-foo", 'UTF-8'
|
96
|
+
}
|
97
|
+
|
98
|
+
subject { setup_filter(CacheBusterFilter.new() { 'foo' }) }
|
99
|
+
|
100
|
+
it 'appends the busting key to the end of the filename' do
|
101
|
+
subject.output_files.should == [ output_file ]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
describe "ChainedFilter" do
|
2
|
+
MemoryFileWrapper ||= Rake::Pipeline::SpecHelpers::MemoryFileWrapper
|
3
|
+
ChainedFilter ||= Rake::Pipeline::Web::Filters::ChainedFilter
|
4
|
+
|
5
|
+
input_file1 = MemoryFileWrapper.new("/path", "input.js.strip_asserts.erb", "UTF-8", <<-CONTENT)
|
6
|
+
assert("must be true", true);
|
7
|
+
Input = {};
|
8
|
+
<%= $chained_filter_title %> = {};
|
9
|
+
CONTENT
|
10
|
+
|
11
|
+
input_file2 = MemoryFileWrapper.new("/path", "input.js.erb.strip_asserts", "UTF-8", <<-CONTENT)
|
12
|
+
assert("must be true", true);
|
13
|
+
Input = {};
|
14
|
+
<%= $chained_filter_title %> = {};
|
15
|
+
CONTENT
|
16
|
+
|
17
|
+
EXPECTED_OUTPUT = <<-EXPECTED
|
18
|
+
|
19
|
+
Input = {};
|
20
|
+
Chained = {};
|
21
|
+
EXPECTED
|
22
|
+
|
23
|
+
let(:erb_filter) do
|
24
|
+
Class.new(Rake::Pipeline::Filter) do
|
25
|
+
def generate_output(inputs, output)
|
26
|
+
inputs.each do |input|
|
27
|
+
output.write ERB.new(input.read).result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:strip_asserts_filter) do
|
34
|
+
Class.new(Rake::Pipeline::Filter) do
|
35
|
+
def generate_output(inputs, output)
|
36
|
+
inputs.each do |input|
|
37
|
+
output.write input.read.gsub(/^assert.*$/, '')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
before do
|
44
|
+
$chained_filter_title = "Chained"
|
45
|
+
end
|
46
|
+
|
47
|
+
after do
|
48
|
+
$chained_filter_title = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
[ input_file1, input_file2 ].each do |file_wrapper|
|
52
|
+
it "should run through the filters in order" do
|
53
|
+
filter = ChainedFilter.new(
|
54
|
+
:types => {
|
55
|
+
:erb => erb_filter,
|
56
|
+
:strip_asserts => strip_asserts_filter
|
57
|
+
}
|
58
|
+
)
|
59
|
+
|
60
|
+
filter.file_wrapper_class = MemoryFileWrapper
|
61
|
+
filter.input_files = [ file_wrapper ]
|
62
|
+
filter.output_root = "/output"
|
63
|
+
filter.rake_application = Rake::Application.new
|
64
|
+
|
65
|
+
filter.output_files.should == [ MemoryFileWrapper.new("/output", "input.js", "UTF-8") ]
|
66
|
+
|
67
|
+
tasks = filter.generate_rake_tasks
|
68
|
+
tasks.each(&:invoke)
|
69
|
+
|
70
|
+
file = MemoryFileWrapper.files["/output/input.js"]
|
71
|
+
file.body.should == EXPECTED_OUTPUT
|
72
|
+
file.encoding.should == "UTF-8"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|