sprockets 3.0.0.beta.3 → 3.0.0.beta.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfc75742a9bbe41f39e393933281cc8210d2e2f2
|
4
|
+
data.tar.gz: ceaf8d045782996a37e7e00f48084bf8fbbd7355
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c59092430bb9da574a2fcbb28b1e2d3ef69dfcfc38103e6e95da4de969e8ce6526d24e2900041bd76d9327453f385386e8225684ea8ade1fa20d740cbdf44897
|
7
|
+
data.tar.gz: 95594832c3a2911d30d3e467271d66fc1f367472b4617e4b5137ed70e2c30aa6124cadf6a4a06bced8f00874a9a5481d2a21a7e45813d5f652e77b7772424946
|
data/lib/sprockets.rb
CHANGED
@@ -40,23 +40,25 @@ module Sprockets
|
|
40
40
|
|
41
41
|
# Extend Sprockets module to provide global registry
|
42
42
|
require 'sprockets/configuration'
|
43
|
+
require 'sprockets/context'
|
43
44
|
extend Configuration
|
44
45
|
|
45
|
-
@root
|
46
|
-
@paths
|
47
|
-
@mime_types
|
48
|
-
@mime_exts
|
49
|
-
@encodings
|
50
|
-
@engines
|
51
|
-
@engine_mime_types
|
52
|
-
@transformers
|
53
|
-
@
|
54
|
-
@
|
55
|
-
@
|
56
|
-
@
|
57
|
-
@
|
58
|
-
@
|
59
|
-
@
|
46
|
+
@root = File.expand_path('..', __FILE__).freeze
|
47
|
+
@paths = [].freeze
|
48
|
+
@mime_types = {}.freeze
|
49
|
+
@mime_exts = {}.freeze
|
50
|
+
@encodings = {}.freeze
|
51
|
+
@engines = {}.freeze
|
52
|
+
@engine_mime_types = {}.freeze
|
53
|
+
@transformers = Hash.new { |h, k| {}.freeze }.freeze
|
54
|
+
@inverted_transformers = Hash.new { |h, k| {}.freeze }.freeze
|
55
|
+
@preprocessors = Hash.new { |h, k| [].freeze }.freeze
|
56
|
+
@postprocessors = Hash.new { |h, k| [].freeze }.freeze
|
57
|
+
@bundle_reducers = Hash.new { |h, k| {}.freeze }.freeze
|
58
|
+
@bundle_processors = Hash.new { |h, k| [].freeze }.freeze
|
59
|
+
@compressors = Hash.new { |h, k| {}.freeze }.freeze
|
60
|
+
@context_class = Context
|
61
|
+
@version = ''
|
60
62
|
|
61
63
|
# Set the default digest
|
62
64
|
require 'digest/sha2'
|
@@ -106,16 +108,17 @@ module Sprockets
|
|
106
108
|
register_encoding :gzip, EncodingUtils::GZIP
|
107
109
|
register_encoding :base64, EncodingUtils::BASE64
|
108
110
|
|
111
|
+
require 'sprockets/directive_processor'
|
109
112
|
register_preprocessor 'text/css', DirectiveProcessor
|
110
113
|
register_preprocessor 'application/javascript', DirectiveProcessor
|
111
114
|
|
115
|
+
require 'sprockets/bundle'
|
112
116
|
register_bundle_processor 'application/javascript', Bundle
|
113
117
|
register_bundle_processor 'text/css', Bundle
|
114
118
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
register_bundle_reducer '*/*', :links, :+
|
119
|
+
register_bundle_metadata_reducer '*/*', :data, :+
|
120
|
+
register_bundle_metadata_reducer 'application/javascript', :data, Utils.method(:concat_javascript_sources)
|
121
|
+
register_bundle_metadata_reducer '*/*', :links, :+
|
119
122
|
|
120
123
|
register_compressor 'text/css', :sass, LazyProcessor.new { SassCompressor }
|
121
124
|
register_compressor 'text/css', :scss, LazyProcessor.new { SassCompressor }
|
data/lib/sprockets/asset.rb
CHANGED
@@ -15,11 +15,19 @@ module Sprockets
|
|
15
15
|
#
|
16
16
|
# Returns Asset.
|
17
17
|
def initialize(environment, attributes = {})
|
18
|
-
@environment
|
19
|
-
@attributes
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
@environment = environment
|
19
|
+
@attributes = attributes
|
20
|
+
@content_type = attributes[:content_type]
|
21
|
+
@filename = attributes[:filename]
|
22
|
+
@id = attributes[:id]
|
23
|
+
@integrity = attributes[:integrity]
|
24
|
+
@load_path = attributes[:load_path]
|
25
|
+
@logical_path = attributes[:logical_path]
|
26
|
+
@metadata = attributes[:metadata]
|
27
|
+
@mtime = attributes[:mtime]
|
28
|
+
@name = attributes[:name]
|
29
|
+
@source = attributes[:source]
|
30
|
+
@uri = attributes[:uri]
|
23
31
|
end
|
24
32
|
|
25
33
|
# Internal: Return all internal instance variables as a hash.
|
@@ -104,7 +112,7 @@ module Sprockets
|
|
104
112
|
# Returns Array of Assets.
|
105
113
|
def to_a
|
106
114
|
if metadata[:included]
|
107
|
-
metadata[:included].map { |uri| @environment.
|
115
|
+
metadata[:included].map { |uri| @environment.load(uri) }
|
108
116
|
else
|
109
117
|
[self]
|
110
118
|
end
|
@@ -123,7 +131,7 @@ module Sprockets
|
|
123
131
|
#
|
124
132
|
# Returns String.
|
125
133
|
def source
|
126
|
-
if
|
134
|
+
if @source
|
127
135
|
@source
|
128
136
|
else
|
129
137
|
# File is read everytime to avoid memory bloat of large binary files
|
@@ -150,10 +158,14 @@ module Sprockets
|
|
150
158
|
# Public: Get charset of source.
|
151
159
|
#
|
152
160
|
# Returns a String charset name or nil if binary.
|
153
|
-
|
161
|
+
def charset
|
162
|
+
metadata[:charset]
|
163
|
+
end
|
154
164
|
|
155
165
|
# Public: Returns Integer length of source.
|
156
|
-
|
166
|
+
def length
|
167
|
+
metadata[:length]
|
168
|
+
end
|
157
169
|
alias_method :bytesize, :length
|
158
170
|
|
159
171
|
# Deprecated: Returns Time of the last time the source was modified.
|
@@ -167,7 +179,7 @@ module Sprockets
|
|
167
179
|
|
168
180
|
# Public: Returns String hexdigest of source.
|
169
181
|
def hexdigest
|
170
|
-
DigestUtils.pack_hexdigest(
|
182
|
+
DigestUtils.pack_hexdigest(metadata[:digest])
|
171
183
|
end
|
172
184
|
|
173
185
|
# Deprecated: Returns String hexdigest of source.
|
@@ -180,7 +192,7 @@ module Sprockets
|
|
180
192
|
|
181
193
|
# Public: Returns String base64 digest of source.
|
182
194
|
def base64digest
|
183
|
-
DigestUtils.pack_base64digest(
|
195
|
+
DigestUtils.pack_base64digest(metadata[:digest])
|
184
196
|
end
|
185
197
|
|
186
198
|
# Public: A "named information" URL for subresource integrity.
|
@@ -197,7 +209,7 @@ module Sprockets
|
|
197
209
|
yield to_s
|
198
210
|
end
|
199
211
|
|
200
|
-
#
|
212
|
+
# Deprecated: Save asset to disk.
|
201
213
|
#
|
202
214
|
# filename - String target
|
203
215
|
#
|
data/lib/sprockets/asset_uri.rb
CHANGED
data/lib/sprockets/base.rb
CHANGED
@@ -1,17 +1,25 @@
|
|
1
|
+
require 'sprockets/asset_uri'
|
1
2
|
require 'sprockets/asset'
|
2
3
|
require 'sprockets/bower'
|
4
|
+
require 'sprockets/cache'
|
5
|
+
require 'sprockets/configuration'
|
6
|
+
require 'sprockets/digest_utils'
|
3
7
|
require 'sprockets/errors'
|
8
|
+
require 'sprockets/http_utils'
|
4
9
|
require 'sprockets/legacy'
|
10
|
+
require 'sprockets/loader'
|
11
|
+
require 'sprockets/path_digest_utils'
|
12
|
+
require 'sprockets/path_utils'
|
5
13
|
require 'sprockets/resolve'
|
6
14
|
require 'sprockets/server'
|
7
15
|
|
8
16
|
module Sprockets
|
9
17
|
# `Base` class for `Environment` and `Cached`.
|
10
18
|
class Base
|
11
|
-
include PathUtils, HTTPUtils, DigestUtils
|
19
|
+
include PathDigestUtils, PathUtils, HTTPUtils, DigestUtils
|
12
20
|
include Configuration
|
13
21
|
include Server
|
14
|
-
include Resolve
|
22
|
+
include Resolve, Loader
|
15
23
|
include Bower
|
16
24
|
include Legacy
|
17
25
|
|
@@ -46,41 +54,18 @@ module Sprockets
|
|
46
54
|
# disk. Also, the mtime is only read to the nearest second. Its
|
47
55
|
# also possible the file was updated more than once in a given second.
|
48
56
|
cache.fetch(['file_digest', path, stat.mtime.to_i]) do
|
49
|
-
|
50
|
-
# If its a directive, digest the list of filenames
|
51
|
-
digest_class.digest(self.entries(path).join(','))
|
52
|
-
elsif stat.file?
|
53
|
-
# If its a file, digest the contents
|
54
|
-
digest_class.file(path.to_s).digest
|
55
|
-
end
|
57
|
+
self.stat_digest(path, stat)
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
60
|
-
# Internal: Compute digest for a set of paths.
|
61
|
-
#
|
62
|
-
# paths - Array of filename or directory paths.
|
63
|
-
#
|
64
|
-
# Returns a String digest.
|
65
|
-
def files_digest(paths)
|
66
|
-
digest(paths.map { |path| file_digest(path) })
|
67
|
-
end
|
68
|
-
|
69
62
|
# Find asset by logical path or expanded path.
|
70
63
|
def find_asset(path, options = {})
|
71
|
-
if uri =
|
72
|
-
|
64
|
+
if uri = locate(path, options)
|
65
|
+
load(uri)
|
73
66
|
end
|
74
67
|
end
|
75
68
|
|
76
|
-
def find_asset_by_uri(uri)
|
77
|
-
_, params = AssetURI.parse(uri)
|
78
|
-
asset = params.key?(:id) ?
|
79
|
-
build_asset_by_id_uri(uri) :
|
80
|
-
build_asset_by_uri(uri)
|
81
|
-
Asset.new(self, asset)
|
82
|
-
end
|
83
|
-
|
84
69
|
def find_all_linked_assets(path, options = {})
|
85
70
|
return to_enum(__method__, path, options) unless block_given?
|
86
71
|
|
@@ -91,7 +76,7 @@ module Sprockets
|
|
91
76
|
stack = asset.links.to_a
|
92
77
|
|
93
78
|
while uri = stack.shift
|
94
|
-
yield asset =
|
79
|
+
yield asset = load(uri)
|
95
80
|
stack = asset.links.to_a + stack
|
96
81
|
end
|
97
82
|
|
@@ -112,103 +97,5 @@ module Sprockets
|
|
112
97
|
"root=#{root.to_s.inspect}, " +
|
113
98
|
"paths=#{paths.inspect}>"
|
114
99
|
end
|
115
|
-
|
116
|
-
protected
|
117
|
-
def build_asset_by_id_uri(uri)
|
118
|
-
path, params = AssetURI.parse(uri)
|
119
|
-
|
120
|
-
# Internal assertion, should be routed through build_asset_by_uri
|
121
|
-
unless id = params.delete(:id)
|
122
|
-
raise ArgumentError, "expected uri to have an id: #{uri}"
|
123
|
-
end
|
124
|
-
|
125
|
-
asset = build_asset_by_uri(AssetURI.build(path, params))
|
126
|
-
|
127
|
-
if id && asset[:id] != id
|
128
|
-
raise VersionNotFound, "could not find specified id: #{id}"
|
129
|
-
end
|
130
|
-
|
131
|
-
asset
|
132
|
-
end
|
133
|
-
|
134
|
-
def build_asset_by_uri(uri)
|
135
|
-
filename, params = AssetURI.parse(uri)
|
136
|
-
|
137
|
-
# Internal assertion, should be routed through build_asset_by_id_uri
|
138
|
-
if params.key?(:id)
|
139
|
-
raise ArgumentError, "expected uri to have no id: #{uri}"
|
140
|
-
end
|
141
|
-
|
142
|
-
type = params[:type]
|
143
|
-
load_path, logical_path = paths_split(self.paths, filename)
|
144
|
-
|
145
|
-
if !file?(filename)
|
146
|
-
raise FileNotFound, "could not find file: #{filename}"
|
147
|
-
elsif type && !resolve_path_transform_type(filename, type)
|
148
|
-
raise ConversionError, "could not convert to type: #{type}"
|
149
|
-
elsif !load_path
|
150
|
-
raise FileOutsidePaths, "#{filename} is no longer under a load path: #{self.paths.join(', ')}"
|
151
|
-
end
|
152
|
-
|
153
|
-
logical_path, file_type, engine_extnames = parse_path_extnames(logical_path)
|
154
|
-
logical_path = normalize_logical_path(logical_path)
|
155
|
-
|
156
|
-
asset = {
|
157
|
-
uri: uri,
|
158
|
-
load_path: load_path,
|
159
|
-
filename: filename,
|
160
|
-
name: logical_path,
|
161
|
-
logical_path: logical_path
|
162
|
-
}
|
163
|
-
|
164
|
-
if type
|
165
|
-
asset[:content_type] = type
|
166
|
-
asset[:logical_path] += mime_types[type][:extensions].first
|
167
|
-
end
|
168
|
-
|
169
|
-
processed_processors = unwrap_preprocessors(file_type) +
|
170
|
-
unwrap_engines(engine_extnames).reverse +
|
171
|
-
unwrap_transformer(file_type, type) +
|
172
|
-
unwrap_postprocessors(type)
|
173
|
-
|
174
|
-
bundled_processors = params[:skip_bundle] ? [] : unwrap_bundle_processors(type)
|
175
|
-
|
176
|
-
processors = bundled_processors.any? ? bundled_processors : processed_processors
|
177
|
-
processors += unwrap_encoding_processors(params[:encoding])
|
178
|
-
|
179
|
-
# Read into memory and process if theres a processor pipeline or the
|
180
|
-
# content type is text.
|
181
|
-
if processors.any? || mime_type_charset_detecter(type)
|
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: file_digest(asset[:filename]),
|
195
|
-
metadata: {}
|
196
|
-
})
|
197
|
-
end
|
198
|
-
|
199
|
-
metadata = asset[:metadata]
|
200
|
-
metadata[:dependency_paths] = Set.new(metadata[:dependency_paths]).merge([asset[:filename]])
|
201
|
-
metadata[:dependency_sources_digest] = files_digest(metadata[:dependency_paths])
|
202
|
-
|
203
|
-
asset[:integrity] = integrity_uri(asset[:digest], asset[:content_type])
|
204
|
-
|
205
|
-
asset[:id] = pack_hexdigest(digest(asset))
|
206
|
-
asset[:uri] = AssetURI.build(filename, params.merge(id: asset[:id]))
|
207
|
-
|
208
|
-
# TODO: Avoid tracking Asset mtime
|
209
|
-
asset[:mtime] = metadata[:dependency_paths].map { |p| stat(p).mtime.to_i }.max
|
210
|
-
|
211
|
-
asset
|
212
|
-
end
|
213
100
|
end
|
214
101
|
end
|
data/lib/sprockets/bundle.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'sprockets/asset_uri'
|
2
|
+
|
1
3
|
module Sprockets
|
2
4
|
# Internal: Bundle processor takes a single file asset and prepends all the
|
3
5
|
# `:required` URIs to the contents.
|
@@ -17,7 +19,7 @@ module Sprockets
|
|
17
19
|
processed_uri = AssetURI.build(input[:filename], type: type, skip_bundle: true)
|
18
20
|
|
19
21
|
cache = Hash.new do |h, uri|
|
20
|
-
h[uri] = env.
|
22
|
+
h[uri] = env.load(uri)
|
21
23
|
end
|
22
24
|
|
23
25
|
find_required = proc { |uri| cache[uri].metadata[:required] }
|
@@ -26,7 +28,12 @@ module Sprockets
|
|
26
28
|
required.subtract(stubbed)
|
27
29
|
assets = required.map { |uri| cache[uri] }
|
28
30
|
|
29
|
-
|
31
|
+
dependency_paths = Set.new
|
32
|
+
(required + stubbed).each do |uri|
|
33
|
+
dependency_paths += cache[uri].metadata[:dependency_paths]
|
34
|
+
end
|
35
|
+
|
36
|
+
env.process_bundle_reducers(assets, env.unwrap_bundle_reducers(type)).merge(dependency_paths: dependency_paths, included: assets.map(&:uri))
|
30
37
|
end
|
31
38
|
end
|
32
39
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'sprockets/asset_uri'
|
1
2
|
require 'sprockets/base'
|
2
3
|
|
3
4
|
module Sprockets
|
@@ -18,6 +19,7 @@ module Sprockets
|
|
18
19
|
@stats = Hash.new { |h, k| h[k] = _stat(k) }
|
19
20
|
@entries = Hash.new { |h, k| h[k] = _entries(k) }
|
20
21
|
@digests = Hash.new { |h, k| h[k] = _file_digest(k) }
|
22
|
+
@uris = Hash.new { |h, k| h[k] = _load(k) }
|
21
23
|
end
|
22
24
|
|
23
25
|
# No-op return self as cached environment.
|
@@ -44,6 +46,12 @@ module Sprockets
|
|
44
46
|
@digests[path]
|
45
47
|
end
|
46
48
|
|
49
|
+
# Internal: Cache Environment#load
|
50
|
+
alias_method :_load, :load
|
51
|
+
def load(uri)
|
52
|
+
@uris[uri]
|
53
|
+
end
|
54
|
+
|
47
55
|
protected
|
48
56
|
def asset_dependency_graph_cache_key(uri)
|
49
57
|
filename, _ = AssetURI.parse(uri)
|
@@ -57,39 +65,47 @@ module Sprockets
|
|
57
65
|
]
|
58
66
|
end
|
59
67
|
|
60
|
-
def
|
68
|
+
def asset_uri_cache_key(uri)
|
61
69
|
[
|
62
|
-
'asset-
|
70
|
+
'asset-uri',
|
63
71
|
VERSION,
|
64
72
|
self.version,
|
65
73
|
uri
|
66
74
|
]
|
67
75
|
end
|
68
76
|
|
69
|
-
def
|
70
|
-
cache.fetch(
|
77
|
+
def load_asset_by_id_uri(uri)
|
78
|
+
cache.fetch(asset_uri_cache_key(uri)) do
|
71
79
|
super
|
72
80
|
end
|
73
81
|
end
|
74
82
|
|
75
|
-
def
|
83
|
+
def load_asset_by_uri(uri)
|
76
84
|
dep_graph_key = asset_dependency_graph_cache_key(uri)
|
77
85
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
86
|
+
if asset = get_asset_dependency_graph_cache(dep_graph_key)
|
87
|
+
asset
|
88
|
+
else
|
89
|
+
asset = super
|
90
|
+
set_asset_dependency_graph_cache(dep_graph_key, asset)
|
91
|
+
asset
|
85
92
|
end
|
93
|
+
end
|
86
94
|
|
87
|
-
|
95
|
+
def get_asset_dependency_graph_cache(key)
|
96
|
+
return unless cached = cache._get(key)
|
97
|
+
paths, digest, uri = cached
|
88
98
|
|
89
|
-
|
90
|
-
|
91
|
-
|
99
|
+
if files_digest(paths) == digest
|
100
|
+
cache._get(asset_uri_cache_key(uri))
|
101
|
+
end
|
102
|
+
end
|
92
103
|
|
104
|
+
def set_asset_dependency_graph_cache(key, asset)
|
105
|
+
uri = asset[:uri]
|
106
|
+
digest, paths = asset[:metadata].values_at(:dependency_sources_digest, :dependency_paths)
|
107
|
+
cache._set(key, [paths, digest, uri])
|
108
|
+
cache.fetch(asset_uri_cache_key(uri)) { asset }
|
93
109
|
asset
|
94
110
|
end
|
95
111
|
|
@@ -100,4 +116,7 @@ module Sprockets
|
|
100
116
|
raise RuntimeError, "can't modify immutable cached environment"
|
101
117
|
end
|
102
118
|
end
|
119
|
+
|
120
|
+
# Deprecated
|
121
|
+
Index = CachedEnvironment
|
103
122
|
end
|