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
@@ -0,0 +1,86 @@
1
+ describe "MarkdownFilter" do
2
+ MarkdownFilter ||= Rake::Pipeline::Web::Filters::MarkdownFilter
3
+ MemoryFileWrapper ||= Rake::Pipeline::SpecHelpers::MemoryFileWrapper
4
+
5
+ let(:markdown_input) { <<-MARKDOWN }
6
+ ## This is an H2
7
+
8
+ Some *important* text. It might have a link: http://foo.com/
9
+
10
+ Some code
11
+
12
+ That's all.
13
+ MARKDOWN
14
+
15
+ let(:expected_html_output) { <<-HTML }
16
+ <h2>This is an H2</h2>
17
+
18
+ <p>Some <em>important</em> text. It might have a link: http://foo.com/</p>
19
+
20
+ <pre><code>Some code
21
+ </code></pre>
22
+
23
+ <p>That&#39;s all.</p>
24
+ HTML
25
+
26
+ def input_file(name, content)
27
+ MemoryFileWrapper.new("/path/to/input", name, "UTF-8", content)
28
+ end
29
+
30
+ def output_file(name)
31
+ MemoryFileWrapper.new("/path/to/output", name, "UTF-8")
32
+ end
33
+
34
+ def setup_filter(filter)
35
+ filter.file_wrapper_class = MemoryFileWrapper
36
+ filter.input_files = [input_file("page.md", markdown_input)]
37
+ filter.output_root = "/path/to/output"
38
+ filter.rake_application = Rake::Application.new
39
+ filter
40
+ end
41
+
42
+ it "generates output" do
43
+ filter = setup_filter MarkdownFilter.new
44
+
45
+ filter.output_files.should == [output_file("page.html")]
46
+
47
+ tasks = filter.generate_rake_tasks
48
+ tasks.each(&:invoke)
49
+
50
+ file = MemoryFileWrapper.files["/path/to/output/page.html"]
51
+ file.body.should == expected_html_output
52
+ file.encoding.should == "UTF-8"
53
+ end
54
+
55
+ describe "naming output files" do
56
+ it "translates .md extensions to .html by default" do
57
+ filter = setup_filter MarkdownFilter.new
58
+ filter.output_files.first.path.should == "page.html"
59
+ end
60
+
61
+ it "accepts a block to customize output file names" do
62
+ filter = setup_filter(MarkdownFilter.new { |input| "octopus" })
63
+ filter.output_files.first.path.should == "octopus"
64
+ end
65
+ end
66
+
67
+ it "passes options to the Markdown compiler" do
68
+ filter = setup_filter(MarkdownFilter.new(:autolink => true))
69
+ filter.input_files = [input_file("page.md", markdown_input)]
70
+ tasks = filter.generate_rake_tasks
71
+ tasks.each(&:invoke)
72
+ file = MemoryFileWrapper.files["/path/to/output/page.html"]
73
+ file.body.should =~ %r{<a href="http://foo\.com/">}
74
+ end
75
+
76
+ it "accepts a :compiler option" do
77
+ filter = setup_filter(MarkdownFilter.new(:compiler => proc { |text, options| text }))
78
+ filter.input_files = [input_file("page.md", markdown_input)]
79
+ tasks = filter.generate_rake_tasks
80
+ tasks.each(&:invoke)
81
+ file = MemoryFileWrapper.files["/path/to/output/page.html"]
82
+ file.body.should == markdown_input
83
+ end
84
+
85
+ end
86
+
@@ -1,11 +1,11 @@
1
+ require "json"
2
+
1
3
  describe "MinispadeFilter" do
2
- MemoryFileWrapper = Rake::Pipeline::SpecHelpers::MemoryFileWrapper
4
+ MemoryFileWrapper ||= Rake::Pipeline::SpecHelpers::MemoryFileWrapper
3
5
 
4
- let(:input_files) {
5
- [
6
- MemoryFileWrapper.new("/path/to/input", "foo.js", "UTF-8", "var foo = 'bar';")
7
- ]
8
- }
6
+ def input_file(contents="var foo = 'bar'; // last-line comment", path="/path/to/input", name="foo.js")
7
+ MemoryFileWrapper.new(path, name, "UTF-8", contents)
8
+ end
9
9
 
