sprockets 3.4.1 → 3.5.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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cb84129a09e33080f696f5eec822299e24279dba
4
- data.tar.gz: fc5e73588c47c119874882bacdc8d8fd8da77567
3
+ metadata.gz: 8b7fa38f3206ba320ebf468c054262dda8eb21b1
4
+ data.tar.gz: b28f04553ef0f97e2d27826f49ce9b17c7ff83a6
5
5
  SHA512:
6
- metadata.gz: e2166e7a2f5b2bea3e6eda0a29d0fd4816709bd9e93e6d99cfd00a85ff7df26747ef7d386c8a9812081726948465f887f0721a46a00c6cf06c832ed5f29b6ea0
7
- data.tar.gz: 19c40eff6ab900018c2e7e0210e5ece20eb7780729daa0b2402cc2819012291adb145863c718340fdce43787acbc25e5407b88794df53558cea8e12c4cd5c545
6
+ metadata.gz: 7a3e8d417bd789f73e322d0f1da0bfdfc4f9542cfdbe785ecc4c71d89603caf66765de776db5b03ce93a534b1d45ad9fa9aac1c8017e91cf7bc28a309bef86d8
7
+ data.tar.gz: e5ec4b5327b80ff10b3f0a3d417ef4f8f429836c5ae6779d570cbfddb576504317fb890e27afdb0a406f2ac7c7c6246d6b98ba5738b6af9b123f1a2b40a50aff
@@ -1,3 +1,9 @@
1
+ **Master**
2
+
3
+ **3.5.0** (December 3, 2015)
4
+
5
+ * Reintroduce Gzip file generation for non-binary assets.
6
+
1
7
  **3.4.1** (November 25, 2015)
2
8
 
3
9
  * PathUtils::Entries will no longer error on an empty directory.
data/README.md CHANGED
@@ -20,6 +20,16 @@ Or include it in your project's `Gemfile` with Bundler:
20
20
  gem 'sprockets', '~> 3.0'
