sprockets 4.1.1 → 4.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5f1a2b7d847a15dff3669ec28a2248484ee0831c88017fc67fee6afe7b6a6f1
4
- data.tar.gz: 2714999cde7d9f9340d0d7f2a98f3e48c9b46d099e36069dd380a12f6c270c54
3
+ metadata.gz: 543299a5bdbb4620f7e14c346728230740474c835519d22f1c31f76110588912
4
+ data.tar.gz: d22cfead2059a729f6e67c990d7fa606f9cf56f9060941bea1ed977bf7fe59f3
5
5
  SHA512:
6
- metadata.gz: db948451245c6a7e6cf20876368d040e6de9b3f178ab5fa0010070b9e834cd08036d449e35f3857a8443ac26fc5318ac20ab5cc16d91a4b65d8fc0f07a796939
7
- data.tar.gz: 2a6e4b9dbb1f2effa1ef15a4f861c7b5cadb6384713bf3452749f8f0be1405ab319d85b23272b1dbc3bdeda7837d0ce55f0caf62273e197eb6190511f0789097
6
+ metadata.gz: 7e0b291f575acdf547fa11e803858f561e38ce57ef76734ce04cc2fce6cfca6516fa2f7b8c5d2390f1ff5400e1e72885c7741b4dc7f28f0956b4aad3a617eec2
7
+ data.tar.gz: 53e8bab09fdc3dcbd113fa33c4d29bf764ca7d1b11b176ed83d6818d6c7a822cca848f18d5ad7d1dea51e5d015a4cc53bd00e456506a8060f7ad2dbd7fd10af9
data/CHANGELOG.md CHANGED
@@ -2,7 +2,23 @@
2
2
 
3
3
  Get upgrade notes from Sprockets 3.x to 4.x at https://github.com/rails/sprockets/blob/master/UPGRADING.md
4
4
 
