sprockets 2.3.2 → 3.0.0

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.

Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +2 -2
  3. data/README.md +332 -115
  4. data/bin/sprockets +8 -0
  5. data/lib/rake/sprocketstask.rb +25 -13
  6. data/lib/sprockets/asset.rb +143 -205
  7. data/lib/sprockets/autoload/closure.rb +7 -0
  8. data/lib/sprockets/autoload/coffee_script.rb +7 -0
  9. data/lib/sprockets/autoload/eco.rb +7 -0
  10. data/lib/sprockets/autoload/ejs.rb +7 -0
  11. data/lib/sprockets/autoload/sass.rb +7 -0
  12. data/lib/sprockets/autoload/uglifier.rb +7 -0
  13. data/lib/sprockets/autoload/yui.rb +7 -0
  14. data/lib/sprockets/autoload.rb +11 -0
  15. data/lib/sprockets/base.rb +49 -257
  16. data/lib/sprockets/bower.rb +58 -0
  17. data/lib/sprockets/bundle.rb +65 -0
  18. data/lib/sprockets/cache/file_store.rb +165 -14
  19. data/lib/sprockets/cache/memory_store.rb +66 -0
  20. data/lib/sprockets/cache/null_store.rb +46 -0
  21. data/lib/sprockets/cache.rb +234 -0
  22. data/lib/sprockets/cached_environment.rb +69 -0
  23. data/lib/sprockets/closure_compressor.rb +53 -0
  24. data/lib/sprockets/coffee_script_processor.rb +25 -0
  25. data/lib/sprockets/coffee_script_template.rb +6 -0
  26. data/lib/sprockets/compressing.rb +74 -0
  27. data/lib/sprockets/configuration.rb +83 -0
  28. data/lib/sprockets/context.rb +125 -131
  29. data/lib/sprockets/dependencies.rb +73 -0
  30. data/lib/sprockets/digest_utils.rb +156 -0
  31. data/lib/sprockets/directive_processor.rb +209 -211
  32. data/lib/sprockets/eco_processor.rb +32 -0
  33. data/lib/sprockets/eco_template.rb +3 -35
  34. data/lib/sprockets/ejs_processor.rb +31 -0
  35. data/lib/sprockets/ejs_template.rb +3 -34
  36. data/lib/sprockets/encoding_utils.rb +258 -0
  37. data/lib/sprockets/engines.rb +45 -38
  38. data/lib/sprockets/environment.rb +17 -67
  39. data/lib/sprockets/erb_processor.rb +30 -0
  40. data/lib/sprockets/erb_template.rb +6 -0
  41. data/lib/sprockets/errors.rb +6 -13
  42. data/lib/sprockets/file_reader.rb +15 -0
  43. data/lib/sprockets/http_utils.rb +115 -0
  44. data/lib/sprockets/jst_processor.rb +35 -19
  45. data/lib/sprockets/legacy.rb +314 -0
  46. data/lib/sprockets/legacy_proc_processor.rb +35 -0
  47. data/lib/sprockets/legacy_tilt_processor.rb +29 -0
  48. data/lib/sprockets/loader.rb +176 -0
  49. data/lib/sprockets/manifest.rb +179 -98
  50. data/lib/sprockets/manifest_utils.rb +45 -0
  51. data/lib/sprockets/mime.rb +114 -32
  52. data/lib/sprockets/path_dependency_utils.rb +85 -0
  53. data/lib/sprockets/path_digest_utils.rb +47 -0
  54. data/lib/sprockets/path_utils.rb +282 -0
  55. data/lib/sprockets/paths.rb +81 -0
  56. data/lib/sprockets/processing.rb +157 -189
  57. data/lib/sprockets/processor_utils.rb +103 -0
  58. data/lib/sprockets/resolve.rb +208 -0
  59. data/lib/sprockets/sass_cache_store.rb +19 -15
  60. data/lib/sprockets/sass_compressor.rb +59 -0
  61. data/lib/sprockets/sass_functions.rb +2 -0
  62. data/lib/sprockets/sass_importer.rb +2 -29
  63. data/lib/sprockets/sass_processor.rb +285 -0
  64. data/lib/sprockets/sass_template.rb +4 -44
  65. data/lib/sprockets/server.rb +109 -84
  66. data/lib/sprockets/transformers.rb +145 -0
  67. data/lib/sprockets/uglifier_compressor.rb +63 -0
  68. data/lib/sprockets/uri_utils.rb +190 -0
  69. data/lib/sprockets/utils.rb +193 -44
  70. data/lib/sprockets/version.rb +1 -1
  71. data/lib/sprockets/yui_compressor.rb +65 -0
  72. data/lib/sprockets.rb +144 -53
  73. metadata +248 -238
  74. data/lib/sprockets/asset_attributes.rb +0 -126
  75. data/lib/sprockets/bundled_asset.rb +0 -79
  76. data/lib/sprockets/caching.rb +0 -96
  77. data/lib/sprockets/charset_normalizer.rb +0 -41
  78. data/lib/sprockets/index.rb +0 -99
  79. data/lib/sprockets/processed_asset.rb +0 -152
  80. data/lib/sprockets/processor.rb +0 -32
  81. data/lib/sprockets/safety_colons.rb +0 -28
  82. data/lib/sprockets/scss_template.rb +0 -13
  83. data/lib/sprockets/static_asset.rb +0 -57
  84. data/lib/sprockets/trail.rb +0 -90