21
21
  ```
22
22
 
23
+ ## Using sprockets
24
+
25
+ For most people interested in using sprockets you will want to see [End User Asset Generation](guides/end_user_asset_generation.md) guide. This contains information about sprocket's directive syntax, and default processing behavior.
26
+
27
+ If you are a framework developer that is using sprockets, see [Building an Asset Processing Framework](guides/building_an_asset_processing_framework.md).
28
+
29
+ If you are a library developer who is extending the functionality of sprockets, see [Extending Sprockets](guides/extending_sprockets.md).
30
+
31
+ Below is a disjointed mix of documentation for all three of these roles. Eventually they will be moved to an appropriate guide, for now the recommended way to consume documentation is to view the appropriate guide first and then supplement with docs from the README.
32
+
23
33
  ## Behavior
24
34
 
25
35
  ### Index files are proxies for folders
@@ -51,6 +51,21 @@ module Sprockets
51
51
  end
52
52
  end
53
53
 
54
+ def gzip?
55
+ return @gzip if defined?(@gzip)
56
+ true
57
+ end
58
+
59
+ def skip_gzip?
60
+ !gzip?
61
+ end
62
+
63
+ # Enable or disable the creation of gzip files,
64
+ # on by default.
65
+ def gzip=(gzip)
66
+ @gzip = gzip
67
+ end
68
+
54
69
  # Assign a compressor to run on `application/javascript` assets.
55
70
  #
56
71
  # The compressor object must respond to `compress`.
@@ -1,6 +1,10 @@
1
1
  require 'json'
2
2
  require 'time'
3
+
4
+ require 'concurrent/future'
5
+
3
6
  require 'sprockets/manifest_utils'
7
+ require 'sprockets/utils/gzip'
4
8
 
5
9
  module Sprockets
6
10
  # The Manifest logs the contents of assets compiled to a single directory. It
@@ -157,7 +161,9 @@ module Sprockets
157
161
  raise Error, "manifest requires environment for compilation"
158
162
  end
159
163
 
160
- filenames = []
164
+ filenames = []
165
+ concurrent_compressors = []
166
+ concurrent_writers = []
161
167
 
162
168
  find(*args) do |asset|
163
169
  files[asset.digest_path] = {
@@ -183,12 +189,26 @@ module Sprockets
183
189
  logger.debug "Skipping #{target}, already exists"
184
190
  else
185
191
  logger.info "Writing #{target}"
186
- asset.write_to target
192
+ write_file = Concurrent::Future.execute { asset.write_to target }
193
+ concurrent_writers << write_file
187
194
  end
188
-
189
195
  filenames << asset.filename
196
+
197
+ next if environment.skip_gzip?
198
+ gzip = Utils::Gzip.new(asset)
199
+ next if gzip.cannot_compress?(environment.mime_types)
200
+
201
+ if File.exist?("#{target}.gz")
202
+ logger.debug "Skipping #{target}.gz, already exists"
203
+ else
204
+ logger.info "Writing #{target}.gz"
205
+ concurrent_compressors << Concurrent::Future.execute { write_file.wait; gzip.compress(target) }
206
+ end
207
+
190
208
  end
191
- save
209
+ concurrent_writers.each(&:wait)
210
+ concurrent_compressors.each(&:wait)
211
+ Concurrent::Future.execute { self.save }.wait
192
212
 
193
213
  filenames
194
214
  end
@@ -200,6 +220,7 @@ module Sprockets
200
220
  #
201
221
  def remove(filename)
202
222
  path = File.join(dir, filename)
223
+ gzip = "#{path}.gz"
203
224
  logical_path = files[filename]['logical_path']
204
225
 
205
226
  if assets[logical_path] == filename
@@ -208,6 +229,7 @@ module Sprockets
208
229
 
209
230
  files.delete(filename)
210
231
  FileUtils.rm(path) if File.exist?(path)
232
+ FileUtils.rm(gzip) if File.exist?(gzip)
211
233
 
212
234
  save
213
235
 
@@ -0,0 +1,56 @@
1
+ module Sprockets
2
+ module Utils
3
+ class Gzip
4
+ # Private: Generates a gzipped file based off of reference file.
5
+ def initialize(asset)
6
+ @content_type = asset.content_type
7
+ @mtime = asset.mtime
8
+ @source = asset.source
9
+ @charset = asset.charset
10
+ end
11
+
12
+ # Private: Returns whether or not an asset can be compressed.
13
+ #
14
+ # We want to compress any file that is text based.
15
+ # You do not want to compress binary
16
+ # files as they may already be compressed and running them
17
+ # through a compression algorithm would make them larger.
18
+ #
19
+ # Return Boolean.
20
+ def can_compress?(mime_types)
21
+ # The "charset" of a mime type is present if the value is
22
+ # encoded text. We can check this value to see if the asset
23
+ # can be compressed.
24
+ #
25
+ # SVG images are text but do not have
26
+ # a charset defined, this is special cased.
27
+ @charset || @content_type == "image/svg+xml".freeze
28
+ end
29
+
30
+ # Private: Opposite of `can_compress?`.
31
+ #
32
+ # Returns Boolean.
33
+ def cannot_compress?(mime_types)
34
+ !can_compress?(mime_types)
35
+ end
36
+
37
+ # Private: Generates a gzipped file based off of reference asset.
38
+ #
39
+ # Compresses the target asset's contents and puts it into a file with
40
+ # the same name plus a `.gz` extension in the same folder as the original.
41
+ # Does not modify the target asset.
42
+ #
43
+ # Returns nothing.
44
+ def compress(target)
45
+ PathUtils.atomic_write("#{target}.gz") do |f|
46
+ gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
47
+ gz.mtime = @mtime.to_i
48
+ gz.write(@source)
49
+ gz.close
50
+ end
51
+
52
+ nil
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,3 +1,3 @@
1
1
  module Sprockets
2
- VERSION = "3.4.1"
2
+ VERSION = "3.5.0"
3
3
  end
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: 3.4.1
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Stephenson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-11-25 00:00:00.000000000 Z
12
+ date: 2015-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -31,6 +31,20 @@ dependencies:
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '3'
34
+ - !ruby/object:Gem::Dependency
35
+ name: concurrent-ruby
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
34
48
  - !ruby/object:Gem::Dependency
35
49
  name: closure-compiler
36
50
  requirement: !ruby/object:Gem::Requirement
@@ -295,6 +309,7 @@ files:
295
309
  - lib/sprockets/uri_tar.rb
296
310
  - lib/sprockets/uri_utils.rb
297
311
  - lib/sprockets/utils.rb
312
+ - lib/sprockets/utils/gzip.rb
298
313
  - lib/sprockets/version.rb
299
314
  - lib/sprockets/yui_compressor.rb
300
315
  homepage: https://github.com/rails/sprockets