sprockets 4.0.3 → 4.1.0

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: f59adc73cec32bd913421523e00e2615eb6557cce967d6b59b8244a9f969051d
4
- data.tar.gz: d970c5ed6ba67c58afd8c3529634f450d9ed1357000cb5952916efa9dca77d4e
3
+ metadata.gz: bd427dc138e916f8edb7b07dd2139da83fa2cad386de0321eeb8dc668cbfc57f
4
+ data.tar.gz: 176fe20e253fde5bd04945f29de4aef9720e77480e2a6f9ef3353fe17bd5b61f
5
5
  SHA512:
6
- metadata.gz: 3fb439abcba98f893e88ee2bc75af8e3b59760c82f510fd4de510706e49a4fb28fbc84d9c0eefcc172dd981aec04bcaec2f5afc572d03081d6600249b3eb9632
7
- data.tar.gz: f28698f721422b64b05de921d7e91ff8972415ba3a82e47d196095f4e6a487103078d69dfcd54b9027341c7852b079d6ef35d6626b68508a63627e44a75c0891
6
+ metadata.gz: a84a1038484ba2649a87f2db4b53f1737b3b38fcd26c22cca5402a9ccb48d6ba3051e59b84e04ef09efcb7bb625cd3a2ecebd51be0c2b46e4950c549d7eb3ea1
7
+ data.tar.gz: d99e8c141117d55f7c10fa8b687f5acb7090f6dd1d7a39f0e2443f2bca8dc6af0d5a00cf9f42f137c3dda9dffe722fc1ab4744a739ca013f8549341c8d759444
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
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
+ ## 4.1.0
6
+
7
+ - Allow age to be altered in asset:clean rake task.
8
+ - Fix `Sprockets::Server` to return lower-cased response headers to comply with Rack::Lint 3.0. [#744](https://github.com/rails/sprockets/pull/744)
9
+ - Adding new directive `depend_on_directory` [#668](https://github.com/rails/sprockets/pull/668)
10
+ - Fix `application/js-sourcemap+json` charset [#669](https://github.com/rails/sprockets/pull/669)
11
+ - Fix `CachedEnvironment` caching nil values [#723](https://github.com/rails/sprockets/pull/723)
12
+ - Process `*.jst.ejs.erb` files with ERBProcessor [#674](https://github.com/rails/sprockets/pull/674)
13
+ - Fix cache key for coffee script processor to be dependent on the filename [#670](https://github.com/rails/sprockets/pull/670)
14
+
5
15
  ## 4.0.3
6
16
 
7
17
  - Fix `Manifest#find` yielding from a Promise causing issue on Ruby 3.1.0-dev. [#720](https://github.com/rails/sprockets/pull/720)
data/README.md CHANGED
@@ -119,6 +119,7 @@ Here is a list of the available directives:
119
119
  - [`link_directory`](#link_directory) - Make target directory compile and be publicly available without adding contents to current
120
120
  - [`link_tree`](#link_tree) - Make target tree compile and be publicly available without adding contents to current
121
121
  - [`depend_on`](#depend_on) - Recompile current file if target has changed
122
+ - [`depend_on_directory`](#depend_on_directory) - Recompile current file if any files in target directory has changed
122
123
  - [`stub`](#stub) - Ignore target file
123
124
 
124
125
  You can see what each of these does below.
@@ -239,7 +240,7 @@ The first time this file is compiled the `application.js` output will be written
239
240
 
240
241
  So, if `b.js` changes it will get recompiled. However instead of having to recompile the other files from `a.js` to `z.js` since they did not change, we can use the prior intermediary files stored in the cached values . If these files were expensive to generate, then this "partial" asset cache strategy can save a lot of time.
241
242
 
242
- Directives such as `require`, `link`, and `depend_on` tell Sprockets what assets need to be re-compiled when a file changes. Files are considered "fresh" based on their mtime on disk and a combination of cache keys.
243
+ Directives such as `require`, `link`, `depend_on`, and `depend_on_directory` tell Sprockets what assets need to be re-compiled when a file changes. Files are considered "fresh" based on their mtime on disk and a combination of cache keys.
243
244
 
244
245
  On Rails you can force a "clean" install by clearing the `public/assets` and `tmp/cache/assets` directories.
245
246
 
@@ -381,6 +382,14 @@ the current file won't work, it must be a logical path.
381
382
 
382
383
  **Caution**: the "link" directive should always have an explicit extension on the end.
383
384
 
385
+ `link` can also be used to include manifest files from mounted Rails engines:
386
+
387
+ ```
388
+ //= link my_engine
389
+ ```
390
+
391
+ This would find a manifest file at `my_engine/app/assets/config/my_engine.js` and include its directives.
392
+
384
393
  ### link_directory
385
394
 
386
395
  `link_directory` *path* links all the files inside the directory specified by the *path*. By "link", we mean they are specified as compilation targets to be written out to disk, and made available to be served to user-agents.
@@ -445,11 +454,53 @@ you need to tell sprockets that it needs to re-compile the file if `bar.data` ch
445
454
  var bar = '<%= File.read("bar.data") %>'
446
455
  ```
447
456
 
457
+ To depend on an entire directory containing multiple files, use `depend_on_directory`
458
+
448
459
  ### depend_on_asset
449
460
 
450
461
  `depend_on_asset` *path* works like `depend_on`, but operates
451
462
  recursively reading the file and following the directives found. This is automatically implied if you use `link`, so consider if it just makes sense using `link` instead of `depend_on_asset`.
452
463
 
464
+ ### depend_on_directory
465
+
466
+ `depend_on_directory` *path* declares all files in the given *path* without
467
+ including them in the bundle. This is useful when you need to expire an
468
+ asset's cache in response to a change in multiple files in a single directory.
469
+
470
+ All paths are relative to your declaration and must begin with `./`
471
+
472
+ Also, your must include these directories in your [load path](guides/building_an_asset_processing_framework.md#the-load-path).
473
+
474
+ **Example:**
475
+
476
+ If we've got a directory called `data` with files `a.data` and `b.data`
477
+
478
+ ```
479
+ // ./data/a.data
480
+ A
481
+ ```
482
+
483
+ ```
484
+ // ./data/b.data
485
+ B
486
+ ```
487
+
488
+ ```
489
+ // ./file.js.erb
490
+ //= depend_on_directory ./data
491
+ var a = '<% File.read('data/a.data') %>'
492
+ var b = '<% File.read('data/b.data') %>'
493
+ ```
494
+
495
+ Would produce:
496
+
497
+ ```js
498
+ var a = "A";
499
+ var b = "B";
500
+ ```
501
+
502
+ You can also see [Index files are proxies for folders](#index-files-are-proxies-for-folders) for another method of organizing folders that will give you more control.
503
+
453
504
  ### stub
454
505
 
455
506
  `stub` *path* excludes that asset and its dependencies from the asset bundle.
@@ -491,9 +542,9 @@ When you modify the `logo.png` on disk, it will force `application.css` to be
491
542
  recompiled so that the fingerprint will be correct in the generated asset.
492
543
 
493
544
  You can manually make sprockets depend on any other file that is generated
494
- by sprockets by using the `depend_on` directive. Rails implements the above
495
- feature by auto calling `depend_on` on the original asset when the `asset_url`
496
- is used inside of an asset.
545
+ by sprockets by using the `depend_on` or `depend_on_directory` directive. Rails
546
+ implements the above feature by auto calling `depend_on` on the original asset
547
+ when the `asset_url` is used inside of an asset.
497
548
 
498
549
  ### Styling with Sass and SCSS
499
550
 
@@ -69,9 +69,12 @@ module Rake
69
69
  #
70
70
  attr_accessor :assets
71
71
 
72
- # Number of old assets to keep.
72
+ # Minimum number of old assets to keep. See Sprockets::Manifest#clean for more information.
73
73
  attr_accessor :keep
74
74
 
75
+ # Assets created within this age will be kept. See Sprockets::Manifest#clean for more information.
76
+ attr_accessor :age
77
+
75
78
  # Logger to use during rake tasks. Defaults to using stderr.
76
79
  #
77
80
  # t.logger = Logger.new($stdout)
@@ -103,6 +106,7 @@ module Rake
103
106
  @logger = Logger.new($stderr)
104
107
  @logger.level = Logger::INFO
105
108
  @keep = 2
109
+ @age = 3600
106
110
 
107
111
  yield self if block_given?
108
112
 
@@ -130,7 +134,7 @@ module Rake
130
134
  desc name == :assets ? "Clean old assets" : "Clean old #{name} assets"
131
135
  task "clean_#{name}" do
132
136
  with_logger do
133
- manifest.clean(keep)
137
+ manifest.clean(keep, age)
134
138
  end
135
139
  end
136
140
 
@@ -31,27 +31,27 @@ module Sprockets
31
31
 
32
32
  # Internal: Cache Environment#entries
33
33
  def entries(path)
34
- @entries[path] ||= super(path)
34
+ @entries.fetch(path){ @entries[path] = super(path) }
35
35
  end
36
36
 
37
37
  # Internal: Cache Environment#stat
38
38
  def stat(path)
39
- @stats[path] ||= super(path)
39
+ @stats.fetch(path){ @stats[path] = super(path) }
40
40
  end
41
41
 
42
42
  # Internal: Cache Environment#load
43
43
  def load(uri)
44
- @uris[uri] ||= super(uri)
44
+ @uris.fetch(uri){ @uris[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[str] ||= super(str)
49
+ @processor_cache_keys.fetch(str){ @processor_cache_keys[str] = super(str) }
50
50
  end
51
51
 
52
52
  # Internal: Cache Environment#resolve_dependency
53
53
  def resolve_dependency(str)
54
- @resolved_dependencies[str] ||= super(str)
54
+ @resolved_dependencies.fetch(str){ @resolved_dependencies[str] = super(str) }
55
55
  end
56
56
 
57
57
  private
@@ -20,7 +20,7 @@ module Sprockets
20
20
  def self.call(input)
21
21
  data = input[:data]
22
22
 
23
- js, map = input[:cache].fetch([self.cache_key, data]) do
23
+ js, map = input[:cache].fetch([self.cache_key, data, input[:filename]]) do
24
24
  result = Autoload::CoffeeScript.compile(
25
25
  data,
26
26
  sourceMap: "v3",
@@ -183,7 +183,7 @@ module Sprockets
183
183
  #
184
184
  # Returns true if the name contains a digest like string and .digested before the extension
185
185
  def already_digested?(name)
186
- return name =~ /-([0-9a-f]{7,128})\.digested/
186
+ return name =~ /-([0-9a-zA-Z]{7,128})\.digested/
187
187
  end
188
188
 
189
189
  private
@@ -285,6 +285,24 @@ module Sprockets
285
285
  to_load(resolve(path))
286
286
  end
287
287
 
288
+ # Allows you to state a dependency on a relative directory
289
+ # without including it.
290
+ #
291
+ # This is used for caching purposes. Any changes made to
292
+ # the dependency directory will invalidate the cache of the
293
+ # source file.
294
+ #
295
+ # This is useful if you are using ERB and File.read to pull
296
+ # in contents from multiple files in a directory.
297
+ #
298
+ # //= depend_on_directory ./data
299
+ #
300
+ def process_depend_on_directory_directive(path = ".", accept = nil)
301
+ path = expand_relative_dirname(:depend_on_directory, path)
302
+ accept = expand_accept_shorthand(accept)
303
+ resolve_paths(*@environment.stat_directory_with_dependencies(path), accept: accept)
304
+ end
305
+
288
306
  # Allows dependency to be excluded from the asset bundle.
289
307
  #
290
308
  # The `path` must be a valid asset and may or may not already
@@ -374,7 +392,7 @@ module Sprockets
374
392
  next if subpath == @filename || stat.directory?
375
393
  uri, deps = @environment.resolve(subpath, **kargs)
376
394
  @dependencies.merge(deps)
377
- yield uri if uri
395
+ yield uri if uri && block_given?
378
396
  end
379
397
  end
380
398
 
@@ -162,7 +162,7 @@ module Sprockets
162
162
  def split_subpath(path, subpath)
163
163
  return "" if path == subpath
164
164
  path = File.join(path, ''.freeze)
165
- if subpath.start_with?(path)
165
+ if subpath&.start_with?(path)
166
166
  subpath[path.length..-1]
167
167
  else
168
168
  nil
@@ -148,39 +148,39 @@ module Sprockets
148
148
  # Returns a 400 Forbidden response tuple
149
149
  def bad_request_response(env)
150
150
  if head_request?(env)
151
- [ 400, { "Content-Type" => "text/plain", "Content-Length" => "0" }, [] ]
151
+ [ 400, { "content-type" => "text/plain", "content-length" => "0" }, [] ]
152
152
  else
153
- [ 400, { "Content-Type" => "text/plain", "Content-Length" => "11" }, [ "Bad Request" ] ]
153
+ [ 400, { "content-type" => "text/plain", "content-length" => "11" }, [ "Bad Request" ] ]
154
154
  end
155
155
  end
156
156
 
157
157
  # Returns a 403 Forbidden response tuple
158
158
  def forbidden_response(env)
159
159
  if head_request?(env)
160
- [ 403, { "Content-Type" => "text/plain", "Content-Length" => "0" }, [] ]
160
+ [ 403, { "content-type" => "text/plain", "content-length" => "0" }, [] ]
161
161
  else
162
- [ 403, { "Content-Type" => "text/plain", "Content-Length" => "9" }, [ "Forbidden" ] ]
162
+ [ 403, { "content-type" => "text/plain", "content-length" => "9" }, [ "Forbidden" ] ]
163
163
  end
164
164
  end
165
165
 
166
166
  # Returns a 404 Not Found response tuple
167
167
  def not_found_response(env)
168
168
  if head_request?(env)
169
- [ 404, { "Content-Type" => "text/plain", "Content-Length" => "0", "X-Cascade" => "pass" }, [] ]
169
+ [ 404, { "content-type" => "text/plain", "content-length" => "0", "x-cascade" => "pass" }, [] ]
170
170
  else
171
- [ 404, { "Content-Type" => "text/plain", "Content-Length" => "9", "X-Cascade" => "pass" }, [ "Not found" ] ]
171
+ [ 404, { "content-type" => "text/plain", "content-length" => "9", "x-cascade" => "pass" }, [ "Not found" ] ]
172
172
  end
173
173
  end
174
174
 
175
175
  def method_not_allowed_response
176
- [ 405, { "Content-Type" => "text/plain", "Content-Length" => "18" }, [ "Method Not Allowed" ] ]
176
+ [ 405, { "content-type" => "text/plain", "content-length" => "18" }, [ "Method Not Allowed" ] ]
177
177
  end
178
178
 
179
179
  def precondition_failed_response(env)
180
180
  if head_request?(env)
181
- [ 412, { "Content-Type" => "text/plain", "Content-Length" => "0", "X-Cascade" => "pass" }, [] ]
181
+ [ 412, { "content-type" => "text/plain", "content-length" => "0", "x-cascade" => "pass" }, [] ]
182
182
  else
183
- [ 412, { "Content-Type" => "text/plain", "Content-Length" => "19", "X-Cascade" => "pass" }, [ "Precondition Failed" ] ]
183
+ [ 412, { "content-type" => "text/plain", "content-length" => "19", "x-cascade" => "pass" }, [ "Precondition Failed" ] ]
184
184
  end
185
185
  end
186
186
 
@@ -189,7 +189,7 @@ module Sprockets
189
189
  def javascript_exception_response(exception)
190
190
  err = "#{exception.class.name}: #{exception.message}\n (in #{exception.backtrace[0]})"
191
191
  body = "throw Error(#{err.inspect})"
192
- [ 200, { "Content-Type" => "application/javascript", "Content-Length" => body.bytesize.to_s }, [ body ] ]
192
+ [ 200, { "content-type" => "application/javascript", "content-length" => body.bytesize.to_s }, [ body ] ]
193
193
  end
194
194
 
195
195
  # Returns a CSS response that hides all elements on the page and
@@ -242,7 +242,7 @@ module Sprockets
242
242
  }
243
243
  CSS
244
244
 
245
- [ 200, { "Content-Type" => "text/css; charset=utf-8", "Content-Length" => body.bytesize.to_s }, [ body ] ]
245
+ [ 200, { "content-type" => "text/css; charset=utf-8", "content-length" => body.bytesize.to_s }, [ body ] ]
246
246
  end
247
247
 
248
248
  # Escape special characters for use inside a CSS content("...") string
@@ -258,18 +258,18 @@ module Sprockets
258
258
  headers = {}
259
259
 
260
260
  # Set caching headers
261
- headers["Cache-Control"] = +"public"
262
- headers["ETag"] = %("#{etag}")
261
+ headers["cache-control"] = +"public"
262
+ headers["etag"] = %("#{etag}")
263
263
 
264
264
  # If the request url contains a fingerprint, set a long
265
265
  # expires on the response
266
266
  if path_fingerprint(env["PATH_INFO"])
267
- headers["Cache-Control"] << ", max-age=31536000, immutable"
267
+ headers["cache-control"] << ", max-age=31536000, immutable"
268
268
 
269
269
  # Otherwise set `must-revalidate` since the asset could be modified.
270
270
  else
271
- headers["Cache-Control"] << ", must-revalidate"
272
- headers["Vary"] = "Accept-Encoding"
271
+ headers["cache-control"] << ", must-revalidate"
272
+ headers["vary"] = "Accept-Encoding"
273
273
  end
274
274
 
275
275
  headers
@@ -279,7 +279,7 @@ module Sprockets
279
279
  headers = {}
280
280
 
281
281
  # Set content length header
282
- headers["Content-Length"] = length.to_s
282
+ headers["content-length"] = length.to_s
283
283
 
284
284
  # Set content type header
285
285
  if type = asset.content_type
@@ -287,7 +287,7 @@ module Sprockets
287
287
  if type.start_with?("text/") && asset.charset
288
288
  type += "; charset=#{asset.charset}"
289
289
  end
290
- headers["Content-Type"] = type
290
+ headers["content-type"] = type
291
291
  end
292
292
 
293
293
  headers.merge(cache_headers(env, asset.etag))
@@ -299,7 +299,7 @@ module Sprockets
299
299
  # # => "0aa2105d29558f3eb790d411d7d8fb66"
300
300
  #
301
301
  def path_fingerprint(path)
302
- path[/-([0-9a-f]{7,128})\.[^.]+\z/, 1]
302
+ path[/-([0-9a-zA-Z]{7,128})\.[^.]+\z/, 1]
303
303
  end
304
304
  end
305
305
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Sprockets
3
- VERSION = "4.0.3"
3
+ VERSION = "4.1.0"
4
4
  end
data/lib/sprockets.rb CHANGED
@@ -51,6 +51,7 @@ module Sprockets
51
51
  register_mime_type 'application/json', extensions: ['.json'], charset: :unicode
52
52
  register_mime_type 'application/ruby', extensions: ['.rb']
53
53
  register_mime_type 'application/xml', extensions: ['.xml']
54
+ register_mime_type 'application/manifest+json', extensions: ['.webmanifest']
54
55
  register_mime_type 'text/css', extensions: ['.css'], charset: :css
55
56
  register_mime_type 'text/html', extensions: ['.html', '.htm'], charset: :html
56
57
  register_mime_type 'text/plain', extensions: ['.txt', '.text']
@@ -89,7 +90,7 @@ module Sprockets
89
90
  register_mime_type 'application/font-woff2', extensions: ['.woff2']
90
91
 
91
92
  require 'sprockets/source_map_processor'
92
- register_mime_type 'application/js-sourcemap+json', extensions: ['.js.map']
93
+ register_mime_type 'application/js-sourcemap+json', extensions: ['.js.map'], charset: :unicode
93
94
  register_mime_type 'application/css-sourcemap+json', extensions: ['.css.map']
94
95
  register_transformer 'application/javascript', 'application/js-sourcemap+json', SourceMapProcessor
95
96
  register_transformer 'text/css', 'application/css-sourcemap+json', SourceMapProcessor
@@ -180,6 +181,7 @@ module Sprockets
180
181
  application/ecmascript-6
181
182
  application/javascript
182
183
  application/json
184
+ application/manifest+json
183
185
  application/xml
184
186
  text/coffeescript
185
187
  text/css
@@ -189,6 +191,7 @@ module Sprockets
189
191
  text/scss
190
192
  text/yaml
191
193
  text/eco
194
+ text/ejs
192
195
  ), 'application/\2+ruby', '.erb', ERBProcessor)
193
196
 
194
197
  register_mime_type 'application/html+ruby', extensions: ['.html.erb', '.erb', '.rhtml'], charset: :html
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sprockets
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.3
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Stephenson
8
8
  - Joshua Peek
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-03-02 00:00:00.000000000 Z
12
+ date: 2022-06-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -423,7 +423,7 @@ homepage: https://github.com/rails/sprockets
423
423
  licenses:
424
424
  - MIT
425
425
  metadata: {}
426
- post_install_message:
426
+ post_install_message:
427
427
  rdoc_options: []
428
428
  require_paths:
429
429
  - lib
@@ -438,8 +438,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
438
438
  - !ruby/object:Gem::Version
439
439
  version: '0'
440
440
  requirements: []
441
- rubygems_version: 3.2.32
442
- signing_key:
441
+ rubygems_version: 3.3.7
442
+ signing_key:
443
443
  specification_version: 4
444
444
  summary: Rack-based asset packaging system
445
445
  test_files: []