benoit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/.gitignore +4 -0
  2. data/.gitmodules +3 -0
  3. data/.rspec +1 -0
  4. data/.rspec-turnip +1 -0
  5. data/.ruby-version +1 -0
  6. data/Assetfile +44 -0
  7. data/Gemfile +5 -0
  8. data/Gemfile.lock +110 -0
  9. data/Rakefile +9 -0
  10. data/benoit.gemspec +50 -0
  11. data/bin/benoit +121 -0
  12. data/bin/bundle-development +1 -0
  13. data/bin/bundle-sandbox +1 -0
  14. data/lib/benoit.rb +36 -0
  15. data/lib/benoit/cadenza.rb +11 -0
  16. data/lib/benoit/cadenza/output_filters.rb +21 -0
  17. data/lib/benoit/cleaner.rb +10 -0
  18. data/lib/benoit/compiler_error.rb +49 -0
  19. data/lib/benoit/configuration.rb +24 -0
  20. data/lib/benoit/current_site.rb +12 -0
  21. data/lib/benoit/file_wrapper_extensions.rb +13 -0
  22. data/lib/benoit/filters.rb +15 -0
  23. data/lib/benoit/filters/base_filter.rb +44 -0
  24. data/lib/benoit/filters/blacklist_filter.rb +18 -0
  25. data/lib/benoit/filters/cadenza_filter.rb +75 -0
  26. data/lib/benoit/filters/content_page_filter.rb +45 -0
  27. data/lib/benoit/filters/markdown_filter.rb +19 -0
  28. data/lib/benoit/filters/metadata_cleaner.rb +30 -0
  29. data/lib/benoit/filters/move_to_root_filter.rb +22 -0
  30. data/lib/benoit/filters/pagination_filter.rb +23 -0
  31. data/lib/benoit/filters/pass_thru_filter.rb +22 -0
  32. data/lib/benoit/filters/sass_filter.rb +74 -0
  33. data/lib/benoit/filters/set_metadata_filter.rb +15 -0
  34. data/lib/benoit/logger.rb +69 -0
  35. data/lib/benoit/page.rb +88 -0
  36. data/lib/benoit/page_metadata.rb +8 -0
  37. data/lib/benoit/page_metadata/container.rb +74 -0
  38. data/lib/benoit/page_metadata/json_converter.rb +28 -0
  39. data/lib/benoit/page_metadata/parser.rb +38 -0
  40. data/lib/benoit/page_metadata/store.rb +75 -0
  41. data/lib/benoit/pipeline.rb +1 -0
  42. data/lib/benoit/pipeline/dsl_extensions.rb +8 -0
  43. data/lib/benoit/pipeline/pagination_matcher.rb +53 -0
  44. data/lib/benoit/pipeline_project.rb +81 -0
  45. data/lib/benoit/site_context.rb +123 -0
  46. data/lib/benoit/utils/finds_layouts_for_template.rb +77 -0
  47. data/lib/benoit/utils/normalizes_path_to_template.rb +43 -0
  48. data/lib/benoit/utils/paginated_list.rb +102 -0
  49. data/lib/benoit/version.rb +3 -0
  50. data/lib/build_notifiers/file_built_notifier.rb +20 -0
  51. data/lib/build_notifiers/progress_notifier.rb +57 -0
  52. data/lib/cli.rb +39 -0
  53. data/spec/.rbenv-gemsets +1 -0
  54. data/spec/Gemfile +9 -0
  55. data/spec/Gemfile.lock +57 -0
  56. data/spec/bin/autospec +16 -0
  57. data/spec/bin/cucumber +16 -0
  58. data/spec/bin/htmldiff +16 -0
  59. data/spec/bin/ldiff +16 -0
  60. data/spec/bin/rspec +16 -0
  61. data/spec/features/build_command.feature +46 -0
  62. data/spec/features/frontmatter_metadata.feature +99 -0
  63. data/spec/features/javascript_files.feature +35 -0
  64. data/spec/features/output_filters.feature +20 -0
  65. data/spec/features/page_layouts.feature +72 -0
  66. data/spec/features/pagination.feature +58 -0
  67. data/spec/features/sass_files.feature +30 -0
  68. data/spec/features/version.feature +5 -0
  69. data/spec/lib/filters/base_filter_spec.rb +141 -0
  70. data/spec/lib/filters/markdown_filter_spec.rb +65 -0
  71. data/spec/lib/filters/sass_filter_spec.rb +73 -0
  72. data/spec/lib/metadata_json_converter_spec.rb +65 -0
  73. data/spec/lib/metadata_store_spec.rb +148 -0
  74. data/spec/lib/page_spec.rb +19 -0
  75. data/spec/lib/site_context_spec.rb +106 -0
  76. data/spec/spec_helper.rb +16 -0
  77. data/spec/steps/output_file_steps.rb +45 -0
  78. data/spec/steps/run_steps.rb +71 -0
  79. data/spec/steps/staticly_steps.rb +194 -0
  80. data/spec/support/aruba/rspec.rb +66 -0
  81. data/spec/support/files/img.png +0 -0
  82. data/spec/support/files/input.css.scss +7 -0
  83. data/spec/support/files/input.scss +7 -0
  84. data/spec/support/spec_helpers/file_helpers.rb +8 -0
  85. data/spec/support/spec_helpers/memory_file_wrapper.rb +43 -0
  86. data/spec/support/spec_helpers/memory_manifest.rb +19 -0
  87. data/spec/turnip_helper.rb +19 -0
  88. data/vendor/frontmatter/frontmatter.gemspec +24 -0
  89. data/vendor/frontmatter/lib/frontmatter.rb +92 -0
  90. data/vendor/frontmatter/lib/frontmatter/version.rb +3 -0
  91. data/vendor/rake-pipeline/.gitignore +18 -0
  92. data/vendor/rake-pipeline/.rspec +1 -0
  93. data/vendor/rake-pipeline/.travis.yml +12 -0
  94. data/vendor/rake-pipeline/.yardopts +2 -0
  95. data/vendor/rake-pipeline/GETTING_STARTED.md +268 -0
  96. data/vendor/rake-pipeline/Gemfile +14 -0
  97. data/vendor/rake-pipeline/LICENSE +20 -0
  98. data/vendor/rake-pipeline/README.markdown +11 -0
  99. data/vendor/rake-pipeline/README.yard +178 -0
  100. data/vendor/rake-pipeline/Rakefile +21 -0
  101. data/vendor/rake-pipeline/bin/rakep +4 -0
  102. data/vendor/rake-pipeline/examples/copying_files.md +12 -0
  103. data/vendor/rake-pipeline/examples/minifying_files.md +37 -0
  104. data/vendor/rake-pipeline/examples/modifying_pipelines.md +67 -0
  105. data/vendor/rake-pipeline/examples/multiple_pipelines.md +77 -0
  106. data/vendor/rake-pipeline/lib/generators/rake/pipeline/install/install_generator.rb +70 -0
  107. data/vendor/rake-pipeline/lib/rake-pipeline.rb +509 -0
  108. data/vendor/rake-pipeline/lib/rake-pipeline/cli.rb +57 -0
  109. data/vendor/rake-pipeline/lib/rake-pipeline/dsl.rb +9 -0
  110. data/vendor/rake-pipeline/lib/rake-pipeline/dsl/pipeline_dsl.rb +246 -0
  111. data/vendor/rake-pipeline/lib/rake-pipeline/dsl/project_dsl.rb +108 -0
  112. data/vendor/rake-pipeline/lib/rake-pipeline/dynamic_file_task.rb +194 -0
  113. data/vendor/rake-pipeline/lib/rake-pipeline/error.rb +17 -0
  114. data/vendor/rake-pipeline/lib/rake-pipeline/file_wrapper.rb +195 -0
  115. data/vendor/rake-pipeline/lib/rake-pipeline/filter.rb +267 -0
  116. data/vendor/rake-pipeline/lib/rake-pipeline/filters.rb +4 -0
  117. data/vendor/rake-pipeline/lib/rake-pipeline/filters/concat_filter.rb +63 -0
  118. data/vendor/rake-pipeline/lib/rake-pipeline/filters/gsub_filter.rb +56 -0
  119. data/vendor/rake-pipeline/lib/rake-pipeline/filters/ordering_concat_filter.rb +38 -0
  120. data/vendor/rake-pipeline/lib/rake-pipeline/filters/pipeline_finalizing_filter.rb +21 -0
  121. data/vendor/rake-pipeline/lib/rake-pipeline/graph.rb +178 -0
  122. data/vendor/rake-pipeline/lib/rake-pipeline/manifest.rb +82 -0
  123. data/vendor/rake-pipeline/lib/rake-pipeline/manifest_entry.rb +34 -0
  124. data/vendor/rake-pipeline/lib/rake-pipeline/matcher.rb +141 -0
  125. data/vendor/rake-pipeline/lib/rake-pipeline/middleware.rb +73 -0
  126. data/vendor/rake-pipeline/lib/rake-pipeline/precompile.rake +8 -0
  127. data/vendor/rake-pipeline/lib/rake-pipeline/project.rb +338 -0
  128. data/vendor/rake-pipeline/lib/rake-pipeline/rails_plugin.rb +10 -0
  129. data/vendor/rake-pipeline/lib/rake-pipeline/railtie.rb +34 -0
  130. data/vendor/rake-pipeline/lib/rake-pipeline/reject_matcher.rb +29 -0
  131. data/vendor/rake-pipeline/lib/rake-pipeline/server.rb +15 -0
  132. data/vendor/rake-pipeline/lib/rake-pipeline/sorted_pipeline.rb +19 -0
  133. data/vendor/rake-pipeline/lib/rake-pipeline/version.rb +6 -0
  134. data/vendor/rake-pipeline/rails/init.rb +2 -0
  135. data/vendor/rake-pipeline/rake-pipeline.gemspec +24 -0
  136. data/vendor/rake-pipeline/spec/cli_spec.rb +73 -0
  137. data/vendor/rake-pipeline/spec/concat_filter_spec.rb +37 -0
  138. data/vendor/rake-pipeline/spec/dsl/pipeline_dsl_spec.rb +165 -0
  139. data/vendor/rake-pipeline/spec/dsl/project_dsl_spec.rb +41 -0
  140. data/vendor/rake-pipeline/spec/dynamic_file_task_spec.rb +119 -0
  141. data/vendor/rake-pipeline/spec/encoding_spec.rb +106 -0
  142. data/vendor/rake-pipeline/spec/file_wrapper_spec.rb +132 -0
  143. data/vendor/rake-pipeline/spec/filter_spec.rb +367 -0
  144. data/vendor/rake-pipeline/spec/graph_spec.rb +56 -0
  145. data/vendor/rake-pipeline/spec/gsub_filter_spec.rb +87 -0
  146. data/vendor/rake-pipeline/spec/manifest_entry_spec.rb +46 -0
  147. data/vendor/rake-pipeline/spec/manifest_spec.rb +67 -0
  148. data/vendor/rake-pipeline/spec/matcher_spec.rb +141 -0
  149. data/vendor/rake-pipeline/spec/middleware_spec.rb +199 -0
  150. data/vendor/rake-pipeline/spec/ordering_concat_filter_spec.rb +42 -0
  151. data/vendor/rake-pipeline/spec/pipeline_spec.rb +232 -0
  152. data/vendor/rake-pipeline/spec/project_spec.rb +295 -0
  153. data/vendor/rake-pipeline/spec/rake_acceptance_spec.rb +720 -0
  154. data/vendor/rake-pipeline/spec/rake_tasks_spec.rb +21 -0
  155. data/vendor/rake-pipeline/spec/reject_matcher_spec.rb +31 -0
  156. data/vendor/rake-pipeline/spec/sorted_pipeline_spec.rb +27 -0
  157. data/vendor/rake-pipeline/spec/spec_helper.rb +38 -0
  158. data/vendor/rake-pipeline/spec/support/spec_helpers/file_utils.rb +35 -0
  159. data/vendor/rake-pipeline/spec/support/spec_helpers/filters.rb +37 -0
  160. data/vendor/rake-pipeline/spec/support/spec_helpers/input_helpers.rb +23 -0
  161. data/vendor/rake-pipeline/spec/support/spec_helpers/memory_file_wrapper.rb +35 -0
  162. data/vendor/rake-pipeline/spec/support/spec_helpers/memory_manifest.rb +19 -0
  163. data/vendor/rake-pipeline/tools/perfs +101 -0
  164. metadata +497 -0
@@ -0,0 +1,3 @@
1
+ module Frontmatter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbx
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ devbin
@@ -0,0 +1 @@
1
+ -c -f progress --order random -r spec_helper.rb
@@ -0,0 +1,12 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - ruby-head
5
+ - jruby-head
6
+
7
+ bundler_args: --without docs
8
+
9
+ notifications:
10
+ email:
11
+ - wycats@gmail.com
12
+ - dudley@steambone.org
@@ -0,0 +1,2 @@
1
+ --readme README.yard
2
+
@@ -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,14 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rake-pipeline.gemspec
4
+ gemspec
5
+ gem "flay"
6
+ gem "flog"
7
+
8
+ gem "simplecov", :require => false
9
+ gem "pry"
10
+
11
+ group :docs do
12
+ gem "yard"
13
+ gem "rdiscount"
14
+ end
@@ -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.