rake-pipeline-web-filters 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +1 -0
  3. data/Rakefile +8 -0
  4. data/lib/rake-pipeline-web-filters.rb +17 -3
  5. data/lib/rake-pipeline-web-filters/cache_buster_filter.rb +42 -0
  6. data/lib/rake-pipeline-web-filters/chained_filter.rb +116 -0
  7. data/lib/rake-pipeline-web-filters/coffee_script_filter.rb +41 -0
  8. data/lib/rake-pipeline-web-filters/filter_with_dependencies.rb +27 -0
  9. data/lib/rake-pipeline-web-filters/gzip_filter.rb +59 -0
  10. data/lib/rake-pipeline-web-filters/handlebars_filter.rb +62 -0
  11. data/lib/rake-pipeline-web-filters/helpers.rb +100 -18
  12. data/lib/rake-pipeline-web-filters/iife_filter.rb +38 -0
  13. data/lib/rake-pipeline-web-filters/less_filter.rb +55 -0
  14. data/lib/rake-pipeline-web-filters/markdown_filter.rb +70 -0
  15. data/lib/rake-pipeline-web-filters/minispade_filter.rb +21 -5
  16. data/lib/rake-pipeline-web-filters/neuter_filter.rb +110 -0
  17. data/lib/rake-pipeline-web-filters/sass_filter.rb +87 -0
  18. data/lib/rake-pipeline-web-filters/stylus_filter.rb +59 -0
  19. data/lib/rake-pipeline-web-filters/tilt_filter.rb +16 -3
  20. data/lib/rake-pipeline-web-filters/uglify_filter.rb +66 -0
  21. data/lib/rake-pipeline-web-filters/version.rb +1 -1
  22. data/lib/rake-pipeline-web-filters/yui_css_filter.rb +70 -0
  23. data/lib/rake-pipeline-web-filters/yui_javascript_filter.rb +59 -0
  24. data/rake-pipeline-web-filters.gemspec +10 -1
  25. data/spec/cache_buster_filter_spec.rb +105 -0
  26. data/spec/chained_filter_spec.rb +76 -0
  27. data/spec/coffee_script_filter_spec.rb +110 -0
  28. data/spec/gzip_filter_spec.rb +49 -0
  29. data/spec/handlebars_filter_spec.rb +70 -0
  30. data/spec/helpers_spec.rb +112 -18
  31. data/spec/iife_filter_spec.rb +55 -0
  32. data/spec/less_filter_spec.rb +59 -0
  33. data/spec/markdown_filter_spec.rb +86 -0
  34. data/spec/minispade_filter_spec.rb +47 -15
  35. data/spec/neuter_filter_spec.rb +204 -0
  36. data/spec/sass_filter_spec.rb +147 -0
  37. data/spec/spec_helper.rb +10 -1
  38. data/spec/stylus_filter_spec.rb +69 -0
  39. data/spec/tilt_filter_spec.rb +25 -1
  40. data/spec/uglify_filter_spec.rb +82 -0
  41. data/spec/yui_css_filter_spec.rb +88 -0
  42. data/spec/yui_javascript_filter_spec.rb +68 -0
  43. metadata +225 -19
  44. data/lib/rake-pipeline-web-filters/ordering_concat_filter.rb +0 -38
  45. data/lib/rake-pipeline-web-filters/sass_compiler.rb +0 -53
  46. data/spec/ordering_concat_filter_spec.rb +0 -39
  47. data/spec/sass_compiler_spec.rb +0 -89
@@ -1,4 +1,4 @@
1
- require 'tilt'
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
@@ -2,7 +2,7 @@ module Rake
2
2
  class Pipeline
3
3
  module Web
4
4
  module Filters
5
- VERSION = "0.5.0"
5
+ VERSION = "0.7.0"
6
6
  end
7
7
  end
8
8
  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