bpm 1.0.0.beta.8 → 1.0.0.beta.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +9 -0
  3. data/bpm.gemspec +2 -7
  4. data/lib/bpm/pipeline/generated_asset.rb +19 -21
  5. data/lib/bpm/pipeline/plugin_context.rb +7 -7
  6. data/lib/bpm/pipeline/plugin_processor.rb +11 -20
  7. data/lib/bpm/pipeline/transport_processor.rb +8 -13
  8. data/lib/bpm/pipeline.rb +47 -42
  9. data/lib/bpm/project_generator.rb +2 -2
  10. data/lib/bpm/version.rb +1 -1
  11. data/lib/bpm.rb +0 -3
  12. data/spec/cli/init_spec.rb +48 -48
  13. data/spec/cli/rebuild_spec.rb +30 -30
  14. data/spec/fixtures/projects/init_app/assets/bpm_libs.js +1 -1
  15. data/spec/fixtures/projects/init_app/assets/bpm_styles.css +1 -1
  16. data/spec/fixtures/projects/init_default/assets/bpm_libs.js +1 -1
  17. data/spec/fixtures/projects/init_default/assets/bpm_styles.css +1 -1
  18. data/spec/plugins/minifier_spec.rb +8 -8
  19. data/templates/project/index.html +0 -2
  20. data/templates/project/{app → lib}/main.js +0 -0
  21. metadata +24 -209
  22. data/.gitmodules +0 -3
  23. data/vendor/sprockets/.gitignore +0 -7
  24. data/vendor/sprockets/.travis.yml +0 -7
  25. data/vendor/sprockets/Gemfile +0 -2
  26. data/vendor/sprockets/LICENSE +0 -20
  27. data/vendor/sprockets/README.md +0 -22
  28. data/vendor/sprockets/Rakefile +0 -8
  29. data/vendor/sprockets/lib/sprockets/asset.rb +0 -198
  30. data/vendor/sprockets/lib/sprockets/asset_attributes.rb +0 -178
  31. data/vendor/sprockets/lib/sprockets/base.rb +0 -134
  32. data/vendor/sprockets/lib/sprockets/bundled_asset.rb +0 -249
  33. data/vendor/sprockets/lib/sprockets/cache/file_store.rb +0 -41
  34. data/vendor/sprockets/lib/sprockets/caching.rb +0 -126
  35. data/vendor/sprockets/lib/sprockets/charset_normalizer.rb +0 -41
  36. data/vendor/sprockets/lib/sprockets/context.rb +0 -221
  37. data/vendor/sprockets/lib/sprockets/digest.rb +0 -73
  38. data/vendor/sprockets/lib/sprockets/directive_processor.rb +0 -397
  39. data/vendor/sprockets/lib/sprockets/eco_template.rb +0 -38
  40. data/vendor/sprockets/lib/sprockets/ejs_template.rb +0 -37
  41. data/vendor/sprockets/lib/sprockets/engines.rb +0 -117
  42. data/vendor/sprockets/lib/sprockets/environment.rb +0 -94
  43. data/vendor/sprockets/lib/sprockets/errors.rb +0 -17
  44. data/vendor/sprockets/lib/sprockets/index.rb +0 -81
  45. data/vendor/sprockets/lib/sprockets/jst_processor.rb +0 -26
  46. data/vendor/sprockets/lib/sprockets/mime.rb +0 -38
  47. data/vendor/sprockets/lib/sprockets/processing.rb +0 -269
  48. data/vendor/sprockets/lib/sprockets/processor.rb +0 -32
  49. data/vendor/sprockets/lib/sprockets/safety_colons.rb +0 -28
  50. data/vendor/sprockets/lib/sprockets/server.rb +0 -270
  51. data/vendor/sprockets/lib/sprockets/static_asset.rb +0 -86
  52. data/vendor/sprockets/lib/sprockets/static_compilation.rb +0 -74
  53. data/vendor/sprockets/lib/sprockets/trail.rb +0 -123
  54. data/vendor/sprockets/lib/sprockets/utils.rb +0 -67
  55. data/vendor/sprockets/lib/sprockets/version.rb +0 -3
  56. data/vendor/sprockets/lib/sprockets.rb +0 -31
  57. data/vendor/sprockets/sprockets.gemspec +0 -30
  58. data/vendor/sprockets/test/fixtures/asset/POW.png +0 -0
  59. data/vendor/sprockets/test/fixtures/asset/application.js +0 -6
  60. data/vendor/sprockets/test/fixtures/asset/bar-utf8.css +0 -2
  61. data/vendor/sprockets/test/fixtures/asset/charset.css +0 -2
  62. data/vendor/sprockets/test/fixtures/asset/circle/a.js +0 -2
  63. data/vendor/sprockets/test/fixtures/asset/circle/b.js +0 -2
  64. data/vendor/sprockets/test/fixtures/asset/circle/c.js +0 -2
  65. data/vendor/sprockets/test/fixtures/asset/compat.js +0 -4
  66. data/vendor/sprockets/test/fixtures/asset/constants.js +0 -2
  67. data/vendor/sprockets/test/fixtures/asset/constants.yml +0 -1
  68. data/vendor/sprockets/test/fixtures/asset/default_mime_type.js +0 -1
  69. data/vendor/sprockets/test/fixtures/asset/filename.js.erb +0 -1
  70. data/vendor/sprockets/test/fixtures/asset/foo-utf8.css +0 -2
  71. data/vendor/sprockets/test/fixtures/asset/included_header.js +0 -4
  72. data/vendor/sprockets/test/fixtures/asset/jquery.tmpl.min.js +0 -1
  73. data/vendor/sprockets/test/fixtures/asset/mismatch.js +0 -1
  74. data/vendor/sprockets/test/fixtures/asset/multiple.js +0 -2
  75. data/vendor/sprockets/test/fixtures/asset/multipleengine.js +0 -1
  76. data/vendor/sprockets/test/fixtures/asset/noengine.js +0 -1
  77. data/vendor/sprockets/test/fixtures/asset/noformat.coffee +0 -1
  78. data/vendor/sprockets/test/fixtures/asset/one.css +0 -1
  79. data/vendor/sprockets/test/fixtures/asset/oneengine.js +0 -1
  80. data/vendor/sprockets/test/fixtures/asset/project.css +0 -1
  81. data/vendor/sprockets/test/fixtures/asset/project.js.erb +0 -4
  82. data/vendor/sprockets/test/fixtures/asset/relative/include.js +0 -4
  83. data/vendor/sprockets/test/fixtures/asset/relative/require.js +0 -1
  84. data/vendor/sprockets/test/fixtures/asset/relative/require_outside_path.js +0 -1
  85. data/vendor/sprockets/test/fixtures/asset/require_self.css +0 -9
  86. data/vendor/sprockets/test/fixtures/asset/require_self_twice.css +0 -8
  87. data/vendor/sprockets/test/fixtures/asset/semicolons/bar.js +0 -1
  88. data/vendor/sprockets/test/fixtures/asset/semicolons/index.js +0 -5
  89. data/vendor/sprockets/test/fixtures/asset/sprite.css.erb +0 -12
  90. data/vendor/sprockets/test/fixtures/asset/tree/all/b/c/d.js +0 -2
  91. data/vendor/sprockets/test/fixtures/asset/tree/all/b/c/e.js +0 -1
  92. data/vendor/sprockets/test/fixtures/asset/tree/all/b/c.js +0 -1
  93. data/vendor/sprockets/test/fixtures/asset/tree/all/b.css +0 -2
  94. data/vendor/sprockets/test/fixtures/asset/tree/all/b.js.erb +0 -1
  95. data/vendor/sprockets/test/fixtures/asset/tree/all/d/c.js.coffee +0 -1
  96. data/vendor/sprockets/test/fixtures/asset/tree/all/d/e.js +0 -1
  97. data/vendor/sprockets/test/fixtures/asset/tree/all_with_require.js +0 -7
  98. data/vendor/sprockets/test/fixtures/asset/tree/all_with_require_directory.js +0 -1
  99. data/vendor/sprockets/test/fixtures/asset/tree/all_with_require_tree.js +0 -2
  100. data/vendor/sprockets/test/fixtures/asset/tree/directory/application.js +0 -2
  101. data/vendor/sprockets/test/fixtures/asset/tree/directory/bar.js +0 -1
  102. data/vendor/sprockets/test/fixtures/asset/tree/directory/foo.js +0 -1
  103. data/vendor/sprockets/test/fixtures/asset/tree/tree/application.js +0 -2
  104. data/vendor/sprockets/test/fixtures/asset/tree/tree/bar.js +0 -1
  105. data/vendor/sprockets/test/fixtures/asset/tree/tree/foo.js +0 -1
  106. data/vendor/sprockets/test/fixtures/asset/tree/with_logical_path/a/a.js +0 -1
  107. data/vendor/sprockets/test/fixtures/asset/tree/with_logical_path/require_tree_with_logical_path.js +0 -1
  108. data/vendor/sprockets/test/fixtures/asset/tree/without_argument/a.js +0 -1
  109. data/vendor/sprockets/test/fixtures/asset/tree/without_argument/b.js +0 -1
  110. data/vendor/sprockets/test/fixtures/asset/tree/without_argument/require_tree_without_argument.js +0 -1
  111. data/vendor/sprockets/test/fixtures/asset/two.css +0 -1
  112. data/vendor/sprockets/test/fixtures/asset/unicode.js +0 -2
  113. data/vendor/sprockets/test/fixtures/asset/unknownexts.min.js +0 -2
  114. data/vendor/sprockets/test/fixtures/asset/users.js.erb.str +0 -4
  115. data/vendor/sprockets/test/fixtures/context/POW.png +0 -0
  116. data/vendor/sprockets/test/fixtures/context/application.js.yml +0 -3
  117. data/vendor/sprockets/test/fixtures/context/bar.js +0 -1
  118. data/vendor/sprockets/test/fixtures/context/foo.js +0 -2
  119. data/vendor/sprockets/test/fixtures/context/helpers.css.erb +0 -3
  120. data/vendor/sprockets/test/fixtures/context/properties.js.erb +0 -7
  121. data/vendor/sprockets/test/fixtures/context/require_glob.js +0 -1
  122. data/vendor/sprockets/test/fixtures/context/resolve_content_type.js.erb +0 -4
  123. data/vendor/sprockets/test/fixtures/context/sprite.css.embed +0 -3
  124. data/vendor/sprockets/test/fixtures/default/application.js.coffee +0 -4
  125. data/vendor/sprockets/test/fixtures/default/blank.gif +0 -0
  126. data/vendor/sprockets/test/fixtures/default/coffee/foo.coffee +0 -1
  127. data/vendor/sprockets/test/fixtures/default/coffee/index.js +0 -3
  128. data/vendor/sprockets/test/fixtures/default/empty +0 -0
  129. data/vendor/sprockets/test/fixtures/default/gallery.css.erb +0 -3
  130. data/vendor/sprockets/test/fixtures/default/gallery.js +0 -1
  131. data/vendor/sprockets/test/fixtures/default/goodbye.jst.eco +0 -1
  132. data/vendor/sprockets/test/fixtures/default/hello.jst.ejs +0 -1
  133. data/vendor/sprockets/test/fixtures/default/hello.txt +0 -1
  134. data/vendor/sprockets/test/fixtures/default/interpolation.js +0 -1
  135. data/vendor/sprockets/test/fixtures/default/missing_require.js +0 -1
  136. data/vendor/sprockets/test/fixtures/default/mobile/a.js +0 -1
  137. data/vendor/sprockets/test/fixtures/default/mobile/b.js +0 -1
  138. data/vendor/sprockets/test/fixtures/default/mobile/c.css +0 -1
  139. data/vendor/sprockets/test/fixtures/default/mobile/d.css +0 -1
  140. data/vendor/sprockets/test/fixtures/default/mobile/index.css +0 -3
  141. data/vendor/sprockets/test/fixtures/default/mobile/index.js +0 -1
  142. data/vendor/sprockets/test/fixtures/default/noreturn.js +0 -1
  143. data/vendor/sprockets/test/fixtures/default/project.js.coffee.erb +0 -2
  144. data/vendor/sprockets/test/fixtures/default/with_data_uri.css.erb +0 -3
  145. data/vendor/sprockets/test/fixtures/directives/code_before_comment +0 -3
  146. data/vendor/sprockets/test/fixtures/directives/comment_without_directives +0 -6
  147. data/vendor/sprockets/test/fixtures/directives/directive_word_splitting +0 -6
  148. data/vendor/sprockets/test/fixtures/directives/directives_after_header +0 -16
  149. data/vendor/sprockets/test/fixtures/directives/double_slash +0 -9
  150. data/vendor/sprockets/test/fixtures/directives/hash +0 -8
  151. data/vendor/sprockets/test/fixtures/directives/no_header +0 -2
  152. data/vendor/sprockets/test/fixtures/directives/slash_star +0 -10
  153. data/vendor/sprockets/test/fixtures/directives/slash_star_single +0 -4
  154. data/vendor/sprockets/test/fixtures/directives/space_between_directive_word +0 -2
  155. data/vendor/sprockets/test/fixtures/directives/triple_hash +0 -10
  156. data/vendor/sprockets/test/fixtures/encoding/ascii.js +0 -1
  157. data/vendor/sprockets/test/fixtures/encoding/ascii_utf8.js +0 -2
  158. data/vendor/sprockets/test/fixtures/encoding/utf16.js +0 -0
  159. data/vendor/sprockets/test/fixtures/encoding/utf8.js +0 -1
  160. data/vendor/sprockets/test/fixtures/encoding/utf8_bom.js +0 -1
  161. data/vendor/sprockets/test/fixtures/engines/hello.alert +0 -1
  162. data/vendor/sprockets/test/fixtures/engines/moo.js.str +0 -1
  163. data/vendor/sprockets/test/fixtures/public/compiled-digest-0aa2105d29558f3eb790d411d7d8fb66.js +0 -3
  164. data/vendor/sprockets/test/fixtures/public/compiled-digest-1c41eb0cf934a0c76babe875f982f9d1.js +0 -1
  165. data/vendor/sprockets/test/fixtures/server/app/javascripts/application.js +0 -5
  166. data/vendor/sprockets/test/fixtures/server/app/javascripts/bar.js +0 -1
  167. data/vendor/sprockets/test/fixtures/server/app/javascripts/foo.js +0 -1
  168. data/vendor/sprockets/test/fixtures/server/app/javascripts/hello.txt +0 -2
  169. data/vendor/sprockets/test/fixtures/server/app/javascripts/tree.js +0 -1
  170. data/vendor/sprockets/test/fixtures/server/vendor/javascripts/missing_require.js +0 -1
  171. data/vendor/sprockets/test/fixtures/server/vendor/stylesheets/missing_require.css +0 -1
  172. data/vendor/sprockets/test/sprockets_test.rb +0 -56
  173. data/vendor/sprockets/test/test_asset.rb +0 -699
  174. data/vendor/sprockets/test/test_asset_attributes.rb +0 -150
  175. data/vendor/sprockets/test/test_caching.rb +0 -62
  176. data/vendor/sprockets/test/test_context.rb +0 -115
  177. data/vendor/sprockets/test/test_directive_processor.rb +0 -124
  178. data/vendor/sprockets/test/test_encoding.rb +0 -65
  179. data/vendor/sprockets/test/test_engines.rb +0 -73
  180. data/vendor/sprockets/test/test_environment.rb +0 -587
  181. data/vendor/sprockets/test/test_server.rb +0 -227