5
- - Fix `Sprockets::Server` to return response headers to compatible with with Rack::Lint 2.0.
5
+ ## 4.2.1
6
+
7
+ - Fix for precompile issues when multiple extensions map to the same MIME type (eg. `.jpeg` / `.jpg`). [#781](https://github.com/rails/sprockets/pull/781)
8
+ - Fix `application/css-sourcemap+json` charset [#764](https://github.com/rails/sprockets/pull/764)
9
+ - Fix compatibility with Rack 2 applications. [#790](https://github.com/rails/sprockets/pull/790)
10
+
11
+ ## 4.2.0
12
+
13
+ - Rack 3 compatibility. [#758](https://github.com/rails/sprockets/pull/758)
14
+ - Fix thread safety of `Sprockets::CachedEnvironment` and `Sprockets::Cache::MemoryStore`. [#771](https://github.com/rails/sprockets/pull/771)
15
+ - Add support for Rack 3.0. Headers set by sprockets will now be lower case. [#758](https://github.com/rails/sprockets/pull/758)
16
+ - Make `Sprockets::Utils.module_include` thread safe on JRuby. [#759](https://github.com/rails/sprockets/pull/759)
17
+ - Fix typo in `asset.rb` file. [#768](https://github.com/rails/sprockets/pull/768)
18
+
19
+ ## 4.1.1
20
+
21
+ - Fix `Sprockets::Server` to return response headers to be compatible with Rack::Lint 2.0.
6
22
 
7
23
  ## 4.1.0
8
24
 
data/README.md CHANGED
@@ -385,10 +385,10 @@ the current file won't work, it must be a logical path.
385
385
  `link` can also be used to include manifest files from mounted Rails engines:
386
386
 
387
387
  ```
388
- //= link my_engine
388
+ //= link my_engine_manifest
389
389
  ```
390
390
 
391
- This would find a manifest file at `my_engine/app/assets/config/my_engine.js` and include its directives.
391
+ This would find a manifest file at `my_engine/app/assets/config/my_engine_manifest.js` and include its directives.
392
392
 
393
393
  ### link_directory
394
394
 
@@ -525,7 +525,7 @@ Generated files are cached. If you're using an `ENV` var then
525
525
  when you change then ENV var the asset will be forced to
526
526
  recompile. This behavior is only true for environment variables,
527
527
  if you are pulling a value from somewhere else, such as a database,
528
- must manually invalidate the cache to see the change.
528
+ you must manually invalidate the cache to see the change.
529
529
 
530
530
  If you're using Rails, there are helpers you can use such as `asset_url`
531
531
  that will cause a recompile if the value changes.
@@ -137,7 +137,7 @@ module Sprockets
137
137
  DigestUtils.pack_hexdigest(digest)
138
138
  end
139
139
 
140
- # Pubic: ETag String of Asset.
140
+ # Public: ETag String of Asset.
141
141
  def etag
142
142
  version = environment_version
143
143
 
@@ -22,6 +22,7 @@ module Sprockets
22
22
  def initialize(max_size = DEFAULT_MAX_SIZE)
23
23
  @max_size = max_size
24
24
  @cache = {}
25
+ @mutex = Mutex.new
25
26
  end
26
27
 
27
28
  # Public: Retrieve value from cache.
@@ -32,12 +33,14 @@ module Sprockets
32
33
  #
33
34
  # Returns Object or nil or the value is not set.
34
35
  def get(key)
35
- exists = true
36
- value = @cache.delete(key) { exists = false }
37
- if exists
38
- @cache[key] = value
39
- else
40
- nil
36
+ @mutex.synchronize do
37
+ exists = true
38
+ value = @cache.delete(key) { exists = false }
39
+ if exists
40
+ @cache[key] = value
41
+ else
42
+ nil
43
+ end
41
44
  end
42
45
  end
43
46
 
@@ -50,9 +53,11 @@ module Sprockets
50
53
  #
51
54
  # Returns Object value.
52
55
  def set(key, value)
53
- @cache.delete(key)
54
- @cache[key] = value
55
- @cache.shift if @cache.size > @max_size
56
+ @mutex.synchronize do
57
+ @cache.delete(key)
58
+ @cache[key] = value
59
+ @cache.shift if @cache.size > @max_size
60
+ end
56
61
  value
57
62
  end
58
63
 
@@ -60,14 +65,18 @@ module Sprockets
60
65
  #
61
66
  # Returns String.
62
67
  def inspect
63
- "#<#{self.class} size=#{@cache.size}/#{@max_size}>"
68
+ @mutex.synchronize do
69
+ "#<#{self.class} size=#{@cache.size}/#{@max_size}>"
70
+ end
64
71
  end
65
72
 
66
73
  # Public: Clear the cache
67
74
  #
68
75
  # Returns true
69
76
  def clear(options=nil)
70
- @cache.clear
77
+ @mutex.synchronize do
78
+ @cache.clear
79
+ end
71
80
  true
72
81
  end
73
82
  end
@@ -16,11 +16,11 @@ module Sprockets
16
16
  initialize_configuration(environment)
17
17
 
18
18
  @cache = environment.cache
19
- @stats = {}
20
- @entries = {}
21
- @uris = {}
22
- @processor_cache_keys = {}
23
- @resolved_dependencies = {}
19
+ @stats = Concurrent::Map.new
20
+ @entries = Concurrent::Map.new
21
+ @uris = Concurrent::Map.new
22
+ @processor_cache_keys = Concurrent::Map.new
23
+ @resolved_dependencies = Concurrent::Map.new
24
24
  end
25
25
 
26
26
  # No-op return self as cached environment.
@@ -31,27 +31,27 @@ module Sprockets
31
31
 
32
32
  # Internal: Cache Environment#entries
33
33
  def entries(path)
34
- @entries.fetch(path){ @entries[path] = super(path) }
34
+ @entries.fetch_or_store(path) { super(path) }
35
35
  end
36
36
 
37
37
  # Internal: Cache Environment#stat
38
38
  def stat(path)
39
- @stats.fetch(path){ @stats[path] = super(path) }
39
+ @stats.fetch_or_store(path) { super(path) }
40
40
  end
41
41
 
42
42
  # Internal: Cache Environment#load
43
43
  def load(uri)
44
- @uris.fetch(uri){ @uris[uri] = super(uri) }
44
+ @uris.fetch_or_store(uri) { super(uri) }
45
45
  end
46
46
 
47
47
  # Internal: Cache Environment#processor_cache_key
48
48
  def processor_cache_key(str)
49
- @processor_cache_keys.fetch(str){ @processor_cache_keys[str] = super(str) }
49
+ @processor_cache_keys.fetch_or_store(str) { super(str) }
50
50
  end
51
51
 
52
52
  # Internal: Cache Environment#resolve_dependency
53
53
  def resolve_dependency(str)
54
- @resolved_dependencies.fetch(str){ @resolved_dependencies[str] = super(str) }
54
+ @resolved_dependencies.fetch_or_store(str) { super(str) }
55
55
  end
56
56
 
57
57
  private
@@ -28,11 +28,11 @@ module Sprockets
28
28
 
29
29
  # Public: Remove Exporting processor `klass` for `mime_type`.
30
30
  #
31
- # environment.unregister_exporter '*/*', Sprockets::Exporters::Zlib
31
+ # environment.unregister_exporter '*/*', Sprockets::Exporters::ZlibExporter
32
32
  #
33
33
  # Can be called without a mime type
34
34
  #
35
- # environment.unregister_exporter Sprockets::Exporters::Zlib
35
+ # environment.unregister_exporter Sprockets::Exporters::ZlibExporter
36
36
  #
37
37
  # Does not remove any exporters that depend on `klass`.
38
38
  def unregister_exporter(mime_types, exporter = nil)
@@ -165,7 +165,9 @@ module Sprockets
165
165
  end
166
166
 
167
167
  if type = unloaded.params[:type]
168
- logical_path += config[:mime_types][type][:extensions].first
168
+ extensions = config[:mime_types][type][:extensions]
169
+ extension = extensions.include?(extname) ? extname : extensions.first
170
+ logical_path += extension
169
171
  end
170
172
 
171
173
  if type != file_type && !config[:transformers][file_type][type]
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'set'
3
3
  require 'time'
4
- require 'rack/utils'
4
+ require 'rack'
5
5
 
6
6
  module Sprockets
7
7
  # `Server` is a concern mixed into `Environment` and
@@ -11,6 +11,16 @@ module Sprockets
11
11
  # Supported HTTP request methods.
12
12
  ALLOWED_REQUEST_METHODS = ['GET', 'HEAD'].to_set.freeze
13
13
 
14
+ # :stopdoc:
15
+ if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3")
16
+ X_CASCADE = "X-Cascade"
17
+ VARY = "Vary"
18
+ else
19
+ X_CASCADE = "x-cascade"
20
+ VARY = "vary"
21
+ end
22
+ # :startdoc:
23
+
14
24
  # `call` implements the Rack 1.x specification which accepts an
15
25
  # `env` Hash and returns a three item tuple with the status code,
16
26
  # headers, and body.
@@ -148,39 +158,39 @@ module Sprockets
148
158
  # Returns a 400 Forbidden response tuple
149
159
  def bad_request_response(env)
150
160
  if head_request?(env)
151
- [ 400, { "Content-Type" => "text/plain", "Content-Length" => "0" }, [] ]
161
+ [ 400, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0" }, [] ]
152
162
  else
153
- [ 400, { "Content-Type" => "text/plain", "Content-Length" => "11" }, [ "Bad Request" ] ]
163
+ [ 400, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "11" }, [ "Bad Request" ] ]
154
164
  end
155
165
  end
156
166
 
157
167
  # Returns a 403 Forbidden response tuple
158
168
  def forbidden_response(env)
159
169
  if head_request?(env)
160
- [ 403, { "Content-Type" => "text/plain", "Content-Length" => "0" }, [] ]
170
+ [ 403, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0" }, [] ]
161
171
  else
162
- [ 403, { "Content-Type" => "text/plain", "Content-Length" => "9" }, [ "Forbidden" ] ]
172
+ [ 403, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "9" }, [ "Forbidden" ] ]
163
173
  end
164
174
  end
165
175
 
166
176
  # Returns a 404 Not Found response tuple
167
177
  def not_found_response(env)
168
178
  if head_request?(env)
169
- [ 404, { "Content-Type" => "text/plain", "Content-Length" => "0", "X-Cascade" => "pass" }, [] ]
179
+ [ 404, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0", X_CASCADE => "pass" }, [] ]
170
180
  else
171
- [ 404, { "Content-Type" => "text/plain", "Content-Length" => "9", "X-Cascade" => "pass" }, [ "Not found" ] ]
181
+ [ 404, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "9", X_CASCADE => "pass" }, [ "Not found" ] ]
172
182
  end
173
183
  end
174
184
 
175
185
  def method_not_allowed_response
176
- [ 405, { "Content-Type" => "text/plain", "Content-Length" => "18" }, [ "Method Not Allowed" ] ]
186
+ [ 405, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "18" }, [ "Method Not Allowed" ] ]
177
187
  end
178
188
 
179
189
  def precondition_failed_response(env)
180
190
  if head_request?(env)
181
- [ 412, { "Content-Type" => "text/plain", "Content-Length" => "0", "X-Cascade" => "pass" }, [] ]
191
+ [ 412, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0", X_CASCADE => "pass" }, [] ]
182
192
  else
183
- [ 412, { "Content-Type" => "text/plain", "Content-Length" => "19", "X-Cascade" => "pass" }, [ "Precondition Failed" ] ]
193
+ [ 412, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "19", X_CASCADE => "pass" }, [ "Precondition Failed" ] ]
184
194
  end
185
195
  end
186
196
 
@@ -189,7 +199,7 @@ module Sprockets
189
199
  def javascript_exception_response(exception)
190
200
  err = "#{exception.class.name}: #{exception.message}\n (in #{exception.backtrace[0]})"
191
201
  body = "throw Error(#{err.inspect})"
192
- [ 200, { "Content-Type" => "application/javascript", "Content-Length" => body.bytesize.to_s }, [ body ] ]
202
+ [ 200, { Rack::CONTENT_TYPE => "application/javascript", Rack::CONTENT_LENGTH => body.bytesize.to_s }, [ body ] ]
193
203
  end
194
204
 
195
205
  # Returns a CSS response that hides all elements on the page and
@@ -242,7 +252,7 @@ module Sprockets
242
252
  }
243
253
  CSS
244
254
 
245
- [ 200, { "Content-Type" => "text/css; charset=utf-8", "Content-Length" => body.bytesize.to_s }, [ body ] ]
255
+ [ 200, { Rack::CONTENT_TYPE => "text/css; charset=utf-8", Rack::CONTENT_LENGTH => body.bytesize.to_s }, [ body ] ]
246
256
  end
247
257
 
248
258
  # Escape special characters for use inside a CSS content("...") string
@@ -258,18 +268,18 @@ module Sprockets
258
268
  headers = {}
259
269
 
260
270
  # Set caching headers
261
- headers["Cache-Control"] = +"public"
262
- headers["ETag"] = %("#{etag}")
271
+ headers[Rack::CACHE_CONTROL] = +"public"
272
+ headers[Rack::ETAG] = %("#{etag}")
263
273
 
264
274
  # If the request url contains a fingerprint, set a long
265
275
  # expires on the response
266
276
  if path_fingerprint(env["PATH_INFO"])
267
- headers["Cache-Control"] << ", max-age=31536000, immutable"
277
+ headers[Rack::CACHE_CONTROL] << ", max-age=31536000, immutable"
268
278
 
269
279
  # Otherwise set `must-revalidate` since the asset could be modified.
270
280
  else
271
- headers["Cache-Control"] << ", must-revalidate"
272
- headers["Vary"] = "Accept-Encoding"
281
+ headers[Rack::CACHE_CONTROL] << ", must-revalidate"
282
+ headers[VARY] = "Accept-Encoding"
273
283
  end
274
284
 
275
285
  headers
@@ -279,7 +289,7 @@ module Sprockets
279
289
  headers = {}
280
290
 
281
291
  # Set content length header
282
- headers["Content-Length"] = length.to_s
292
+ headers[Rack::CONTENT_LENGTH] = length.to_s
283
293
 
284
294
  # Set content type header
285
295
  if type = asset.content_type
@@ -287,7 +297,7 @@ module Sprockets
287
297
  if type.start_with?("text/") && asset.charset
288
298
  type += "; charset=#{asset.charset}"
289
299
  end
290
- headers["Content-Type"] = type
300
+ headers[Rack::CONTENT_TYPE] = type
291
301
  end
292
302
 
293
303
  headers.merge(cache_headers(env, asset.etag))
@@ -53,7 +53,7 @@ module Sprockets
53
53
  path = path[1..-1]
54
54
  end
55
55
 
56
- [scheme, host, path, query]
56
+ [scheme, host || '', path, query]
57
57
  end
58
58
 
59
59
  # Internal: Join file: URI component parts into String.
@@ -118,33 +118,38 @@ module Sprockets
118
118
  buf
119
119
  end
120
120
 
121
+ MODULE_INCLUDE_MUTEX = Mutex.new
122
+ private_constant :MODULE_INCLUDE_MUTEX
123
+
121
124
  # Internal: Inject into target module for the duration of the block.
122
125
  #
123
126
  # mod - Module
124
127
  #
125
128
  # Returns result of block.
126
129
  def module_include(base, mod)
127
- old_methods = {}
130
+ MODULE_INCLUDE_MUTEX.synchronize do
131
+ old_methods = {}
128
132
 
129
- mod.instance_methods.each do |sym|
130
- old_methods[sym] = base.instance_method(sym) if base.method_defined?(sym)
131
- end
133
+ mod.instance_methods.each do |sym|
134
+ old_methods[sym] = base.instance_method(sym) if base.method_defined?(sym)
135
+ end
132
136
 
133
- mod.instance_methods.each do |sym|
134
- method = mod.instance_method(sym)
135
- if base.method_defined?(sym)
136
- base.send(:alias_method, sym, sym)
137
+ mod.instance_methods.each do |sym|
138
+ method = mod.instance_method(sym)
139
+ if base.method_defined?(sym)
140
+ base.send(:alias_method, sym, sym)
141
+ end
142
+ base.send(:define_method, sym, method)
137
143
  end
138
- base.send(:define_method, sym, method)
139
- end
140
144
 
141
- yield
142
- ensure
143
- mod.instance_methods.each do |sym|
144
- base.send(:undef_method, sym) if base.method_defined?(sym)
145
- end
146
- old_methods.each do |sym, method|
147
- base.send(:define_method, sym, method)
145
+ yield
146
+ ensure
147
+ mod.instance_methods.each do |sym|
148
+ base.send(:undef_method, sym) if base.method_defined?(sym)
149
+ end
150
+ old_methods.each do |sym, method|
151
+ base.send(:define_method, sym, method)
152
+ end
148
153
  end
149
154
  end
150
155
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Sprockets
3
- VERSION = "4.1.1"
3
+ VERSION = "4.2.1"
4
4
  end
data/lib/sprockets.rb CHANGED
@@ -91,7 +91,7 @@ module Sprockets
91
91
 
92
92
  require 'sprockets/source_map_processor'
93
93
  register_mime_type 'application/js-sourcemap+json', extensions: ['.js.map'], charset: :unicode
94
- register_mime_type 'application/css-sourcemap+json', extensions: ['.css.map']
94
+ register_mime_type 'application/css-sourcemap+json', extensions: ['.css.map'], charset: :unicode
95
95
  register_transformer 'application/javascript', 'application/js-sourcemap+json', SourceMapProcessor
96
96
  register_transformer 'text/css', 'application/css-sourcemap+json', SourceMapProcessor
97
97
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sprockets
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 4.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Stephenson
@@ -9,28 +9,28 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-06-27 00:00:00.000000000 Z
12
+ date: 2023-09-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '1'
20
+ version: 2.2.4
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: '3'
23
+ version: '4'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ">"
28
+ - - ">="
29
29
  - !ruby/object:Gem::Version
30
- version: '1'
30
+ version: 2.2.4
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: '3'
33
+ version: '4'
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: concurrent-ruby
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -219,14 +219,14 @@ dependencies:
219
219
  requirements:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
- version: '0.6'
222
+ version: 2.0.0
223
223
  type: :development
224
224
  prerelease: false
225
225
  version_requirements: !ruby/object:Gem::Requirement
226
226
  requirements:
227
227
  - - "~>"
228
228
  - !ruby/object:Gem::Version
229
- version: '0.6'
229
+ version: 2.0.0
230
230
  - !ruby/object:Gem::Dependency
231
231
  name: rake
232
232
  requirement: !ruby/object:Gem::Requirement
@@ -438,7 +438,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
438
438
  - !ruby/object:Gem::Version
439
439
  version: '0'
440
440
  requirements: []
441
- rubygems_version: 3.3.7
441
+ rubygems_version: 3.4.10
442
442
  signing_key:
443
443
  specification_version: 4
444
444
  summary: Rack-based asset packaging system