sprockets 2.12.5 → 3.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +296 -0
- data/LICENSE +2 -2
- data/README.md +235 -262
- data/bin/sprockets +1 -0
- data/lib/rake/sprocketstask.rb +5 -4
- data/lib/sprockets/asset.rb +143 -212
- data/lib/sprockets/autoload/closure.rb +7 -0
- data/lib/sprockets/autoload/coffee_script.rb +7 -0
- data/lib/sprockets/autoload/eco.rb +7 -0
- data/lib/sprockets/autoload/ejs.rb +7 -0
- data/lib/sprockets/autoload/sass.rb +7 -0
- data/lib/sprockets/autoload/uglifier.rb +7 -0
- data/lib/sprockets/autoload/yui.rb +7 -0
- data/lib/sprockets/autoload.rb +11 -0
- data/lib/sprockets/base.rb +56 -393
- data/lib/sprockets/bower.rb +58 -0
- data/lib/sprockets/bundle.rb +69 -0
- data/lib/sprockets/cache/file_store.rb +168 -14
- data/lib/sprockets/cache/memory_store.rb +66 -0
- data/lib/sprockets/cache/null_store.rb +46 -0
- data/lib/sprockets/cache.rb +236 -0
- data/lib/sprockets/cached_environment.rb +69 -0
- data/lib/sprockets/closure_compressor.rb +35 -10
- data/lib/sprockets/coffee_script_processor.rb +25 -0
- data/lib/sprockets/coffee_script_template.rb +17 -0
- data/lib/sprockets/compressing.rb +44 -23
- data/lib/sprockets/configuration.rb +83 -0
- data/lib/sprockets/context.rb +86 -144
- data/lib/sprockets/dependencies.rb +73 -0
- data/lib/sprockets/deprecation.rb +90 -0
- data/lib/sprockets/digest_utils.rb +180 -0
- data/lib/sprockets/directive_processor.rb +207 -211
- data/lib/sprockets/eco_processor.rb +32 -0
- data/lib/sprockets/eco_template.rb +9 -30
- data/lib/sprockets/ejs_processor.rb +31 -0
- data/lib/sprockets/ejs_template.rb +9 -29
- data/lib/sprockets/encoding_utils.rb +261 -0
- data/lib/sprockets/engines.rb +53 -35
- data/lib/sprockets/environment.rb +17 -64
- data/lib/sprockets/erb_processor.rb +30 -0
- data/lib/sprockets/erb_template.rb +11 -0
- data/lib/sprockets/errors.rb +4 -13
- data/lib/sprockets/file_reader.rb +15 -0
- data/lib/sprockets/http_utils.rb +117 -0
- data/lib/sprockets/jst_processor.rb +35 -15
- data/lib/sprockets/legacy.rb +330 -0
- data/lib/sprockets/legacy_proc_processor.rb +35 -0
- data/lib/sprockets/legacy_tilt_processor.rb +29 -0
- data/lib/sprockets/loader.rb +325 -0
- data/lib/sprockets/manifest.rb +202 -127
- data/lib/sprockets/manifest_utils.rb +45 -0
- data/lib/sprockets/mime.rb +112 -31
- data/lib/sprockets/path_dependency_utils.rb +85 -0
- data/lib/sprockets/path_digest_utils.rb +47 -0
- data/lib/sprockets/path_utils.rb +287 -0
- data/lib/sprockets/paths.rb +42 -19
- data/lib/sprockets/processing.rb +178 -126
- data/lib/sprockets/processor_utils.rb +180 -0
- data/lib/sprockets/resolve.rb +211 -0
- data/lib/sprockets/sass_cache_store.rb +22 -17
- data/lib/sprockets/sass_compressor.rb +39 -15
- data/lib/sprockets/sass_functions.rb +2 -70
- data/lib/sprockets/sass_importer.rb +2 -30
- data/lib/sprockets/sass_processor.rb +292 -0
- data/lib/sprockets/sass_template.rb +12 -59
- data/lib/sprockets/server.rb +129 -84
- data/lib/sprockets/transformers.rb +145 -0
- data/lib/sprockets/uglifier_compressor.rb +39 -12
- data/lib/sprockets/unloaded_asset.rb +137 -0
- data/lib/sprockets/uri_tar.rb +98 -0
- data/lib/sprockets/uri_utils.rb +188 -0
- data/lib/sprockets/utils/gzip.rb +67 -0
- data/lib/sprockets/utils.rb +210 -44
- data/lib/sprockets/version.rb +1 -1
- data/lib/sprockets/yui_compressor.rb +39 -11
- data/lib/sprockets.rb +142 -81
- metadata +96 -90
- 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/scss_template.rb +0 -13
- data/lib/sprockets/static_asset.rb +0 -60
data/bin/sprockets
CHANGED
data/lib/rake/sprocketstask.rb
CHANGED
@@ -37,10 +37,11 @@ module Rake
|
|
37
37
|
end
|
38
38
|
attr_writer :environment
|
39
39
|
|
40
|
-
# Returns cached
|
41
|
-
def
|
42
|
-
@
|
40
|
+
# Returns cached cached environment
|
41
|
+
def cached
|
42
|
+
@cached ||= environment.cached if environment
|
43
43
|
end
|
44
|
+
alias_method :index, :cached
|
44
45
|
|
45
46
|
# `Manifest` instance used for already compiled assets.
|
46
47
|
#
|
@@ -97,7 +98,7 @@ module Rake
|
|
97
98
|
def initialize(name = :assets)
|
98
99
|
@name = name
|
99
100
|
@environment = lambda { Sprockets::Environment.new(Dir.pwd) }
|
100
|
-
@manifest = lambda { Sprockets::Manifest.new(
|
101
|
+
@manifest = lambda { Sprockets::Manifest.new(cached, output) }
|
101
102
|
@logger = Logger.new($stderr)
|
102
103
|
@logger.level = Logger::INFO
|
103
104
|
@keep = 2
|
data/lib/sprockets/asset.rb
CHANGED
@@ -1,269 +1,200 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'fileutils'
|
2
|
+
require 'sprockets/digest_utils'
|
3
3
|
|
4
4
|
module Sprockets
|
5
|
-
# `Asset` is the base class for `BundledAsset` and `StaticAsset`.
|
6
5
|
class Asset
|
7
|
-
|
8
|
-
def self.from_hash(environment, hash)
|
9
|
-
return unless hash.is_a?(Hash)
|
6
|
+
attr_reader :logical_path
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
8
|
+
# Private: Intialize Asset wrapper from attributes Hash.
|
9
|
+
#
|
10
|
+
# Asset wrappers should not be initialized directly, only
|
11
|
+
# Environment#find_asset should vend them.
|
12
|
+
#
|
13
|
+
# attributes - Hash of ivars
|
14
|
+
#
|
15
|
+
# Returns Asset.
|
16
|
+
def initialize(environment, attributes = {})
|
17
|
+
@environment = environment
|
18
|
+
@attributes = attributes
|
19
|
+
@content_type = attributes[:content_type]
|
20
|
+
@filename = attributes[:filename]
|
21
|
+
@id = attributes[:id]
|
22
|
+
@load_path = attributes[:load_path]
|
23
|
+
@logical_path = attributes[:logical_path]
|
24
|
+
@metadata = attributes[:metadata]
|
25
|
+
@mtime = attributes[:mtime]
|
26
|
+
@name = attributes[:name]
|
27
|
+
@source = attributes[:source]
|
28
|
+
@uri = attributes[:uri]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Internal: Return all internal instance variables as a hash.
|
32
|
+
#
|
33
|
+
# Returns a Hash.
|
34
|
+
def to_hash
|
35
|
+
@attributes
|
29
36
|
end
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
|
38
|
+
# Public: Metadata accumulated from pipeline process.
|
39
|
+
#
|
40
|
+
# The API status of the keys is dependent on the pipeline processors
|
41
|
+
# itself. So some values maybe considered public and others internal.
|
42
|
+
# See the pipeline proccessor documentation itself.
|
43
|
+
#
|
44
|
+
# Returns Hash.
|
45
|
+
attr_reader :metadata
|
34
46
|
|
35
|
-
|
36
|
-
|
47
|
+
# Public: Returns String path of asset.
|
48
|
+
attr_reader :filename
|
37
49
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
# drop precision to 1 second, same pattern followed elsewhere
|
43
|
-
@mtime = Time.at(environment.stat(pathname).mtime.to_i)
|
44
|
-
@length = environment.stat(pathname).size
|
45
|
-
@digest = environment.file_digest(pathname).hexdigest
|
46
|
-
end
|
50
|
+
# Internal: Unique asset object ID.
|
51
|
+
#
|
52
|
+
# Returns a String.
|
53
|
+
attr_reader :id
|
47
54
|
|
48
|
-
#
|
49
|
-
|
50
|
-
|
55
|
+
# Public: Internal URI to lookup asset by.
|
56
|
+
#
|
57
|
+
# NOT a publically accessible URL.
|
58
|
+
#
|
59
|
+
# Returns URI.
|
60
|
+
attr_reader :uri
|
51
61
|
|
52
|
-
|
53
|
-
|
54
|
-
|
62
|
+
# Public: Return logical path with digest spliced in.
|
63
|
+
#
|
64
|
+
# "foo/bar-37b51d194a7513e45b56f6524f2d51f2.js"
|
65
|
+
#
|
66
|
+
# Returns String.
|
67
|
+
def digest_path
|
68
|
+
logical_path.sub(/\.(\w+)$/) { |ext| "-#{etag}#{ext}" }
|
69
|
+
end
|
55
70
|
|
56
|
-
|
57
|
-
|
58
|
-
@pathname = Pathname.new(expand_root_path(pathname))
|
59
|
-
end
|
71
|
+
# Public: Returns String MIME type of asset. Returns nil if type is unknown.
|
72
|
+
attr_reader :content_type
|
60
73
|
|
61
|
-
|
62
|
-
|
63
|
-
|
74
|
+
# Public: Get all externally linked asset filenames from asset.
|
75
|
+
#
|
76
|
+
# All linked assets should be compiled anytime this asset is.
|
77
|
+
#
|
78
|
+
# Returns Set of String asset URIs.
|
79
|
+
def links
|
80
|
+
metadata[:links] || Set.new
|
81
|
+
end
|
64
82
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
83
|
+
# Public: Get all internally required assets that were concated into this
|
84
|
+
# asset.
|
85
|
+
#
|
86
|
+
# Returns Array of String asset URIs.
|
87
|
+
def included
|
88
|
+
metadata[:included]
|
69
89
|
end
|
70
90
|
|
71
|
-
#
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
91
|
+
# Public: Return `String` of concatenated source.
|
92
|
+
#
|
93
|
+
# Returns String.
|
94
|
+
def source
|
95
|
+
if @source
|
96
|
+
@source
|
97
|
+
else
|
98
|
+
# File is read everytime to avoid memory bloat of large binary files
|
99
|
+
File.binread(filename)
|
100
|
+
end
|
80
101
|
end
|
81
102
|
|
82
|
-
#
|
103
|
+
# Public: Alias for #source.
|
83
104
|
#
|
84
|
-
#
|
105
|
+
# Returns String.
|
106
|
+
def to_s
|
107
|
+
source
|
108
|
+
end
|
109
|
+
|
110
|
+
# Public: Get charset of source.
|
85
111
|
#
|
86
|
-
|
87
|
-
|
112
|
+
# Returns a String charset name or nil if binary.
|
113
|
+
def charset
|
114
|
+
metadata[:charset]
|
88
115
|
end
|
89
116
|
|
90
|
-
#
|
91
|
-
def
|
92
|
-
[]
|
117
|
+
# Public: Returns Integer length of source.
|
118
|
+
def length
|
119
|
+
metadata[:length]
|
93
120
|
end
|
121
|
+
alias_method :bytesize, :length
|
94
122
|
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
# the asset's contents as a whole.
|
99
|
-
#
|
100
|
-
# This allows you to link to individual files for debugging
|
101
|
-
# purposes.
|
102
|
-
def to_a
|
103
|
-
[self]
|
123
|
+
# Public: Returns String hexdigest of source.
|
124
|
+
def hexdigest
|
125
|
+
DigestUtils.pack_hexdigest(metadata[:digest])
|
104
126
|
end
|
105
127
|
|
106
|
-
#
|
107
|
-
|
108
|
-
|
128
|
+
# Deprecated: Returns String hexdigest of source.
|
129
|
+
#
|
130
|
+
# In 4.x this will be changed to return a raw Digest byte String.
|
131
|
+
alias_method :digest, :hexdigest
|
132
|
+
|
133
|
+
# Pubic: ETag String of Asset.
|
134
|
+
alias_method :etag, :hexdigest
|
135
|
+
|
136
|
+
# Public: Returns String base64 digest of source.
|
137
|
+
def base64digest
|
138
|
+
DigestUtils.pack_base64digest(metadata[:digest])
|
109
139
|
end
|
110
140
|
|
111
|
-
#
|
112
|
-
def
|
113
|
-
|
141
|
+
# Public: A "named information" URL for subresource integrity.
|
142
|
+
def integrity
|
143
|
+
DigestUtils.integrity_uri(metadata[:digest])
|
114
144
|
end
|
115
145
|
|
116
|
-
# Add enumerator to allow `Asset` instances to be used as Rack
|
146
|
+
# Public: Add enumerator to allow `Asset` instances to be used as Rack
|
117
147
|
# compatible body objects.
|
148
|
+
#
|
149
|
+
# block
|
150
|
+
# part - String body chunk
|
151
|
+
#
|
152
|
+
# Returns nothing.
|
118
153
|
def each
|
119
154
|
yield to_s
|
120
155
|
end
|
121
156
|
|
122
|
-
#
|
123
|
-
# digest to the inmemory model.
|
157
|
+
# Deprecated: Save asset to disk.
|
124
158
|
#
|
125
|
-
#
|
126
|
-
def fresh?(environment)
|
127
|
-
# Check current mtime and digest
|
128
|
-
dependency_fresh?(environment, self)
|
129
|
-
end
|
130
|
-
|
131
|
-
# Checks if Asset is stale by comparing the actual mtime and
|
132
|
-
# digest to the inmemory model.
|
159
|
+
# filename - String target
|
133
160
|
#
|
134
|
-
#
|
135
|
-
def
|
136
|
-
!fresh?(environment)
|
137
|
-
end
|
138
|
-
|
139
|
-
# Save asset to disk.
|
140
|
-
def write_to(filename, options = {})
|
141
|
-
# Gzip contents if filename has '.gz'
|
142
|
-
unless options.key?(:compress)
|
143
|
-
options[:compress] = File.extname(filename) == '.gz' && File.extname(logical_path) != '.gz'
|
144
|
-
end
|
145
|
-
|
161
|
+
# Returns nothing.
|
162
|
+
def write_to(filename)
|
146
163
|
FileUtils.mkdir_p File.dirname(filename)
|
147
164
|
|
148
|
-
|
149
|
-
|
150
|
-
# Run contents through `Zlib`
|
151
|
-
gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
|
152
|
-
gz.mtime = mtime.to_i
|
153
|
-
gz.write to_s
|
154
|
-
gz.close
|
155
|
-
else
|
156
|
-
# Write out as is
|
157
|
-
f.write to_s
|
158
|
-
end
|
165
|
+
PathUtils.atomic_write(filename) do |f|
|
166
|
+
f.write source
|
159
167
|
end
|
160
168
|
|
161
|
-
# Atomic write
|
162
|
-
FileUtils.mv("#{filename}+", filename)
|
163
|
-
|
164
169
|
# Set mtime correctly
|
165
170
|
File.utime(mtime, mtime, filename)
|
166
171
|
|
167
172
|
nil
|
168
|
-
ensure
|
169
|
-
# Ensure tmp file gets cleaned up
|
170
|
-
FileUtils.rm("#{filename}+") if File.exist?("#{filename}+")
|
171
173
|
end
|
172
174
|
|
173
|
-
# Pretty inspect
|
175
|
+
# Public: Pretty inspect
|
176
|
+
#
|
177
|
+
# Returns String.
|
174
178
|
def inspect
|
175
|
-
"#<#{self.class}
|
176
|
-
"pathname=#{pathname.to_s.inspect}, " +
|
177
|
-
"mtime=#{mtime.inspect}, " +
|
178
|
-
"digest=#{digest.inspect}" +
|
179
|
-
">"
|
179
|
+
"#<#{self.class}:#{object_id.to_s(16)} #{uri.inspect}>"
|
180
180
|
end
|
181
181
|
|
182
|
+
# Public: Implements Object#hash so Assets can be used as a Hash key or
|
183
|
+
# in a Set.
|
184
|
+
#
|
185
|
+
# Returns Integer hash of the id.
|
182
186
|
def hash
|
183
|
-
|
187
|
+
id.hash
|
184
188
|
end
|
185
189
|
|
186
|
-
#
|
190
|
+
# Public: Compare assets.
|
191
|
+
#
|
192
|
+
# Assets are equal if they share the same path and digest.
|
193
|
+
#
|
194
|
+
# Returns true or false.
|
187
195
|
def eql?(other)
|
188
|
-
|
189
|
-
other.logical_path == self.logical_path &&
|
190
|
-
other.mtime.to_i == self.mtime.to_i &&
|
191
|
-
other.digest == self.digest
|
196
|
+
self.class == other.class && self.id == other.id
|
192
197
|
end
|
193
198
|
alias_method :==, :eql?
|
194
|
-
|
195
|
-
protected
|
196
|
-
# Internal: String paths that are marked as dependencies after processing.
|
197
|
-
#
|
198
|
-
# Default to an empty `Array`.
|
199
|
-
def dependency_paths
|
200
|
-
@dependency_paths ||= []
|
201
|
-
end
|
202
|
-
|
203
|
-
# Internal: `ProccessedAsset`s that are required after processing.
|
204
|
-
#
|
205
|
-
# Default to an empty `Array`.
|
206
|
-
def required_assets
|
207
|
-
@required_assets ||= []
|
208
|
-
end
|
209
|
-
|
210
|
-
# Get pathname with its root stripped.
|
211
|
-
def relative_pathname
|
212
|
-
@relative_pathname ||= Pathname.new(relativize_root_path(pathname))
|
213
|
-
end
|
214
|
-
|
215
|
-
# Replace `$root` placeholder with actual environment root.
|
216
|
-
def expand_root_path(path)
|
217
|
-
path.to_s.sub(/^\$root/, @root)
|
218
|
-
end
|
219
|
-
|
220
|
-
# Replace actual environment root with `$root` placeholder.
|
221
|
-
def relativize_root_path(path)
|
222
|
-
path.to_s.sub(/^#{Regexp.escape(@root)}/, '$root')
|
223
|
-
end
|
224
|
-
|
225
|
-
# Check if dependency is fresh.
|
226
|
-
#
|
227
|
-
# `dep` is a `Hash` with `path`, `mtime` and `hexdigest` keys.
|
228
|
-
#
|
229
|
-
# A `Hash` is used rather than other `Asset` object because we
|
230
|
-
# want to test non-asset files and directories.
|
231
|
-
def dependency_fresh?(environment, dep)
|
232
|
-
path, mtime, hexdigest = dep.pathname.to_s, dep.mtime, dep.digest
|
233
|
-
|
234
|
-
stat = environment.stat(path)
|
235
|
-
|
236
|
-
# If path no longer exists, its definitely stale.
|
237
|
-
if stat.nil?
|
238
|
-
return false
|
239
|
-
end
|
240
|
-
|
241
|
-
# Compare dependency mtime to the actual mtime. If the
|
242
|
-
# dependency mtime is newer than the actual mtime, the file
|
243
|
-
# hasn't changed since we created this `Asset` instance.
|
244
|
-
#
|
245
|
-
# However, if the mtime is newer it doesn't mean the asset is
|
246
|
-
# stale. Many deployment environments may recopy or recheckout
|
247
|
-
# assets on each deploy. In this case the mtime would be the
|
248
|
-
# time of deploy rather than modified time.
|
249
|
-
#
|
250
|
-
# Note: to_i is used in eql? and write_to we assume fidelity of 1 second
|
251
|
-
# if people save files more frequently than 1 second sprockets may
|
252
|
-
# not pick it up, by design
|
253
|
-
if mtime.to_i >= stat.mtime.to_i
|
254
|
-
return true
|
255
|
-
end
|
256
|
-
|
257
|
-
digest = environment.file_digest(path)
|
258
|
-
|
259
|
-
# If the mtime is newer, do a full digest comparsion. Return
|
260
|
-
# fresh if the digests match.
|
261
|
-
if hexdigest == digest.hexdigest
|
262
|
-
return true
|
263
|
-
end
|
264
|
-
|
265
|
-
# Otherwise, its stale.
|
266
|
-
false
|
267
|
-
end
|
268
199
|
end
|
269
200
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Sprockets
|
2
|
+
module Autoload
|
3
|
+
autoload :Closure, 'sprockets/autoload/closure'
|
4
|
+
autoload :CoffeeScript, 'sprockets/autoload/coffee_script'
|
5
|
+
autoload :Eco, 'sprockets/autoload/eco'
|
6
|
+
autoload :EJS, 'sprockets/autoload/ejs'
|
7
|
+
autoload :Sass, 'sprockets/autoload/sass'
|
8
|
+
autoload :Uglifier, 'sprockets/autoload/uglifier'
|
9
|
+
autoload :YUI, 'sprockets/autoload/yui'
|
10
|
+
end
|
11
|
+
end
|