10
10
  let(:output_files) {
11
11
  [
@@ -17,10 +17,10 @@ describe "MinispadeFilter" do
17
17
  MemoryFileWrapper.files["/path/to/output/foo.js"]
18
18
  }
19
19
 
20
- def make_filter(*args)
20
+ def make_filter(input_file, *args)
21
21
  filter = Rake::Pipeline::Web::Filters::MinispadeFilter.new(*args)
22
22
  filter.file_wrapper_class = MemoryFileWrapper
23
- filter.input_files = input_files
23
+ filter.input_files = [input_file]
24
24
  filter.output_root = "/path/to/output"
25
25
  filter.rake_application = Rake::Application.new
26
26
  filter.generate_rake_tasks.each(&:invoke)
@@ -28,20 +28,52 @@ describe "MinispadeFilter" do
28
28
  end
29
29
 
30
30
  it "generates output" do
31
- filter = make_filter
32
-
31
+ filter = make_filter(input_file)
33
32
  filter.output_files.should == output_files
34
- output_file.body.should == "minispade.register('/path/to/input/foo.js',function() { var foo = 'bar'; });"
35
33
  output_file.encoding.should == "UTF-8"
34
+ output_file.body.should ==
35
+ "minispade.register('/path/to/input/foo.js', function() {var foo = 'bar'; // last-line comment\n});"
36
36
  end
37
37
 
38
38
  it "uses strict if asked" do
39
- filter = make_filter(:use_strict => true)
40
- output_file.body.should == "minispade.register('/path/to/input/foo.js',function() { \"use strict\"; var foo = 'bar'; });"
39
+ filter = make_filter(input_file, :use_strict => true)
40
+ output_file.body.should ==
41
+ "minispade.register('/path/to/input/foo.js', function() {\"use strict\";\nvar foo = 'bar'; // last-line comment\n});"
42
+ end
43
+
44
+ it "compiles a string if asked" do
45
+ filter = make_filter(input_file, :string => true)
46
+ output_file.body.should ==
47
+ %{minispade.register('/path/to/input/foo.js', "(function() {var foo = 'bar'; // last-line comment\\n})();\\n//@ sourceURL=/path/to/input/foo.js");}
41
48
  end
42
49
 
43
50
  it "takes a proc to name the module" do
44
- filter = make_filter(:module_id_generator => proc { |input| "octopus" })
45
- output_file.body.should == "minispade.register('octopus',function() { var foo = 'bar'; });"
51
+ filter = make_filter(input_file, :module_id_generator => proc { |input| "octopus" })
52
+ output_file.body.should ==
53
+ "minispade.register('octopus', function() {var foo = 'bar'; // last-line comment\n});"
54
+ end
55
+
56
+ it "rewrites requires if asked" do
57
+ filter = make_filter(input_file("require('octopus');"), :rewrite_requires => true)
58
+ output_file.body.should ==
59
+ "minispade.register('/path/to/input/foo.js', function() {minispade.require('octopus');\n});"
60
+ end
61
+
62
+ it "rewrites requires if asked even spaces wrap tokens in the require statement" do
63
+ filter = make_filter(input_file("require ( 'octopus');"), :rewrite_requires => true)
64
+ output_file.body.should ==
65
+ "minispade.register('/path/to/input/foo.js', function() {minispade.require('octopus');\n});"
66
+ end
67
+
68
+ it "rewrites requireAll if asked" do
69
+ filter = make_filter(input_file("requireAll('octopus');"), :rewrite_requires => true)
70
+ output_file.body.should ==
71
+ "minispade.register('/path/to/input/foo.js', function() {minispade.requireAll('octopus');\n});"
72
+ end
73
+
74
+ it "rewrites requireAll if asked even spaces wrap tokens in the require statement" do
75
+ filter = make_filter(input_file("requireAll ( 'octopus');"), :rewrite_requires => true)
76
+ output_file.body.should ==
77
+ "minispade.register('/path/to/input/foo.js', function() {minispade.requireAll('octopus');\n});"
46
78
  end
47
79
  end
@@ -0,0 +1,204 @@
1
+ require 'stringio'
2
+
3
+ describe "NeuterFilter" do
4
+ MemoryFileWrapper ||= Rake::Pipeline::SpecHelpers::MemoryFileWrapper
5
+
6
+ def make_input(name, data)
7
+ make_data(name, data)
8
+ MemoryFileWrapper.new("/path/to/input", name, "UTF-8")
9
+ end
10
+
11
+ def make_data(name, data)
12
+ MemoryFileWrapper.data["/path/to/input/#{name}"] = data
13
+ end
14
+
15
+ def make_filter(input_files, *args)
16
+ opts = args.last.is_a?(Hash) ? args.pop : {}
17
+ opts[:additional_dependencies] ||= proc{|input| %w(b c) }
18
+ args.push(opts)
19
+
20
+ filter = Rake::Pipeline::Web::Filters::NeuterFilter.new(*args)
21
+ filter.file_wrapper_class = MemoryFileWrapper
22
+ filter.input_files = input_files
23
+ filter.output_root = "/path/to/output"
24
+ filter.rake_application = Rake::Application.new
25
+ filter.generate_rake_tasks.each(&:invoke)
26
+ filter
27
+ end
28
+
29
+ def make_filter_with_inputs(inputs, options={})
30
+ input_file = make_input(inputs[0][0], inputs[0][1])
31
+ inputs[1..-1].each{|input| make_data(input[0], input[1]) }
32
+ make_filter([input_file], "processed", options)
33
+ end
34
+
35
+ def capture(*streams)
36
+ streams.map! { |stream| stream.to_s }
37
+ begin
38
+ result = StringIO.new
39
+ streams.each { |stream| eval "$#{stream} = result" }
40
+ yield
41
+ ensure
42
+ streams.each { |stream| eval("$#{stream} = #{stream.upcase}") }
43
+ end
44
+ result.string
45
+ end
46
+
47
+ after(:each) do
48
+ MemoryFileWrapper.data.clear
49
+ end
50
+
51
+ let(:output_files) {
52
+ [
53
+ MemoryFileWrapper.new("/path/to/output", "processed", "BINARY")
54
+ ]
55
+ }
56
+
57
+ let(:output_file) {
58
+ MemoryFileWrapper.files["/path/to/output/processed"]
59
+ }
60
+
61
+ it "generates basic output" do
62
+ input_file = make_input("contents", "data")
63
+ filter = make_filter([input_file], "processed")
64
+
65
+ filter.output_files.should == output_files
66
+ # ConcatFilter forces Binary, not sure if this is right in this case
67
+ output_file.encoding.should == "BINARY"
68
+ output_file.body.should == "data"
69
+ end
70
+
71
+ it "orders required files" do
72
+ make_filter_with_inputs([
73
+ ["a", "require('b');\nA"],
74
+ ["b", "require('c');\nB"],
75
+ ["c", "C"]
76
+ ])
77
+
78
+ output_file.body.should == "C\n\nB\n\nA"
79
+ end
80
+
81
+ it "works with paths" do
82
+ make_filter_with_inputs([
83
+ ["lib/a", "require('lib/b');\nA"],
84
+ ["lib/b", "require('lib/c');\nB"],
85
+ ["lib/c", "C"]
86
+ ], :additional_dependencies => proc{ %w(lib/b lib/c) })
87
+
88
+ output_file.body.should == "C\n\nB\n\nA"
89
+ end
90
+
91
+ it "should handle circular requires" do
92
+ make_filter_with_inputs([
93
+ ["a", "require('b');\nA"],
94
+ ["b", "require('c');\nB"],
95
+ ["c", "require('a');\nC"]
96
+ ])
97
+
98
+ output_file.body.should == "C\n\nB\n\nA"
99
+ end
100
+
101
+ it "should not require the same file twice" do
102
+ make_filter_with_inputs([
103
+ ["a", "require('b');\nrequire('c');\nA"],
104
+ ["b", "require('c');\nB"],
105
+ ["c", "require('a');\nC"]
106
+ ])
107
+
108
+ output_file.body.should == "C\n\nB\n\nA"
109
+ end
110
+
111
+ # Feature not yet supported
112
+ it "does not duplicate files both matched and required"
113
+
114
+ describe "config" do
115
+ describe "require_regexp" do
116
+ it "works with minispade format" do
117
+ make_filter_with_inputs([
118
+ ["a", "minispade.require('b');\nA"],
119
+ ["b", "minispade.require('c');\nB"],
120
+ ["c", "C"]
121
+ ], :require_regexp => %r{^\s*minispade\.require\(['"]([^'"]*)['"]\);?\s*})
122
+
123
+ output_file.body.should == "C\n\nB\n\nA"
124
+ end
125
+
126
+ it "works with sprockets format" do
127
+ make_filter_with_inputs([
128
+ ["a", "//= require b\nA"],
129
+ ["b", "//= require c\nB"],
130
+ ["c", "C"]
131
+ ], :require_regexp => %r{^//= require (\S+)\s*})
132
+
133
+ output_file.body.should == "C\n\nB\n\nA"
134
+ end
135
+ end
136
+
137
+ describe "path_transform" do
138
+ it "converts paths" do
139
+ make_filter_with_inputs([
140
+ ["lib/a.js", "require('b');\nA"],
141
+ ["lib/b.js", "require('c');\nB"],
142
+ ["lib/c.js", "C"]
143
+ ], :path_transform => proc{|path| "lib/#{path}.js" },
144
+ :additional_dependencies => proc{ %w(lib/b.js lib/c.js) })
145
+
146
+ output_file.body.should == "C\n\nB\n\nA"
147
+ end
148
+ end
149
+
150
+ describe "closure_wrap" do
151
+ it "wraps in a javascript closure" do
152
+ make_filter_with_inputs([
153
+ ["a", "require('b');\nA"],
154
+ ["b", "require('c');\nB"],
155
+ ["c", "C"]
156
+ ], :closure_wrap => true)
157
+
158
+ output_file.body.should == "(function() {\nC\n})();\n\n\n\n(function() {\nB\n})();\n\n\n\n(function() {\nA\n})();\n\n"
159
+ end
160
+
161
+ # Not yet supported
162
+ it "allows other wrapper types"
163
+ end
164
+
165
+ describe "filename_comment" do
166
+ it "shows a comment with the filename" do
167
+ make_filter_with_inputs([
168
+ ["a", "require('b');\nA"],
169
+ ["b", "require('c');\nB"],
170
+ ["c", "C"],
171
+ ], :filename_comment => proc{|input| "/* #{input.fullpath} */" })
172
+
173
+ output_file.body.should == "/* /path/to/input/c */\nC\n\n/* /path/to/input/b */\nB\n\n/* /path/to/input/a */\nA"
174
+ end
175
+ end
176
+
177
+ describe "additional_dependencies" do
178
+ it "warns if required file is not contained" do
179
+ output = capture(:stderr) do
180
+ make_filter_with_inputs([
181
+ ["d", "require('e');\nD"],
182
+ ["e", "require('f');\nE"],
183
+ ["f", "F"]
184
+ ])
185
+ end
186
+
187
+ output.should include("Included '/path/to/input/e', which is not listed in :additional_dependencies. The pipeline may not invalidate properly.")
188
+ output.should include("Included '/path/to/input/f', which is not listed in :additional_dependencies. The pipeline may not invalidate properly.")
189
+ end
190
+
191
+ it "does not warn if full paths are provided" do
192
+ output = capture(:stderr) do
193
+ make_filter_with_inputs([
194
+ ["d", "require('e');\nD"],
195
+ ["e", "require('f');\nE"],
196
+ ["f", "F"]
197
+ ], :additional_dependencies => proc{ %w(/path/to/input/e /path/to/input/f) })
198
+ end
199
+
200
+ output.should == ""
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,147 @@
1
+ describe "SassFilter" do
2
+ SassFilter ||= Rake::Pipeline::Web::Filters::SassFilter
3
+ MemoryFileWrapper ||= Rake::Pipeline::SpecHelpers::MemoryFileWrapper
4
+
5
+ let(:scss_input) { <<-SCSS }
6
+ $blue: #3bbfce;
7
+
8
+ .border {
9
+ border-color: $blue;
10
+ }
11
+ SCSS
12
+
13
+ let(:sass_input) { <<-SASS }
14
+ $blue: #3bbfce
15
+
16
+ .border
17
+ border-color: $blue
18
+ SASS
19
+
20
+ def expected_css_output(filename)
21
+ <<-CSS
22
+ /* line 3, /path/to/input/#{filename} */
23
+ .border {
24
+ border-color: #3bbfce;
25
+ }
26
+ CSS
27
+ end
28
+
29
+ def input_file(name, content)
30
+ MemoryFileWrapper.new("/path/to/input", name, "UTF-8", content)
31
+ end
32
+
33
+ def output_file(name)
34
+ MemoryFileWrapper.new("/path/to/output", name, "UTF-8")
35
+ end
36
+
37
+ def setup_filter(filter, input_files=nil)
38
+ filter.file_wrapper_class = MemoryFileWrapper
39
+ filter.input_files = input_files || [input_file("border.scss", scss_input)]
40
+ filter.output_root = "/path/to/output"
41
+ filter.rake_application = Rake::Application.new
42
+ filter
43
+ end
44
+
45
+ it "generates output" do
46
+ filter = setup_filter SassFilter.new
47
+ filter.output_files.should == [output_file("border.css")]
48
+
49
+ tasks = filter.generate_rake_tasks
50
+ tasks.each(&:invoke)
51
+
52
+ file = MemoryFileWrapper.files["/path/to/output/border.css"]
53
+ file.body.should == expected_css_output("border.scss")
54
+ file.encoding.should == "UTF-8"
55
+ end
56
+
57
+ describe "naming output files" do
58
+ it "translates .scss extensions to .css by default" do
59
+ filter = setup_filter SassFilter.new
60
+ filter.output_files.first.path.should == "border.css"
61
+ end
62
+
63
+ it "accepts a block to customize output file names" do
64
+ filter = setup_filter(SassFilter.new { |input| "octopus" })
65
+ filter.output_files.first.path.should == "octopus"
66
+ end
67
+ end
68
+
69
+ it "accepts options to pass to the Sass compiler" do
70
+ input_files = [input_file("border.sass_file", sass_input)]
71
+ filter = setup_filter(SassFilter.new(:syntax => :sass), input_files)
72
+ tasks = filter.generate_rake_tasks
73
+ tasks.each(&:invoke)
74
+ file = MemoryFileWrapper.files["/path/to/output/border.sass_file"]
75
+ file.body.should == expected_css_output("border.sass_file")
76
+ end
77
+
78
+ it "compiles files with a .sass extension as sass" do
79
+ input_files = [input_file("border.sass", sass_input)]
80
+ filter = setup_filter(SassFilter.new, input_files)
81
+ tasks = filter.generate_rake_tasks
82
+ tasks.each(&:invoke)
83
+ file = MemoryFileWrapper.files["/path/to/output/border.css"]
84
+ file.body.should == expected_css_output("border.sass")
85
+ end
86
+
87
+ it "passes Compass's options to the Sass compiler" do
88
+ Compass.configuration do |c|
89
+ c.preferred_syntax = :sass
90
+ end
91
+
92
+ input_files = [input_file("border.css", scss_input)]
93
+ filter = setup_filter(SassFilter.new, input_files)
94
+ tasks = filter.generate_rake_tasks
95
+ tasks.each(&:invoke)
96
+ file = MemoryFileWrapper.files["/path/to/output/border.css"]
97
+ file.body.should == expected_css_output("border.css")
98
+ end
99
+
100
+ describe "additional load paths" do
101
+ it "is empty by default" do
102
+ filter = setup_filter(SassFilter.new)
103
+ filter.additional_load_paths == []
104
+ end
105
+
106
+ it "transforms to array" do
107
+ filter = setup_filter(SassFilter.new(:additional_load_paths => "additional"))
108
+ filter.additional_load_paths == ["additional"]
109
+ end
110
+
111
+ it "accepts array" do
112
+ filter = setup_filter(SassFilter.new(:additional_load_paths => ["additional", "extra"]))
113
+ filter.additional_load_paths == ["additional", "extra"]
114
+ end
115
+ end
116
+
117
+ describe "additional dependencies" do
118
+ def write_input_file(filename, contents='', root=tmp)
119
+ mkdir_p root
120
+ File.open(File.join(root, filename), 'w') { |f| f.puts contents }
121
+ Rake::Pipeline::FileWrapper.new(root, filename)
122
+ end
123
+
124
+ let(:main_scss) { '@import "blue";' }
125
+ let(:blue_scss) { '$blue: #3bbfce;' }
126
+ let!(:main) { write_input_file('main.scss', main_scss) }
127
+ let!(:blue) { write_input_file('blue.scss', blue_scss) }
128
+
129
+ before do
130
+ File.open(main.fullpath, "w") { |f| f.puts main_scss }
131
+ File.open(blue.fullpath, "w") { |f| f.puts blue_scss }
132
+ end
133
+
134
+ it "includes @imported files" do
135
+ filter = SassFilter.new
136
+ filter.input_files = [main]
137
+ filter.output_root = "#{tmp}/output"
138
+ filter.rake_application = Rake::Application.new
139
+
140
+ filter.additional_dependencies(main).should include(blue.fullpath)
141
+
142
+ tasks = filter.generate_rake_tasks
143
+ tasks.each(&:invoke)
144
+ end
145
+ end
146
+
147
+ end