sprockets 2.2.3 → 2.12.2
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 +4 -4
- data/README.md +131 -4
- data/bin/sprockets +8 -0
- data/lib/rake/sprocketstask.rb +24 -13
- data/lib/sprockets.rb +52 -8
- data/lib/sprockets/asset.rb +14 -7
- data/lib/sprockets/asset_attributes.rb +15 -4
- data/lib/sprockets/base.rb +154 -14
- data/lib/sprockets/bundled_asset.rb +5 -6
- data/lib/sprockets/caching.rb +39 -39
- data/lib/sprockets/closure_compressor.rb +22 -0
- data/lib/sprockets/compressing.rb +73 -0
- data/lib/sprockets/context.rb +57 -3
- data/lib/sprockets/directive_processor.rb +3 -1
- data/lib/sprockets/engines.rb +4 -4
- data/lib/sprockets/environment.rb +12 -15
- data/lib/sprockets/errors.rb +1 -0
- data/lib/sprockets/index.rb +1 -0
- data/lib/sprockets/jst_processor.rb +2 -6
- data/lib/sprockets/manifest.rb +77 -19
- data/lib/sprockets/mime.rb +5 -4
- data/lib/sprockets/{trail.rb → paths.rb} +5 -37
- data/lib/sprockets/processed_asset.rb +1 -1
- data/lib/sprockets/processing.rb +3 -77
- data/lib/sprockets/processor.rb +1 -1
- data/lib/sprockets/sass_cache_store.rb +29 -0
- data/lib/sprockets/sass_compressor.rb +27 -0
- data/lib/sprockets/sass_functions.rb +70 -0
- data/lib/sprockets/sass_importer.rb +30 -0
- data/lib/sprockets/sass_template.rb +66 -0
- data/lib/sprockets/scss_template.rb +13 -0
- data/lib/sprockets/server.rb +7 -7
- data/lib/sprockets/static_asset.rb +1 -0
- data/lib/sprockets/uglifier_compressor.rb +29 -0
- data/lib/sprockets/version.rb +1 -1
- data/lib/sprockets/yui_compressor.rb +27 -0
- metadata +73 -6
@@ -13,20 +13,19 @@ module Sprockets
|
|
13
13
|
def initialize(environment, logical_path, pathname)
|
14
14
|
super(environment, logical_path, pathname)
|
15
15
|
|
16
|
-
@processed_asset
|
17
|
-
@required_assets
|
18
|
-
|
19
|
-
@source = ""
|
16
|
+
@processed_asset = environment.find_asset(pathname, :bundle => false)
|
17
|
+
@required_assets = @processed_asset.required_assets
|
18
|
+
@dependency_paths = @processed_asset.dependency_paths
|
20
19
|
|
21
20
|
# Explode Asset into parts and gather the dependency bodies
|
22
|
-
to_a.
|
21
|
+
@source = to_a.map { |dependency| dependency.to_s }.join
|
23
22
|
|
24
23
|
# Run bundle processors on concatenated source
|
25
24
|
context = environment.context_class.new(environment, logical_path, pathname)
|
26
25
|
@source = context.evaluate(pathname, :data => @source,
|
27
26
|
:processors => environment.bundle_processors(content_type))
|
28
27
|
|
29
|
-
@mtime = to_a.map(&:mtime).max
|
28
|
+
@mtime = (to_a + @dependency_paths).map(&:mtime).max
|
30
29
|
@length = Rack::Utils.bytesize(source)
|
31
30
|
@digest = environment.digest.update(source).hexdigest
|
32
31
|
end
|
data/lib/sprockets/caching.rb
CHANGED
@@ -2,6 +2,45 @@ module Sprockets
|
|
2
2
|
# `Caching` is an internal mixin whose public methods are exposed on
|
3
3
|
# the `Environment` and `Index` classes.
|
4
4
|
module Caching
|
5
|
+
# Low level cache getter for `key`. Checks a number of supported
|
6
|
+
# cache interfaces.
|
7
|
+
def cache_get(key)
|
8
|
+
# `Cache#get(key)` for Memcache
|
9
|
+
if cache.respond_to?(:get)
|
10
|
+
cache.get(key)
|
11
|
+
|
12
|
+
# `Cache#[key]` so `Hash` can be used
|
13
|
+
elsif cache.respond_to?(:[])
|
14
|
+
cache[key]
|
15
|
+
|
16
|
+
# `Cache#read(key)` for `ActiveSupport::Cache` support
|
17
|
+
elsif cache.respond_to?(:read)
|
18
|
+
cache.read(key)
|
19
|
+
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Low level cache setter for `key`. Checks a number of supported
|
26
|
+
# cache interfaces.
|
27
|
+
def cache_set(key, value)
|
28
|
+
# `Cache#set(key, value)` for Memcache
|
29
|
+
if cache.respond_to?(:set)
|
30
|
+
cache.set(key, value)
|
31
|
+
|
32
|
+
# `Cache#[key]=value` so `Hash` can be used
|
33
|
+
elsif cache.respond_to?(:[]=)
|
34
|
+
cache[key] = value
|
35
|
+
|
36
|
+
# `Cache#write(key, value)` for `ActiveSupport::Cache` support
|
37
|
+
elsif cache.respond_to?(:write)
|
38
|
+
cache.write(key, value)
|
39
|
+
end
|
40
|
+
|
41
|
+
value
|
42
|
+
end
|
43
|
+
|
5
44
|
protected
|
6
45
|
# Cache helper method. Takes a `path` argument which maybe a
|
7
46
|
# logical path or fully expanded path. The `&block` is passed
|
@@ -53,44 +92,5 @@ module Sprockets
|
|
53
92
|
cache_set(expand_cache_key(key), hash)
|
54
93
|
hash
|
55
94
|
end
|
56
|
-
|
57
|
-
# Low level cache getter for `key`. Checks a number of supported
|
58
|
-
# cache interfaces.
|
59
|
-
def cache_get(key)
|
60
|
-
# `Cache#get(key)` for Memcache
|
61
|
-
if cache.respond_to?(:get)
|
62
|
-
cache.get(key)
|
63
|
-
|
64
|
-
# `Cache#[key]` so `Hash` can be used
|
65
|
-
elsif cache.respond_to?(:[])
|
66
|
-
cache[key]
|
67
|
-
|
68
|
-
# `Cache#read(key)` for `ActiveSupport::Cache` support
|
69
|
-
elsif cache.respond_to?(:read)
|
70
|
-
cache.read(key)
|
71
|
-
|
72
|
-
else
|
73
|
-
nil
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Low level cache setter for `key`. Checks a number of supported
|
78
|
-
# cache interfaces.
|
79
|
-
def cache_set(key, value)
|
80
|
-
# `Cache#set(key, value)` for Memcache
|
81
|
-
if cache.respond_to?(:set)
|
82
|
-
cache.set(key, value)
|
83
|
-
|
84
|
-
# `Cache#[key]=value` so `Hash` can be used
|
85
|
-
elsif cache.respond_to?(:[]=)
|
86
|
-
cache[key] = value
|
87
|
-
|
88
|
-
# `Cache#write(key, value)` for `ActiveSupport::Cache` support
|
89
|
-
elsif cache.respond_to?(:write)
|
90
|
-
cache.write(key, value)
|
91
|
-
end
|
92
|
-
|
93
|
-
value
|
94
|
-
end
|
95
95
|
end
|
96
96
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
class ClosureCompressor < Tilt::Template
|
5
|
+
self.default_mime_type = 'application/javascript'
|
6
|
+
|
7
|
+
def self.engine_initialized?
|
8
|
+
defined?(::Closure::Compiler)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_engine
|
12
|
+
require_template_library 'closure-compiler'
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare
|
16
|
+
end
|
17
|
+
|
18
|
+
def evaluate(context, locals, &block)
|
19
|
+
Closure::Compiler.new.compile(data)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Sprockets
|
2
|
+
# `Compressing` is an internal mixin whose public methods are exposed on
|
3
|
+
# the `Environment` and `Index` classes.
|
4
|
+
module Compressing
|
5
|
+
def compressors
|
6
|
+
deep_copy_hash(@compressors)
|
7
|
+
end
|
8
|
+
|
9
|
+
def register_compressor(mime_type, sym, klass)
|
10
|
+
@compressors[mime_type][sym] = klass
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return CSS compressor or nil if none is set
|
14
|
+
def css_compressor
|
15
|
+
@css_compressor if defined? @css_compressor
|
16
|
+
end
|
17
|
+
|
18
|
+
# Assign a compressor to run on `text/css` assets.
|
19
|
+
#
|
20
|
+
# The compressor object must respond to `compress`.
|
21
|
+
def css_compressor=(compressor)
|
22
|
+
unregister_bundle_processor 'text/css', css_compressor if css_compressor
|
23
|
+
@css_compressor = nil
|
24
|
+
return unless compressor
|
25
|
+
|
26
|
+
if compressor.is_a?(Symbol)
|
27
|
+
compressor = compressors['text/css'][compressor] || raise(Error, "unknown compressor: #{compressor}")
|
28
|
+
end
|
29
|
+
|
30
|
+
if compressor.respond_to?(:compress)
|
31
|
+
klass = Class.new(Processor) do
|
32
|
+
@name = "css_compressor"
|
33
|
+
@processor = proc { |context, data| compressor.compress(data) }
|
34
|
+
end
|
35
|
+
@css_compressor = :css_compressor
|
36
|
+
else
|
37
|
+
@css_compressor = klass = compressor
|
38
|
+
end
|
39
|
+
|
40
|
+
register_bundle_processor 'text/css', klass
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return JS compressor or nil if none is set
|
44
|
+
def js_compressor
|
45
|
+
@js_compressor if defined? @js_compressor
|
46
|
+
end
|
47
|
+
|
48
|
+
# Assign a compressor to run on `application/javascript` assets.
|
49
|
+
#
|
50
|
+
# The compressor object must respond to `compress`.
|
51
|
+
def js_compressor=(compressor)
|
52
|
+
unregister_bundle_processor 'application/javascript', js_compressor if js_compressor
|
53
|
+
@js_compressor = nil
|
54
|
+
return unless compressor
|
55
|
+
|
56
|
+
if compressor.is_a?(Symbol)
|
57
|
+
compressor = compressors['application/javascript'][compressor] || raise(Error, "unknown compressor: #{compressor}")
|
58
|
+
end
|
59
|
+
|
60
|
+
if compressor.respond_to?(:compress)
|
61
|
+
klass = Class.new(Processor) do
|
62
|
+
@name = "js_compressor"
|
63
|
+
@processor = proc { |context, data| compressor.compress(data) }
|
64
|
+
end
|
65
|
+
@js_compressor = :js_compressor
|
66
|
+
else
|
67
|
+
@js_compressor = klass = compressor
|
68
|
+
end
|
69
|
+
|
70
|
+
register_bundle_processor 'application/javascript', klass
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/sprockets/context.rb
CHANGED
@@ -53,7 +53,7 @@ module Sprockets
|
|
53
53
|
# # => 'application'
|
54
54
|
#
|
55
55
|
def logical_path
|
56
|
-
@logical_path
|
56
|
+
@logical_path.chomp(File.extname(@logical_path))
|
57
57
|
end
|
58
58
|
|
59
59
|
# Returns content type of file
|
@@ -81,7 +81,11 @@ module Sprockets
|
|
81
81
|
attributes = environment.attributes_for(pathname)
|
82
82
|
|
83
83
|
if pathname.absolute?
|
84
|
-
pathname
|
84
|
+
if environment.stat(pathname)
|
85
|
+
pathname
|
86
|
+
else
|
87
|
+
raise FileNotFound, "couldn't find file '#{pathname}'"
|
88
|
+
end
|
85
89
|
|
86
90
|
elsif content_type = options[:content_type]
|
87
91
|
content_type = self.content_type if content_type == :self
|
@@ -101,7 +105,7 @@ module Sprockets
|
|
101
105
|
|
102
106
|
raise FileNotFound, "couldn't find file '#{path}'"
|
103
107
|
else
|
104
|
-
environment.resolve(path, :base_path => self.pathname.dirname, &block)
|
108
|
+
environment.resolve(path, {:base_path => self.pathname.dirname}.merge(options), &block)
|
105
109
|
end
|
106
110
|
end
|
107
111
|
|
@@ -217,6 +221,56 @@ module Sprockets
|
|
217
221
|
"data:#{asset.content_type};base64,#{Rack::Utils.escape(base64)}"
|
218
222
|
end
|
219
223
|
|
224
|
+
# Expands logical path to full url to asset.
|
225
|
+
#
|
226
|
+
# NOTE: This helper is currently not implemented and should be
|
227
|
+
# customized by the application. Though, in the future, some
|
228
|
+
# basics implemention may be provided with different methods that
|
229
|
+
# are required to be overridden.
|
230
|
+
def asset_path(path, options = {})
|
231
|
+
message = <<-EOS
|
232
|
+
Custom asset_path helper is not implemented
|
233
|
+
|
234
|
+
Extend your environment context with a custom method.
|
235
|
+
|
236
|
+
environment.context_class.class_eval do
|
237
|
+
def asset_path(path, options = {})
|
238
|
+
end
|
239
|
+
end
|
240
|
+
EOS
|
241
|
+
raise NotImplementedError, message
|
242
|
+
end
|
243
|
+
|
244
|
+
# Expand logical image asset path.
|
245
|
+
def image_path(path)
|
246
|
+
asset_path(path, :type => :image)
|
247
|
+
end
|
248
|
+
|
249
|
+
# Expand logical video asset path.
|
250
|
+
def video_path(path)
|
251
|
+
asset_path(path, :type => :video)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Expand logical audio asset path.
|
255
|
+
def audio_path(path)
|
256
|
+
asset_path(path, :type => :audio)
|
257
|
+
end
|
258
|
+
|
259
|
+
# Expand logical font asset path.
|
260
|
+
def font_path(path)
|
261
|
+
asset_path(path, :type => :font)
|
262
|
+
end
|
263
|
+
|
264
|
+
# Expand logical javascript asset path.
|
265
|
+
def javascript_path(path)
|
266
|
+
asset_path(path, :type => :javascript)
|
267
|
+
end
|
268
|
+
|
269
|
+
# Expand logical stylesheet asset path.
|
270
|
+
def stylesheet_path(path)
|
271
|
+
asset_path(path, :type => :stylesheet)
|
272
|
+
end
|
273
|
+
|
220
274
|
private
|
221
275
|
# Annotates exception backtrace with the original template that
|
222
276
|
# the exception was raised in.
|
@@ -65,7 +65,7 @@ module Sprockets
|
|
65
65
|
# //= require "foo"
|
66
66
|
#
|
67
67
|
DIRECTIVE_PATTERN = /
|
68
|
-
^
|
68
|
+
^ \W* = \s* (\w+.*?) (\*\/)? $
|
69
69
|
/x
|
70
70
|
|
71
71
|
attr_reader :pathname
|
@@ -92,6 +92,8 @@ module Sprockets
|
|
92
92
|
@context = context
|
93
93
|
|
94
94
|
@result = ""
|
95
|
+
@result.force_encoding(body.encoding) if body.respond_to?(:encoding)
|
96
|
+
|
95
97
|
@has_written_body = false
|
96
98
|
|
97
99
|
process_directives
|
data/lib/sprockets/engines.rb
CHANGED
@@ -28,12 +28,12 @@ module Sprockets
|
|
28
28
|
# Sprockets.register_engine '.sass', SassTemplate
|
29
29
|
#
|
30
30
|
module Engines
|
31
|
-
# Returns
|
32
|
-
#
|
33
|
-
#
|
31
|
+
# Returns a `Hash` of `Engine`s registered on the `Environment`.
|
32
|
+
# If an `ext` argument is supplied, the `Engine` associated with
|
33
|
+
# that extension will be returned.
|
34
34
|
#
|
35
35
|
# environment.engines
|
36
|
-
# # =>
|
36
|
+
# # => {".coffee" => CoffeeScriptTemplate, ".sass" => SassTemplate, ...}
|
37
37
|
#
|
38
38
|
# environment.engines('.coffee')
|
39
39
|
# # => CoffeeScriptTemplate
|
@@ -1,9 +1,6 @@
|
|
1
1
|
require 'sprockets/base'
|
2
|
-
require 'sprockets/charset_normalizer'
|
3
2
|
require 'sprockets/context'
|
4
|
-
require 'sprockets/directive_processor'
|
5
3
|
require 'sprockets/index'
|
6
|
-
require 'sprockets/safety_colons'
|
7
4
|
|
8
5
|
require 'hike'
|
9
6
|
require 'logger'
|
@@ -35,24 +32,24 @@ module Sprockets
|
|
35
32
|
@digest_class = ::Digest::MD5
|
36
33
|
@version = ''
|
37
34
|
|
38
|
-
@mime_types =
|
35
|
+
@mime_types = Sprockets.registered_mime_types
|
39
36
|
@engines = Sprockets.engines
|
40
|
-
@preprocessors =
|
41
|
-
@postprocessors =
|
42
|
-
@bundle_processors =
|
37
|
+
@preprocessors = Sprockets.preprocessors
|
38
|
+
@postprocessors = Sprockets.postprocessors
|
39
|
+
@bundle_processors = Sprockets.bundle_processors
|
40
|
+
@compressors = Sprockets.compressors
|
41
|
+
|
42
|
+
Sprockets.paths.each do |path|
|
43
|
+
append_path(path)
|
44
|
+
end
|
43
45
|
|
44
46
|
@engines.each do |ext, klass|
|
45
47
|
add_engine_to_trail(ext, klass)
|
46
48
|
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
register_preprocessor 'text/css', DirectiveProcessor
|
52
|
-
register_preprocessor 'application/javascript', DirectiveProcessor
|
53
|
-
|
54
|
-
register_postprocessor 'application/javascript', SafetyColons
|
55
|
-
register_bundle_processor 'text/css', CharsetNormalizer
|
50
|
+
@mime_types.each do |ext, type|
|
51
|
+
@trail.append_extension(ext)
|
52
|
+
end
|
56
53
|
|
57
54
|
expire_index!
|
58
55
|
|
data/lib/sprockets/errors.rb
CHANGED
data/lib/sprockets/index.rb
CHANGED
@@ -2,9 +2,7 @@ require 'tilt'
|
|
2
2
|
|
3
3
|
module Sprockets
|
4
4
|
class JstProcessor < Tilt::Template
|
5
|
-
|
6
|
-
'application/javascript'
|
7
|
-
end
|
5
|
+
self.default_mime_type = 'application/javascript'
|
8
6
|
|
9
7
|
def self.default_namespace
|
10
8
|
'this.JST'
|
@@ -18,9 +16,7 @@ module Sprockets
|
|
18
16
|
|
19
17
|
def evaluate(scope, locals, &block)
|
20
18
|
<<-JST
|
21
|
-
(function() {
|
22
|
-
#{namespace} || (#{namespace} = {});
|
23
|
-
#{namespace}[#{scope.logical_path.inspect}] = #{indent(data)};
|
19
|
+
(function() { #{namespace} || (#{namespace} = {}); #{namespace}[#{scope.logical_path.inspect}] = #{indent(data)};
|
24
20
|
}).call(this);
|
25
21
|
JST
|
26
22
|
end
|
data/lib/sprockets/manifest.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'multi_json'
|
2
|
+
require 'securerandom'
|
2
3
|
require 'time'
|
3
4
|
|
4
5
|
module Sprockets
|
@@ -18,26 +19,50 @@ module Sprockets
|
|
18
19
|
# a full path to the manifest json file. The file may or may not
|
19
20
|
# already exist. The dirname of the `path` will be used to write
|
20
21
|
# compiled assets to. Otherwise, if the path is a directory, the
|
21
|
-
# filename will default
|
22
|
+
# filename will default a random "manifest-123.json" file in that
|
23
|
+
# directory.
|
22
24
|
#
|
23
25
|
# Manifest.new(environment, "./public/assets/manifest.json")
|
24
26
|
#
|
25
|
-
def initialize(
|
26
|
-
|
27
|
+
def initialize(*args)
|
28
|
+
if args.first.is_a?(Base) || args.first.nil?
|
29
|
+
@environment = args.shift
|
30
|
+
end
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
@dir, @path = args[0], args[1]
|
33
|
+
|
34
|
+
# Expand paths
|
35
|
+
@dir = File.expand_path(@dir) if @dir
|
36
|
+
@path = File.expand_path(@path) if @path
|
37
|
+
|
38
|
+
# If path is given as the second arg
|
39
|
+
if @dir && File.extname(@dir) != ""
|
40
|
+
@dir, @path = nil, @dir
|
41
|
+
end
|
42
|
+
|
43
|
+
# Default dir to the directory of the path
|
44
|
+
@dir ||= File.dirname(@path) if @path
|
45
|
+
|
46
|
+
# If directory is given w/o path, pick a random manifest.json location
|
47
|
+
if @dir && @path.nil?
|
48
|
+
# Find the first manifest.json in the directory
|
49
|
+
paths = Dir[File.join(@dir, "manifest*.json")]
|
50
|
+
if paths.any?
|
51
|
+
@path = paths.first
|
52
|
+
else
|
53
|
+
@path = File.join(@dir, "manifest-#{SecureRandom.hex(16)}.json")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
unless @dir && @path
|
58
|
+
raise ArgumentError, "manifest requires output path"
|
34
59
|
end
|
35
60
|
|
36
61
|
data = nil
|
37
62
|
|
38
63
|
begin
|
39
64
|
if File.exist?(@path)
|
40
|
-
data =
|
65
|
+
data = json_decode(File.read(@path))
|
41
66
|
end
|
42
67
|
rescue MultiJson::DecodeError => e
|
43
68
|
logger.error "#{@path} is invalid: #{e.class} #{e.message}"
|
@@ -83,14 +108,19 @@ module Sprockets
|
|
83
108
|
# compile("application.js")
|
84
109
|
#
|
85
110
|
def compile(*args)
|
111
|
+
unless environment
|
112
|
+
raise Error, "manifest requires environment for compilation"
|
113
|
+
end
|
114
|
+
|
86
115
|
paths = environment.each_logical_path(*args).to_a +
|
87
|
-
args.flatten.select { |fn| Pathname.new(fn).absolute? }
|
116
|
+
args.flatten.select { |fn| Pathname.new(fn).absolute? if fn.is_a?(String)}
|
88
117
|
|
89
118
|
paths.each do |path|
|
90
119
|
if asset = find_asset(path)
|
91
120
|
files[asset.digest_path] = {
|
92
121
|
'logical_path' => asset.logical_path,
|
93
122
|
'mtime' => asset.mtime.iso8601,
|
123
|
+
'size' => asset.bytesize,
|
94
124
|
'digest' => asset.digest
|
95
125
|
}
|
96
126
|
assets[asset.logical_path] = asset.digest_path
|
@@ -102,12 +132,13 @@ module Sprockets
|
|
102
132
|
else
|
103
133
|
logger.info "Writing #{target}"
|
104
134
|
asset.write_to target
|
135
|
+
asset.write_to "#{target}.gz" if asset.is_a?(BundledAsset)
|
105
136
|
end
|
106
137
|
|
107
|
-
save
|
108
|
-
asset
|
109
138
|
end
|
110
139
|
end
|
140
|
+
save
|
141
|
+
paths
|
111
142
|
end
|
112
143
|
|
113
144
|
# Removes file from directory and from manifest. `filename` must
|
@@ -117,6 +148,7 @@ module Sprockets
|
|
117
148
|
#
|
118
149
|
def remove(filename)
|
119
150
|
path = File.join(dir, filename)
|
151
|
+
gzip = "#{path}.gz"
|
120
152
|
logical_path = files[filename]['logical_path']
|
121
153
|
|
122
154
|
if assets[logical_path] == filename
|
@@ -125,10 +157,11 @@ module Sprockets
|
|
125
157
|
|
126
158
|
files.delete(filename)
|
127
159
|
FileUtils.rm(path) if File.exist?(path)
|
160
|
+
FileUtils.rm(gzip) if File.exist?(gzip)
|
128
161
|
|
129
162
|
save
|
130
163
|
|
131
|
-
logger.
|
164
|
+
logger.info "Removed #{filename}"
|
132
165
|
|
133
166
|
nil
|
134
167
|
end
|
@@ -151,7 +184,7 @@ module Sprockets
|
|
151
184
|
# Wipe directive
|
152
185
|
def clobber
|
153
186
|
FileUtils.rm_r(@dir) if File.exist?(@dir)
|
154
|
-
logger.
|
187
|
+
logger.info "Removed #{@dir}"
|
155
188
|
nil
|
156
189
|
end
|
157
190
|
|
@@ -177,21 +210,46 @@ module Sprockets
|
|
177
210
|
ms = benchmark do
|
178
211
|
asset = environment.find_asset(logical_path)
|
179
212
|
end
|
180
|
-
logger.
|
213
|
+
logger.debug "Compiled #{logical_path} (#{ms}ms)"
|
181
214
|
asset
|
182
215
|
end
|
183
216
|
|
184
217
|
# Persist manfiest back to FS
|
185
218
|
def save
|
186
|
-
FileUtils.mkdir_p
|
219
|
+
FileUtils.mkdir_p File.dirname(path)
|
187
220
|
File.open(path, 'w') do |f|
|
188
|
-
f.write
|
221
|
+
f.write json_encode(@data)
|
189
222
|
end
|
190
223
|
end
|
191
224
|
|
192
225
|
private
|
226
|
+
# Feature detect newer MultiJson API
|
227
|
+
if MultiJson.respond_to?(:dump)
|
228
|
+
def json_decode(obj)
|
229
|
+
MultiJson.load(obj)
|
230
|
+
end
|
231
|
+
|
232
|
+
def json_encode(obj)
|
233
|
+
MultiJson.dump(obj)
|
234
|
+
end
|
235
|
+
else
|
236
|
+
def json_decode(obj)
|
237
|
+
MultiJson.decode(obj)
|
238
|
+
end
|
239
|
+
|
240
|
+
def json_encode(obj)
|
241
|
+
MultiJson.encode(obj)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
193
245
|
def logger
|
194
|
-
environment
|
246
|
+
if environment
|
247
|
+
environment.logger
|
248
|
+
else
|
249
|
+
logger = Logger.new($stderr)
|
250
|
+
logger.level = Logger::FATAL
|
251
|
+
logger
|
252
|
+
end
|
195
253
|
end
|
196
254
|
|
197
255
|
def benchmark
|