zip_kit 6.2.2 → 6.3.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: e1136ebba851638486c9e47150a8d706c49a2bbc0074f457c794582d8ce19089
4
- data.tar.gz: 80de3edcb5bc748aaf855a7bf0b1f19439522c8efa4b97754f813fe9413bac2c
3
+ metadata.gz: dcd59b7f9d367a40895c9bac2f909f3e22ebd0a96ee737073ef5153c4d486c70
4
+ data.tar.gz: 05665ca021d401cad02f80c38d8965c2e5fef1a477317f7ee92246d1c54a21ae
5
5
  SHA512:
6
- metadata.gz: 20c5922a4178f2068a4f06388b201bd263f01c387d308c2c6297feba1c05385d601072cae0451d59a4a0b4e1ba1e354a6fa7f622ff1b58daf70947e6991b1e82
7
- data.tar.gz: c373972ec6980000b40d1808247759b44f317a7aa3795b406e02005412cf0687e0f2311e5809f011eb1fbc19e6b2b7eb2a6a8f036cafe27a2645f6476cf0c441
6
+ metadata.gz: b13d15a467565ef66ce6a21ac3891e8a26b30246d538c232aca193c3fe24a24a8f3a2d844d48eaeaeeb5ccc2f92cfcaab20e4afa1a2717b89ba27f55bb4635e4
7
+ data.tar.gz: 29aacf905b670323861812a4aece1446917ac2f94ece22b948f5d2f77a6eb7574c39598177e7c4f33cc230fd863b4f1c02eb961c5b48e4823d40854a25368101
data/.yardopts CHANGED
@@ -1 +1 @@
1
- --markup markdown
1
+ --markup markdown --no-private --protected lib/**/*.rb - LICENSE.txt IMPLEMENTATION_DETAILS.md RUBYZIP_DIFFERENCES.md CONTRIBUTING.md CODE_OF_CONDUCT.md CHANGELOG.md
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 6.3.0
2
+
3
+ * Include `RailsStreaming` automatically via a Railtie. It is not really necessary to force people to manage it manually.
4
+
1
5
  ## 6.2.2
2
6
 
3
7
  * Make sure "zlib" gets required at the top, as it is used everywhere
data/CONTRIBUTING.md CHANGED
@@ -16,7 +16,7 @@ If you are interested in contributing code and would like to learn more about th
16
16
 
