sprockets 2.12.5 → 3.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sprockets might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/LICENSE +2 -2
- data/README.md +61 -34
- data/lib/rake/sprocketstask.rb +5 -4
- data/lib/sprockets.rb +123 -85
- data/lib/sprockets/asset.rb +161 -200
- data/lib/sprockets/asset_uri.rb +64 -0
- data/lib/sprockets/base.rb +138 -373
- data/lib/sprockets/bower.rb +56 -0
- data/lib/sprockets/bundle.rb +32 -0
- data/lib/sprockets/cache.rb +220 -0
- data/lib/sprockets/cache/file_store.rb +145 -13
- data/lib/sprockets/cache/memory_store.rb +66 -0
- data/lib/sprockets/cache/null_store.rb +46 -0
- data/lib/sprockets/cached_environment.rb +103 -0
- data/lib/sprockets/closure_compressor.rb +30 -12
- data/lib/sprockets/coffee_script_template.rb +23 -0
- data/lib/sprockets/compressing.rb +20 -25
- data/lib/sprockets/configuration.rb +95 -0
- data/lib/sprockets/context.rb +68 -131
- data/lib/sprockets/directive_processor.rb +138 -179
- data/lib/sprockets/eco_template.rb +10 -19
- data/lib/sprockets/ejs_template.rb +10 -19
- data/lib/sprockets/encoding_utils.rb +246 -0
- data/lib/sprockets/engines.rb +40 -29
- data/lib/sprockets/environment.rb +10 -66
- data/lib/sprockets/erb_template.rb +23 -0
- data/lib/sprockets/errors.rb +5 -13
- data/lib/sprockets/http_utils.rb +97 -0
- data/lib/sprockets/jst_processor.rb +28 -15
- data/lib/sprockets/lazy_processor.rb +15 -0
- data/lib/sprockets/legacy.rb +23 -0
- data/lib/sprockets/legacy_proc_processor.rb +35 -0
- data/lib/sprockets/legacy_tilt_processor.rb +29 -0
- data/lib/sprockets/manifest.rb +128 -99
- data/lib/sprockets/mime.rb +114 -33
- data/lib/sprockets/path_utils.rb +179 -0
- data/lib/sprockets/paths.rb +13 -26
- data/lib/sprockets/processing.rb +198 -107
- data/lib/sprockets/resolve.rb +289 -0
- data/lib/sprockets/sass_compressor.rb +36 -17
- data/lib/sprockets/sass_template.rb +269 -46
- data/lib/sprockets/server.rb +113 -83
- data/lib/sprockets/transformers.rb +69 -0
- data/lib/sprockets/uglifier_compressor.rb +36 -15
- data/lib/sprockets/utils.rb +161 -44
- data/lib/sprockets/version.rb +1 -1
- data/lib/sprockets/yui_compressor.rb +37 -12
- metadata +64 -106
- data/lib/sprockets/asset_attributes.rb +0 -137
- data/lib/sprockets/bundled_asset.rb +0 -78
- data/lib/sprockets/caching.rb +0 -96
- data/lib/sprockets/charset_normalizer.rb +0 -41
- data/lib/sprockets/index.rb +0 -100
- data/lib/sprockets/processed_asset.rb +0 -152
- data/lib/sprockets/processor.rb +0 -32
- data/lib/sprockets/safety_colons.rb +0 -28
- data/lib/sprockets/sass_cache_store.rb +0 -29
- data/lib/sprockets/sass_functions.rb +0 -70
- data/lib/sprockets/sass_importer.rb +0 -30
- data/lib/sprockets/scss_template.rb +0 -13
- data/lib/sprockets/static_asset.rb +0 -60
data/lib/sprockets/base.rb
CHANGED
@@ -1,89 +1,19 @@
|
|
1
|
-
require 'sprockets/
|
2
|
-
require 'sprockets/
|
3
|
-
require 'sprockets/caching'
|
1
|
+
require 'sprockets/asset'
|
2
|
+
require 'sprockets/bower'
|
4
3
|
require 'sprockets/errors'
|
5
|
-
require 'sprockets/
|
4
|
+
require 'sprockets/legacy'
|
5
|
+
require 'sprockets/resolve'
|
6
6
|
require 'sprockets/server'
|
7
|
-
require 'sprockets/static_asset'
|
8
|
-
require 'multi_json'
|
9
|
-
require 'pathname'
|
10
7
|
|
11
8
|
module Sprockets
|
12
|
-
# `Base` class for `Environment` and `
|
9
|
+
# `Base` class for `Environment` and `Cached`.
|
13
10
|
class Base
|
14
|
-
include
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# Assign a `Digest` implementation class. This may be any Ruby
|
22
|
-
# `Digest::` implementation such as `Digest::MD5` or
|
23
|
-
# `Digest::SHA1`.
|
24
|
-
#
|
25
|
-
# environment.digest_class = Digest::SHA1
|
26
|
-
#
|
27
|
-
def digest_class=(klass)
|
28
|
-
expire_index!
|
29
|
-
@digest_class = klass
|
30
|
-
end
|
31
|
-
|
32
|
-
# The `Environment#version` is a custom value used for manually
|
33
|
-
# expiring all asset caches.
|
34
|
-
#
|
35
|
-
# Sprockets is able to track most file and directory changes and
|
36
|
-
# will take care of expiring the cache for you. However, its
|
37
|
-
# impossible to know when any custom helpers change that you mix
|
38
|
-
# into the `Context`.
|
39
|
-
#
|
40
|
-
# It would be wise to increment this value anytime you make a
|
41
|
-
# configuration change to the `Environment` object.
|
42
|
-
attr_reader :version
|
43
|
-
|
44
|
-
# Assign an environment version.
|
45
|
-
#
|
46
|
-
# environment.version = '2.0'
|
47
|
-
#
|
48
|
-
def version=(version)
|
49
|
-
expire_index!
|
50
|
-
@version = version
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns a `Digest` instance for the `Environment`.
|
54
|
-
#
|
55
|
-
# This value serves two purposes. If two `Environment`s have the
|
56
|
-
# same digest value they can be treated as equal. This is more
|
57
|
-
# useful for comparing environment states between processes rather
|
58
|
-
# than in the same. Two equal `Environment`s can share the same
|
59
|
-
# cached assets.
|
60
|
-
#
|
61
|
-
# The value also provides a seed digest for all `Asset`
|
62
|
-
# digests. Any change in the environment digest will affect all of
|
63
|
-
# its assets.
|
64
|
-
def digest
|
65
|
-
# Compute the initial digest using the implementation class. The
|
66
|
-
# Sprockets release version and custom environment version are
|
67
|
-
# mixed in. So any new releases will affect all your assets.
|
68
|
-
@digest ||= digest_class.new.update(VERSION).update(version.to_s)
|
69
|
-
|
70
|
-
# Returned a dupped copy so the caller can safely mutate it with `.update`
|
71
|
-
@digest.dup
|
72
|
-
end
|
73
|
-
|
74
|
-
# Get and set `Logger` instance.
|
75
|
-
attr_accessor :logger
|
76
|
-
|
77
|
-
# Get `Context` class.
|
78
|
-
#
|
79
|
-
# This class maybe mutated and mixed in with custom helpers.
|
80
|
-
#
|
81
|
-
# environment.context_class.instance_eval do
|
82
|
-
# include MyHelpers
|
83
|
-
# def asset_url; end
|
84
|
-
# end
|
85
|
-
#
|
86
|
-
attr_reader :context_class
|
11
|
+
include PathUtils, HTTPUtils
|
12
|
+
include Configuration
|
13
|
+
include Server
|
14
|
+
include Resolve
|
15
|
+
include Bower
|
16
|
+
include Legacy
|
87
17
|
|
88
18
|
# Get persistent cache store
|
89
19
|
attr_reader :cache
|
@@ -94,197 +24,80 @@ module Sprockets
|
|
94
24
|
# setters. Either `get(key)`/`set(key, value)`,
|
95
25
|
# `[key]`/`[key]=value`, `read(key)`/`write(key, value)`.
|
96
26
|
def cache=(cache)
|
97
|
-
|
98
|
-
@cache = cache
|
99
|
-
end
|
100
|
-
|
101
|
-
def prepend_path(path)
|
102
|
-
# Overrides the global behavior to expire the index
|
103
|
-
expire_index!
|
104
|
-
super
|
27
|
+
@cache = Cache.new(cache, logger)
|
105
28
|
end
|
106
29
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
super
|
111
|
-
end
|
112
|
-
|
113
|
-
def clear_paths
|
114
|
-
# Overrides the global behavior to expire the index
|
115
|
-
expire_index!
|
116
|
-
super
|
30
|
+
# Return an `Cached`. Must be implemented by the subclass.
|
31
|
+
def cached
|
32
|
+
raise NotImplementedError
|
117
33
|
end
|
34
|
+
alias_method :index, :cached
|
118
35
|
|
119
|
-
#
|
120
|
-
# searching the environment's paths.
|
36
|
+
# Internal: Compute hexdigest for path.
|
121
37
|
#
|
122
|
-
#
|
123
|
-
# # => "/path/to/app/javascripts/application.js.coffee"
|
38
|
+
# path - String filename or directory path.
|
124
39
|
#
|
125
|
-
#
|
126
|
-
def
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
if extname == "" || extname == File.extname(fn)
|
141
|
-
yield pathname.dirname.join(fn)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
else
|
146
|
-
yield pathname
|
40
|
+
# Returns a String SHA1 hexdigest or nil.
|
41
|
+
def file_hexdigest(path)
|
42
|
+
if stat = self.stat(path)
|
43
|
+
# Caveat: Digests are cached by the path's current mtime. Its possible
|
44
|
+
# for a files contents to have changed and its mtime to have been
|
45
|
+
# negligently reset thus appearing as if the file hasn't changed on
|
46
|
+
# disk. Also, the mtime is only read to the nearest second. Its
|
47
|
+
# also possible the file was updated more than once in a given second.
|
48
|
+
cache.fetch(['file_hexdigest', path, stat.mtime.to_i]) do
|
49
|
+
if stat.directory?
|
50
|
+
# If its a directive, digest the list of filenames
|
51
|
+
Digest::SHA1.hexdigest(self.entries(path).join(','))
|
52
|
+
elsif stat.file?
|
53
|
+
# If its a file, digest the contents
|
54
|
+
Digest::SHA1.file(path.to_s).hexdigest
|
147
55
|
end
|
148
56
|
end
|
149
|
-
else
|
150
|
-
resolve(logical_path, options) do |pathname|
|
151
|
-
return pathname
|
152
|
-
end
|
153
|
-
raise FileNotFound, "couldn't find file '#{logical_path}'"
|
154
57
|
end
|
155
58
|
end
|
156
59
|
|
157
|
-
#
|
158
|
-
def register_mime_type(mime_type, ext)
|
159
|
-
# Overrides the global behavior to expire the index
|
160
|
-
expire_index!
|
161
|
-
@trail.append_extension(ext)
|
162
|
-
super
|
163
|
-
end
|
164
|
-
|
165
|
-
# Registers a new Engine `klass` for `ext`.
|
166
|
-
def register_engine(ext, klass)
|
167
|
-
# Overrides the global behavior to expire the index
|
168
|
-
expire_index!
|
169
|
-
add_engine_to_trail(ext, klass)
|
170
|
-
super
|
171
|
-
end
|
172
|
-
|
173
|
-
def register_preprocessor(mime_type, klass, &block)
|
174
|
-
# Overrides the global behavior to expire the index
|
175
|
-
expire_index!
|
176
|
-
super
|
177
|
-
end
|
178
|
-
|
179
|
-
def unregister_preprocessor(mime_type, klass)
|
180
|
-
# Overrides the global behavior to expire the index
|
181
|
-
expire_index!
|
182
|
-
super
|
183
|
-
end
|
184
|
-
|
185
|
-
def register_postprocessor(mime_type, klass, &block)
|
186
|
-
# Overrides the global behavior to expire the index
|
187
|
-
expire_index!
|
188
|
-
super
|
189
|
-
end
|
190
|
-
|
191
|
-
def unregister_postprocessor(mime_type, klass)
|
192
|
-
# Overrides the global behavior to expire the index
|
193
|
-
expire_index!
|
194
|
-
super
|
195
|
-
end
|
196
|
-
|
197
|
-
def register_bundle_processor(mime_type, klass, &block)
|
198
|
-
# Overrides the global behavior to expire the index
|
199
|
-
expire_index!
|
200
|
-
super
|
201
|
-
end
|
202
|
-
|
203
|
-
def unregister_bundle_processor(mime_type, klass)
|
204
|
-
# Overrides the global behavior to expire the index
|
205
|
-
expire_index!
|
206
|
-
super
|
207
|
-
end
|
208
|
-
|
209
|
-
# Return an `Index`. Must be implemented by the subclass.
|
210
|
-
def index
|
211
|
-
raise NotImplementedError
|
212
|
-
end
|
213
|
-
|
214
|
-
if defined? Encoding.default_external
|
215
|
-
# Define `default_external_encoding` accessor on 1.9.
|
216
|
-
# Defaults to UTF-8.
|
217
|
-
attr_accessor :default_external_encoding
|
218
|
-
end
|
219
|
-
|
220
|
-
# Works like `Dir.entries`.
|
60
|
+
# Internal: Compute hexdigest for a set of paths.
|
221
61
|
#
|
222
|
-
#
|
223
|
-
def entries(pathname)
|
224
|
-
@trail.entries(pathname)
|
225
|
-
end
|
226
|
-
|
227
|
-
# Works like `File.stat`.
|
62
|
+
# paths - Array of filename or directory paths.
|
228
63
|
#
|
229
|
-
#
|
230
|
-
def
|
231
|
-
|
64
|
+
# Returns a String SHA1 hexdigest.
|
65
|
+
def dependencies_hexdigest(paths)
|
66
|
+
digest = Digest::SHA1.new
|
67
|
+
paths.each { |path| digest.update(file_hexdigest(path).to_s) }
|
68
|
+
digest.hexdigest
|
232
69
|
end
|
233
70
|
|
234
|
-
#
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
if stat = self.stat(path)
|
239
|
-
# If its a file, digest the contents
|
240
|
-
if stat.file?
|
241
|
-
digest.file(path.to_s)
|
242
|
-
|
243
|
-
# If its a directive, digest the list of filenames
|
244
|
-
elsif stat.directory?
|
245
|
-
contents = self.entries(path).join(',')
|
246
|
-
digest.update(contents)
|
247
|
-
end
|
71
|
+
# Find asset by logical path or expanded path.
|
72
|
+
def find_asset(path, options = {})
|
73
|
+
if uri = resolve_asset_uri(path, options)
|
74
|
+
Asset.new(self, build_asset_by_uri(uri))
|
248
75
|
end
|
249
76
|
end
|
250
77
|
|
251
|
-
|
252
|
-
|
253
|
-
|
78
|
+
def find_asset_by_uri(uri)
|
79
|
+
_, params = AssetURI.parse(uri)
|
80
|
+
asset = params.key?(:id) ?
|
81
|
+
build_asset_by_id_uri(uri) :
|
82
|
+
build_asset_by_uri(uri)
|
83
|
+
Asset.new(self, asset)
|
254
84
|
end
|
255
85
|
|
256
|
-
|
257
|
-
|
258
|
-
attributes_for(path).content_type
|
259
|
-
end
|
86
|
+
def find_all_linked_assets(path, options = {})
|
87
|
+
return to_enum(__method__, path, options) unless block_given?
|
260
88
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
begin
|
271
|
-
pathname = resolve(logical_path)
|
272
|
-
|
273
|
-
# If logical path is missing a mime type extension, append
|
274
|
-
# the absolute path extname so it has one.
|
275
|
-
#
|
276
|
-
# Ensures some consistency between finding "foo/bar" vs
|
277
|
-
# "foo/bar.js".
|
278
|
-
if File.extname(logical_path) == ""
|
279
|
-
expanded_logical_path = attributes_for(pathname).logical_path
|
280
|
-
logical_path += File.extname(expanded_logical_path)
|
281
|
-
end
|
282
|
-
rescue FileNotFound
|
283
|
-
return nil
|
284
|
-
end
|
89
|
+
asset = find_asset(path, options)
|
90
|
+
return unless asset
|
91
|
+
|
92
|
+
yield asset
|
93
|
+
stack = asset.links.to_a
|
94
|
+
|
95
|
+
while uri = stack.shift
|
96
|
+
yield asset = find_asset_by_uri(uri)
|
97
|
+
stack = asset.links.to_a + stack
|
285
98
|
end
|
286
99
|
|
287
|
-
|
100
|
+
nil
|
288
101
|
end
|
289
102
|
|
290
103
|
# Preferred `find_asset` shorthand.
|
@@ -295,153 +108,105 @@ module Sprockets
|
|
295
108
|
find_asset(*args)
|
296
109
|
end
|
297
110
|
|
298
|
-
def each_entry(root, &block)
|
299
|
-
return to_enum(__method__, root) unless block_given?
|
300
|
-
root = Pathname.new(root) unless root.is_a?(Pathname)
|
301
|
-
|
302
|
-
paths = []
|
303
|
-
entries(root).sort.each do |filename|
|
304
|
-
path = root.join(filename)
|
305
|
-
paths << path
|
306
|
-
|
307
|
-
if stat(path).directory?
|
308
|
-
each_entry(path) do |subpath|
|
309
|
-
paths << subpath
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
paths.sort_by(&:to_s).each(&block)
|
315
|
-
|
316
|
-
nil
|
317
|
-
end
|
318
|
-
|
319
|
-
def each_file
|
320
|
-
return to_enum(__method__) unless block_given?
|
321
|
-
paths.each do |root|
|
322
|
-
each_entry(root) do |path|
|
323
|
-
if !stat(path).directory?
|
324
|
-
yield path
|
325
|
-
end
|
326
|
-
end
|
327
|
-
end
|
328
|
-
nil
|
329
|
-
end
|
330
|
-
|
331
|
-
def each_logical_path(*args, &block)
|
332
|
-
return to_enum(__method__, *args) unless block_given?
|
333
|
-
filters = args.flatten
|
334
|
-
files = {}
|
335
|
-
each_file do |filename|
|
336
|
-
if logical_path = logical_path_for_filename(filename, filters)
|
337
|
-
unless files[logical_path]
|
338
|
-
if block.arity == 2
|
339
|
-
yield logical_path, filename.to_s
|
340
|
-
else
|
341
|
-
yield logical_path
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
files[logical_path] = true
|
346
|
-
end
|
347
|
-
end
|
348
|
-
nil
|
349
|
-
end
|
350
|
-
|
351
111
|
# Pretty inspect
|
352
112
|
def inspect
|
353
113
|
"#<#{self.class}:0x#{object_id.to_s(16)} " +
|
354
114
|
"root=#{root.to_s.inspect}, " +
|
355
|
-
"paths=#{paths.inspect}
|
356
|
-
"digest=#{digest.to_s.inspect}" +
|
357
|
-
">"
|
115
|
+
"paths=#{paths.inspect}>"
|
358
116
|
end
|
359
117
|
|
360
118
|
protected
|
361
|
-
|
362
|
-
|
363
|
-
raise NotImplementedError
|
364
|
-
end
|
119
|
+
def build_asset_by_id_uri(uri)
|
120
|
+
path, params = AssetURI.parse(uri)
|
365
121
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
# If there are any processors to run on the pathname, use
|
370
|
-
# `BundledAsset`. Otherwise use `StaticAsset` and treat is as binary.
|
371
|
-
if attributes_for(pathname).processors.any?
|
372
|
-
if options[:bundle] == false
|
373
|
-
circular_call_protection(pathname.to_s) do
|
374
|
-
ProcessedAsset.new(index, logical_path, pathname)
|
375
|
-
end
|
376
|
-
else
|
377
|
-
BundledAsset.new(index, logical_path, pathname)
|
378
|
-
end
|
379
|
-
else
|
380
|
-
StaticAsset.new(index, logical_path, pathname)
|
122
|
+
# Internal assertion, should be routed through build_asset_by_uri
|
123
|
+
unless id = params.delete(:id)
|
124
|
+
raise ArgumentError, "expected uri to have an id: #{uri}"
|
381
125
|
end
|
382
|
-
end
|
383
126
|
|
384
|
-
|
385
|
-
"#{path}:#{options[:bundle] ? '1' : '0'}"
|
386
|
-
end
|
127
|
+
asset = build_asset_by_uri(AssetURI.build(path, params))
|
387
128
|
|
388
|
-
|
389
|
-
|
390
|
-
calls = Thread.current[:sprockets_circular_calls] ||= Set.new
|
391
|
-
if calls.include?(path)
|
392
|
-
raise CircularDependencyError, "#{path} has already been required"
|
129
|
+
if id && asset[:id] != id
|
130
|
+
raise VersionNotFound, "could not find specified id: #{id}"
|
393
131
|
end
|
394
|
-
|
395
|
-
|
396
|
-
ensure
|
397
|
-
Thread.current[:sprockets_circular_calls] = nil if reset
|
132
|
+
|
133
|
+
asset
|
398
134
|
end
|
399
135
|
|
400
|
-
def
|
401
|
-
|
136
|
+
def build_asset_by_uri(uri)
|
137
|
+
filename, params = AssetURI.parse(uri)
|
402
138
|
|
403
|
-
|
404
|
-
|
139
|
+
# Internal assertion, should be routed through build_asset_by_id_uri
|
140
|
+
if params.key?(:id)
|
141
|
+
raise ArgumentError, "expected uri to have no id: #{uri}"
|
405
142
|
end
|
406
143
|
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
144
|
+
type = params[:type]
|
145
|
+
load_path, logical_path = paths_split(self.paths, filename)
|
146
|
+
|
147
|
+
if !file?(filename)
|
148
|
+
raise FileNotFound, "could not find file: #{filename}"
|
149
|
+
elsif type && !resolve_path_transform_type(filename, type)
|
150
|
+
raise ConversionError, "could not convert to type: #{type}"
|
151
|
+
elsif !load_path
|
152
|
+
raise FileOutsidePaths, "#{filename} is no longer under a load path: #{self.paths.join(', ')}"
|
413
153
|
end
|
414
154
|
|
415
|
-
|
416
|
-
|
155
|
+
logical_path, file_type, engine_extnames = parse_path_extnames(logical_path)
|
156
|
+
logical_path = normalize_logical_path(logical_path)
|
417
157
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
if filter.arity == 1
|
426
|
-
filter.call(logical_path)
|
427
|
-
else
|
428
|
-
filter.call(logical_path, filename.to_s)
|
429
|
-
end
|
430
|
-
else
|
431
|
-
File.fnmatch(filter.to_s, logical_path)
|
432
|
-
end
|
433
|
-
end
|
434
|
-
end
|
158
|
+
asset = {
|
159
|
+
uri: uri,
|
160
|
+
load_path: load_path,
|
161
|
+
filename: filename,
|
162
|
+
name: logical_path,
|
163
|
+
logical_path: logical_path
|
164
|
+
}
|
435
165
|
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
MultiJson.load(obj)
|
166
|
+
if type
|
167
|
+
asset[:content_type] = type
|
168
|
+
asset[:logical_path] += mime_types[type][:extensions].first
|
440
169
|
end
|
441
|
-
|
442
|
-
|
443
|
-
|
170
|
+
|
171
|
+
processed_processors = unwrap_preprocessors(file_type) +
|
172
|
+
unwrap_engines(engine_extnames).reverse +
|
173
|
+
unwrap_transformer(file_type, type) +
|
174
|
+
unwrap_postprocessors(type)
|
175
|
+
|
176
|
+
bundled_processors = params[:skip_bundle] ? [] : unwrap_bundle_processors(type)
|
177
|
+
|
178
|
+
processors = bundled_processors.any? ? bundled_processors : processed_processors
|
179
|
+
processors += unwrap_encoding_processors(params[:encoding])
|
180
|
+
|
181
|
+
if processors.any?
|
182
|
+
asset.merge!(process(
|
183
|
+
[method(:read_input)] + processors,
|
184
|
+
asset[:uri],
|
185
|
+
asset[:filename],
|
186
|
+
asset[:load_path],
|
187
|
+
asset[:name],
|
188
|
+
asset[:content_type]
|
189
|
+
))
|
190
|
+
else
|
191
|
+
asset.merge!({
|
192
|
+
encoding: Encoding::BINARY,
|
193
|
+
length: self.stat(asset[:filename]).size,
|
194
|
+
digest: digest_class.file(asset[:filename]).hexdigest,
|
195
|
+
metadata: {}
|
196
|
+
})
|
444
197
|
end
|
198
|
+
|
199
|
+
metadata = asset[:metadata]
|
200
|
+
metadata[:dependency_paths] = Set.new(metadata[:dependency_paths]).merge([asset[:filename]])
|
201
|
+
metadata[:dependency_digest] = dependencies_hexdigest(metadata[:dependency_paths])
|
202
|
+
|
203
|
+
asset[:id] = Utils.hexdigest(asset)
|
204
|
+
asset[:uri] = AssetURI.build(filename, params.merge(id: asset[:id]))
|
205
|
+
|
206
|
+
# TODO: Avoid tracking Asset mtime
|
207
|
+
asset[:mtime] = metadata[:dependency_paths].map { |p| stat(p).mtime.to_i }.max
|
208
|
+
|
209
|
+
asset
|
445
210
|
end
|
446
211
|
end
|
447
212
|
end
|