rake-pipeline 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.
- data/.travis.yml +12 -0
- data/Gemfile +1 -0
- data/README.markdown +1 -1
- data/README.yard +61 -32
- data/Rakefile +9 -0
- data/bin/rakep +1 -24
- data/lib/generators/rake/pipeline/install/install_generator.rb +70 -0
- data/lib/rake-pipeline.rb +117 -53
- data/lib/rake-pipeline/cli.rb +56 -0
- data/lib/rake-pipeline/dsl.rb +3 -140
- data/lib/rake-pipeline/dsl/pipeline_dsl.rb +168 -0
- data/lib/rake-pipeline/dsl/project_dsl.rb +108 -0
- data/lib/rake-pipeline/dynamic_file_task.rb +188 -0
- data/lib/rake-pipeline/file_wrapper.rb +1 -1
- data/lib/rake-pipeline/filter.rb +45 -15
- data/lib/rake-pipeline/filters.rb +3 -1
- data/lib/rake-pipeline/filters/{concat.rb → concat_filter.rb} +0 -0
- data/lib/rake-pipeline/filters/ordering_concat_filter.rb +38 -0
- data/lib/rake-pipeline/filters/pipeline_finalizing_filter.rb +19 -0
- data/lib/rake-pipeline/graph.rb +178 -0
- data/lib/rake-pipeline/manifest.rb +63 -0
- data/lib/rake-pipeline/manifest_entry.rb +34 -0
- data/lib/rake-pipeline/matcher.rb +65 -30
- data/lib/rake-pipeline/middleware.rb +15 -12
- data/lib/rake-pipeline/precompile.rake +8 -0
- data/lib/rake-pipeline/project.rb +280 -0
- data/lib/rake-pipeline/railtie.rb +16 -1
- data/lib/rake-pipeline/server.rb +15 -0
- data/lib/rake-pipeline/version.rb +2 -2
- data/rake-pipeline.gemspec +2 -0
- data/spec/cli_spec.rb +71 -0
- data/spec/concat_filter_spec.rb +1 -27
- data/spec/{dsl_spec.rb → dsl/pipeline_dsl_spec.rb} +32 -18
- data/spec/dsl/project_dsl_spec.rb +41 -0
- data/spec/dynamic_file_task_spec.rb +111 -0
- data/spec/encoding_spec.rb +6 -8
- data/spec/file_wrapper_spec.rb +19 -2
- data/spec/filter_spec.rb +120 -22
- data/spec/graph_spec.rb +56 -0
- data/spec/manifest_entry_spec.rb +51 -0
- data/spec/manifest_spec.rb +67 -0
- data/spec/matcher_spec.rb +35 -2
- data/spec/middleware_spec.rb +123 -75
- data/spec/ordering_concat_filter_spec.rb +39 -0
- data/spec/pipeline_spec.rb +95 -34
- data/spec/project_spec.rb +293 -0
- data/spec/rake_acceptance_spec.rb +307 -67
- data/spec/rake_tasks_spec.rb +21 -0
- data/spec/spec_helper.rb +11 -48
- data/spec/support/spec_helpers/file_utils.rb +35 -0
- data/spec/support/spec_helpers/filters.rb +16 -0
- data/spec/support/spec_helpers/input_helpers.rb +23 -0
- data/spec/support/spec_helpers/memory_file_wrapper.rb +31 -0
- data/tools/perfs +107 -0
- metadata +100 -12
data/spec/middleware_spec.rb
CHANGED
@@ -5,16 +5,6 @@ require "rack/test"
|
|
5
5
|
describe "Rake::Pipeline Middleware" do
|
6
6
|
include Rack::Test::Methods
|
7
7
|
|
8
|
-
ConcatFilter = Rake::Pipeline::SpecHelpers::Filters::ConcatFilter
|
9
|
-
|
10
|
-
class StripAssertsFilter < Rake::Pipeline::Filter
|
11
|
-
def generate_output(inputs, output)
|
12
|
-
inputs.each do |input|
|
13
|
-
output.write input.read.gsub(%r{^\s*assert\(.*\)\s*;?\s*$}m, '')
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
8
|
inputs = {
|
19
9
|
"app/javascripts/jquery.js" => "var jQuery = {};\n",
|
20
10
|
|
@@ -25,8 +15,8 @@ describe "Rake::Pipeline Middleware" do
|
|
25
15
|
HERE
|
26
16
|
|
27
17
|
"app/index.html" => "<html>HI</html>",
|
28
|
-
|
29
|
-
|
18
|
+
"app/javascripts/index.html" => "<html>JAVASCRIPT</html>",
|
19
|
+
"app/empty_dir" => nil
|
30
20
|
}
|
31
21
|
|
32
22
|
expected_output = <<-HERE.gsub(/^ {4}/, '')
|
@@ -36,114 +26,172 @@ describe "Rake::Pipeline Middleware" do
|
|
36
26
|
SC.hi = function() { console.log("hi"); };
|
37
27
|
HERE
|
38
28
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
app = lambda { |env| [404, {}, ['not found']] }
|
29
|
+
assetfile_source = <<-HERE.gsub(/^ {4}/, '')
|
30
|
+
require "#{tmp}/../support/spec_helpers/filters"
|
31
|
+
output "public"
|
43
32
|
|
44
|
-
|
45
|
-
|
33
|
+
map "/dynamic-request.js" do
|
34
|
+
[200, { "Content-Type" => "text/plain" }, ["I am dynamic!"]]
|
35
|
+
end
|
46
36
|
|
37
|
+
input "#{tmp}", "app/**/*" do
|
47
38
|
match "*.js" do
|
48
|
-
|
49
|
-
filter(StripAssertsFilter) { |input| input }
|
39
|
+
concat "javascripts/application.js"
|
40
|
+
filter(Rake::Pipeline::SpecHelpers::Filters::StripAssertsFilter) { |input| input }
|
50
41
|
end
|
51
42
|
|
52
43
|
# copy the rest
|
53
|
-
|
54
|
-
|
55
|
-
output "public"
|
44
|
+
concat { |input| input.sub(%r|^app/|, '') }
|
56
45
|
end
|
46
|
+
HERE
|
57
47
|
|
58
|
-
|
48
|
+
modified_assetfile_source = <<-HERE.gsub(/^ {4}/, '')
|
49
|
+
require "#{tmp}/../support/spec_helpers/filters"
|
50
|
+
output "public"
|
59
51
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
File.open(path, "w") { |file| file.write(string) }
|
65
|
-
else
|
66
|
-
mkdir_p path
|
52
|
+
input "#{tmp}", "app/**/*" do
|
53
|
+
match "*.js" do
|
54
|
+
concat { "javascripts/app.js" }
|
55
|
+
filter(Rake::Pipeline::SpecHelpers::Filters::StripAssertsFilter) { |input| input }
|
67
56
|
end
|
57
|
+
|
58
|
+
# copy the rest
|
59
|
+
concat { |input| input.sub(%r|^app/|, '') }
|
68
60
|
end
|
61
|
+
HERE
|
69
62
|
|
70
|
-
|
71
|
-
end
|
63
|
+
app = middleware = nil
|
72
64
|
|
73
65
|
let(:app) { middleware }
|
74
66
|
|
75
|
-
|
76
|
-
|
67
|
+
before do
|
68
|
+
assetfile_path = File.join(tmp, "Assetfile")
|
69
|
+
File.open(assetfile_path, "w") { |file| file.write(assetfile_source) }
|
77
70
|
|
78
|
-
|
79
|
-
|
71
|
+
app = lambda { |env| [404, {}, ['not found']] }
|
72
|
+
middleware = Rake::Pipeline::Middleware.new(app, assetfile_path)
|
80
73
|
end
|
81
74
|
|
82
|
-
|
83
|
-
|
75
|
+
describe "dynamic requests" do
|
76
|
+
it "returns the value from the given block for paths that have been mapped" do
|
77
|
+
get "/dynamic-request.js"
|
84
78
|
|
85
|
-
|
86
|
-
|
79
|
+
last_response.should be_ok
|
80
|
+
last_response.headers["Content-Type"].should == "text/plain"
|
81
|
+
last_response.body.should == "I am dynamic!"
|
87
82
|
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "static requests" do
|
86
|
+
before do
|
87
|
+
inputs.each do |name, string|
|
88
|
+
path = File.join(tmp, name)
|
89
|
+
if string
|
90
|
+
mkdir_p File.dirname(path)
|
91
|
+
File.open(path, "w") { |file| file.write(string) }
|
92
|
+
else
|
93
|
+
mkdir_p path
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
get "/javascripts/application.js"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns files relative to the output directory" do
|
101
|
+
last_response.should be_ok
|
102
|
+
|
103
|
+
last_response.body.should == expected_output
|
104
|
+
last_response.headers["Content-Type"].should == "application/javascript"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "updates the output when files change" do
|
108
|
+
age_existing_files
|
88
109
|
|
89
|
-
|
110
|
+
File.open(File.join(tmp, "app/javascripts/jquery.js"), "w") do |file|
|
111
|
+
file.write "var jQuery = {};\njQuery.trim = function() {};\n"
|
112
|
+
end
|
113
|
+
|
114
|
+
expected = <<-HERE.gsub(/^ {6}/, '')
|
90
115
|
var jQuery = {};
|
91
116
|
jQuery.trim = function() {};
|
92
117
|
var SC = {};
|
93
118
|
|
94
119
|
SC.hi = function() { console.log("hi"); };
|
95
|
-
|
120
|
+
HERE
|
96
121
|
|
97
|
-
|
122
|
+
get "/javascripts/application.js"
|
98
123
|
|
99
|
-
|
100
|
-
|
101
|
-
|
124
|
+
last_response.body.should == expected
|
125
|
+
last_response.headers["Content-Type"].should == "application/javascript"
|
126
|
+
end
|
102
127
|
|
103
|
-
|
104
|
-
|
128
|
+
it "updates the output when new files are added" do
|
129
|
+
age_existing_files
|
105
130
|
|
106
|
-
|
107
|
-
|
108
|
-
|
131
|
+
File.open(File.join(tmp, "app/javascripts/history.js"), "w") do |file|
|
132
|
+
file.write "var History = {};\n"
|
133
|
+
end
|
109
134
|
|
110
|
-
|
135
|
+
expected = <<-HERE.gsub(/^ {6}/, '')
|
111
136
|
var History = {};
|
112
137
|
var jQuery = {};
|
113
138
|
var SC = {};
|
114
139
|
|
115
140
|
SC.hi = function() { console.log("hi"); };
|
116
|
-
|
141
|
+
HERE
|
117
142
|
|
118
|
-
|
143
|
+
get "/javascripts/application.js"
|
119
144
|
|
120
|
-
|
121
|
-
|
122
|
-
|
145
|
+
last_response.body.should == expected
|
146
|
+
last_response.headers["Content-Type"].should == "application/javascript"
|
147
|
+
end
|
123
148
|
|
124
|
-
|
125
|
-
|
149
|
+
it "returns index.html for directories" do
|
150
|
+
get "/"
|
126
151
|
|
127
|
-
|
128
|
-
|
152
|
+
last_response.body.should == "<html>HI</html>"
|
153
|
+
last_response.headers["Content-Type"].should == "text/html"
|
129
154
|
|
130
|
-
|
155
|
+
get "/javascripts"
|
131
156
|
|
132
|
-
|
133
|
-
|
134
|
-
|
157
|
+
last_response.body.should == "<html>JAVASCRIPT</html>"
|
158
|
+
last_response.headers["Content-Type"].should == "text/html"
|
159
|
+
end
|
135
160
|
|
136
|
-
|
137
|
-
|
161
|
+
it "ignores directories without index.html" do
|
162
|
+
get "/empty_dir"
|
138
163
|
|
139
|
-
|
140
|
-
|
141
|
-
|
164
|
+
last_response.body.should == "not found"
|
165
|
+
last_response.status.should == 404
|
166
|
+
end
|
167
|
+
|
168
|
+
it "falls back to the app" do
|
169
|
+
get "/zomg.notfound"
|
170
|
+
|
171
|
+
last_response.body.should == "not found"
|
172
|
+
last_response.status.should == 404
|
173
|
+
end
|
142
174
|
|
143
|
-
|
144
|
-
|
175
|
+
it "recreates the pipeline when the Assetfile changes" do
|
176
|
+
get "/javascripts/app.js"
|
177
|
+
last_response.body.should == "not found"
|
178
|
+
last_response.status.should == 404
|
145
179
|
|
146
|
-
|
147
|
-
|
180
|
+
File.open(File.join(tmp, "Assetfile"), "w") do |file|
|
181
|
+
file.write(modified_assetfile_source)
|
182
|
+
end
|
183
|
+
|
184
|
+
expected = <<-HERE.gsub(/^ {6}/, '')
|
185
|
+
var jQuery = {};
|
186
|
+
var SC = {};
|
187
|
+
|
188
|
+
SC.hi = function() { console.log("hi"); };
|
189
|
+
HERE
|
190
|
+
|
191
|
+
get "/javascripts/app.js"
|
192
|
+
|
193
|
+
last_response.body.should == expected
|
194
|
+
last_response.headers["Content-Type"].should == "application/javascript"
|
195
|
+
end
|
148
196
|
end
|
149
197
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe "OrderingConcatFilter" do
|
2
|
+
MemoryFileWrapper = Rake::Pipeline::SpecHelpers::MemoryFileWrapper
|
3
|
+
|
4
|
+
let(:input_files) {
|
5
|
+
[
|
6
|
+
MemoryFileWrapper.new("/path/to/input", "first.txt", "UTF-8", "FIRST"),
|
7
|
+
MemoryFileWrapper.new("/path/to/input", "second.txt", "UTF-8", "SECOND"),
|
8
|
+
MemoryFileWrapper.new("/path/to/input", "last.txt", "UTF-8", "LAST")
|
9
|
+
]
|
10
|
+
}
|
11
|
+
|
12
|
+
let(:output_files) {
|
13
|
+
[
|
14
|
+
MemoryFileWrapper.new("/path/to/output", "all.txt", "BINARY")
|
15
|
+
]
|
16
|
+
}
|
17
|
+
|
18
|
+
let(:output_file) {
|
19
|
+
MemoryFileWrapper.files["/path/to/output/all.txt"]
|
20
|
+
}
|
21
|
+
|
22
|
+
def make_filter(ordering)
|
23
|
+
filter = Rake::Pipeline::OrderingConcatFilter.new(ordering, "all.txt")
|
24
|
+
filter.file_wrapper_class = MemoryFileWrapper
|
25
|
+
filter.input_files = input_files
|
26
|
+
filter.output_root = "/path/to/output"
|
27
|
+
filter.rake_application = Rake::Application.new
|
28
|
+
filter.generate_rake_tasks.each(&:invoke)
|
29
|
+
filter
|
30
|
+
end
|
31
|
+
|
32
|
+
it "generates output" do
|
33
|
+
filter = make_filter(["first.txt", "second.txt"])
|
34
|
+
|
35
|
+
filter.output_files.should == output_files
|
36
|
+
output_file.body.should == "FIRSTSECONDLAST"
|
37
|
+
output_file.encoding.should == "BINARY"
|
38
|
+
end
|
39
|
+
end
|
data/spec/pipeline_spec.rb
CHANGED
@@ -5,17 +5,11 @@ describe "Rake::Pipeline" do
|
|
5
5
|
let(:pipeline) { Rake::Pipeline.new }
|
6
6
|
|
7
7
|
it "accepts a input root" do
|
8
|
-
pipeline.
|
9
|
-
pipeline.
|
8
|
+
pipeline.add_input "app/assets"
|
9
|
+
pipeline.inputs["app/assets"].should == '**/*'
|
10
10
|
end
|
11
11
|
|
12
12
|
it "raises an exception on #relative_input_files if input_files are not provided" do
|
13
|
-
pipeline.input_root = "app/assets"
|
14
|
-
lambda { pipeline.input_files }.should raise_error(Rake::Pipeline::Error)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "raises an exception on #relative_input_files if input_root is not provided" do
|
18
|
-
pipeline.input_glob = "app/assets/javascripts/**/*.js"
|
19
13
|
lambda { pipeline.input_files }.should raise_error(Rake::Pipeline::Error)
|
20
14
|
end
|
21
15
|
|
@@ -39,15 +33,73 @@ describe "Rake::Pipeline" do
|
|
39
33
|
pipeline.rake_application.should == Rake.application
|
40
34
|
end
|
41
35
|
|
42
|
-
|
43
|
-
|
44
|
-
|
36
|
+
describe ".build" do
|
37
|
+
it "evaluates a block against a new Pipeline" do
|
38
|
+
pipeline = Rake::Pipeline.build do
|
39
|
+
output "octopus"
|
40
|
+
end
|
41
|
+
pipeline.should be_kind_of(Rake::Pipeline)
|
42
|
+
pipeline.output_root.should == File.expand_path("octopus")
|
43
|
+
end
|
45
44
|
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
Rake::Pipeline
|
46
|
+
describe "#build" do
|
47
|
+
it "evaluates a block against an existing Pipeline" do
|
48
|
+
pipeline = Rake::Pipeline.new
|
49
|
+
pipeline.output_root = "octopus"
|
50
|
+
|
51
|
+
pipeline.build do
|
52
|
+
output "squid"
|
53
|
+
end
|
54
|
+
pipeline.output_root.should == File.expand_path("squid")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "the constructor" do
|
59
|
+
it "accepts an :inputs option" do
|
60
|
+
pipeline = Rake::Pipeline.new(:inputs => {"app/assets" => "**/*"})
|
61
|
+
pipeline.inputs.should == {"app/assets" => "**/*"}
|
62
|
+
end
|
63
|
+
|
64
|
+
it "accepts a :tmpdir option" do
|
65
|
+
pipeline = Rake::Pipeline.new(:tmpdir => "tmp")
|
66
|
+
pipeline.tmpdir.should == "tmp"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "accepts an :output_root option" do
|
70
|
+
pipeline = Rake::Pipeline.new(:output_root => "public")
|
71
|
+
pipeline.output_root.should == File.expand_path("public")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "accepts a :rake_application option" do
|
75
|
+
app = Rake::Application.new
|
76
|
+
pipeline = Rake::Pipeline.new(:rake_application => app)
|
77
|
+
pipeline.rake_application.should == app
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "adding filters" do
|
82
|
+
let(:filter) { ConcatFilter.new }
|
83
|
+
|
84
|
+
it "can have filters added to it" do
|
85
|
+
pipeline.add_filter filter
|
86
|
+
end
|
87
|
+
|
88
|
+
it "sets an added filter's rake_application" do
|
89
|
+
app = Rake::Application.new
|
90
|
+
pipeline.rake_application = app
|
91
|
+
pipeline.add_filter filter
|
92
|
+
filter.rake_application.should == app
|
93
|
+
end
|
94
|
+
|
95
|
+
it "sets an added filter's pipeline" do
|
96
|
+
pipeline.add_filter filter
|
97
|
+
filter.pipeline.should == pipeline
|
50
98
|
end
|
99
|
+
end
|
100
|
+
|
101
|
+
shared_examples_for "when working with input" do
|
102
|
+
include Rake::Pipeline::SpecHelpers::InputHelpers
|
51
103
|
|
52
104
|
let(:files) do
|
53
105
|
%w(javascripts/jquery.js javascripts/sproutcore.js).map do |filename|
|
@@ -55,18 +107,14 @@ describe "Rake::Pipeline" do
|
|
55
107
|
end
|
56
108
|
end
|
57
109
|
|
110
|
+
def setup_roots
|
111
|
+
pipeline.add_input "app/assets"
|
112
|
+
end
|
113
|
+
|
58
114
|
before do
|
59
115
|
Rake.application = Rake::Application.new
|
60
|
-
|
61
|
-
|
62
|
-
mkdir_p File.dirname(file.fullpath)
|
63
|
-
|
64
|
-
File.open(file.fullpath, "w") do |file|
|
65
|
-
file.write "// This is #{file.path}\n"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
pipeline.input_root = "app/assets"
|
116
|
+
create_files(files)
|
117
|
+
setup_roots
|
70
118
|
setup_input(pipeline)
|
71
119
|
pipeline.output_root = "public"
|
72
120
|
end
|
@@ -111,8 +159,11 @@ describe "Rake::Pipeline" do
|
|
111
159
|
|
112
160
|
deps = task.prerequisites
|
113
161
|
deps.size.should == 2
|
114
|
-
|
115
|
-
|
162
|
+
|
163
|
+
root = File.expand_path(pipeline.inputs.keys.first)
|
164
|
+
|
165
|
+
deps[0].should == File.join(root, "javascripts/jquery.js")
|
166
|
+
deps[1].should == File.join(root, "javascripts/sproutcore.js")
|
116
167
|
|
117
168
|
Rake.application.tasks.size.should == 3
|
118
169
|
end
|
@@ -128,19 +179,29 @@ describe "Rake::Pipeline" do
|
|
128
179
|
end
|
129
180
|
end
|
130
181
|
|
131
|
-
describe "using
|
182
|
+
describe "when using multiple input roots" do
|
132
183
|
it_behaves_like "when working with input"
|
133
184
|
|
185
|
+
def setup_roots
|
186
|
+
pipeline.add_input File.join(tmp, 'tmp1', "app/assets"), '**/*.js'
|
187
|
+
pipeline.add_input File.join(tmp, 'tmp2', "app/assets"), '**/*.css'
|
188
|
+
end
|
189
|
+
|
134
190
|
def setup_input(pipeline)
|
135
|
-
pipeline.input_glob = "javascripts/**/*.js"
|
136
191
|
end
|
137
|
-
end
|
138
192
|
|
139
|
-
|
140
|
-
|
193
|
+
let(:files) do
|
194
|
+
f = []
|
141
195
|
|
142
|
-
|
143
|
-
|
196
|
+
%w(javascripts/jquery.js javascripts/sproutcore.js).map do |filename|
|
197
|
+
f << input_file(filename, File.join(tmp, 'tmp1', "app/assets"))
|
198
|
+
end
|
199
|
+
|
200
|
+
%w(stylesheets/jquery.css stylesheets/sproutcore.css).map do |filename|
|
201
|
+
f << input_file(filename, File.join(tmp, 'tmp2', "app/assets"))
|
202
|
+
end
|
203
|
+
|
204
|
+
f
|
144
205
|
end
|
145
206
|
end
|
146
207
|
|
@@ -149,7 +210,7 @@ describe "Rake::Pipeline" do
|
|
149
210
|
|
150
211
|
def setup_input(pipeline)
|
151
212
|
Dir.chdir("app/assets") do
|
152
|
-
files = Dir["javascripts/**/*.js"]
|
213
|
+
files = Dir["javascripts/**/*.js"].sort
|
153
214
|
wrappers = files.map do |file|
|
154
215
|
Rake::Pipeline::FileWrapper.new(File.join(tmp, "app/assets"), file)
|
155
216
|
end
|