sprockets 4.2.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c5995147a647a6d47d625b6cc9f10586506f3832cff0070985ec9560ee3fc0d
4
- data.tar.gz: 1befd6f705efbef88f05dc58b38f719f11b445f76c60a95f854a43ef8e84c21d
3
+ metadata.gz: e90597d41c004cb5a71036473da429c30f7fea114de88b48f8c5b0bbd1e82531
4
+ data.tar.gz: 496cf47db6004a4335fe2afa6e5c0c70f8322be6a57dbed5c7a4f1976717df93
5
5
  SHA512:
6
- metadata.gz: 9d47aea08307515c8a0fab29615fbde5f892c91300668afd83b2739032adeb77794d4303e6ecb56c570bc784695d25304f7481fa45c4ab7bbe0727281ee7deab
7
- data.tar.gz: 6d0f0b116766053d96402f5d88602374829ef9610160bd8398a093db33ceaafe31a2f2b33a8d0c615769f0bbba7c39d867db90dfded9bc5ff35d0c0ff4482e36
6
+ metadata.gz: d5665dc8d05a3aafbff29fe6287c9732f1b51a3dd5164a38d5ba0a289cd660a18ef061fdc3560f3f2b481da450beb5e0864279394e1f8164b859b0e15dafb531
7
+ data.tar.gz: 80a297f58bf9d94f4d78f21898477ffa2a7a9bf8f00d0cdb7d4a6351d0c28646cbcba97cdd491472fd329c170ca013bb9defe14fd5e43003eb1022377e396573
data/CHANGELOG.md CHANGED
@@ -2,12 +2,39 @@
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.4.0
6
+
7
+ - Implement `ignore_mtime` option. [#831](https://github.com/rails/sprockets/pull/832)
8
+ - Allow disabling cache limits. [#831](https://github.com/rails/sprockets/pull/831)
9
+
10
+ ## 4.3.0
11
+
12
+ - Fixed compatibility with `json` 3+.
13
+ - Do not set variable `GZip#mtime` but do always set `File#mtime`. [#821](https://github.com/rails/sprockets/pull/821)
14
+
15
+ ## 4.2.2
16
+
17
+ - Added missing dependency on `logger`. [#813](https://github.com/rails/sprockets/pull/813)
18
+ - Fix `URI::RFC3986_PARSER` warnings. [#812](https://github.com/rails/sprockets/pull/812)
19
+ - Removed dependency on `base64`. [#810](https://github.com/rails/sprockets/pull/810)
20
+
21
+ ## 4.2.1
22
+
23
+ - Fix for precompile issues when multiple extensions map to the same MIME type (eg. `.jpeg` / `.jpg`). [#781](https://github.com/rails/sprockets/pull/781)
24
+ - Fix `application/css-sourcemap+json` charset [#764](https://github.com/rails/sprockets/pull/764)
25
+ - Fix compatibility with Rack 2 applications. [#790](https://github.com/rails/sprockets/pull/790)
26
+
5
27
  ## 4.2.0
6
28
 
7
29
  - Rack 3 compatibility. [#758](https://github.com/rails/sprockets/pull/758)
8
30
  - Fix thread safety of `Sprockets::CachedEnvironment` and `Sprockets::Cache::MemoryStore`. [#771](https://github.com/rails/sprockets/pull/771)
9
31
  - Add support for Rack 3.0. Headers set by sprockets will now be lower case. [#758](https://github.com/rails/sprockets/pull/758)
10
32
  - Make `Sprockets::Utils.module_include` thread safe on JRuby. [#759](https://github.com/rails/sprockets/pull/759)
33
+ - Fix typo in `asset.rb` file. [#768](https://github.com/rails/sprockets/pull/768)
34
+
35
+ ## 4.1.1
36
+
37
+ - Fix `Sprockets::Server` to return response headers to be compatible with Rack::Lint 2.0.
11
38
 
12
39
  ## 4.1.0
13
40
 
data/README.md CHANGED
@@ -44,7 +44,7 @@ If you want to work on Sprockets or better understand how it works read [How Spr
44
44
 
45
45
  You can interact with Sprockets primarily through directives and file extensions. This section covers how to use each of these things, and the defaults that ship with Sprockets.
46
46
 
47
- Since you are likely using Sprockets through another framework (such as the [the Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)), there will be configuration options you can toggle that will change behavior such as what directories or files get compiled. For that documentation you should see your framework's documentation.
47
+ Since you are likely using Sprockets through another framework (such as the [Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)), there will be configuration options you can toggle that will change behavior such as what directories or files get compiled. For that documentation you should see your framework's documentation.
48
48
 
49
49
  #### Accessing Assets
50
50
 
@@ -119,7 +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
+ - [`depend_on_directory`](#depend_on_directory) - Recompile current file if any files in target directory have changed
123
123
  - [`stub`](#stub) - Ignore target file
124
124
 
125
125
  You can see what each of these does below.
@@ -150,7 +150,7 @@ When "asking" for a compiled file, you always ask for the extension you want. Fo
150
150
  asset_path("application.css")
151
151
  ```
152
152
 
153
- Sprockets understands that `application.scss.erb` will compile down to a `application.css`. Ask for what you need, not what you have.
153
+ Sprockets understands that `application.scss.erb` will compile down to an `application.css`. Ask for what you need, not what you have.
154
154
 
155
155
  If this isn't working like you expect, make sure you didn't typo an extension, and make sure the file is on a "load path" (see framework docs for adding new load paths).
156
156
 
@@ -174,7 +174,7 @@ beta.js
174
174
  jquery.js
175
175
  ```
176
176
 
177
- Then `alpha.js` will be loaded before either of the other two. This can be a problem if `alpha.js` uses jquery. For this reason it is not recommend to use `require_directory` with files that are ordering dependent. You can either require individual files manually:
177
+ Then `alpha.js` will be loaded before either of the other two. This can be a problem if `alpha.js` uses jquery. For this reason it is not recommended to use `require_directory` with files that are ordering dependent. You can either require individual files manually:
178
178
 
179
179
  ```js
180
180
  //= require jquery
@@ -253,7 +253,7 @@ Directives take a path or a path to a file. Paths for directive can be relative
253
253
  //= require ../foo.js
254
254
  ```
255
255
 
256
- This would load the file up one directory and named `foo.js`. However this isn't required if `foo.js` is on one of Sprocket's load paths. You can simply use
256
+ This would load a file named `foo.js` from one directory up. However this isn't required if `foo.js` is on one of Sprocket's load paths. You can simply use
257
257
 
258
258
  ```js
259
259
  //= require foo.js
@@ -396,7 +396,7 @@ This would find a manifest file at `my_engine/app/assets/config/my_engine_manife
396
396
 
397
397
  Files in subdirectories will not be linked (Compare to [link_tree](#link_tree)).
398
398
 
399
- The *path* argument to `link_directory` is _not_ a logical path (it does not use the asset load paths), but is a path relative to the file the `link_directory` directive is found in, and can use `..` to . For instance, you might want:
399
+ The *path* argument to `link_directory` is _not_ a logical path (it does not use the asset load paths), but is a path relative to the file the `link_directory` directive is found in, and can use `..` to reference parent directories. For instance, you might want:
400
400
 
401
401
  ```js
402
402
  //= link_directory ../stylesheets
@@ -426,7 +426,7 @@ Example:
426
426
  //= link_tree ./path/to/folder
427
427
  ```
428
428
 
429
- Like `link_directory`, the argument is path relative to the current file, it is *not* a 'logical path' tresolved against load paths.
429
+ Like `link_directory`, the argument is a path relative to the current file, it is *not* a 'logical path' resolved against load paths.
430
430
 
431
431
 
432
432
  As with `link_directory`, you can also specify a second argument -- separated by a space -- so any extra files not matching the content-type specified will be ignored:
@@ -469,7 +469,7 @@ asset's cache in response to a change in multiple files in a single directory.
469
469
 
470
470
  All paths are relative to your declaration and must begin with `./`
471
471
 
472
- Also, your must include these directories in your [load path](guides/building_an_asset_processing_framework.md#the-load-path).
472
+ Also, you must include these directories in your [load path](guides/building_an_asset_processing_framework.md#the-load-path).
473
473
 
474
474
  **Example:**
475
475
 
@@ -488,8 +488,8 @@ B
488
488
  ```
489
489
  // ./file.js.erb
490
490
  //= depend_on_directory ./data
491
- var a = '<% File.read('data/a.data') %>'
492
- var b = '<% File.read('data/b.data') %>'
491
+ var a = '<%= File.read("data/a.data") %>'
492
+ var b = '<%= File.read("data/b.data") %>'
493
493
  ```
494
494
 
495
495
  Would produce:
@@ -514,7 +514,7 @@ Sprockets provides an ERB engine for preprocessing assets using
514
514
  embedded Ruby code. Append `.erb` to a CSS or JavaScript asset's
515
515
  filename to enable the ERB engine.
516
516
 
517
- For example if you have an `app/application/javascripts/app_name.js.erb`
517
+ For example if you have an `app/assets/javascripts/app_name.js.erb`
518
518
  you could have this in the template
519
519
 
520
520
  ```js
@@ -559,7 +559,7 @@ Sprockets supports both Sass syntaxes. For the original
559
559
  whitespace-sensitive syntax, use the extension `.sass`. For the
560
560
  new SCSS syntax, use the extension `.scss`.
561
561
 
562
- In Rails if you have `app/application/stylesheets/foo.scss` it can
562
+ In Rails if you have `app/assets/stylesheets/foo.scss` it can
563
563
  be referenced with `<%= asset_path("foo.css") %>`. When referencing
564
564
  an asset in Rails, always specify the extension you want. Sprockets will
565
565
  convert `foo.scss` to `foo.css`.
@@ -580,7 +580,7 @@ on your system to invoke it.
580
580
  To write JavaScript assets with CoffeeScript, use the extension
581
581
  `.coffee`.
582
582
 
583
- In Rails if you have `app/application/javascripts/foo.coffee` it can
583
+ In Rails if you have `app/assets/javascripts/foo.coffee` it can
584
584
  be referenced with `<%= asset_path("foo.js") %>`. When referencing
585
585
  an asset in Rails, always specify the extension you want. Sprockets will
586
586
  convert `foo.coffee` to `foo.js`.
@@ -97,7 +97,7 @@ module Sprockets
97
97
  if @source
98
98
  @source
99
99
  else
100
- # File is read everytime to avoid memory bloat of large binary files
100
+ # File is read every time to avoid memory bloat of large binary files
101
101
  File.binread(filename)
102
102
  end
103
103
  end
@@ -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
 
@@ -55,6 +55,13 @@ module Sprockets
55
55
  end
56
56
  alias_method :index, :cached
57
57
 
58
+ # By default sprockets tries to quickly revalidate the cache for a source file
59
+ # by comparing its last modified time.
60
+ # This is efficient in development, but in some CI or producton environments
61
+ # where the source files are restored from version control, the last modified time
62
+ # tend to be somewhat random, and checking it is just needless overhead.
63
+ attr_accessor :ignore_mtime
64
+
58
65
  # Internal: Compute digest for path.
59
66
  #
60
67
  # path - String filename or directory path.
@@ -62,14 +69,18 @@ module Sprockets
62
69
  # Returns a String digest or nil.
63
70
  def file_digest(path)
64
71
  if stat = self.stat(path)
65
- # Caveat: Digests are cached by the path's current mtime. Its possible
66
- # for a files contents to have changed and its mtime to have been
67
- # negligently reset thus appearing as if the file hasn't changed on
68
- # disk. Also, the mtime is only read to the nearest second. It's
69
- # also possible the file was updated more than once in a given second.
70
- key = UnloadedAsset.new(path, self).file_digest_key(stat.mtime.to_i)
71
- cache.fetch(key) do
72
+ if ignore_mtime
72
73
  self.stat_digest(path, stat)
74
+ else
75
+ # Caveat: Digests are cached by the path's current mtime. Its possible
76
+ # for a files contents to have changed and its mtime to have been
77
+ # negligently reset thus appearing as if the file hasn't changed on
78
+ # disk. Also, the mtime is only read to the nearest second. It's
79
+ # also possible the file was updated more than once in a given second.
80
+ key = UnloadedAsset.new(path, self).file_digest_key(stat.mtime.to_i)
81
+ cache.fetch(key) do
82
+ self.stat_digest(path, stat)
83
+ end
73
84
  end
74
85
  end
75
86
  end
@@ -46,7 +46,7 @@ module Sprockets
46
46
  #
47
47
  # Returns nothing.
48
48
  def read_bower_main(dirname, filename)
49
- bower = JSON.parse(File.read(filename), create_additions: false)
49
+ bower = JSON.parse(File.read(filename))
50
50
 
51
51
  case bower['main']
52
52
  when String
@@ -36,13 +36,13 @@ module Sprockets
36
36
  #
37
37
  # root - A String path to a directory to persist cached values to.
38
38
  # max_size - A Integer of the maximum size the store will hold (in bytes).
39
- # (default: 25MB).
39
+ # (default: 25MB). Can be set to +false+ for no limit.
40
40
  # logger - The logger to which some info will be printed.
41
41
  # (default logger level is FATAL and won't output anything).
42
42
  def initialize(root, max_size = DEFAULT_MAX_SIZE, logger = self.class.default_logger)
43
43
  @root = root
44
44
  @max_size = max_size
45
- @gc_size = max_size * 0.75
45
+ @gc_size = max_size * 0.75 if max_size
46
46
  @logger = logger
47
47
  end
48
48
 
@@ -111,11 +111,13 @@ module Sprockets
111
111
  # Write data
112
112
  PathUtils.atomic_write(path) do |f|
113
113
  f.write(raw)
114
- @size = size + f.size unless exists
114
+ if defined?(@size) && !exists
115
+ @size += f.size
116
+ end
115
117
  end
116
118
 
117
119
  # GC if necessary
118
- gc! if size > @max_size
120
+ gc! if @max_size && size > @max_size
119
121
 
120
122
  value
121
123
  end
@@ -18,7 +18,7 @@ module Sprockets
18
18
  # Public: Initialize the cache store.
19
19
  #
20
20
  # max_size - A Integer of the maximum number of keys the store will hold.
21
- # (default: 1000).
21
+ # (default: 1000). Can be set to +false+ for no limit.
22
22
  def initialize(max_size = DEFAULT_MAX_SIZE)
23
23
  @max_size = max_size
24
24
  @cache = {}
@@ -56,7 +56,7 @@ module Sprockets
56
56
  @mutex.synchronize do
57
57
  @cache.delete(key)
58
58
  @cache[key] = value
59
- @cache.shift if @cache.size > @max_size
59
+ @cache.shift if @max_size && @cache.size > @max_size
60
60
  end
61
61
  value
62
62
  end
@@ -106,7 +106,7 @@ module Sprockets
106
106
  #
107
107
  # environment.gzip = false
108
108
  #
109
- # To enable set to a truthy value. By default zlib wil
109
+ # To enable set to a truthy value. By default zlib will
110
110
  # be used to gzip assets. If you have the Zopfli gem
111
111
  # installed you can specify the zopfli algorithm to be used
112
112
  # instead:
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'base64'
3
2
  require 'stringio'
4
3
  require 'zlib'
5
4
 
@@ -51,6 +50,8 @@ module Sprockets
51
50
  Marshal.load(marshaled)
52
51
  end
53
52
 
53
+ GZIP_MTIME = RUBY_VERSION >= "2.7" ? 0 : 1
54
+
54
55
  # Public: Use gzip to compress data.
55
56
  #
56
57
  # str - String data
@@ -59,7 +60,7 @@ module Sprockets
59
60
  def gzip(str)
60
61
  io = StringIO.new
61
62
  gz = Zlib::GzipWriter.new(io, Zlib::BEST_COMPRESSION)
62
- gz.mtime = 1
63
+ gz.mtime = Sprockets::EncodingUtils::GZIP_MTIME
63
64
  gz << str
64
65
  gz.finish
65
66
  io.string
@@ -71,7 +72,7 @@ module Sprockets
71
72
  #
72
73
  # Returns a encoded String
73
74
  def base64(str)
74
- Base64.strict_encode64(str)
75
+ [str].pack("m0")
75
76
  end
76
77
 
77
78
 
@@ -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]
@@ -177,7 +179,7 @@ module Sprockets
177
179
  processors_dep_uri = build_processors_uri(type, file_type, pipeline)
178
180
  dependencies = config[:dependencies] + [processors_dep_uri]
179
181
 
180
- # Read into memory and process if theres a processor pipeline
182
+ # Read into memory and process if there's a processor pipeline
181
183
  if processors.any?
182
184
  result = call_processors(processors, {
183
185
  environment: self,
@@ -120,14 +120,14 @@ module Sprockets
120
120
  return to_enum(__method__, *args) unless block_given?
121
121
 
122
122
  environment = self.environment.cached
123
- promises = args.flatten.map do |path|
124
- Concurrent::Promise.execute(executor: executor) do
123
+ futures = args.flatten.map do |path|
124
+ Concurrent::Promises.future_on(executor) do
125
125
  environment.find_all_linked_assets(path).to_a
126
126
  end
127
127
  end
128
128
 
129
- promises.each do |promise|
130
- promise.value!.each(&block)
129
+ futures.each do |future|
130
+ future.value!.each(&block)
131
131
  end
132
132
 
133
133
  nil
@@ -188,15 +188,15 @@ module Sprockets
188
188
 
189
189
  filenames << asset.filename
190
190
 
191
- promise = nil
191
+ future = nil
192
192
  exporters_for_asset(asset) do |exporter|
193
193
  next if exporter.skip?(logger)
194
194
 
195
- if promise.nil?
196
- promise = Concurrent::Promise.new(executor: executor) { exporter.call }
197
- concurrent_exporters << promise.execute
195
+ if future.nil?
196
+ future = Concurrent::Promises.future_on(executor) { exporter.call }
197
+ concurrent_exporters << future
198
198
  else
199
- concurrent_exporters << promise.then { exporter.call }
199
+ concurrent_exporters << future.then { exporter.call }
200
200
  end
201
201
  end
202
202
  end
@@ -315,7 +315,7 @@ module Sprockets
315
315
  end
316
316
 
317
317
  def json_decode(obj)
318
- JSON.parse(obj, create_additions: false)
318
+ JSON.parse(obj)
319
319
  end
320
320
 
321
321
  def json_encode(obj)
data/lib/sprockets/npm.rb CHANGED
@@ -37,7 +37,7 @@ module Sprockets
37
37
  #
38
38
  # Returns nothing.
39
39
  def read_package_directives(dirname, filename)
40
- package = JSON.parse(File.read(filename), create_additions: false)
40
+ package = JSON.parse(File.read(filename))
41
41
 
42
42
  case package['main']
43
43
  when String
@@ -18,7 +18,7 @@ module Sprockets
18
18
  # The returned dependency set can be passed to resolve_dependencies(deps)
19
19
  # to check if the returned result is still fresh. In this case, entry always
20
20
  # returns a single path, but multiple calls should accumulate dependencies
21
- # into a single set thats saved off and checked later.
21
+ # into a single set that's saved off and checked later.
22
22
  #
23
23
  # resolve_dependencies(deps)
24
24
  # # => "\x01\x02\x03"
@@ -91,6 +91,8 @@ module Sprockets
91
91
  SEPARATOR_PATTERN = "#{Regexp.quote(File::SEPARATOR)}"
92
92
  end
93
93
 
94
+ RELATIVE_PATH_PATTERN = /^\.\.?($|#{SEPARATOR_PATTERN})/
95
+
94
96
  # Public: Check if path is explicitly relative.
95
97
  # Starts with "./" or "../".
96
98
  #
@@ -98,7 +100,7 @@ module Sprockets
98
100
  #
99
101
  # Returns true if path is relative, otherwise false.
100
102
  def relative_path?(path)
101
- path.match?(/^\.\.?($|#{SEPARATOR_PATTERN})/) ? true : false
103
+ path.match?(RELATIVE_PATH_PATTERN) ? true : false
102
104
  end
103
105
 
104
106
  # Public: Get relative path from `start` to `dest`.
@@ -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))
@@ -21,6 +21,9 @@ module Sprockets
21
21
  module URIUtils
22
22
  extend self
23
23
 
24
+ URI_PARSER = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::Generic::DEFAULT_PARSER
25
+ private_constant :URI_PARSER
26
+
24
27
  # Internal: Parse URI into component parts.
25
28
  #
26
29
  # uri - String uri
@@ -45,7 +48,7 @@ module Sprockets
45
48
  def split_file_uri(uri)
46
49
  scheme, _, host, _, _, path, _, query, _ = URI.split(uri)
47
50
 
48
- path = URI::Generic::DEFAULT_PARSER.unescape(path)
51
+ path = URI_PARSER.unescape(path)
49
52
  path.force_encoding(Encoding::UTF_8)
50
53
 
51
54
  # Hack for parsing Windows "/C:/Users/IEUser" paths
@@ -63,7 +66,7 @@ module Sprockets
63
66
  str = +"#{scheme}://"
64
67
  str << host if host
65
68
  path = "/#{path}" unless path.start_with?("/".freeze)
66
- str << URI::Generic::DEFAULT_PARSER.escape(path)
69
+ str << URI_PARSER.escape(path)
67
70
  str << "?#{query}" if query
68
71
  str
69
72
  end
@@ -162,7 +165,7 @@ module Sprockets
162
165
  when Integer
163
166
  query << "#{key}=#{value}"
164
167
  when String, Symbol
165
- query << "#{key}=#{URI::Generic::DEFAULT_PARSER.escape(value.to_s)}"
168
+ query << "#{key}=#{URI_PARSER.escape(value.to_s)}"
166
169
  when TrueClass
167
170
  query << "#{key}"
168
171
  when FalseClass, NilClass
@@ -182,7 +185,7 @@ module Sprockets
182
185
  def parse_uri_query_params(query)
183
186
  query.to_s.split('&'.freeze).reduce({}) do |h, p|
184
187
  k, v = p.split('='.freeze, 2)
185
- v = URI::Generic::DEFAULT_PARSER.unescape(v) if v
188
+ v = URI_PARSER.unescape(v) if v
186
189
  h[k.to_sym] = v || true
187
190
  h
188
191
  end
@@ -10,13 +10,15 @@ module Sprockets
10
10
  # writes contents to the `file` passed in. Sets `mtime` of
11
11
  # written file to passed in `mtime`
12
12
  module ZlibArchiver
13
- def self.call(file, source, mtime)
13
+ MTIME = RUBY_VERSION >= "2.7" ? 0 : 1
14
+
15
+ def self.call(file, source)
14
16
  gz = Zlib::GzipWriter.new(file, Zlib::BEST_COMPRESSION)
15
- gz.mtime = mtime
17
+ gz.mtime = MTIME
16
18
  gz.write(source)
17
19
  gz.close
18
20
 
19
- File.utime(mtime, mtime, file.path)
21
+ nil
20
22
  end
21
23
  end
22
24
 
@@ -28,8 +30,8 @@ module Sprockets
28
30
  # writes contents to the `file` passed in. Sets `mtime` of
29
31
  # written file to passed in `mtime`
30
32
  module ZopfliArchiver
31
- def self.call(file, source, mtime)
32
- compressed_source = Autoload::Zopfli.deflate(source, format: :gzip, mtime: mtime)
33
+ def self.call(file, source)
34
+ compressed_source = Autoload::Zopfli.deflate(source, format: :gzip)
33
35
  file.write(compressed_source)
34
36
  file.close
35
37
 
@@ -49,7 +51,7 @@ module Sprockets
49
51
 
50
52
  # What non-text mime types should we compress? This list comes from:
51
53
  # https://www.fastly.com/blog/new-gzip-settings-and-deciding-what-compress
52
- COMPRESSABLE_MIME_TYPES = {
54
+ COMPRESSIBLE_MIME_TYPES = {
53
55
  "application/vnd.ms-fontobject" => true,
54
56
  "application/x-font-opentype" => true,
55
57
  "application/x-font-ttf" => true,
@@ -71,7 +73,7 @@ module Sprockets
71
73
  # can be compressed.
72
74
  #
73
75
  # We also check against our list of non-text compressible mime types
74
- @charset || COMPRESSABLE_MIME_TYPES.include?(@content_type)
76
+ @charset || COMPRESSIBLE_MIME_TYPES.include?(@content_type)
75
77
  end
76
78
 
77
79
  # Private: Opposite of `can_compress?`.
@@ -90,7 +92,8 @@ module Sprockets
90
92
  # Returns nothing.
91
93
  def compress(file, target)
92
94
  mtime = Sprockets::PathUtils.stat(target).mtime
93
- archiver.call(file, source, mtime)
95
+ archiver.call(file, source)
96
+ File.utime(mtime, mtime, file.path)
94
97
 
95
98
  nil
96
99
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Sprockets
3
- VERSION = "4.2.0"
3
+ VERSION = "4.4.0"
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,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sprockets
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.0
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Stephenson
8
8
  - Joshua Peek
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2022-12-20 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rack
@@ -37,14 +36,28 @@ dependencies:
37
36
  requirements:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: '1.0'
39
+ version: '1.1'
41
40
  type: :runtime
42
41
  prerelease: false
43
42
  version_requirements: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - "~>"
46
45
  - !ruby/object:Gem::Version
47
- version: '1.0'
46
+ version: '1.1'
47
+ - !ruby/object:Gem::Dependency
48
+ name: logger
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
48
61
  - !ruby/object:Gem::Dependency
49
62
  name: m
50
63
  requirement: !ruby/object:Gem::Requirement
@@ -233,14 +246,14 @@ dependencies:
233
246
  requirements:
234
247
  - - "~>"
235
248
  - !ruby/object:Gem::Version
236
- version: '12.0'
249
+ version: '13.2'
237
250
  type: :development
238
251
  prerelease: false
239
252
  version_requirements: !ruby/object:Gem::Requirement
240
253
  requirements:
241
254
  - - "~>"
242
255
  - !ruby/object:Gem::Version
243
- version: '12.0'
256
+ version: '13.2'
244
257
  - !ruby/object:Gem::Dependency
245
258
  name: sass
246
259
  requirement: !ruby/object:Gem::Requirement
@@ -423,7 +436,6 @@ homepage: https://github.com/rails/sprockets
423
436
  licenses:
424
437
  - MIT
425
438
  metadata: {}
426
- post_install_message:
427
439
  rdoc_options: []
428
440
  require_paths:
429
441
  - lib
@@ -438,8 +450,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
438
450
  - !ruby/object:Gem::Version
439
451
  version: '0'
440
452
  requirements: []
441
- rubygems_version: 3.3.7
442
- signing_key:
453
+ rubygems_version: 4.0.16
443
454
  specification_version: 4
444
455
  summary: Rack-based asset packaging system
445
456
  test_files: []