@@ -0,0 +1,66 @@
1
+ module Sprockets
2
+ class Cache
3
+ # Public: Basic in memory LRU cache.
4
+ #
5
+ # Assign the instance to the Environment#cache.
6
+ #
7
+ # environment.cache = Sprockets::Cache::MemoryStore.new(1000)
8
+ #
9
+ # See Also
10
+ #
11
+ # ActiveSupport::Cache::MemoryStore
12
+ #
13
+ class MemoryStore
14
+ # Internal: Default key limit for store.
15
+ DEFAULT_MAX_SIZE = 1000
16
+
17
+ # Public: Initialize the cache store.
18
+ #
19
+ # max_size - A Integer of the maximum number of keys the store will hold.
20
+ # (default: 1000).
21
+ def initialize(max_size = DEFAULT_MAX_SIZE)
22
+ @max_size = max_size
23
+ @cache = {}
24
+ end
25
+
26
+ # Public: Retrieve value from cache.
27
+ #
28
+ # This API should not be used directly, but via the Cache wrapper API.
29
+ #
30
+ # key - String cache key.
31
+ #
32
+ # Returns Object or nil or the value is not set.
33
+ def get(key)
34
+ exists = true
35
+ value = @cache.delete(key) { exists = false }
36
+ if exists
37
+ @cache[key] = value
38
+ else
39
+ nil
40
+ end
41
+ end
42
+
43
+ # Public: Set a key and value in the cache.
44
+ #
45
+ # This API should not be used directly, but via the Cache wrapper API.
46
+ #
47
+ # key - String cache key.
48
+ # value - Object value.
49
+ #
50
+ # Returns Object value.
51
+ def set(key, value)
52
+ @cache.delete(key)
53
+ @cache[key] = value
54
+ @cache.shift if @cache.size > @max_size
55
+ value
56
+ end
57
+
58
+ # Public: Pretty inspect
59
+ #
60
+ # Returns String.
61
+ def inspect
62
+ "#<#{self.class} size=#{@cache.size}/#{@max_size}>"
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,46 @@
1
+ module Sprockets
2
+ class Cache
3
+ # Public: A compatible cache store that doesn't store anything. Used by
4
+ # default when no Environment#cache is configured.
5
+ #
6
+ # Assign the instance to the Environment#cache.
7
+ #
8
+ # environment.cache = Sprockets::Cache::NullStore.new
9
+ #
10
+ # See Also
11
+ #
12
+ # ActiveSupport::Cache::NullStore
13
+ #
14
+ class NullStore
15
+ # Public: Simulate a cache miss.
16
+ #
17
+ # This API should not be used directly, but via the Cache wrapper API.
18
+ #
19
+ # key - String cache key.
20
+ #
21
+ # Returns nil.
22
+ def get(key)
23
+ nil
24
+ end
25
+
26
+ # Public: Simulate setting a value in the cache.
27
+ #
28
+ # This API should not be used directly, but via the Cache wrapper API.
29
+ #
30
+ # key - String cache key.
31
+ # value - Object value.
32
+ #
33
+ # Returns Object value.
34
+ def set(key, value)
35
+ value
36
+ end
37
+
38
+ # Public: Pretty inspect
39
+ #
40
+ # Returns String.
41
+ def inspect
42
+ "#<#{self.class}>"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,234 @@
1
+ require 'logger'
2
+ require 'sprockets/digest_utils'
3
+
4
+ module Sprockets
5
+ # Public: Wrapper interface to backend cache stores. Ensures a consistent API
6
+ # even when the backend uses get/set or read/write.
7
+ #
8
+ # Public cache interface
9
+ #
10
+ # Always assign the backend store instance to Environment#cache=.
11
+ #
12
+ # environment.cache = Sprockets::Cache::MemoryStore.new(1000)
13
+ #
14
+ # Environment#cache will always return a wrapped Cache interface. See the
15
+ # methods marked public on this class.
16
+ #
17
+ #
18
+ # Backend cache interface
19
+ #
20
+ # The Backend cache store must implement two methods.
21
+ #
22
+ # get(key)
23
+ #
24
+ # key - An opaque String with a length less than 250 characters.
25
+ #
26
+ # Returns an JSON serializable object.
27
+ #
28
+ # set(key, value)
29
+ #
30
+ # Will only be called once per key. Setting a key "foo" with value "bar",
31
+ # then later key "foo" with value "baz" is an undefined behavior.
32
+ #
33
+ # key - An opaque String with a length less than 250 characters.
34
+ # value - A JSON serializable object.
35
+ #
36
+ # Returns argument value.
37
+ #
38
+ class Cache
39
+ # Builtin cache stores.
40
+ autoload :FileStore, 'sprockets/cache/file_store'
41
+ autoload :MemoryStore, 'sprockets/cache/memory_store'
42
+ autoload :NullStore, 'sprockets/cache/null_store'
43
+
44
+ # Internal: Cache key version for this class. Rarely should have to change
45
+ # unless the cache format radically changes. Will be bump on major version
46
+ # releases though.
47
+ VERSION = '3.0'
48
+
49
+ def self.default_logger
50
+ logger = Logger.new($stderr)
51
+ logger.level = Logger::FATAL
52
+ logger
53
+ end
54
+
55
+ # Internal: Wrap a backend cache store.
56
+ #
57
+ # Always assign a backend cache store instance to Environment#cache= and
58
+ # use Environment#cache to retreive a wrapped interface.
59
+ #
60
+ # cache - A compatible backend cache store instance.
61
+ def initialize(cache = nil, logger = self.class.default_logger)
62
+ @cache_wrapper = get_cache_wrapper(cache)
63
+ @fetch_cache = Cache::MemoryStore.new(4096)
64
+ @logger = logger
65
+ end
66
+
67
+ # Public: Prefer API to retrieve and set values in the cache store.
68
+ #
69
+ # key - JSON serializable key
70
+ # block -
71
+ # Must return a consistent JSON serializable object for the given key.
72
+ #
73
+ # Examples
74
+ #
75
+ # cache.fetch("foo") { "bar" }
76
+ #
77
+ # Returns a JSON serializable object.
78
+ def fetch(key)
79
+ start = Time.now.to_f
80
+ expanded_key = expand_key(key)
81
+ value = @fetch_cache.get(expanded_key)
82
+ if value.nil?
83
+ value = @cache_wrapper.get(expanded_key)
84
+ if value.nil?
85
+ value = yield
86
+ @cache_wrapper.set(expanded_key, value)
87
+ @logger.debug do
88
+ ms = "(#{((Time.now.to_f - start) * 1000).to_i}ms)"
89
+ "Sprockets Cache miss #{peek_key(key)} #{ms}"
90
+ end
91
+ end
92
+ @fetch_cache.set(expanded_key, value)
93
+ end
94
+ value
95
+ end
96
+
97
+ # Public: Low level API to retrieve item directly from the backend cache
98
+ # store.
99
+ #
100
+ # This API may be used publicaly, but may have undefined behavior
101
+ # depending on the backend store being used. Prefer the
102
+ # Cache#fetch API over using this.
103
+ #
104
+ # key - JSON serializable key
105
+ # local - Check local cache first (default: false)
106
+ #
107
+ # Returns a JSON serializable object or nil if there was a cache miss.
108
+ def get(key, local = false)
109
+ expanded_key = expand_key(key)
110
+
111
+ if local && value = @fetch_cache.get(expanded_key)
112
+ return value
113
+ end
114
+
115
+ value = @cache_wrapper.get(expanded_key)
116
+ @fetch_cache.set(expanded_key, value) if local
117
+
118
+ value
119
+ end
120
+
121
+ # Public: Low level API to set item directly to the backend cache store.
122
+ #
123
+ # This API may be used publicaly, but may have undefined behavior
124
+ # depending on the backend store being used. Prefer the
125
+ # Cache#fetch API over using this.
126
+ #
127
+ # key - JSON serializable key
128
+ # value - A consistent JSON serializable object for the given key. Setting
129
+ # a different value for the given key has undefined behavior.
130
+ # local - Set on local cache (default: false)
131
+ #
132
+ # Returns the value argument.
133
+ def set(key, value, local = false)
134
+ expanded_key = expand_key(key)
135
+ @fetch_cache.set(expanded_key, value) if local
136
+ @cache_wrapper.set(expanded_key, value)
137
+ end
138
+
139
+ # Public: Pretty inspect
140
+ #
141
+ # Returns String.
142
+ def inspect
143
+ "#<#{self.class} local=#{@fetch_cache.inspect} store=#{@cache_wrapper.cache.inspect}>"
144
+ end
145
+
146
+ private
147
+ # Internal: Expand object cache key into a short String key.
148
+ #
149
+ # The String should be under 250 characters so its compatible with
150
+ # Memcache.
151
+ #
152
+ # key - JSON serializable key
153
+ #
154
+ # Returns a String with a length less than 250 characters.
155
+ def expand_key(key)
156
+ "sprockets/v#{VERSION}/#{DigestUtils.pack_urlsafe_base64digest(DigestUtils.digest(key))}"
157
+ end
158
+
159
+ PEEK_SIZE = 100
160
+
161
+ # Internal: Show first 100 characters of cache key for logging purposes.
162
+ #
163
+ # Returns a String with a length less than 100 characters.
164
+ def peek_key(key)
165
+ case key
166
+ when Integer
167
+ key.to_s
168
+ when String
169
+ key[0, PEEK_SIZE].inspect
170
+ when Array
171
+ str = []
172
+ key.each { |k| str << peek_key(k) }
173
+ str.join(':')[0, PEEK_SIZE]
174
+ else
175
+ peek_key(DigestUtils.pack_urlsafe_base64digest(DigestUtils.digest(key)))
176
+ end
177
+ end
178
+
179
+ def get_cache_wrapper(cache)
180
+ if cache.is_a?(Cache)
181
+ cache
182
+
183
+ # `Cache#get(key)` for Memcache
184
+ elsif cache.respond_to?(:get)
185
+ GetWrapper.new(cache)
186
+
187
+ # `Cache#[key]` so `Hash` can be used
188
+ elsif cache.respond_to?(:[])
189
+ HashWrapper.new(cache)
190
+
191
+ # `Cache#read(key)` for `ActiveSupport::Cache` support
192
+ elsif cache.respond_to?(:read)
193
+ ReadWriteWrapper.new(cache)
194
+
195
+ else
196
+ cache = Sprockets::Cache::NullStore.new
197
+ GetWrapper.new(cache)
198
+ end
199
+ end
200
+
201
+ class Wrapper < Struct.new(:cache)
202
+ end
203
+
204
+ class GetWrapper < Wrapper
205
+ def get(key)
206
+ cache.get(key)
207
+ end
208
+
209
+ def set(key, value)
210
+ cache.set(key, value)
211
+ end
212
+ end
213
+
214
+ class HashWrapper < Wrapper
215
+ def get(key)
216
+ cache[key]
217
+ end
218
+
219
+ def set(key, value)
220
+ cache[key] = value
221
+ end
222
+ end
223
+
224
+ class ReadWriteWrapper < Wrapper
225
+ def get(key)
226
+ cache.read(key)
227
+ end
228
+
229
+ def set(key, value)
230
+ cache.write(key, value)
231
+ end
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,69 @@
1
+ require 'sprockets/base'
2
+
3
+ module Sprockets
4
+ # `Cached` is a special cached version of `Environment`.
5
+ #
6
+ # The expection is that all of its file system methods are cached
7
+ # for the instances lifetime. This makes `Cached` much faster. This
8
+ # behavior is ideal in production environments where the file system
9
+ # is immutable.
10
+ #
11
+ # `Cached` should not be initialized directly. Instead use
12
+ # `Environment#cached`.
13
+ class CachedEnvironment < Base
14
+ def initialize(environment)
15
+ initialize_configuration(environment)
16
+
17
+ @cache = environment.cache
18
+ @stats = Hash.new { |h, k| h[k] = _stat(k) }
19
+ @entries = Hash.new { |h, k| h[k] = _entries(k) }
20
+ @uris = Hash.new { |h, k| h[k] = _load(k) }
21
+
22
+ @processor_cache_keys = Hash.new { |h, k| h[k] = _processor_cache_key(k) }
23
+ @resolved_dependencies = Hash.new { |h, k| h[k] = _resolve_dependency(k) }
24
+ end
25
+
26
+ # No-op return self as cached environment.
27
+ def cached
28
+ self
29
+ end
30
+ alias_method :index, :cached
31
+
32
+ # Internal: Cache Environment#entries
33
+ alias_method :_entries, :entries
34
+ def entries(path)
35
+ @entries[path]
36
+ end
37
+
38
+ # Internal: Cache Environment#stat
39
+ alias_method :_stat, :stat
40
+ def stat(path)
41
+ @stats[path]
42
+ end
43
+
44
+ # Internal: Cache Environment#load
45
+ alias_method :_load, :load
46
+ def load(uri)
47
+ @uris[uri]
48
+ end
49
+
50
+ # Internal: Cache Environment#processor_cache_key
51
+ alias_method :_processor_cache_key, :processor_cache_key
52
+ def processor_cache_key(str)
53
+ @processor_cache_keys[str]
54
+ end
55
+
56
+ # Internal: Cache Environment#resolve_dependency
57
+ alias_method :_resolve_dependency, :resolve_dependency
58
+ def resolve_dependency(str)
59
+ @resolved_dependencies[str]
60
+ end
61
+
62
+ private
63
+ # Cache is immutable, any methods that try to change the runtime config
64
+ # should bomb.
65
+ def config=(config)
66
+ raise RuntimeError, "can't modify immutable cached environment"
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,53 @@
1
+ require 'sprockets/autoload'
2
+
3
+ module Sprockets
4
+ # Public: Closure Compiler minifier.
5
+ #
6
+ # To accept the default options
7
+ #
8
+ # environment.register_bundle_processor 'application/javascript',
9
+ # Sprockets::ClosureCompressor
10
+ #
11
+ # Or to pass options to the Closure::Compiler class.
12
+ #
13
+ # environment.register_bundle_processor 'application/javascript',
14
+ # Sprockets::ClosureCompressor.new({ ... })
15
+ #
16
+ class ClosureCompressor
17
+ VERSION = '1'
18
+
19
+ # Public: Return singleton instance with default options.
20
+ #
21
+ # Returns ClosureCompressor object.
22
+ def self.instance
23
+ @instance ||= new
24
+ end
25
+
26
+ def self.call(input)
27
+ instance.call(input)
28
+ end
29
+
30
+ def self.cache_key
31
+ instance.cache_key
32
+ end
33
+
34
+ attr_reader :cache_key
35
+
36
+ def initialize(options = {})
37
+ @compiler = Autoload::Closure::Compiler.new(options)
38
+ @cache_key = [
39
+ self.class.name,
40
+ Autoload::Closure::VERSION,
41
+ Autoload::Closure::COMPILER_VERSION,
42
+ VERSION,
43
+ options
44
+ ].freeze
45
+ end
46
+
47
+ def call(input)
48
+ input[:cache].fetch(@cache_key + [input[:data]]) do
49
+ @compiler.compile(input[:data])
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,25 @@
1
+ require 'sprockets/autoload'
2
+
3
+ module Sprockets
4
+ # Processor engine class for the CoffeeScript compiler.
5
+ # Depends on the `coffee-script` and `coffee-script-source` gems.
6
+ #
7
+ # For more infomation see:
8
+ #
9
+ # https://github.com/josh/ruby-coffee-script
10
+ #
11
+ module CoffeeScriptProcessor
12
+ VERSION = '1'
13
+
14
+ def self.cache_key
15
+ @cache_key ||= [name, Autoload::CoffeeScript::Source.version, VERSION].freeze
16
+ end
17
+
18
+ def self.call(input)
19
+ data = input[:data]
20
+ input[:cache].fetch(self.cache_key + [data]) do
21
+ Autoload::CoffeeScript.compile(data)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ require 'sprockets/coffee_script_processor'
2
+
3
+ module Sprockets
4
+ # Deprecated
5
+ CoffeeScriptTemplate = CoffeeScriptProcessor
6
+ end
@@ -0,0 +1,74 @@
1
+ require 'sprockets/utils'
2
+
3
+ module Sprockets
4
+ # `Compressing` is an internal mixin whose public methods are exposed on
5
+ # the `Environment` and `CachedEnvironment` classes.
6
+ module Compressing
7
+ include Utils
8
+
9
+ def compressors
10
+ config[:compressors]
11
+ end
12
+
13
+ def register_compressor(mime_type, sym, klass)
14
+ self.config = hash_reassoc(config, :compressors, mime_type) do |compressors|
15
+ compressors[sym] = klass
16
+ compressors
17
+ end
18
+ end
19
+
20
+ # Return CSS compressor or nil if none is set
21
+ def css_compressor
22
+ if defined? @css_compressor
23
+ @css_compressor
24
+ end
25
+ end
26
+
27
+ # Assign a compressor to run on `text/css` assets.
28
+ #
29
+ # The compressor object must respond to `compress`.
30
+ def css_compressor=(compressor)
31
+ unregister_bundle_processor 'text/css', @css_compressor if defined? @css_compressor
32
+ @css_compressor = nil
33
+ return unless compressor
34
+
35
+ if compressor.is_a?(Symbol)
36
+ @css_compressor = klass = config[:compressors]['text/css'][compressor] || raise(Error, "unknown compressor: #{compressor}")
37
+ elsif compressor.respond_to?(:compress)
38
+ klass = LegacyProcProcessor.new(:css_compressor, proc { |context, data| compressor.compress(data) })
39
+ @css_compressor = :css_compressor
40
+ else
41
+ @css_compressor = klass = compressor
42
+ end
43
+
44
+ register_bundle_processor 'text/css', klass
45
+ end
46
+
47
+ # Return JS compressor or nil if none is set
48
+ def js_compressor
49
+ if defined? @js_compressor
50
+ @js_compressor
51
+ end
52
+ end
53
+
54
+ # Assign a compressor to run on `application/javascript` assets.
55
+ #
56
+ # The compressor object must respond to `compress`.
57
+ def js_compressor=(compressor)
58
+ unregister_bundle_processor 'application/javascript', @js_compressor if defined? @js_compressor
59
+ @js_compressor = nil
60
+ return unless compressor
61
+
62
+ if compressor.is_a?(Symbol)
63
+ @js_compressor = klass = config[:compressors]['application/javascript'][compressor] || raise(Error, "unknown compressor: #{compressor}")
64
+ elsif compressor.respond_to?(:compress)
65
+ klass = LegacyProcProcessor.new(:js_compressor, proc { |context, data| compressor.compress(data) })
66
+ @js_compressor = :js_compressor
67
+ else
68
+ @js_compressor = klass = compressor
69
+ end
70
+
71
+ register_bundle_processor 'application/javascript', klass
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,83 @@
1
+ require 'sprockets/compressing'
2
+ require 'sprockets/dependencies'
3
+ require 'sprockets/engines'
4
+ require 'sprockets/mime'
5
+ require 'sprockets/paths'
6
+ require 'sprockets/processing'
7
+ require 'sprockets/transformers'
8
+ require 'sprockets/utils'
9
+
10
+ module Sprockets
11
+ module Configuration
12
+ include Paths, Mime, Engines, Transformers, Processing, Compressing, Dependencies, Utils
13
+
14
+ def initialize_configuration(parent)
15
+ @config = parent.config
16
+ @computed_config = parent.computed_config
17
+ @logger = parent.logger
18
+ @context_class = Class.new(parent.context_class)
19
+ end
20
+
21
+ attr_reader :config
22
+
23
+ attr_accessor :computed_config
24
+
25
+ def config=(config)
26
+ raise TypeError, "can't assign mutable config" unless config.frozen?
27
+ @config = config
28
+ end
29
+
30
+ # Get and set `Logger` instance.
31
+ attr_accessor :logger
32
+
33
+ # The `Environment#version` is a custom value used for manually
34
+ # expiring all asset caches.
35
+ #
36
+ # Sprockets is able to track most file and directory changes and
37
+ # will take care of expiring the cache for you. However, its
38
+ # impossible to know when any custom helpers change that you mix
39
+ # into the `Context`.
40
+ #
41
+ # It would be wise to increment this value anytime you make a
42
+ # configuration change to the `Environment` object.
43
+ def version
44
+ config[:version]
45
+ end
46
+
47
+ # Assign an environment version.
48
+ #
49
+ # environment.version = '2.0'
50
+ #
51
+ def version=(version)
52
+ self.config = hash_reassoc(config, :version) { version.dup }
53
+ end
54
+
55
+ # Public: Returns a `Digest` implementation class.
56
+ #
57
+ # Defaults to `Digest::SHA256`.
58
+ def digest_class
59
+ config[:digest_class]
60
+ end
61
+
62
+ # Deprecated: Assign a `Digest` implementation class. This maybe any Ruby
63
+ # `Digest::` implementation such as `Digest::SHA256` or
64
+ # `Digest::MD5`.
65
+ #
66
+ # environment.digest_class = Digest::MD5
67
+ #
68
+ def digest_class=(klass)
69
+ self.config = config.merge(digest_class: klass).freeze
70
+ end
71
+
72
+ # Deprecated: Get `Context` class.
73
+ #
74
+ # This class maybe mutated and mixed in with custom helpers.
75
+ #
76
+ # environment.context_class.instance_eval do
77
+ # include MyHelpers
78
+ # def asset_url; end
79
+ # end
80
+ #
81
+ attr_reader :context_class
82
+ end
83
+ end