rake-pipeline-fork 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +12 -0
  5. data/.yardopts +2 -0
  6. data/GETTING_STARTED.md +268 -0
  7. data/Gemfile +14 -0
  8. data/LICENSE +20 -0
  9. data/README.markdown +11 -0
  10. data/README.yard +178 -0
  11. data/Rakefile +21 -0
  12. data/bin/rakep +4 -0
  13. data/examples/copying_files.md +12 -0
  14. data/examples/minifying_files.md +37 -0
  15. data/examples/modifying_pipelines.md +67 -0
  16. data/examples/multiple_pipelines.md +77 -0
  17. data/lib/generators/rake/pipeline/install/install_generator.rb +70 -0
  18. data/lib/rake-pipeline.rb +462 -0
  19. data/lib/rake-pipeline/cli.rb +56 -0
  20. data/lib/rake-pipeline/dsl.rb +9 -0
  21. data/lib/rake-pipeline/dsl/pipeline_dsl.rb +246 -0
  22. data/lib/rake-pipeline/dsl/project_dsl.rb +108 -0
  23. data/lib/rake-pipeline/dynamic_file_task.rb +194 -0
  24. data/lib/rake-pipeline/error.rb +17 -0
  25. data/lib/rake-pipeline/file_wrapper.rb +182 -0
  26. data/lib/rake-pipeline/filter.rb +249 -0
  27. data/lib/rake-pipeline/filters.rb +4 -0
  28. data/lib/rake-pipeline/filters/concat_filter.rb +63 -0
  29. data/lib/rake-pipeline/filters/gsub_filter.rb +56 -0
  30. data/lib/rake-pipeline/filters/ordering_concat_filter.rb +38 -0
  31. data/lib/rake-pipeline/filters/pipeline_finalizing_filter.rb +21 -0
  32. data/lib/rake-pipeline/graph.rb +178 -0
  33. data/lib/rake-pipeline/manifest.rb +86 -0
  34. data/lib/rake-pipeline/manifest_entry.rb +34 -0
  35. data/lib/rake-pipeline/matcher.rb +141 -0
  36. data/lib/rake-pipeline/middleware.rb +72 -0
  37. data/lib/rake-pipeline/precompile.rake +8 -0
  38. data/lib/rake-pipeline/project.rb +335 -0
  39. data/lib/rake-pipeline/rails_plugin.rb +10 -0
  40. data/lib/rake-pipeline/railtie.rb +34 -0
  41. data/lib/rake-pipeline/reject_matcher.rb +29 -0
  42. data/lib/rake-pipeline/server.rb +15 -0
  43. data/lib/rake-pipeline/sorted_pipeline.rb +19 -0
  44. data/lib/rake-pipeline/version.rb +6 -0
  45. data/rails/init.rb +2 -0
  46. data/rake-pipeline.gemspec +24 -0
  47. data/spec/cli_spec.rb +71 -0
  48. data/spec/concat_filter_spec.rb +37 -0
  49. data/spec/dsl/pipeline_dsl_spec.rb +165 -0
  50. data/spec/dsl/project_dsl_spec.rb +41 -0
  51. data/spec/dynamic_file_task_spec.rb +119 -0
  52. data/spec/encoding_spec.rb +106 -0
  53. data/spec/file_wrapper_spec.rb +132 -0
  54. data/spec/filter_spec.rb +332 -0
  55. data/spec/graph_spec.rb +56 -0
  56. data/spec/gsub_filter_spec.rb +87 -0
  57. data/spec/manifest_entry_spec.rb +46 -0
  58. data/spec/manifest_spec.rb +67 -0
  59. data/spec/matcher_spec.rb +141 -0
  60. data/spec/middleware_spec.rb +199 -0
  61. data/spec/ordering_concat_filter_spec.rb +42 -0
  62. data/spec/pipeline_spec.rb +232 -0
  63. data/spec/project_spec.rb +295 -0
  64. data/spec/rake_acceptance_spec.rb +738 -0
  65. data/spec/rake_tasks_spec.rb +21 -0
  66. data/spec/reject_matcher_spec.rb +31 -0
  67. data/spec/sorted_pipeline_spec.rb +27 -0
  68. data/spec/spec_helper.rb +38 -0
  69. data/spec/support/spec_helpers/file_utils.rb +35 -0
  70. data/spec/support/spec_helpers/filters.rb +37 -0
  71. data/spec/support/spec_helpers/input_helpers.rb +23 -0
  72. data/spec/support/spec_helpers/memory_file_wrapper.rb +31 -0
  73. data/spec/support/spec_helpers/memory_manifest.rb +19 -0
  74. data/tools/perfs +101 -0
  75. metadata +215 -0
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NGIzYWYzYzBiN2VjZDI5ZTAyMjMxMDYxNGI4YTQ3OTgyZGI3OGQ3OQ==
5
+ data.tar.gz: !binary |-
6
+ M2RiMzExYWU2YzE0NTc4M2UxYzQ2OGI3OGE4ZDY5ZTgyN2NkOTZhZQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjY5OGRlOThhOTkyNjliM2E3YjM4MmMxNmU4ZWQ3NmE5MDRjNmIzOThkZWMx
10
+ ZWZkNDEzZTRkMWI1MDRkZGYyNmEyZWYxODg2MTc5NWE4YzM5YjRkNmRjMGZm
11
+ YjUyZGMxY2U3NDQwNDM4ZjhlYThkY2E0MjBhNmVjMzkwZmU5NmU=
12
+ data.tar.gz: !binary |-
13
+ M2RlM2ZkODQwMDNjYjE1MmU1ZGE0YjkxODkwZTExMmFkOTFiN2RjYTAzNTk2
14
+ MDlhY2M2ZDAwNzhlODFhNjIxOTY1MGQ0ZDRiNDliZTViYTAxNzQ2Y2I5ZDAx
15
+ OTk1Nzk5ZWE5ZmM2NDlmZWJjNjc3NTQxZGQwZDQ4YjExZDJkMWU=
@@ -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
data/.rspec ADDED
@@ -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
+ # Set the Pipeline's output directory
40
+ output "compiled"
41
+
42
+ # input defines operations on a set of files. All files processed in
43
+ # this block go into the output directory
44
+ input "source" do
45
+
46
+ # Select all the CSS files
47
+ match "css/**/*.css" do
48
+
49
+ # concatenate all files in directory into a file named
50
+ # "application.css"
51
+ concat "application.css"
52
+ end
53
+
54
+ # Repeat for javascript files
55
+ match "javascript/**/*.js" do
56
+ concat "application.js"
57
+ end
58
+ end
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
+ # Set the Pipeline's output directory
97
+ output "compiled"
98
+
99
+ # input defines operations on a set of files. All files processed in
100
+ # this block go into the output directory
101
+ input "source" do
102
+
103
+ # Select all the CSS files
104
+ match "css/**/*.css" do
105
+
106
+ # concatenate all files in directory into a file named
107
+ # "application.css"
108
+ concat "application.css"
109
+ end
110
+
111
+ # Repeat for javascript files
112
+ match "javascript/**/*.js" do
113
+ concat "application.js"
114
+ end
115
+
116
+ # Explicitly select the HTML file. We don't want to copy
117
+ # over anything else
118
+ match "index.html" do
119
+
120
+ # copy also accepts a block. When called without any arguments it
121
+ # simply uses the same filename
122
+ copy
123
+ end
124
+ end
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
+ output "compiled"
164
+
165
+ input "source" do
166
+ match "**/*.coffee" do
167
+ filter CoffeeScript
168
+ end
169
+ end
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
+ output "compiled"
224
+
225
+ input "source" do
226
+ match "javascript/**/*.coffee" do
227
+ # Compile all .coffee files into.js
228
+ filter CoffeeScript
229
+ end
230
+
231
+ # Select the JS generated by previous filters.
232
+ match "javascript/**/*.js" do
233
+ concat "application.js"
234
+ end
235
+
236
+ match "css/**/*.css" do
237
+ concat "application.css"
238
+ end
239
+
240
+ match "index.html" do
241
+ copy
242
+ end
243
+ end
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.
data/Gemfile ADDED
@@ -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
data/LICENSE ADDED
@@ -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.