17
17
  - [ruby](https://ruby-doc.org)
18
18
  - [rubyzip](https://github.com/rubyzip/rubyzip) as we like to test "our implementation against theirs"
19
- - [rspec](http://rspec.info/) and [appraisal]() https://github.com/thoughtbot/appraisal) for testing
19
+ - [rspec](http://rspec.info/) for testing
20
20
  - [zip files](https://en.wikipedia.org/wiki/Zip_(file_format))
21
21
 
22
22
  # How do I make a contribution?
@@ -78,8 +78,8 @@ you can try this:
78
78
 
79
79
  [Encoding::CP437, Encoding::ISO_8859_1, Encoding::UTF_8]
80
80
 
81
- We don't want no such thing, and sorry Windows users, you are going to need a decent unarchiver
82
- that honors the standard. Alas, alas.
81
+ While this could work, we found it to be broken in practice as the decoding of the filename
82
+ also depends on the system locale.
83
83
 
84
84
  Additionally, the tests with the unarchivers we _do_ support have shown that including the InfoZIP
85
85
  extra field does not actually help any of them recognize the file name correctly. And the use of
data/README.md CHANGED
@@ -14,8 +14,13 @@ point. Usable for creating very large ZIP archives for immediate sending out to
14
14
  large ZIP archives without memory inflation.
15
15
 
16
16
  The original gem (zip_tricks) handled all the zipping needs (millions of ZIP files generated per day),
17
- for a large file transfer service, so we are pretty confident it is widely compatible with a large number
18
- of unarchiving end-user applications and is well tested.
17
+ for WeTransfer, it is widely compatible with a large number of unarchiving end-user applications.
18
+
19
+ ## How does it work? How is it different from Rubyzip?
20
+
21
+ Check out [the implementation details](IMPLEMENTATION_DETAILS.md) on the design of the library, and
22
+ we have a separate [reference](RUBYZIP_DIFFERENCES.md) on why you might want to use ZipKit over
23
+ Rubyzip and vice versa.
19
24
 
20
25
  ## Requirements
21
26
 
@@ -23,13 +28,11 @@ Ruby 2.6+ syntax support is required, as well as a a working zlib (all available
23
28
 
24
29
  ## Diving in: send some large CSV reports from Rails
25
30
 
26
- The easiest is to include the `ZipKit::RailsStreaming` module into your
27
- controller. You will then have a `zip_kit_stream` method available which accepts a block:
31
+ The included `Railtie` will automatically include `ZipKit::RailsStreaming` into the
32
+ `ActionController::Base` class. You will then have a `zip_kit_stream` method available which accepts a block:
28
33
 
29
34
  ```ruby
30
35
  class ZipsController < ActionController::Base
31
- include ZipKit::RailsStreaming
32
-
33
36
  def download
34
37
  zip_kit_stream do |zip|
35
38
  zip.write_file('report1.csv') do |sink|
@@ -48,6 +51,8 @@ class ZipsController < ActionController::Base
48
51
  end
49
52
  ```
50
53
 
54
+ The block receives the `ZipKit::Streamer` object you can write your files through.
55
+
51
56
  The `write_file` method will use some heuristics to determine whether your output file would benefit
52
57
  from compression, and pick the appropriate storage mode for the file accordingly.
53
58
 
@@ -0,0 +1,56 @@
1
+ # Key differences between Rubyzip and ZipKit
2
+
3
+ Please bear in mind that this is written down not to disparage [Rubyzip.](https://github.com/rubyzip/rubyzip)
4
+
5
+ Rubyzip is, by all means, a very mature, fully featured library, and while ZipKit does have overlap with it in some functionality there are
6
+ differences in supported features which may be important for you when choosing.
7
+
8
+ ## What ZipKit supports and Rubyzip does not
9
+
10
+ * ZipKit outputs archives in a streaming fashion, using data descriptors.
11
+ This allows output of archives of very large size, without buffering.
12
+ Rubyzip will seek in the already written archive to overwrite the local entry after the write of every file into the output ZIP.
13
+ At the moment, it is difficult to build a streaming Rubyzip solution due to the output of extra field placeholders.
14
+ * ZipKit supports block-deflate which allows for distributed compression of files
15
+ * ZipKit reads files from the central directory, which allows for very rapid reading. Reading works well with data descriptors
16
+ and Zip64, and is economical enough to enable "remote uncapping" where pieces of a ZIP file get read over HTTP to reconstruct
17
+ the archive structure. Actual reading can then be done on a per-entry basis. Rubyzip reads entry data from local entries, which
18
+ is error prone and much less economical than using the central directory
19
+ * ZipKit deliberately _does not_ allow you to crawl directories to add to an archive, as this has been used for security exploits
20
+ in Rubyzip.
21
+ * ZipKit deliberately _does not_ allow you to extract a ZIP archive directly to the filesystem, as this has been used for security
22
+ exploits in Rubyzip.
23
+ * When writing, ZipKit applies careful buffering to speed up CRC32 calculations. Rubyzip combines CRC32 values at every write, which
24
+ can be slow if there are many small writes.
25
+ * ZipKit comes with a Rails helper and a Rack-compatible response body for facilitating streaming. Rubyzip has no Rails integration
26
+ and no Rack integration.
27
+ * ZipKit allows you to estimate the exact size of an archive ahead of time
28
+ * ZipKit has a heuristic module which picks the storage mode (stored or deflated) depending on how well your input compresses
29
+ * ZipKit requires components using autoloading, which means that your application will likely boot faster as you will almost never
30
+ need all of the features in one codebase. Rubyzip requires its components eagerly.
31
+ * ZipKit comes with exhaustive YARD documentation and `.rbi` typedefs for [Sorbet/Tapioca](https://sorbet.org/blog/2022/07/27/srb-tapioca)
32
+
33
+ ## What Rubyzip supports and ZipKit does not
34
+
35
+ * Rubyzip allows limited manipulation of existing ZIP files by overwriting the archive entries
36
+ * Rubyzip supports "classic" ZIP encryption - both for reading and writing. ZipKit has no encryption support.
37
+ * Rubyzip allows extraction into a directory, ZipKit avoids implementing this for security reasons
38
+ * Rubyzip allows archiving a directory, ZipKit avoids implementing this for security reasons
39
+ * Rubyzip supports separate atime and ctime in the `UniversalTime` extra fields. ZipKit outputs just one timestamp
40
+ * Rubyzip attempts to faithfully replicate UNIX permissions on the files being output. ZipKit does not attempt that
41
+ because it turned out that these permissions can break unarchiving of folders on macOS.
42
+
43
+ ## Where there is currently feature parity
44
+
45
+ These used to be different, but Rubyzip has made great progress in addressing.
46
+
47
+ * ZipKit automatically applies the EFS flag for Unicode filenames in the archive. This used to be optional in RubyZip
48
+ * ZipKit automatically enables Zip64 and does so only when necessary. applies the EFS flag for Unicode filenames in the archive. This used to be optional in RubyZip.
49
+ * ZipKit outputs the `UT` precise time extra field
50
+ * ZipKit used to be distributed under the MIT-Hippocratic license which is much more restrictive than the Rubyzip BSD-2-Clause. ZipKit is now MIT-licensed.
51
+
52
+ ## Code style differences
53
+
54
+ Rubyzip is written in a somewhat Java-like style, with a lot of encapsulation and data hiding. ZipKit aims to be more approachable and have "less" of everything.
55
+ Less modules, less classes, less OOP - just enough to be useful. But that is a matter of taste, and as such should not matter to you all that much
56
+ when picking one over the other. Or it might, you never know ;-)
data/Rakefile CHANGED
@@ -11,11 +11,7 @@ task :format do
11
11
  `bundle exec magic_frozen_string_literal ./lib`
12
12
  end
13
13
 
14
- YARD::Rake::YardocTask.new(:doc) do |t|
15
- # The dash has to be between the two to "divide" the source files and
16
- # miscellaneous documentation files that contain no code
17
- t.files = ["lib/**/*.rb", "-", "LICENSE.txt", "IMPLEMENTATION_DETAILS.md"]
18
- end
14
+ YARD::Rake::YardocTask.new(:doc)
19
15
  RSpec::Core::RakeTask.new(:spec)
20
16
 
21
17
  task :generate_typedefs do
@@ -3,8 +3,7 @@
3
3
  # Should be included into a Rails controller for easy ZIP output from any action.
4
4
  module ZipKit::RailsStreaming
5
5
  # Opens a {ZipKit::Streamer} and yields it to the caller. The output of the streamer
6
- # gets automatically forwarded to the Rails response stream. When the output completes,
7
- # the Rails response stream is going to be closed automatically.
6
+ # will be sent through to the HTTP response body as it gets produced.
8
7
  #
9
8
  # Note that there is an important difference in how this method works, depending whether
10
9
  # you use it in a controller which includes `ActionController::Live` vs. one that does not.
@@ -25,7 +24,7 @@ module ZipKit::RailsStreaming
25
24
  # @param use_chunked_transfer_encoding[Boolean] whether to forcibly encode output as chunked. Normally you should not need this.
26
25
  # @param output_enumerator_options[Hash] options that will be passed to the OutputEnumerator - these include
27
26
  # options for the Streamer. See {ZipKit::OutputEnumerator#initialize} for the full list of options.
28
- # @yieldparam [ZipKit::Streamer] the streamer that can be written to
27
+ # @yieldparam [ZipKit::Streamer] zip the {ZipKit::Streamer} that can be written to
29
28
  # @return [Boolean] always returns true
30
29
  def zip_kit_stream(filename: "download.zip", type: "application/zip", use_chunked_transfer_encoding: false, **output_enumerator_options, &zip_streaming_blk)
31
30
  # We want some common headers for file sending. Rails will also set
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ZipKit::Railtie < ::Rails::Railtie
4
+ initializer "zip_kit.install_extensions" do |app|
5
+ ActionController::Base.include(ZipKit::RailsStreaming)
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ZipKit
4
- VERSION = "6.2.2"
4
+ VERSION = "6.3.0"
5
5
  end
data/lib/zip_kit.rb CHANGED
@@ -24,4 +24,6 @@ module ZipKit
24
24
  autoload :WriteShovel, File.dirname(__FILE__) + "/zip_kit/write_shovel.rb"
25
25
  autoload :RackChunkedBody, File.dirname(__FILE__) + "/zip_kit/rack_chunked_body.rb"
26
26
  autoload :RackTempfileBody, File.dirname(__FILE__) + "/zip_kit/rack_tempfile_body.rb"
27
+
28
+ require_relative "zip_kit/railtie" if defined?(::Rails)
27
29
  end
data/rbi/zip_kit.rbi CHANGED
@@ -1,6 +1,9 @@
1
1
  # typed: strong
2
2
  module ZipKit
3
- VERSION = T.let("6.2.2", T.untyped)
3
+ VERSION = T.let("6.3.0", T.untyped)
4
+
5
+ class Railtie < Rails::Railtie
6
+ end
4
7
 
5
8
  # A ZIP archive contains a flat list of entries. These entries can implicitly
6
9
  # create directories when the archive is expanded. For example, an entry with
@@ -1976,8 +1979,7 @@ end, T.untyped)
1976
1979
  # Should be included into a Rails controller for easy ZIP output from any action.
1977
1980
  module RailsStreaming
1978
1981
  # Opens a {ZipKit::Streamer} and yields it to the caller. The output of the streamer
1979
- # gets automatically forwarded to the Rails response stream. When the output completes,
1980
- # the Rails response stream is going to be closed automatically.
1982
+ # will be sent through to the HTTP response body as it gets produced.
1981
1983
  #
1982
1984
  # Note that there is an important difference in how this method works, depending whether
1983
1985
  # you use it in a controller which includes `ActionController::Live` vs. one that does not.
@@ -2008,7 +2010,7 @@ end, T.untyped)
2008
2010
  type: String,
2009
2011
  use_chunked_transfer_encoding: T::Boolean,
2010
2012
  output_enumerator_options: T::Hash[T.untyped, T.untyped],
2011
- zip_streaming_blk: T.proc.params(the: ZipKit::Streamer).void
2013
+ zip_streaming_blk: T.proc.params(zip: ZipKit::Streamer).void
2012
2014
  ).returns(T::Boolean)
2013
2015
  end
2014
2016
  def zip_kit_stream(filename: "download.zip", type: "application/zip", use_chunked_transfer_encoding: false, **output_enumerator_options, &zip_streaming_blk); end
data/zip_kit.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  # zip_kit does not use any runtime dependencies (besides zlib). However, for testing
28
28
  # things quite a few things are used - and for a good reason.
29
29
 
30
- spec.add_development_dependency "rubyzip", "~> 1" # We test our output with _another_ ZIP library, which is the way to go here
30
+ spec.add_development_dependency "rubyzip", "~> 2" # We test our output with _another_ ZIP library, which is the way to go here
31
31
  spec.add_development_dependency "rack" # For tests where we spin up a server. Both for streaming out and for testing reads over HTTP
32
32
  spec.add_development_dependency "rake", "~> 12.2"
33
33
  spec.add_development_dependency "rspec", "~> 3"
@@ -40,6 +40,7 @@ Gem::Specification.new do |spec|
40
40
  spec.add_development_dependency "standard", "1.28.5" # Very specific version of standard for 2.6 with _known_ settings
41
41
  spec.add_development_dependency "magic_frozen_string_literal"
42
42
  spec.add_development_dependency "puma"
43
+ spec.add_development_dependency "rails", "~> 5" # For testing RailsStreaming against an actual Rails controller
43
44
  spec.add_development_dependency "actionpack", "~> 5" # For testing RailsStreaming against an actual Rails controller
44
45
  spec.add_development_dependency "nokogiri", "~> 1", ">= 1.13" # Rails 5 does by mistake use an older Nokogiri otherwise
45
46
  spec.add_development_dependency "sinatra"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zip_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.2.2
4
+ version: 6.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: exe
14
14
  cert_chain: []
15
- date: 2024-03-27 00:00:00.000000000 Z
15
+ date: 2024-04-01 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bundler
@@ -34,14 +34,14 @@ dependencies:
34
34
  requirements:
35
35
  - - "~>"
36
36
  - !ruby/object:Gem::Version
37
- version: '1'
37
+ version: '2'
38
38
  type: :development
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
42
  - - "~>"
43
43
  - !ruby/object:Gem::Version
44
- version: '1'
44
+ version: '2'
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: rack
47
47
  requirement: !ruby/object:Gem::Requirement
@@ -216,6 +216,20 @@ dependencies:
216
216
  - - ">="
217
217
  - !ruby/object:Gem::Version
218
218
  version: '0'
219
+ - !ruby/object:Gem::Dependency
220
+ name: rails
221
+ requirement: !ruby/object:Gem::Requirement
222
+ requirements:
223
+ - - "~>"
224
+ - !ruby/object:Gem::Version
225
+ version: '5'
226
+ type: :development
227
+ prerelease: false
228
+ version_requirements: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - "~>"
231
+ - !ruby/object:Gem::Version
232
+ version: '5'
219
233
  - !ruby/object:Gem::Dependency
220
234
  name: actionpack
221
235
  requirement: !ruby/object:Gem::Requirement
@@ -298,6 +312,7 @@ files:
298
312
  - IMPLEMENTATION_DETAILS.md
299
313
  - LICENSE.txt
300
314
  - README.md
315
+ - RUBYZIP_DIFFERENCES.md
301
316
  - Rakefile
302
317
  - bench/buffered_crc32_bench.rb
303
318
  - examples/archive_size_estimate.rb
@@ -319,6 +334,7 @@ files:
319
334
  - lib/zip_kit/rack_chunked_body.rb
320
335
  - lib/zip_kit/rack_tempfile_body.rb
321
336
  - lib/zip_kit/rails_streaming.rb
337
+ - lib/zip_kit/railtie.rb
322
338
  - lib/zip_kit/remote_io.rb
323
339
  - lib/zip_kit/remote_uncap.rb
324
340
  - lib/zip_kit/size_estimator.rb
@@ -358,7 +374,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
358
374
  - !ruby/object:Gem::Version
359
375
  version: '0'
360
376
  requirements: []
361
- rubygems_version: 3.1.6
377
+ rubygems_version: 3.0.3
362
378
  signing_key:
363
379
  specification_version: 4
364
380
  summary: Stream out ZIP files from Ruby. Successor to zip_tricks.