benoit 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/.rspec-turnip +1 -0
- data/.ruby-version +1 -0
- data/Assetfile +44 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +110 -0
- data/Rakefile +9 -0
- data/benoit.gemspec +50 -0
- data/bin/benoit +121 -0
- data/bin/bundle-development +1 -0
- data/bin/bundle-sandbox +1 -0
- data/lib/benoit.rb +36 -0
- data/lib/benoit/cadenza.rb +11 -0
- data/lib/benoit/cadenza/output_filters.rb +21 -0
- data/lib/benoit/cleaner.rb +10 -0
- data/lib/benoit/compiler_error.rb +49 -0
- data/lib/benoit/configuration.rb +24 -0
- data/lib/benoit/current_site.rb +12 -0
- data/lib/benoit/file_wrapper_extensions.rb +13 -0
- data/lib/benoit/filters.rb +15 -0
- data/lib/benoit/filters/base_filter.rb +44 -0
- data/lib/benoit/filters/blacklist_filter.rb +18 -0
- data/lib/benoit/filters/cadenza_filter.rb +75 -0
- data/lib/benoit/filters/content_page_filter.rb +45 -0
- data/lib/benoit/filters/markdown_filter.rb +19 -0
- data/lib/benoit/filters/metadata_cleaner.rb +30 -0
- data/lib/benoit/filters/move_to_root_filter.rb +22 -0
- data/lib/benoit/filters/pagination_filter.rb +23 -0
- data/lib/benoit/filters/pass_thru_filter.rb +22 -0
- data/lib/benoit/filters/sass_filter.rb +74 -0
- data/lib/benoit/filters/set_metadata_filter.rb +15 -0
- data/lib/benoit/logger.rb +69 -0
- data/lib/benoit/page.rb +88 -0
- data/lib/benoit/page_metadata.rb +8 -0
- data/lib/benoit/page_metadata/container.rb +74 -0
- data/lib/benoit/page_metadata/json_converter.rb +28 -0
- data/lib/benoit/page_metadata/parser.rb +38 -0
- data/lib/benoit/page_metadata/store.rb +75 -0
- data/lib/benoit/pipeline.rb +1 -0
- data/lib/benoit/pipeline/dsl_extensions.rb +8 -0
- data/lib/benoit/pipeline/pagination_matcher.rb +53 -0
- data/lib/benoit/pipeline_project.rb +81 -0
- data/lib/benoit/site_context.rb +123 -0
- data/lib/benoit/utils/finds_layouts_for_template.rb +77 -0
- data/lib/benoit/utils/normalizes_path_to_template.rb +43 -0
- data/lib/benoit/utils/paginated_list.rb +102 -0
- data/lib/benoit/version.rb +3 -0
- data/lib/build_notifiers/file_built_notifier.rb +20 -0
- data/lib/build_notifiers/progress_notifier.rb +57 -0
- data/lib/cli.rb +39 -0
- data/spec/.rbenv-gemsets +1 -0
- data/spec/Gemfile +9 -0
- data/spec/Gemfile.lock +57 -0
- data/spec/bin/autospec +16 -0
- data/spec/bin/cucumber +16 -0
- data/spec/bin/htmldiff +16 -0
- data/spec/bin/ldiff +16 -0
- data/spec/bin/rspec +16 -0
- data/spec/features/build_command.feature +46 -0
- data/spec/features/frontmatter_metadata.feature +99 -0
- data/spec/features/javascript_files.feature +35 -0
- data/spec/features/output_filters.feature +20 -0
- data/spec/features/page_layouts.feature +72 -0
- data/spec/features/pagination.feature +58 -0
- data/spec/features/sass_files.feature +30 -0
- data/spec/features/version.feature +5 -0
- data/spec/lib/filters/base_filter_spec.rb +141 -0
- data/spec/lib/filters/markdown_filter_spec.rb +65 -0
- data/spec/lib/filters/sass_filter_spec.rb +73 -0
- data/spec/lib/metadata_json_converter_spec.rb +65 -0
- data/spec/lib/metadata_store_spec.rb +148 -0
- data/spec/lib/page_spec.rb +19 -0
- data/spec/lib/site_context_spec.rb +106 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/steps/output_file_steps.rb +45 -0
- data/spec/steps/run_steps.rb +71 -0
- data/spec/steps/staticly_steps.rb +194 -0
- data/spec/support/aruba/rspec.rb +66 -0
- data/spec/support/files/img.png +0 -0
- data/spec/support/files/input.css.scss +7 -0
- data/spec/support/files/input.scss +7 -0
- data/spec/support/spec_helpers/file_helpers.rb +8 -0
- data/spec/support/spec_helpers/memory_file_wrapper.rb +43 -0
- data/spec/support/spec_helpers/memory_manifest.rb +19 -0
- data/spec/turnip_helper.rb +19 -0
- data/vendor/frontmatter/frontmatter.gemspec +24 -0
- data/vendor/frontmatter/lib/frontmatter.rb +92 -0
- data/vendor/frontmatter/lib/frontmatter/version.rb +3 -0
- data/vendor/rake-pipeline/.gitignore +18 -0
- data/vendor/rake-pipeline/.rspec +1 -0
- data/vendor/rake-pipeline/.travis.yml +12 -0
- data/vendor/rake-pipeline/.yardopts +2 -0
- data/vendor/rake-pipeline/GETTING_STARTED.md +268 -0
- data/vendor/rake-pipeline/Gemfile +14 -0
- data/vendor/rake-pipeline/LICENSE +20 -0
- data/vendor/rake-pipeline/README.markdown +11 -0
- data/vendor/rake-pipeline/README.yard +178 -0
- data/vendor/rake-pipeline/Rakefile +21 -0
- data/vendor/rake-pipeline/bin/rakep +4 -0
- data/vendor/rake-pipeline/examples/copying_files.md +12 -0
- data/vendor/rake-pipeline/examples/minifying_files.md +37 -0
- data/vendor/rake-pipeline/examples/modifying_pipelines.md +67 -0
- data/vendor/rake-pipeline/examples/multiple_pipelines.md +77 -0
- data/vendor/rake-pipeline/lib/generators/rake/pipeline/install/install_generator.rb +70 -0
- data/vendor/rake-pipeline/lib/rake-pipeline.rb +509 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/cli.rb +57 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/dsl.rb +9 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/dsl/pipeline_dsl.rb +246 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/dsl/project_dsl.rb +108 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/dynamic_file_task.rb +194 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/error.rb +17 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/file_wrapper.rb +195 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/filter.rb +267 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/filters.rb +4 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/filters/concat_filter.rb +63 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/filters/gsub_filter.rb +56 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/filters/ordering_concat_filter.rb +38 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/filters/pipeline_finalizing_filter.rb +21 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/graph.rb +178 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/manifest.rb +82 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/manifest_entry.rb +34 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/matcher.rb +141 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/middleware.rb +73 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/precompile.rake +8 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/project.rb +338 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/rails_plugin.rb +10 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/railtie.rb +34 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/reject_matcher.rb +29 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/server.rb +15 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/sorted_pipeline.rb +19 -0
- data/vendor/rake-pipeline/lib/rake-pipeline/version.rb +6 -0
- data/vendor/rake-pipeline/rails/init.rb +2 -0
- data/vendor/rake-pipeline/rake-pipeline.gemspec +24 -0
- data/vendor/rake-pipeline/spec/cli_spec.rb +73 -0
- data/vendor/rake-pipeline/spec/concat_filter_spec.rb +37 -0
- data/vendor/rake-pipeline/spec/dsl/pipeline_dsl_spec.rb +165 -0
- data/vendor/rake-pipeline/spec/dsl/project_dsl_spec.rb +41 -0
- data/vendor/rake-pipeline/spec/dynamic_file_task_spec.rb +119 -0
- data/vendor/rake-pipeline/spec/encoding_spec.rb +106 -0
- data/vendor/rake-pipeline/spec/file_wrapper_spec.rb +132 -0
- data/vendor/rake-pipeline/spec/filter_spec.rb +367 -0
- data/vendor/rake-pipeline/spec/graph_spec.rb +56 -0
- data/vendor/rake-pipeline/spec/gsub_filter_spec.rb +87 -0
- data/vendor/rake-pipeline/spec/manifest_entry_spec.rb +46 -0
- data/vendor/rake-pipeline/spec/manifest_spec.rb +67 -0
- data/vendor/rake-pipeline/spec/matcher_spec.rb +141 -0
- data/vendor/rake-pipeline/spec/middleware_spec.rb +199 -0
- data/vendor/rake-pipeline/spec/ordering_concat_filter_spec.rb +42 -0
- data/vendor/rake-pipeline/spec/pipeline_spec.rb +232 -0
- data/vendor/rake-pipeline/spec/project_spec.rb +295 -0
- data/vendor/rake-pipeline/spec/rake_acceptance_spec.rb +720 -0
- data/vendor/rake-pipeline/spec/rake_tasks_spec.rb +21 -0
- data/vendor/rake-pipeline/spec/reject_matcher_spec.rb +31 -0
- data/vendor/rake-pipeline/spec/sorted_pipeline_spec.rb +27 -0
- data/vendor/rake-pipeline/spec/spec_helper.rb +38 -0
- data/vendor/rake-pipeline/spec/support/spec_helpers/file_utils.rb +35 -0
- data/vendor/rake-pipeline/spec/support/spec_helpers/filters.rb +37 -0
- data/vendor/rake-pipeline/spec/support/spec_helpers/input_helpers.rb +23 -0
- data/vendor/rake-pipeline/spec/support/spec_helpers/memory_file_wrapper.rb +35 -0
- data/vendor/rake-pipeline/spec/support/spec_helpers/memory_manifest.rb +19 -0
- data/vendor/rake-pipeline/tools/perfs +101 -0
- metadata +497 -0
@@ -0,0 +1 @@
|
|
1
|
+
-c -f progress --order random -r spec_helper.rb
|
@@ -0,0 +1,268 @@
|
|
1
|
+
# Rake::Pipeline Basics
|
2
|
+
|
3
|
+
`Rake::Pipeline` provides a basic extraction over a build process. It
|
4
|
+
doesn't have many filters out of the box, but it is very powerful. This
|
5
|
+
guide gives you an introduction to `Rake::Pipeline`. `Rake::Pipeline`
|
6
|
+
was originally designed for frontend development (HTML, CSS,
|
7
|
+
Javascript). The examples assume this type of project just to create
|
8
|
+
some context.
|
9
|
+
|
10
|
+
## Getting Started
|
11
|
+
|
12
|
+
`Rake::Pipeline` comes with two main functionalities out of the box:
|
13
|
+
matching and concatentation. You can specify a match (IE: all css files)
|
14
|
+
then run them through a concatenation filter (combine them into one
|
15
|
+
file). There is also an order concatenation filter which allows you to
|
16
|
+
specify order (A should come before B).
|
17
|
+
|
18
|
+
Your pipeline is written in an `Assetfile`. The `Assetfile` uses a nice
|
19
|
+
DSL to make things easier. The `Assetfile` should live in your project's
|
20
|
+
root directory.
|
21
|
+
|
22
|
+
Let's get started by writing a basic pipeline. Assume we have this
|
23
|
+
directory structure:
|
24
|
+
|
25
|
+
```
|
26
|
+
/source
|
27
|
+
/css
|
28
|
+
/javascript
|
29
|
+
/compiled
|
30
|
+
Assetfile
|
31
|
+
```
|
32
|
+
|
33
|
+
The pipeline should simply concatenate all the individual JSS and CSS
|
34
|
+
files into single files. So the JSS and CSS directories are the inputs
|
35
|
+
and 2 files are outputs. The `source` directory is input and the output
|
36
|
+
will go into `compiled`. Here's the `Assetfile` to do just that:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# input defines operations on a set of files. All files processed in
|
40
|
+
# this block go into the output directory
|
41
|
+
input "source" do
|
42
|
+
|
43
|
+
# Select all the CSS files
|
44
|
+
match "css/**/*.css" do
|
45
|
+
|
46
|
+
# concatenate all files in directory into a file named
|
47
|
+
# "application.css"
|
48
|
+
concat "application.css"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Repeat for javascript files
|
52
|
+
match "javascript/**/*.js" do
|
53
|
+
concat "application.js"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Set the Pipeline's output directory
|
58
|
+
output "compiled"
|
59
|
+
```
|
60
|
+
|
61
|
+
Now run `rakep build` from the project root to compile everything.
|
62
|
+
Given there are files in `source/css` and `source/javascript` you will
|
63
|
+
see files in `compiled` named `application.js` and `application.css`.
|
64
|
+
You've just written your first pipeline!
|
65
|
+
|
66
|
+
## Previewing Your Work
|
67
|
+
|
68
|
+
`Rake::Pipeline` also comes with a bundled preview server. Let's add an
|
69
|
+
HTML file to the source directory to serve the compiled site. Here's the
|
70
|
+
HTML:
|
71
|
+
|
72
|
+
```html
|
73
|
+
<!-- source/index.html -->
|
74
|
+
|
75
|
+
<!DOCTYPE html>
|
76
|
+
<html>
|
77
|
+
<head>
|
78
|
+
<meta charset="utf-8">
|
79
|
+
<title>Rake::Pipeline Example</title>
|
80
|
+
<link rel="stylesheet" href="/application.css">
|
81
|
+
</head>
|
82
|
+
<body>
|
83
|
+
<script src="/application.js"></script>
|
84
|
+
</body>
|
85
|
+
</html>
|
86
|
+
```
|
87
|
+
|
88
|
+
Save that file in `source/index.html`. Now we must add some more code to
|
89
|
+
the `Assetfile` to copy the HTML file into the output directory.
|
90
|
+
`Rake::Pipeline` also bundles a copy filter. Note that this isn't
|
91
|
+
actually a separate filter, but a file that concatenates itself to a
|
92
|
+
different location. In short, `concat` is aliased to `copy` as well.
|
93
|
+
Here's the updated `Assetfile`:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
# input defines operations on a set of files. All files processed in
|
97
|
+
# this block go into the output directory
|
98
|
+
input "source" do
|
99
|
+
|
100
|
+
# Select all the CSS files
|
101
|
+
match "css/**/*.css" do
|
102
|
+
|
103
|
+
# concatenate all files in directory into a file named
|
104
|
+
# "application.css"
|
105
|
+
concat "application.css"
|
106
|
+
end
|
107
|
+
|
108
|
+
# Repeat for javascript files
|
109
|
+
match "javascript/**/*.js" do
|
110
|
+
concat "application.js"
|
111
|
+
end
|
112
|
+
|
113
|
+
# Explicitly select the HTML file. We don't want to copy
|
114
|
+
# over anything else
|
115
|
+
match "index.html" do
|
116
|
+
|
117
|
+
# copy also accepts a block. When called without any arguments it
|
118
|
+
# simply uses the same filename
|
119
|
+
copy
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Set the Pipeline's output directory
|
124
|
+
output "compiled"
|
125
|
+
```
|
126
|
+
|
127
|
+
Now we can run `rakep server` inside the projects root. You'll see some
|
128
|
+
output in the terminal with a URL to connect to. Now you an preview your
|
129
|
+
work as you go.
|
130
|
+
|
131
|
+
## Writing Filters
|
132
|
+
|
133
|
+
It's very likely that you'll need to do more than just copy and
|
134
|
+
concatenate files. You must write your own filters to do this. Luckily,
|
135
|
+
writing filters is pretty easy. Filters are classes that have
|
136
|
+
`generate_output` method. This is core API requirement. There also other
|
137
|
+
method you may implement, but this is the most important. Let's take a
|
138
|
+
stab at writing a coffeescript filter.
|
139
|
+
|
140
|
+
Filters are Ruby classes. They map a set of inputs to outputs and
|
141
|
+
finally generate the output. Here is an absolute bare bones filter:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
# Inherit from Rake::Pipeline::Filter to get basic API implemented
|
145
|
+
class CoffeeScriptFilter < Rake::Pipeline::Filter
|
146
|
+
|
147
|
+
# This method takes the input files and does whatever is required
|
148
|
+
# to generate the proper output.
|
149
|
+
def generate_output(inputs, output)
|
150
|
+
inputs.each do |input|
|
151
|
+
output.write input.read
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
```
|
156
|
+
|
157
|
+
Notice `generate_output`'s method signature: `inputs` and `output`. The
|
158
|
+
default semantic is to take N input files and map them to one output
|
159
|
+
file. You can overide this or do much more fancy things. This is covered
|
160
|
+
in a different file. We could use this filter like this:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
input "source" do
|
164
|
+
match "**/*.coffee" do
|
165
|
+
filter CoffeeScript
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
output "compiled"
|
170
|
+
```
|
171
|
+
|
172
|
+
Now this filter doesn't do anything at the moment besides copy the
|
173
|
+
files. Time to implement coffeescript compiling.
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
require "coffee-script"
|
177
|
+
|
178
|
+
class CoffeeScriptFilter < Rake::Pipeline::Filter
|
179
|
+
def generate_output(inputs, output)
|
180
|
+
inputs.each do |input|
|
181
|
+
output.write CoffeeScript.compile(input.read)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
187
|
+
Great! Now the CoffeeScript files are compiled to JavaScript. However,
|
188
|
+
you may have noticed they are compiled "in place". This means
|
189
|
+
`source/app.coffee` will become `source/app.coffee` but as JavaScript.
|
190
|
+
This works in our simple example, but what happens when we need to work
|
191
|
+
with Javascript later in the pipeline or next build steps expect ".js"
|
192
|
+
files? The filter has to customize the name. The most correct thing to
|
193
|
+
do is make the output file has the same name except as ".js".
|
194
|
+
|
195
|
+
This behavior is defined in the filter's initializer. This may seem odd
|
196
|
+
to you. It was odd to me until I understood what was happening.
|
197
|
+
`Rake::Pipeline` instantiates all the filters in order to setup how
|
198
|
+
input files map to output files before the pipeline is compiled. This is
|
199
|
+
how one filter can use another's outputs for inputs. This order must be
|
200
|
+
known at compile time, so that's why it happens here. The internal API
|
201
|
+
expects a block that takes a path and maps it to an output path.
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
require "coffee-script"
|
205
|
+
|
206
|
+
class CoffeeScriptFilter < Rake::Pipeline::Filter
|
207
|
+
def initialize(&block)
|
208
|
+
&block ||= proc { |input| input.path.gsub(/\.coffee, ".js")
|
209
|
+
super(&block)
|
210
|
+
end
|
211
|
+
|
212
|
+
def generate_output(inputs, output)
|
213
|
+
inputs.each do |input|
|
214
|
+
output.write CoffeeScript.compile(input.read)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
```
|
219
|
+
|
220
|
+
Let's take a fresh look at the `Assetfile` now.
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
input "source" do
|
224
|
+
match "javascript/**/*.coffee" do
|
225
|
+
# Compile all .coffee files into.js
|
226
|
+
filter CoffeeScript
|
227
|
+
end
|
228
|
+
|
229
|
+
# Select the JS generated by previous filters.
|
230
|
+
match "javascript/**/*.js" do
|
231
|
+
concat "application.js"
|
232
|
+
end
|
233
|
+
|
234
|
+
match "css/**/*.css" do
|
235
|
+
concat "application.css"
|
236
|
+
end
|
237
|
+
|
238
|
+
match "index.html" do
|
239
|
+
copy
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
output "compiled"
|
244
|
+
```
|
245
|
+
|
246
|
+
Calling the filter without a block uses the default block in the filter.
|
247
|
+
The default block that replaces ".js" with ".coffee". This is defined
|
248
|
+
with `||=` in the initializer. Conversely you could call `filter` with a
|
249
|
+
block and do what you want. Here's an example:
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
# output all coffeescript files as "app.coffee.awesome"
|
253
|
+
filter CoffeeScript do |input|
|
254
|
+
"#{input.path}.awesome"
|
255
|
+
end
|
256
|
+
```
|
257
|
+
|
258
|
+
That covers the basics of writing filters. There is much more you can do
|
259
|
+
with filters that are outside the scope of this guide. You can find many
|
260
|
+
useful (as well as plenty of examples) in the
|
261
|
+
[rake-pipeline-web-filters](https://github.com/wycats/rake-pipeline-web-filters)
|
262
|
+
project.
|
263
|
+
|
264
|
+
That also concludes this guide. You should know everything you need to
|
265
|
+
know to get started writing your own pipelines now. There is still much
|
266
|
+
to cover though. You can find additonal information in the `examples`
|
267
|
+
directory. If you'd like to add anything to this guide or find an error
|
268
|
+
please open a pull request to fix it.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (C) 2011 by LivingSocial, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
20
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Rake::Pipeline
|
2
|
+
|
3
|
+
The canonical documentation for Rake::Pipeline is hosted at
|
4
|
+
<a href="http://rubydoc.info/github/livingsocial/rake-pipeline/master/file/README.yard">rubydoc.info</a>.
|
5
|
+
|
6
|
+
New users are recommended to read `GETTING_STARTED.md` before anything
|
7
|
+
else. Additional examples can be found in the `examples` directory.
|
8
|
+
|
9
|
+
Users are also recommended to checkout
|
10
|
+
[rake-pipeline-web-filters](https://github.com/wycats/rake-pipeline-web-filters)
|
11
|
+
for commonly used filters.
|
@@ -0,0 +1,178 @@
|
|
1
|
+
= Rake::Pipeline
|
2
|
+
|
3
|
+
Rake::Pipeline is a system for packaging assets for deployment to the
|
4
|
+
web. It uses Rake under the hood for dependency management and updating
|
5
|
+
output files based on input changes.
|
6
|
+
|
7
|
+
= Usage
|
8
|
+
|
9
|
+
The easiest way to use Rake::Pipeline is via an +Assetfile+ file in the
|
10
|
+
root of your project.
|
11
|
+
|
12
|
+
A sample +Assetfile+ looks like this:
|
13
|
+
|
14
|
+
!!!ruby
|
15
|
+
output "public"
|
16
|
+
|
17
|
+
input "assets" do
|
18
|
+
# this block will take all JS inputs, wrap them in a closure,
|
19
|
+
# add some additional metadata, and concatenate them all into
|
20
|
+
# application.scripts.js.
|
21
|
+
match "*.js" do
|
22
|
+
filter ClosureWrapper
|
23
|
+
filter DataWrapper
|
24
|
+
concat "application.scripts.js"
|
25
|
+
end
|
26
|
+
|
27
|
+
# this block will take all HTML and CSS inputs, convert them
|
28
|
+
# into JavaScript
|
29
|
+
match "*/*.{html,css}" do
|
30
|
+
filter DataWrapper
|
31
|
+
concat "application.assets.js"
|
32
|
+
end
|
33
|
+
|
34
|
+
match "*.js" do
|
35
|
+
concat "application.js"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Each +input+ block defines a collection of files, and a pipeline
|
40
|
+
that transforms those files. Within each pipeline, you can specify
|
41
|
+
a series of filters to describe the transformations you'd like to
|
42
|
+
apply to the files.
|
43
|
+
|
44
|
+
= Upgrading from Previous Versions
|
45
|
+
|
46
|
+
The +Assetfile+ syntax has changed in version 0.6.0. In previous
|
47
|
+
versions, each +Assetfile+ defined a single pipeline, and +input+
|
48
|
+
statements would add input files to that pipeline. After version
|
49
|
+
0.6.0, multiple pipelines can be defined in an +Assetfile+. The
|
50
|
+
+input+ method now takes a block, and this block defines a pipeline.
|
51
|
+
This means that any +match+ blocks or filters must be defined
|
52
|
+
inside an +input+ block, and no longer at the top level. For example,
|
53
|
+
this:
|
54
|
+
|
55
|
+
!!!ruby
|
56
|
+
# Prior to 0.6.0
|
57
|
+
output "public"
|
58
|
+
input "assets"
|
59
|
+
|
60
|
+
match "**/*.js" do
|
61
|
+
concat
|
62
|
+
end
|
63
|
+
|
64
|
+
would now be written as:
|
65
|
+
|
66
|
+
!!!ruby
|
67
|
+
# After 0.6.0
|
68
|
+
output "public"
|
69
|
+
|
70
|
+
input "assets" do
|
71
|
+
match "**/*.js" do
|
72
|
+
concat
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
= Filters
|
77
|
+
|
78
|
+
A filter is a simple class that inherits from
|
79
|
+
{Rake::Pipeline::Filter}. A filter must implement a single
|
80
|
+
method, called +generate_output+, which takes
|
81
|
+
two parameters: a list of input files and the output file.
|
82
|
+
|
83
|
+
Both the input and output files are {Rake::Pipeline::FileWrapper} objects.
|
84
|
+
The most important methods on a {Rake::Pipeline::FileWrapper FileWrapper} are:
|
85
|
+
|
86
|
+
* {Rake::Pipeline::FileWrapper#path path}: the path of the file, relative to its input root
|
87
|
+
* {Rake::Pipeline::FileWrapper#read read}: read the contents of the file
|
88
|
+
* {Rake::Pipeline::FileWrapper#write write(string)}: write a String to the file
|
89
|
+
|
90
|
+
For example, a simple concatenation filter would look like:
|
91
|
+
|
92
|
+
!!!ruby
|
93
|
+
class ConcatFilter < Rake::Pipeline::Filter
|
94
|
+
def generate_output(inputs, output)
|
95
|
+
inputs.each do |input|
|
96
|
+
output.write input.read
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
If you had a series of input files like:
|
102
|
+
|
103
|
+
* +app/javascripts/one.js+
|
104
|
+
* +app/javascripts/two.js+
|
105
|
+
* +app/javascripts/three.js+
|
106
|
+
|
107
|
+
and you specified the +ConcatFilter+ in your
|
108
|
+
+Assetfile+ like:
|
109
|
+
|
110
|
+
!!!ruby
|
111
|
+
filter ConcatFilter, "application.js"
|
112
|
+
|
113
|
+
The filter would receive a single call to
|
114
|
+
+generate_output+ with an Array of {Rake::Pipeline::FileWrapper FileWrapper}s
|
115
|
+
representing each of the three files, and a {Rake::Pipeline::FileWrapper FileWrapper}
|
116
|
+
representing +application.js+.
|
117
|
+
|
118
|
+
== Binary Data
|
119
|
+
|
120
|
+
If your filter is operating on binary data, like images,
|
121
|
+
rather than textual data, like source code, you can specify
|
122
|
+
that in your filter:
|
123
|
+
|
124
|
+
!!!ruby
|
125
|
+
class ConcatFilter < Rake::Pipeline::Filter
|
126
|
+
processes_binary_files
|
127
|
+
|
128
|
+
def generate_output(inputs, output)
|
129
|
+
inputs.each do |input|
|
130
|
+
output.write input.read
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
This will stop `Rake::Pipeline` from trying to interpret the
|
136
|
+
input files as `UTF-8`, which obviously will not work on
|
137
|
+
binary data.
|
138
|
+
|
139
|
+
= Filters
|
140
|
+
|
141
|
+
+Rake::Pipeline+ comes with a built-in filter,
|
142
|
+
{Rake::Pipeline::ConcatFilter}. Its implementation is the same as the
|
143
|
+
+ConcatFilter+ above. Other filters that are useful for web development
|
144
|
+
like a +CoffeeScriptFilter+ and +SassFilter+ are available in
|
145
|
+
[rake-pipeline-web-filters](https://github.com/wycats/rake-pipeline-web-filters).
|
146
|
+
|
147
|
+
= Preview Server
|
148
|
+
|
149
|
+
To start up the preview server, run +rakep server+. This will start up
|
150
|
+
a server that automatically recompiles files for you on the fly
|
151
|
+
and serves up the files you need.
|
152
|
+
|
153
|
+
This should allow you to have a single index.html file pointing
|
154
|
+
at the same files in both development and production.
|
155
|
+
|
156
|
+
= Compiling Assets
|
157
|
+
|
158
|
+
To compile all assets before deployment, simply run:
|
159
|
+
|
160
|
+
$ rakep build
|
161
|
+
|
162
|
+
= Encodings
|
163
|
+
|
164
|
+
If a filter does not specify that it processes binary files,
|
165
|
+
+Rake::Pipeline+ will open all inputs and outputs as +UTF-8+.
|
166
|
+
|
167
|
+
This means that if you have files encoded in other encodings,
|
168
|
+
like +Latin-1+, +Rake::Pipeline+ will raise an exception. In
|
169
|
+
this situation, you need to open the offending file in your
|
170
|
+
text editor and re-save it as +UTF-8+.
|
171
|
+
|
172
|
+
= Public Release Requirement
|
173
|
+
|
174
|
+
Before publicly releasing this code, we need to properly support
|
175
|
+
encodings other than UTF-8. That means using the
|
176
|
+
+default_external+ instead of hardcoding to UTF-8 and
|
177
|
+
providing a mechanism for specifying the encoding of a file using
|
178
|
+
a magic comment.
|