sprockets 3.0.0.beta.3 → 3.0.0.beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/sprockets.rb +22 -19
- data/lib/sprockets/asset.rb +24 -12
- data/lib/sprockets/asset_uri.rb +0 -1
- data/lib/sprockets/base.rb +14 -127
- data/lib/sprockets/bundle.rb +9 -2
- data/lib/sprockets/cached_environment.rb +35 -16
- data/lib/sprockets/configuration.rb +19 -18
- data/lib/sprockets/context.rb +41 -20
- data/lib/sprockets/directive_processor.rb +36 -19
- data/lib/sprockets/environment.rb +1 -0
- data/lib/sprockets/legacy.rb +67 -0
- data/lib/sprockets/loader.rb +168 -0
- data/lib/sprockets/mime.rb +1 -4
- data/lib/sprockets/path_digest_utils.rb +47 -0
- data/lib/sprockets/path_utils.rb +22 -0
- data/lib/sprockets/paths.rb +21 -0
- data/lib/sprockets/processing.rb +4 -48
- data/lib/sprockets/resolve.rb +73 -181
- data/lib/sprockets/transformers.rb +36 -2
- data/lib/sprockets/version.rb +1 -1
- metadata +4 -2
@@ -10,23 +10,24 @@ module Sprockets
|
|
10
10
|
include Paths, Mime, Engines, Transformers, Processing, Compressing
|
11
11
|
|
12
12
|
def initialize_configuration(parent)
|
13
|
-
@logger
|
14
|
-
@version
|
15
|
-
@digest_class
|
16
|
-
@context_class
|
17
|
-
@root
|
18
|
-
@paths
|
19
|
-
@mime_types
|
20
|
-
@mime_exts
|
21
|
-
@encodings
|
22
|
-
@engines
|
23
|
-
@engine_mime_types
|
24
|
-
@transformers
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@
|
28
|
-
@
|
29
|
-
@
|
13
|
+
@logger = parent.logger
|
14
|
+
@version = parent.version
|
15
|
+
@digest_class = parent.digest_class
|
16
|
+
@context_class = Class.new(parent.context_class)
|
17
|
+
@root = parent.root
|
18
|
+
@paths = parent.paths
|
19
|
+
@mime_types = parent.mime_types
|
20
|
+
@mime_exts = parent.mime_exts
|
21
|
+
@encodings = parent.encodings
|
22
|
+
@engines = parent.engines
|
23
|
+
@engine_mime_types = parent.engine_mime_types
|
24
|
+
@transformers = parent.transformers
|
25
|
+
@inverted_transformers = parent.inverted_transformers
|
26
|
+
@preprocessors = parent.preprocessors
|
27
|
+
@postprocessors = parent.postprocessors
|
28
|
+
@bundle_reducers = parent.bundle_reducers
|
29
|
+
@bundle_processors = parent.bundle_processors
|
30
|
+
@compressors = parent.compressors
|
30
31
|
end
|
31
32
|
|
32
33
|
# Get and set `Logger` instance.
|
@@ -52,7 +53,7 @@ module Sprockets
|
|
52
53
|
mutate_config(:version) { version.dup }
|
53
54
|
end
|
54
55
|
|
55
|
-
#
|
56
|
+
# Public: Returns a `Digest` implementation class.
|
56
57
|
#
|
57
58
|
# Defaults to `Digest::SHA256`.
|
58
59
|
attr_reader :digest_class
|
data/lib/sprockets/context.rb
CHANGED
@@ -66,6 +66,39 @@ module Sprockets
|
|
66
66
|
#
|
67
67
|
attr_reader :content_type
|
68
68
|
|
69
|
+
# Internal
|
70
|
+
def _resolve(method, path, options = {})
|
71
|
+
options[:content_type] = self.content_type if options[:content_type] == :self
|
72
|
+
options[:accept] = options.delete(:content_type)
|
73
|
+
|
74
|
+
if environment.absolute_path?(path)
|
75
|
+
filename = path
|
76
|
+
elsif environment.relative_path?(path)
|
77
|
+
path = File.expand_path(path, @dirname)
|
78
|
+
if logical_path = @environment.split_subpath(load_path, path)
|
79
|
+
if filename = environment.send(method, logical_path, options.merge(load_paths: [load_path]))
|
80
|
+
accept = options[:accept]
|
81
|
+
message = "couldn't find file '#{logical_path}' under '#{load_path}'"
|
82
|
+
message << " with type '#{accept}'" if accept
|
83
|
+
raise FileNotFound, message
|
84
|
+
end
|
85
|
+
else
|
86
|
+
raise FileOutsidePaths, "#{path} isn't under path: #{load_path}"
|
87
|
+
end
|
88
|
+
else
|
89
|
+
filename = environment.send(method, path, options)
|
90
|
+
end
|
91
|
+
|
92
|
+
if filename
|
93
|
+
filename
|
94
|
+
else
|
95
|
+
accept = options[:accept]
|
96
|
+
message = "couldn't find file '#{path}'"
|
97
|
+
message << " with type '#{accept}'" if accept
|
98
|
+
raise FileNotFound, message
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
69
102
|
# Given a logical path, `resolve` will find and return the fully
|
70
103
|
# expanded path. Relative paths will also be resolved. An optional
|
71
104
|
# `:content_type` restriction can be supplied to restrict the
|
@@ -78,21 +111,11 @@ module Sprockets
|
|
78
111
|
# # => "/path/to/app/javascripts/bar.js"
|
79
112
|
#
|
80
113
|
def resolve(path, options = {})
|
81
|
-
|
82
|
-
|
114
|
+
_resolve(:resolve, path, options)
|
115
|
+
end
|
83
116
|
|
84
|
-
|
85
|
-
|
86
|
-
elsif environment.relative_path?(path)
|
87
|
-
path = File.expand_path(path, @dirname)
|
88
|
-
if logical_path = @environment.split_subpath(load_path, path)
|
89
|
-
environment.resolve_in_load_path(load_path, logical_path, options)
|
90
|
-
else
|
91
|
-
raise FileOutsidePaths, "#{path} isn't under path: #{load_path}"
|
92
|
-
end
|
93
|
-
else
|
94
|
-
environment.resolve(path, options)
|
95
|
-
end
|
117
|
+
def locate(path, options = {})
|
118
|
+
_resolve(:locate, path, options)
|
96
119
|
end
|
97
120
|
|
98
121
|
# `depend_on` allows you to state a dependency on a file without
|
@@ -114,7 +137,7 @@ module Sprockets
|
|
114
137
|
# file. Unlike `depend_on`, this will include recursively include
|
115
138
|
# the target asset's dependencies.
|
116
139
|
def depend_on_asset(path)
|
117
|
-
if asset = @environment.
|
140
|
+
if asset = @environment.load(locate(path))
|
118
141
|
@dependency_paths.merge(asset.metadata[:dependency_paths])
|
119
142
|
end
|
120
143
|
nil
|
@@ -130,8 +153,7 @@ module Sprockets
|
|
130
153
|
# <%= require_asset "#{framework}.js" %>
|
131
154
|
#
|
132
155
|
def require_asset(path)
|
133
|
-
|
134
|
-
@required << @environment.resolve_asset_uri(filename, accept: @content_type, bundle: false)
|
156
|
+
@required << locate(path, accept: @content_type, bundle: false)
|
135
157
|
nil
|
136
158
|
end
|
137
159
|
|
@@ -139,8 +161,7 @@ module Sprockets
|
|
139
161
|
# `path` must be an asset which may or may not already be included
|
140
162
|
# in the bundle.
|
141
163
|
def stub_asset(path)
|
142
|
-
|
143
|
-
@stubbed << @environment.resolve_asset_uri(filename, accept: @content_type, bundle: false)
|
164
|
+
@stubbed << @environment.locate(path, accept: @content_type, bundle: false)
|
144
165
|
nil
|
145
166
|
end
|
146
167
|
|
@@ -150,7 +171,7 @@ module Sprockets
|
|
150
171
|
#
|
151
172
|
# Returns an Asset or nil.
|
152
173
|
def link_asset(path)
|
153
|
-
if asset = @environment.
|
174
|
+
if asset = @environment.load(locate(path))
|
154
175
|
@dependency_paths.merge(asset.metadata[:dependency_paths])
|
155
176
|
@links << asset.uri
|
156
177
|
end
|
@@ -196,7 +196,7 @@ module Sprockets
|
|
196
196
|
# //= require "./bar"
|
197
197
|
#
|
198
198
|
def process_require_directive(path)
|
199
|
-
@required <<
|
199
|
+
@required << locate(path, accept: @content_type, bundle: false)
|
200
200
|
end
|
201
201
|
|
202
202
|
# `require_self` causes the body of the current file to be inserted
|
@@ -235,8 +235,10 @@ module Sprockets
|
|
235
235
|
@environment.stat_directory(root).each do |subpath, stat|
|
236
236
|
if subpath == @filename
|
237
237
|
next
|
238
|
-
elsif
|
239
|
-
|
238
|
+
elsif stat.directory?
|
239
|
+
next
|
240
|
+
elsif uri = @environment.locate(subpath, accept: @content_type, bundle: false)
|
241
|
+
@required << uri
|
240
242
|
end
|
241
243
|
end
|
242
244
|
else
|
@@ -260,19 +262,15 @@ module Sprockets
|
|
260
262
|
|
261
263
|
@dependency_paths << root
|
262
264
|
|
263
|
-
|
264
|
-
@environment.stat_tree(root).each do |subpath, stat|
|
265
|
+
@environment.stat_sorted_tree(root).each do |subpath, stat|
|
265
266
|
if subpath == @filename
|
266
267
|
next
|
267
268
|
elsif stat.directory?
|
268
269
|
@dependency_paths << subpath
|
269
|
-
elsif @environment.
|
270
|
-
required <<
|
270
|
+
elsif uri = @environment.locate(subpath, accept: @content_type, bundle: false)
|
271
|
+
@required << uri
|
271
272
|
end
|
272
273
|
end
|
273
|
-
required.sort_by(&:to_s).each do |subpath|
|
274
|
-
@required << @environment.resolve_asset_uri(subpath, accept: @content_type, bundle: false)
|
275
|
-
end
|
276
274
|
else
|
277
275
|
# The path must be relative and start with a `./`.
|
278
276
|
raise ArgumentError, "require_tree argument must be a relative path"
|
@@ -292,7 +290,7 @@ module Sprockets
|
|
292
290
|
# //= depend_on "foo.png"
|
293
291
|
#
|
294
292
|
def process_depend_on_directive(path)
|
295
|
-
@dependency_paths << resolve(path
|
293
|
+
@dependency_paths << resolve(path)
|
296
294
|
end
|
297
295
|
|
298
296
|
# Allows you to state a dependency on an asset without including
|
@@ -307,7 +305,7 @@ module Sprockets
|
|
307
305
|
# //= depend_on_asset "bar.js"
|
308
306
|
#
|
309
307
|
def process_depend_on_asset_directive(path)
|
310
|
-
if asset = @environment.
|
308
|
+
if asset = @environment.load(locate(path))
|
311
309
|
@dependency_paths.merge(asset.metadata[:dependency_paths])
|
312
310
|
end
|
313
311
|
end
|
@@ -321,7 +319,7 @@ module Sprockets
|
|
321
319
|
# //= stub "jquery"
|
322
320
|
#
|
323
321
|
def process_stub_directive(path)
|
324
|
-
@stubbed <<
|
322
|
+
@stubbed << locate(path, accept: @content_type, bundle: false)
|
325
323
|
end
|
326
324
|
|
327
325
|
# Declares a linked dependency on the target asset.
|
@@ -333,7 +331,7 @@ module Sprockets
|
|
333
331
|
# /*= link "logo.png" */
|
334
332
|
#
|
335
333
|
def process_link_directive(path)
|
336
|
-
if asset = @environment.
|
334
|
+
if asset = @environment.load(locate(path))
|
337
335
|
@dependency_paths.merge(asset.metadata[:dependency_paths])
|
338
336
|
@links << asset.uri
|
339
337
|
end
|
@@ -344,23 +342,42 @@ module Sprockets
|
|
344
342
|
File.expand_path(path, @dirname)
|
345
343
|
end
|
346
344
|
|
347
|
-
def
|
348
|
-
|
349
|
-
@environment.resolve_asset_uri(filename, accept: @content_type, bundle: false)
|
345
|
+
def locate(path, options = {})
|
346
|
+
_resolve(:locate, path, options)
|
350
347
|
end
|
351
348
|
|
352
349
|
def resolve(path, options = {})
|
350
|
+
_resolve(:resolve, path, options)
|
351
|
+
end
|
352
|
+
|
353
|
+
def _resolve(method, path, options = {})
|
353
354
|
if @environment.absolute_path?(path)
|
354
355
|
raise FileOutsidePaths, "can't require absolute file: #{path}"
|
355
356
|
elsif @environment.relative_path?(path)
|
356
357
|
path = expand_relative_path(path)
|
357
358
|
if logical_path = @environment.split_subpath(@load_path, path)
|
358
|
-
@environment.
|
359
|
+
if filename = @environment.send(method, logical_path, options.merge(load_paths: [@load_path]))
|
360
|
+
filename
|
361
|
+
else
|
362
|
+
accept = options[:accept]
|
363
|
+
message = "couldn't find file '#{logical_path}' under '#{@load_path}'"
|
364
|
+
message << " with type '#{accept}'" if accept
|
365
|
+
raise FileNotFound, message
|
366
|
+
end
|
359
367
|
else
|
360
368
|
raise FileOutsidePaths, "#{path} isn't under path: #{@load_path}"
|
361
369
|
end
|
362
370
|
else
|
363
|
-
@environment.
|
371
|
+
filename = @environment.send(method, path, options)
|
372
|
+
end
|
373
|
+
|
374
|
+
if filename
|
375
|
+
filename
|
376
|
+
else
|
377
|
+
accept = options[:accept]
|
378
|
+
message = "couldn't find file '#{path}'"
|
379
|
+
message << " with type '#{accept}'" if accept
|
380
|
+
raise FileNotFound, message
|
364
381
|
end
|
365
382
|
end
|
366
383
|
end
|
data/lib/sprockets/legacy.rb
CHANGED
@@ -1,5 +1,58 @@
|
|
1
|
+
require 'sprockets/manifest'
|
2
|
+
|
1
3
|
module Sprockets
|
2
4
|
module Legacy
|
5
|
+
# Deprecated: Iterate over all logical paths with a matcher.
|
6
|
+
#
|
7
|
+
# Remove from 4.x.
|
8
|
+
#
|
9
|
+
# args - List of matcher objects.
|
10
|
+
#
|
11
|
+
# Returns Enumerator if no block is given.
|
12
|
+
def each_logical_path(*args, &block)
|
13
|
+
return to_enum(__method__, *args) unless block_given?
|
14
|
+
|
15
|
+
filters = args.flatten.map { |arg| Manifest.compile_match_filter(arg) }
|
16
|
+
logical_paths.each do |a, b|
|
17
|
+
if filters.any? { |f| f.call(a, b) }
|
18
|
+
if block.arity == 2
|
19
|
+
yield a, b
|
20
|
+
else
|
21
|
+
yield a
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# Deprecated: Enumerate over all logical paths in the environment.
|
30
|
+
#
|
31
|
+
# Returns an Enumerator of [logical_path, filename].
|
32
|
+
def logical_paths
|
33
|
+
return to_enum(__method__) unless block_given?
|
34
|
+
|
35
|
+
seen = Set.new
|
36
|
+
|
37
|
+
self.paths.each do |load_path|
|
38
|
+
stat_tree(load_path).each do |filename, stat|
|
39
|
+
next unless stat.file?
|
40
|
+
|
41
|
+
path = split_subpath(load_path, filename)
|
42
|
+
path, mime_type, _ = parse_path_extnames(path)
|
43
|
+
path = normalize_logical_path(path)
|
44
|
+
path += mime_types[mime_type][:extensions].first if mime_type
|
45
|
+
|
46
|
+
if !seen.include?(path)
|
47
|
+
yield path, filename
|
48
|
+
seen << path
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
3
56
|
private
|
4
57
|
# Deprecated: Seriously.
|
5
58
|
def matches_filter(filters, logical_path, filename)
|
@@ -19,5 +72,19 @@ module Sprockets
|
|
19
72
|
end
|
20
73
|
end
|
21
74
|
end
|
75
|
+
|
76
|
+
# URI.unescape is deprecated on 1.9. We need to use URI::Parser
|
77
|
+
# if its available.
|
78
|
+
if defined? URI::DEFAULT_PARSER
|
79
|
+
def unescape(str)
|
80
|
+
str = URI::DEFAULT_PARSER.unescape(str)
|
81
|
+
str.force_encoding(Encoding.default_internal) if Encoding.default_internal
|
82
|
+
str
|
83
|
+
end
|
84
|
+
else
|
85
|
+
def unescape(str)
|
86
|
+
URI.unescape(str)
|
87
|
+
end
|
88
|
+
end
|
22
89
|
end
|
23
90
|
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'sprockets/asset_uri'
|
2
|
+
require 'sprockets/asset'
|
3
|
+
require 'sprockets/digest_utils'
|
4
|
+
require 'sprockets/engines'
|
5
|
+
require 'sprockets/errors'
|
6
|
+
require 'sprockets/mime'
|
7
|
+
require 'sprockets/path_utils'
|
8
|
+
require 'sprockets/processing'
|
9
|
+
require 'sprockets/resolve'
|
10
|
+
require 'sprockets/transformers'
|
11
|
+
|
12
|
+
module Sprockets
|
13
|
+
# The loader phase takes a asset URI location and returns a constructed Asset
|
14
|
+
# object.
|
15
|
+
module Loader
|
16
|
+
include DigestUtils, Engines, Mime, PathUtils, Processing, Resolve, Transformers
|
17
|
+
|
18
|
+
# Public: Load Asset by AssetURI.
|
19
|
+
#
|
20
|
+
# uri - AssetURI
|
21
|
+
#
|
22
|
+
# Returns Asset.
|
23
|
+
def load(uri)
|
24
|
+
_, params = AssetURI.parse(uri)
|
25
|
+
asset = params.key?(:id) ?
|
26
|
+
load_asset_by_id_uri(uri) :
|
27
|
+
load_asset_by_uri(uri)
|
28
|
+
Asset.new(self, asset)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def load_asset_by_id_uri(uri)
|
33
|
+
path, params = AssetURI.parse(uri)
|
34
|
+
|
35
|
+
# Internal assertion, should be routed through load_asset_by_uri
|
36
|
+
unless id = params.delete(:id)
|
37
|
+
raise ArgumentError, "expected uri to have an id: #{uri}"
|
38
|
+
end
|
39
|
+
|
40
|
+
asset = load_asset_by_uri(AssetURI.build(path, params))
|
41
|
+
|
42
|
+
if id && asset[:id] != id
|
43
|
+
raise VersionNotFound, "could not find specified id: #{id}"
|
44
|
+
end
|
45
|
+
|
46
|
+
asset
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_asset_by_uri(uri)
|
50
|
+
filename, params = AssetURI.parse(uri)
|
51
|
+
|
52
|
+
# Internal assertion, should be routed through load_asset_by_id_uri
|
53
|
+
if params.key?(:id)
|
54
|
+
raise ArgumentError, "expected uri to have no id: #{uri}"
|
55
|
+
end
|
56
|
+
|
57
|
+
unless file?(filename)
|
58
|
+
raise FileNotFound, "could not find file: #{filename}"
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
type = params[:type]
|
63
|
+
load_path, logical_path = paths_split(self.paths, filename)
|
64
|
+
|
65
|
+
unless load_path
|
66
|
+
raise FileOutsidePaths, "#{filename} is no longer under a load path: #{self.paths.join(', ')}"
|
67
|
+
end
|
68
|
+
|
69
|
+
logical_path, file_type, engine_extnames = parse_path_extnames(logical_path)
|
70
|
+
logical_path = normalize_logical_path(logical_path)
|
71
|
+
|
72
|
+
asset = {
|
73
|
+
uri: uri,
|
74
|
+
load_path: load_path,
|
75
|
+
filename: filename,
|
76
|
+
name: logical_path,
|
77
|
+
logical_path: logical_path
|
78
|
+
}
|
79
|
+
|
80
|
+
if type
|
81
|
+
asset[:content_type] = type
|
82
|
+
asset[:logical_path] += mime_types[type][:extensions].first
|
83
|
+
end
|
84
|
+
|
85
|
+
if type != file_type
|
86
|
+
transformers = unwrap_transformer(file_type, type)
|
87
|
+
unless transformers.any?
|
88
|
+
raise ConversionError, "could not convert #{file_type.inspect} to #{type.inspect}"
|
89
|
+
end
|
90
|
+
else
|
91
|
+
transformers = []
|
92
|
+
end
|
93
|
+
|
94
|
+
processed_processors = unwrap_preprocessors(file_type) +
|
95
|
+
unwrap_engines(engine_extnames).reverse +
|
96
|
+
transformers +
|
97
|
+
unwrap_postprocessors(type)
|
98
|
+
|
99
|
+
bundled_processors = params[:skip_bundle] ? [] : unwrap_bundle_processors(type)
|
100
|
+
|
101
|
+
processors = bundled_processors.any? ? bundled_processors : processed_processors
|
102
|
+
processors += unwrap_encoding_processors(params[:encoding])
|
103
|
+
|
104
|
+
# Read into memory and process if theres a processor pipeline or the
|
105
|
+
# content type is text.
|
106
|
+
if processors.any? || mime_type_charset_detecter(type)
|
107
|
+
data = read_file(asset[:filename], asset[:content_type])
|
108
|
+
metadata = {}
|
109
|
+
|
110
|
+
input = {
|
111
|
+
environment: self,
|
112
|
+
cache: self.cache,
|
113
|
+
uri: asset[:uri],
|
114
|
+
filename: asset[:filename],
|
115
|
+
load_path: asset[:load_path],
|
116
|
+
name: asset[:name],
|
117
|
+
content_type: asset[:content_type],
|
118
|
+
metadata: metadata
|
119
|
+
}
|
120
|
+
|
121
|
+
processors.each do |processor|
|
122
|
+
begin
|
123
|
+
result = processor.call(input.merge(data: data, metadata: metadata))
|
124
|
+
case result
|
125
|
+
when NilClass
|
126
|
+
# noop
|
127
|
+
when Hash
|
128
|
+
data = result[:data] if result.key?(:data)
|
129
|
+
metadata = metadata.merge(result)
|
130
|
+
metadata.delete(:data)
|
131
|
+
when String
|
132
|
+
data = result
|
133
|
+
else
|
134
|
+
raise Error, "invalid processor return type: #{result.class}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
asset[:source] = data
|
140
|
+
asset[:metadata] = metadata.merge(
|
141
|
+
charset: data.encoding.name.downcase,
|
142
|
+
digest: digest(data),
|
143
|
+
length: data.bytesize
|
144
|
+
)
|
145
|
+
else
|
146
|
+
asset[:metadata] = {
|
147
|
+
encoding: Encoding::BINARY,
|
148
|
+
digest: file_digest(asset[:filename]),
|
149
|
+
length: self.stat(asset[:filename]).size
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
metadata = asset[:metadata]
|
154
|
+
metadata[:dependency_paths] = Set.new(metadata[:dependency_paths]).merge([asset[:filename]])
|
155
|
+
metadata[:dependency_sources_digest] = files_digest(metadata[:dependency_paths])
|
156
|
+
|
157
|
+
asset[:integrity] = integrity_uri(asset[:metadata][:digest], asset[:content_type])
|
158
|
+
|
159
|
+
asset[:id] = pack_hexdigest(digest(asset))
|
160
|
+
asset[:uri] = AssetURI.build(filename, params.merge(id: asset[:id]))
|
161
|
+
|
162
|
+
# Deprecated: Avoid tracking Asset mtime
|
163
|
+
asset[:mtime] = metadata[:dependency_paths].map { |p| stat(p).mtime.to_i }.max
|
164
|
+
|
165
|
+
asset
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|