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
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
|