@@ -1,270 +0,0 @@
1
- require 'rack/request'
2
- require 'time'
3
-
4
- module Sprockets
5
- # `Server` is a concern mixed into `Environment` and
6
- # `Index` that provides a Rack compatible `call`
7
- # interface and url generation helpers.
8
- module Server
9
- # `call` implements the Rack 1.x specification which accepts an
10
- # `env` Hash and returns a three item tuple with the status code,
11
- # headers, and body.
12
- #
13
- # Mapping your environment at a url prefix will serve all assets
14
- # in the path.
15
- #
16
- # map "/assets" do
17
- # run Sprockets::Environment.new
18
- # end
19
- #
20
- # A request for `"/assets/foo/bar.js"` will search your
21
- # environment for `"foo/bar.js"`.
22
- def call(env)
23
- start_time = Time.now.to_f
24
- time_elapsed = lambda { ((Time.now.to_f - start_time) * 1000).to_i }
25
-
26
- msg = "Served asset #{env['PATH_INFO']} -"
27
-
28
- # URLs containing a `".."` are rejected for security reasons.
29
- if forbidden_request?(env)
30
- return forbidden_response
31
- end
32
-
33
- # Mark session as "skipped" so no `Set-Cookie` header is set
34
- env['rack.session.options'] ||= {}
35
- env['rack.session.options'][:defer] = true
36
- env['rack.session.options'][:skip] = true
37
-
38
- # Extract the path from everything after the leading slash
39
- path = env['PATH_INFO'].to_s.sub(/^\//, '')
40
-
41
- # Look up the asset.
42
- asset = find_asset(path)
43
- asset.to_a if asset
44
-
45
- # `find_asset` returns nil if the asset doesn't exist
46
- if asset.nil?
47
- logger.info "#{msg} 404 Not Found (#{time_elapsed.call}ms)"
48
-
49
- # Return a 404 Not Found
50
- not_found_response
51
-
52
- # Check request headers `HTTP_IF_MODIFIED_SINCE` and
53
- # `HTTP_IF_NONE_MATCH` against the assets mtime and digest
54
- elsif not_modified?(asset, env) || etag_match?(asset, env)
55
- logger.info "#{msg} 304 Not Modified (#{time_elapsed.call}ms)"
56
-
57
- # Return a 304 Not Modified
58
- not_modified_response(asset, env)
59
-
60
- else
61
- logger.info "#{msg} 200 OK (#{time_elapsed.call}ms)"
62
-
63
- # Return a 200 with the asset contents
64
- ok_response(asset, env)
65
- end
66
- rescue Exception => e
67
- logger.error "Error compiling asset #{path}:"
68
- logger.error "#{e.class.name}: #{e.message}"
69
-
70
- case content_type_of(path)
71
- when "application/javascript"
72
- # Re-throw JavaScript asset exceptions to the browser
73
- logger.info "#{msg} 500 Internal Server Error\n\n"
74
- return javascript_exception_response(e)
75
- when "text/css"
76
- # Display CSS asset exceptions in the browser
77
- logger.info "#{msg} 500 Internal Server Error\n\n"
78
- return css_exception_response(e)
79
- else
80
- raise
81
- end
82
- end
83
-
84
- # `path` is a url helper that looks up an asset given a
85
- # `logical_path` and returns a path String. By default, the
86
- # asset's digest fingerprint is spliced into the filename.
87
- #
88
- # /assets/application-3676d55f84497cbeadfc614c1b1b62fc.js
89
- #
90
- # A third `prefix` argument can be pass along to be prepended to
91
- # the string.
92
- def path(logical_path, fingerprint = true, prefix = nil)
93
- if fingerprint && asset = find_asset(logical_path.to_s.sub(/^\//, ''))
94
- url = attributes_for(logical_path).path_with_fingerprint(asset.digest)
95
- else
96
- url = logical_path
97
- end
98
-
99
- url = File.join(prefix, url) if prefix
100
- url = "/#{url}" unless url =~ /^\//
101
-
102
- url
103
- end
104
-
105
- # Similar to `path`, `url` returns a full url given a Rack `env`
106
- # Hash and a `logical_path`.
107
- def url(env, logical_path, fingerprint = true, prefix = nil)
108
- req = Rack::Request.new(env)
109
-
110
- url = req.scheme + "://"
111
- url << req.host
112
-
113
- if req.scheme == "https" && req.port != 443 ||
114
- req.scheme == "http" && req.port != 80
115
- url << ":#{req.port}"
116
- end
117
-
118
- url << path(logical_path, fingerprint, prefix)
119
-
120
- url
121
- end
122
-
123
- private
124
- def forbidden_request?(env)
125
- # Prevent access to files elsewhere on the file system
126
- #
127
- # http://example.org/assets/../../../etc/passwd
128
- #
129
- env["PATH_INFO"].include?("..")
130
- end
131
-
132
- # Returns a 403 Forbidden response tuple
133
- def forbidden_response
134
- [ 403, { "Content-Type" => "text/plain", "Content-Length" => "9" }, [ "Forbidden" ] ]
135
- end
136
-
137
- # Returns a 404 Not Found response tuple
138
- def not_found_response
139
- [ 404, { "Content-Type" => "text/plain", "Content-Length" => "9", "X-Cascade" => "pass" }, [ "Not found" ] ]
140
- end
141
-
142
- # Returns a JavaScript response that re-throws a Ruby exception
143
- # in the browser
144
- def javascript_exception_response(exception)
145
- err = "#{exception.class.name}: #{exception.message}"
146
- body = "throw Error(#{err.inspect})"
147
- [ 200, { "Content-Type" => "application/javascript", "Content-Length" => Rack::Utils.bytesize(body).to_s }, [ body ] ]
148
- end
149
-
150
- # Returns a CSS response that hides all elements on the page and
151
- # displays the exception
152
- def css_exception_response(exception)
153
- message = "\n#{exception.class.name}: #{exception.message}"
154
- backtrace = "\n #{exception.backtrace.first}"
155
-
156
- body = <<-CSS
157
- html {
158
- padding: 18px 36px;
159
- }
160
-
161
- head {
162
- display: block;
163
- }
164
-
165
- body {
166
- margin: 0;
167
- padding: 0;
168
- }
169
-
170
- body > * {
171
- display: none !important;
172
- }
173
-
174
- head:after, body:before, body:after {
175
- display: block !important;
176
- }
177
-
178
- head:after {
179
- font-family: sans-serif;
180
- font-size: large;
181
- font-weight: bold;
182
- content: "Error compiling CSS asset";
183
- }
184
-
185
- body:before, body:after {
186
- font-family: monospace;
187
- white-space: pre-wrap;
188
- }
189
-
190
- body:before {
191
- font-weight: bold;
192
- content: "#{escape_css_content(message)}";
193
- }
194
-
195
- body:after {
196
- content: "#{escape_css_content(backtrace)}";
197
- }
198
- CSS
199
-
200
- [ 200, { "Content-Type" => "text/css;charset=utf-8", "Content-Length" => Rack::Utils.bytesize(body).to_s }, [ body ] ]
201
- end
202
-
203
- # Escape special characters for use inside a CSS content("...") string
204
- def escape_css_content(content)
205
- content.
206
- gsub('\\', '\\\\005c ').
207
- gsub("\n", '\\\\000a ').
208
- gsub('"', '\\\\0022 ').
209
- gsub('/', '\\\\002f ')
210
- end
211
-
212
- # Compare the requests `HTTP_IF_MODIFIED_SINCE` against the
213
- # assets mtime
214
- def not_modified?(asset, env)
215
- env["HTTP_IF_MODIFIED_SINCE"] == asset.mtime.httpdate
216
- end
217
-
218
- # Compare the requests `HTTP_IF_NONE_MATCH` against the assets digest
219
- def etag_match?(asset, env)
220
- env["HTTP_IF_NONE_MATCH"] == etag(asset)
221
- end
222
-
223
- # Test if `?body=1` or `body=true` query param is set
224
- def body_only?(env)
225
- env["QUERY_STRING"].to_s =~ /body=(1|t)/
226
- end
227
-
228
- # Returns a 304 Not Modified response tuple
229
- def not_modified_response(asset, env)
230
- [ 304, {}, [] ]
231
- end
232
-
233
- # Returns a 200 OK response tuple
234
- def ok_response(asset, env)
235
- if body_only?(env)
236
- [ 200, headers(env, asset, Rack::Utils.bytesize(asset.body)), [asset.body] ]
237
- else
238
- [ 200, headers(env, asset, asset.length), asset ]
239
- end
240
- end
241
-
242
- def headers(env, asset, length)
243
- Hash.new.tap do |headers|
244
- # Set content type and length headers
245
- headers["Content-Type"] = asset.content_type
246
- headers["Content-Length"] = length.to_s
247
-
248
- # Set caching headers
249
- headers["Cache-Control"] = "public"
250
- headers["Last-Modified"] = asset.mtime.httpdate
251
- headers["ETag"] = etag(asset)
252
-
253
- # If the request url contains a fingerprint, set a long
254
- # expires on the response
255
- if attributes_for(env["PATH_INFO"]).path_fingerprint
256
- headers["Cache-Control"] << ", max-age=31536000"
257
-
258
- # Otherwise set `must-revalidate` since the asset could be modified.
259
- else
260
- headers["Cache-Control"] << ", must-revalidate"
261
- end
262
- end
263
- end
264
-
265
- # Helper to quote the assets digest for use as an ETag.
266
- def etag(asset)
267
- %("#{asset.digest}")
268
- end
269
- end
270
- end
@@ -1,86 +0,0 @@
1
- require 'sprockets/asset'
2
- require 'fileutils'
3
- require 'zlib'
4
-
5
- module Sprockets
6
- # `StaticAsset`s are used for files that are served verbatim without
7
- # any processing or concatenation. These are typical images and
8
- # other binary files.
9
- class StaticAsset < Asset
10
- # Define extra attributes to be serialized.
11
- def self.serialized_attributes
12
- super + %w( content_type mtime length digest )
13
- end
14
-
15
- def initialize(environment, logical_path, pathname, digest = nil)
16
- super(environment, logical_path, pathname)
17
- @digest = digest
18
- load!
19
- end
20
-
21
- # Returns file contents as its `body`.
22
- def body
23
- # File is read everytime to avoid memory bloat of large binary files
24
- pathname.open('rb') { |f| f.read }
25
- end
26
-
27
- # Checks if Asset is fresh by comparing the actual mtime and
28
- # digest to the inmemory model.
29
- def fresh?
30
- # Check current mtime and digest
31
- dependency_fresh?('path' => pathname, 'mtime' => mtime, 'hexdigest' => digest)
32
- end
33
-
34
- # Implemented for Rack SendFile support.
35
- def to_path
36
- pathname.to_s
37
- end
38
-
39
- # `to_s` is aliased to body since static assets can't have any dependencies.
40
- def to_s
41
- body
42
- end
43
-
44
- # Save asset to disk.
45
- def write_to(filename, options = {})
46
- # Gzip contents if filename has '.gz'
47
- options[:compress] ||= File.extname(filename) == '.gz'
48
-
49
- if options[:compress]
50
- # Open file and run it through `Zlib`
51
- pathname.open('rb') do |rd|
52
- File.open("#{filename}+", 'wb') do |wr|
53
- gz = Zlib::GzipWriter.new(wr, Zlib::BEST_COMPRESSION)
54
- buf = ""
55
- while rd.read(16384, buf)
56
- gz.write(buf)
57
- end
58
- gz.close
59
- end
60
- end
61
- else
62
- # If no compression needs to be done, we can just copy it into place.
63
- FileUtils.cp(pathname, "#{filename}+")
64
- end
65
-
66
- # Atomic write
67
- FileUtils.mv("#{filename}+", filename)
68
-
69
- # Set mtime correctly
70
- File.utime(mtime, mtime, filename)
71
-
72
- nil
73
- ensure
74
- # Ensure tmp file gets cleaned up
75
- FileUtils.rm("#{filename}+") if File.exist?("#{filename}+")
76
- end
77
-
78
- private
79
- def load!
80
- content_type
81
- mtime
82
- length
83
- digest
84
- end
85
- end
86
- end
@@ -1,74 +0,0 @@
1
- require 'sprockets/static_asset'
2
-
3
- require 'fileutils'
4
- require 'pathname'
5
-
6
- module Sprockets
7
- # `Caching` is an internal mixin whose public methods are exposed on
8
- # the `Environment` and `Index` classes.
9
- module StaticCompilation
10
- # `static_root` is a special path where compiled assets are served
11
- # from. This is usually set to a `/public` or `/static` directory.
12
- #
13
- # In a production environment, Apache or nginx should be
14
- # configured to serve assets from the directory.
15
- def static_root
16
- @static_root
17
- end
18
-
19
- # Assign a static root directory.
20
- def static_root=(root)
21
- expire_index!
22
- @static_root = root ? Pathname.new(root) : nil
23
- end
24
-
25
- # `precompile` takes a like of paths, globs, or `Regexp`s to
26
- # compile into `static_root`.
27
- #
28
- # precompile "application.js", "*.css", /.+\.(png|jpg)/
29
- #
30
- # This usually ran via a rake task.
31
- def precompile(*paths)
32
- raise "missing static root" unless static_root
33
-
34
- paths.each do |path|
35
- files.each do |logical_path|
36
- if path.is_a?(Regexp)
37
- # Match path against `Regexp`
38
- next unless path.match(logical_path)
39
- else
40
- # Otherwise use fnmatch glob syntax
41
- next unless File.fnmatch(path.to_s, logical_path)
42
- end
43
-
44
- if asset = find_asset(logical_path)
45
- attributes = attributes_for(logical_path)
46
- digest_path = attributes.path_with_fingerprint(asset.digest)
47
- filename = static_root.join(digest_path)
48
-
49
- # Ensure directory exists
50
- FileUtils.mkdir_p filename.dirname
51
-
52
- # Write file
53
- asset.write_to(filename)
54
-
55
- # Write compressed file if its a bundled asset like .js or .css
56
- asset.write_to("#{filename}.gz") if asset.is_a?(BundledAsset)
57
- end
58
- end
59
- end
60
- end
61
-
62
- private
63
- # Get all reachable files in environment path
64
- def files
65
- files = Set.new
66
- paths.each do |base_path|
67
- Dir["#{base_path}/**/*"].each do |filename|
68
- files << attributes_for(filename).logical_path
69
- end
70
- end
71
- files
72
- end
73
- end
74
- end
@@ -1,123 +0,0 @@
1
- require 'sprockets/errors'
2
- require 'pathname'
3
-
4
- module Sprockets
5
- # `Trail` is an internal mixin whose public methods are exposed on
6
- # the `Environment` and `Index` classes.
7
- module Trail
8
- # Returns `Environment` root.
9
- #
10
- # All relative paths are expanded with root as its base. To be
11
- # useful set this to your applications root directory. (`Rails.root`)
12
- def root
13
- trail.root.dup
14
- end
15
-
16
- # Returns an `Array` of path `String`s.
17
- #
18
- # These paths will be used for asset logical path lookups.
19
- #
20
- # Note that a copy of the `Array` is returned so mutating will
21
- # have no affect on the environment. See `append_path`,
22
- # `prepend_path`, and `clear_paths`.
23
- def paths
24
- trail.paths.dup
25
- end
26
-
27
- # Prepend a `path` to the `paths` list.
28
- #
29
- # Paths at the end of the `Array` have the least priority.
30
- def prepend_path(path)
31
- expire_index!
32
- @trail.paths.unshift(path)
33
- end
34
-
35
- # Append a `path` to the `paths` list.
36
- #
37
- # Paths at the beginning of the `Array` have a higher priority.
38
- def append_path(path)
39
- expire_index!
40
- @trail.paths.push(path)
41
- end
42
-
43
- # Clear all paths and start fresh.
44
- #
45
- # There is no mechanism for reordering paths, so its best to
46
- # completely wipe the paths list and reappend them in the order
47
- # you want.
48
- def clear_paths
49
- expire_index!
50
- @trail.paths.clear
51
- end
52
-
53
- # Returns an `Array` of extensions.
54
- #
55
- # These extensions maybe omitted from logical path searches.
56
- #
57
- # # => [".js", ".css", ".coffee", ".sass", ...]
58
- #
59
- def extensions
60
- trail.extensions.dup
61
- end
62
-
63
- # Finds the expanded real path for a given logical path by
64
- # searching the environment's paths.
65
- #
66
- # resolve("application.js")
67
- # # => "/path/to/app/javascripts/application.js.coffee"
68
- #
69
- # A `FileNotFound` exception is raised if the file does not exist.
70
- def resolve(logical_path, options = {})
71
- # If a block is given, preform an iterable search
72
- if block_given?
73
- args = attributes_for(logical_path).search_paths + [options]
74
- trail.find(*args) do |path|
75
- yield Pathname.new(path)
76
- end
77
- else
78
- resolve(logical_path, options) do |pathname|
79
- return pathname
80
- end
81
- raise FileNotFound, "couldn't find file '#{logical_path}'"
82
- end
83
- end
84
-
85
- protected
86
- def trail
87
- @trail
88
- end
89
-
90
- def compute_digest
91
- digest = super
92
-
93
- # Add paths to environment digest.
94
- digest << trail.paths.map { |p| attributes_for(p).relativize_root }.join(',')
95
-
96
- digest
97
- end
98
-
99
- def find_asset_in_path(logical_path, options = {})
100
- # Strip fingerprint on logical path if there is one.
101
- # Not sure how valuable this feature is...
102
- if fingerprint = attributes_for(logical_path).path_fingerprint
103
- pathname = resolve(logical_path.to_s.sub("-#{fingerprint}", ''))
104
- else
105
- pathname = resolve(logical_path)
106
- end
107
- rescue FileNotFound
108
- nil
109
- else
110
- # Build the asset for the actual pathname
111
- asset = build_asset(logical_path, pathname, options)
112
-
113
- # Double check request fingerprint against actual digest
114
- # Again, not sure if this code path is even reachable
115
- if fingerprint && fingerprint != asset.digest
116
- logger.error "Nonexistent asset #{logical_path} @ #{fingerprint}"
117
- asset = nil
118
- end
119
-
120
- asset
121
- end
122
- end
123
- end
@@ -1,67 +0,0 @@
1
- module Sprockets
2
- # `Utils`, we didn't know where else to put it!
3
- module Utils
4
- # If theres encoding support (aka Ruby 1.9)
5
- if "".respond_to?(:valid_encoding?)
6
- # Define UTF-8 BOM pattern matcher.
7
- # Avoid using a Regexp literal because it inheirts the files
8
- # encoding and we want to avoid syntax errors in other interpreters.
9
- UTF8_BOM_PATTERN = Regexp.new("\\A\uFEFF".encode('utf-8'))
10
-
11
- def self.read_unicode(pathname)
12
- pathname.read.tap do |data|
13
- # Eager validate the file's encoding. In most cases we
14
- # expect it to be UTF-8 unless `default_external` is set to
15
- # something else. An error is usually raised if the file is
16
- # saved as UTF-16 when we expected UTF-8.
17
- if !data.valid_encoding?
18
- raise EncodingError, "#{pathname} has a invalid " +
19
- "#{data.encoding} byte sequence"
20
-
21
- # If the file is UTF-8 and theres a BOM, strip it for safe concatenation.
22
- elsif data.encoding.name == "UTF-8" && data =~ UTF8_BOM_PATTERN
23
- data.sub!(UTF8_BOM_PATTERN, "")
24
- end
25
- end
26
- end
27
-
28
- else
29
- # Define UTF-8 and UTF-16 BOM pattern matchers.
30
- # Avoid using a Regexp literal to prevent syntax errors in other interpreters.
31
- UTF8_BOM_PATTERN = Regexp.new("\\A\\xEF\\xBB\\xBF")
32
- UTF16_BOM_PATTERN = Regexp.new("\\A(\\xFE\\xFF|\\xFF\\xFE)")
33
-
34
- def self.read_unicode(pathname)
35
- pathname.read.tap do |data|
36
- # If the file is UTF-8 and theres a BOM, strip it for safe concatenation.
37
- if data =~ UTF8_BOM_PATTERN
38
- data.sub!(UTF8_BOM_PATTERN, "")
39
-
40
- # If we find a UTF-16 BOM, theres nothing we can do on
41
- # 1.8. Only UTF-8 is supported.
42
- elsif data =~ UTF16_BOM_PATTERN
43
- raise EncodingError, "#{pathname} has a UTF-16 BOM. " +
44
- "Resave the file as UTF-8 or upgrade to Ruby 1.9."
45
- end
46
- end
47
- end
48
- end
49
-
50
- # Prepends a leading "." to an extension if its missing.
51
- #
52
- # normalize_extension("js")
53
- # # => ".js"
54
- #
55
- # normalize_extension(".css")
56
- # # => ".css"
57
- #
58
- def self.normalize_extension(extension)
59
- extension = extension.to_s
60
- if extension[/^\./]
61
- extension
62
- else
63
- ".#{extension}"
64
- end
65
- end
66
- end
67
- end
@@ -1,3 +0,0 @@
1
- module Sprockets
2
- VERSION = "2.0.0.beta.11"
3
- end
@@ -1,31 +0,0 @@
1
- require 'sprockets/version'
2
-
3
- module Sprockets
4
- autoload :ArgumentError, "sprockets/errors"
5
- autoload :Asset, "sprockets/asset"
6
- autoload :AssetAttributes, "sprockets/asset_attributes"
7
- autoload :BundledAsset, "sprockets/bundled_asset"
8
- autoload :CharsetNormalizer, "sprockets/charset_normalizer"
9
- autoload :CircularDependencyError, "sprockets/errors"
10
- autoload :ContentTypeMismatch, "sprockets/errors"
11
- autoload :Context, "sprockets/context"
12
- autoload :DirectiveProcessor, "sprockets/directive_processor"
13
- autoload :EcoTemplate, "sprockets/eco_template"
14
- autoload :EjsTemplate, "sprockets/ejs_template"
15
- autoload :EngineError, "sprockets/errors"
16
- autoload :Engines, "sprockets/engines"
17
- autoload :Environment, "sprockets/environment"
18
- autoload :Error, "sprockets/errors"
19
- autoload :FileNotFound, "sprockets/errors"
20
- autoload :Index, "sprockets/index"
21
- autoload :JstProcessor, "sprockets/jst_processor"
22
- autoload :Processing, "sprockets/processing"
23
- autoload :Processor, "sprockets/processor"
24
- autoload :Server, "sprockets/server"
25
- autoload :StaticAsset, "sprockets/static_asset"
26
- autoload :Utils, "sprockets/utils"
27
-
28
- module Cache
29
- autoload :FileStore, "sprockets/cache/file_store"
30
- end
31
- end
@@ -1,30 +0,0 @@
1
- unless defined? Sprockets::VERSION
2
- $:.unshift File.expand_path("../lib", __FILE__)
3
- require "sprockets/version"
4
- end
5
-
6
- Gem::Specification.new do |s|
7
- s.name = "sprockets"
8
- s.version = Sprockets::VERSION
9
- s.summary = "Rack-based asset packaging system"
10
- s.description = "Sprockets is a Rack-based asset packaging system that concatenates and serves JavaScript, CoffeeScript, CSS, LESS, Sass, and SCSS."
11
-
12
- s.files = Dir["README.md", "LICENSE", "lib/**/*.rb"]
13
-
14
- s.add_dependency "hike", "~> 1.1"
15
- s.add_dependency "rack", "~> 1.0"
16
- s.add_dependency "tilt", ["~> 1.1", "!= 1.3.0"]
17
-
18
- s.add_development_dependency "coffee-script", "~> 2.0"
19
- s.add_development_dependency "eco", "~> 1.0"
20
- s.add_development_dependency "ejs", "~> 1.0"
21
- s.add_development_dependency "execjs", "~> 1.0"
22
- s.add_development_dependency "json"
23
- s.add_development_dependency "rack-test"
24
- s.add_development_dependency "rake"
25
-
26
- s.authors = ["Sam Stephenson", "Joshua Peek"]
27
- s.email = "sstephenson@gmail.com"
28
- s.homepage = "http://getsprockets.org/"
29
- s.rubyforge_project = "sprockets"
30
- end
@@ -1,6 +0,0 @@
1
- // =require "project"
2
- // =require "users"
3
-
4
- document.on('dom:loaded', function() {
5
- $('search').focus();
6
- });