zip_tricks 5.5.0 → 5.6.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 +4 -4
- data/.github/workflows/ci.yml +96 -0
- data/.gitignore +2 -1
- data/CHANGELOG.md +4 -0
- data/CONTRIBUTING.md +4 -4
- data/README.md +2 -2
- data/lib/zip_tricks/rails_streaming.rb +1 -2
- data/lib/zip_tricks/streamer.rb +23 -10
- data/lib/zip_tricks/streamer/entry.rb +1 -1
- data/lib/zip_tricks/version.rb +1 -1
- data/lib/zip_tricks/zip_writer.rb +21 -21
- data/zip_tricks.gemspec +2 -4
- metadata +7 -34
- data/.travis.yml +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39403ce8cb20b4f772e5f44420b91be7e120df38b99de7de2a0db46f318760a8
|
4
|
+
data.tar.gz: c1c02357d9e5f322daf6d3ce338092020e753e362b3a70b3caf8d35a782925e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b16f5a53ee31ea9f1f5ec1316a62d172c897c510df9f1bb9f7fabe12aafe89e2b4e43f1533a01b5507b9d1a0fe438ee3646c7c10eb1117f8053403796167aad
|
7
|
+
data.tar.gz: 3808c09040d549644cb7aba6e8eb4aa0fcbae2123753e406d86db683e4e8d332453112622303be0b8027cff4c43dc60e6678073eb3e7c80cac3359200379210f
|
@@ -0,0 +1,96 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
- push
|
5
|
+
- pull_request
|
6
|
+
|
7
|
+
env:
|
8
|
+
BUNDLE_PATH: vendor/bundle
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
lint:
|
12
|
+
name: Code Style
|
13
|
+
runs-on: ubuntu-18.04
|
14
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
15
|
+
strategy:
|
16
|
+
matrix:
|
17
|
+
ruby:
|
18
|
+
- '2.7'
|
19
|
+
steps:
|
20
|
+
- name: Checkout
|
21
|
+
uses: actions/checkout@v2
|
22
|
+
- name: Setup Ruby
|
23
|
+
uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
26
|
+
- name: Gemfile Cache
|
27
|
+
uses: actions/cache@v2
|
28
|
+
with:
|
29
|
+
path: Gemfile.lock
|
30
|
+
key: ${{ runner.os }}-gemlock-${{ matrix.ruby }}-${{ hashFiles('Gemfile', 'zip_tricks.gemspec') }}
|
31
|
+
restore-keys: |
|
32
|
+
${{ runner.os }}-gemlock-${{ matrix.ruby }}-
|
33
|
+
- name: Bundle Cache
|
34
|
+
id: cache-gems
|
35
|
+
uses: actions/cache@v2
|
36
|
+
with:
|
37
|
+
path: vendor/bundle
|
38
|
+
key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ hashFiles('Gemfile', 'Gemfile.lock', 'zip_tricks.gemspec') }}
|
39
|
+
restore-keys: |
|
40
|
+
${{ runner.os }}-gems-${{ matrix.ruby }}-
|
41
|
+
${{ runner.os }}-gems-
|
42
|
+
- name: Bundle Install
|
43
|
+
if: steps.cache-gems.outputs.cache-hit != 'true'
|
44
|
+
run: bundle install --jobs 4 --retry 3
|
45
|
+
- name: Rubocop Cache
|
46
|
+
uses: actions/cache@v2
|
47
|
+
with:
|
48
|
+
path: ~/.cache/rubocop_cache
|
49
|
+
key: ${{ runner.os }}-rubocop-${{ hashFiles('.rubocop.yml') }}
|
50
|
+
restore-keys: |
|
51
|
+
${{ runner.os }}-rubocop-
|
52
|
+
- name: Rubocop
|
53
|
+
run: bundle exec rubocop
|
54
|
+
test:
|
55
|
+
name: Specs
|
56
|
+
runs-on: ubuntu-18.04
|
57
|
+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
58
|
+
strategy:
|
59
|
+
matrix:
|
60
|
+
ruby:
|
61
|
+
- '2.7'
|
62
|
+
- '2.1'
|
63
|
+
- 'jruby-9.2'
|
64
|
+
experimental: [false]
|
65
|
+
include:
|
66
|
+
- ruby: 3.0
|
67
|
+
experimental: true
|
68
|
+
steps:
|
69
|
+
- name: Checkout
|
70
|
+
uses: actions/checkout@v2
|
71
|
+
- name: Setup Ruby
|
72
|
+
uses: ruby/setup-ruby@v1
|
73
|
+
with:
|
74
|
+
ruby-version: ${{ matrix.ruby }}
|
75
|
+
- name: Gemfile Cache
|
76
|
+
uses: actions/cache@v2
|
77
|
+
with:
|
78
|
+
path: Gemfile.lock
|
79
|
+
key: ${{ runner.os }}-gemlock-${{ matrix.ruby }}-${{ hashFiles('Gemfile', 'zip_tricks.gemspec') }}
|
80
|
+
restore-keys: |
|
81
|
+
${{ runner.os }}-gemlock-${{ matrix.ruby }}-
|
82
|
+
- name: Bundle Cache
|
83
|
+
id: cache-gems
|
84
|
+
uses: actions/cache@v2
|
85
|
+
with:
|
86
|
+
path: vendor/bundle
|
87
|
+
key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ hashFiles('Gemfile', 'Gemfile.lock', 'zip_tricks.gemspec') }}
|
88
|
+
restore-keys: |
|
89
|
+
${{ runner.os }}-gems-${{ matrix.ruby }}-
|
90
|
+
${{ runner.os }}-gems-
|
91
|
+
- name: Bundle Install
|
92
|
+
if: steps.cache-gems.outputs.cache-hit != 'true'
|
93
|
+
run: bundle install --jobs 4 --retry 3
|
94
|
+
- name: RSpec
|
95
|
+
continue-on-error: ${{ matrix.experimental }}
|
96
|
+
run: bundle exec rspec
|
data/.gitignore
CHANGED
@@ -19,7 +19,7 @@ Gemfile.lock
|
|
19
19
|
# jeweler generated
|
20
20
|
pkg
|
21
21
|
|
22
|
-
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
22
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
23
23
|
#
|
24
24
|
# * Create a file at ~/.gitignore
|
25
25
|
# * Include files you want ignored
|
@@ -36,6 +36,7 @@ pkg
|
|
36
36
|
|
37
37
|
tmp
|
38
38
|
testing/*.zip
|
39
|
+
.ruby-version
|
39
40
|
|
40
41
|
# For TextMate
|
41
42
|
#*.tmproj
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 5.6.0
|
2
|
+
|
3
|
+
* Add customisable `unix_permissions` to Streamer and ZipWriter. Beware that customising these permissions can lead to the archive failing to expand with some unarchiving applications, and is especially sensitive for directories.
|
4
|
+
|
1
5
|
## 5.5.0
|
2
6
|
|
3
7
|
* In `OutputEnumerator` apply some amount of buffering to be within a UNIX socket size for metatada writes. This
|
data/CONTRIBUTING.md
CHANGED
@@ -27,7 +27,7 @@ The issue tracker is the preferred channel for [bug reports](#bug-reports),
|
|
27
27
|
[feature requests](#feature-requests) and [submitting pull
|
28
28
|
requests](#pull-requests), but please respect the following restrictions:
|
29
29
|
|
30
|
-
* Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. Adhere to the principles set out in the [Code of Conduct](https://github.com/WeTransfer/zip_tricks/blob/
|
30
|
+
* Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. Adhere to the principles set out in the [Code of Conduct](https://github.com/WeTransfer/zip_tricks/blob/main/CODE_OF_CONDUCT.md).
|
31
31
|
|
32
32
|
## Bug reports
|
33
33
|
|
@@ -41,7 +41,7 @@ Guidelines for bug reports:
|
|
41
41
|
reported.
|
42
42
|
|
43
43
|
2. **Check if the issue has been fixed** — try to reproduce it using the
|
44
|
-
latest `
|
44
|
+
latest `main` branch in the repository.
|
45
45
|
|
46
46
|
3. **Isolate the problem** — create a [reduced test
|
47
47
|
case](http://css-tricks.com/reduced-test-cases/) and a live example.
|
@@ -96,7 +96,7 @@ accurate comments, etc.) and any other requirements (such as test coverage).
|
|
96
96
|
The project uses Rubocop which can be run using `bundle exec rubocop`. The test
|
97
97
|
suite can be run with `bundle exec rspec`. You are also encouraged to use the
|
98
98
|
script in the `testing` directory to create test files that you can then verify
|
99
|
-
with various zip/unzip utilities. Further instructions are [here](https://github.com/WeTransfer/zip_tricks/blob/
|
99
|
+
with various zip/unzip utilities. Further instructions are [here](https://github.com/WeTransfer/zip_tricks/blob/main/testing/README_TESTING.md).
|
100
100
|
|
101
101
|
Follow this process if you'd like your work considered for inclusion in the
|
102
102
|
project:
|
@@ -148,4 +148,4 @@ project:
|
|
148
148
|
|
149
149
|
**IMPORTANT**: By submitting a patch, you agree to allow the project owner to
|
150
150
|
license your work under the same license as that used by the project, which you
|
151
|
-
can see by clicking [here](https://github.com/WeTransfer/zip_tricks/blob/
|
151
|
+
can see by clicking [here](https://github.com/WeTransfer/zip_tricks/blob/main/LICENSE.txt).
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# zip_tricks
|
2
2
|
|
3
|
-
[](https://travis-ci.org/WeTransfer/zip_tricks)
|
4
4
|
[](https://badge.fury.io/rb/zip_tricks)
|
5
5
|
|
6
6
|
Allows streaming, non-rewinding ZIP file output from Ruby.
|
@@ -175,7 +175,7 @@ that have not been formally verified (ours hasn't been).
|
|
175
175
|
|
176
176
|
## Contributing to zip_tricks
|
177
177
|
|
178
|
-
* Check out the latest
|
178
|
+
* Check out the latest `main` to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
179
179
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
180
180
|
* Fork the project.
|
181
181
|
* Start a feature/bugfix branch.
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Should be included into a Rails controller
|
4
|
-
# for easy ZIP output from any action.
|
3
|
+
# Should be included into a Rails controller for easy ZIP output from any action.
|
5
4
|
module ZipTricks::RailsStreaming
|
6
5
|
# Opens a {ZipTricks::Streamer} and yields it to the caller. The output of the streamer
|
7
6
|
# gets automatically forwarded to the Rails response stream. When the output completes,
|
data/lib/zip_tricks/streamer.rb
CHANGED
@@ -200,14 +200,16 @@ class ZipTricks::Streamer
|
|
200
200
|
# @param uncompressed_size [Integer] the size of the entry when uncompressed, in bytes
|
201
201
|
# @param crc32 [Integer] the CRC32 checksum of the entry when uncompressed
|
202
202
|
# @param use_data_descriptor [Boolean] whether the entry body will be followed by a data descriptor
|
203
|
+
# @param unix_permissions[Fixnum?] which UNIX permissions to set, normally the default should be used
|
203
204
|
# @return [Integer] the offset the output IO is at after writing the entry header
|
204
|
-
def add_deflated_entry(filename:, modification_time: Time.now.utc, compressed_size: 0, uncompressed_size: 0, crc32: 0, use_data_descriptor: false)
|
205
|
+
def add_deflated_entry(filename:, modification_time: Time.now.utc, compressed_size: 0, uncompressed_size: 0, crc32: 0, unix_permissions: nil, use_data_descriptor: false)
|
205
206
|
add_file_and_write_local_header(filename: filename,
|
206
207
|
modification_time: modification_time,
|
207
208
|
crc32: crc32,
|
208
209
|
storage_mode: DEFLATED,
|
209
210
|
compressed_size: compressed_size,
|
210
211
|
uncompressed_size: uncompressed_size,
|
212
|
+
unix_permissions: unix_permissions,
|
211
213
|
use_data_descriptor: use_data_descriptor)
|
212
214
|
@out.tell
|
213
215
|
end
|
@@ -222,14 +224,16 @@ class ZipTricks::Streamer
|
|
222
224
|
# @param size [Integer] the size of the file when uncompressed, in bytes
|
223
225
|
# @param crc32 [Integer] the CRC32 checksum of the entry when uncompressed
|
224
226
|
# @param use_data_descriptor [Boolean] whether the entry body will be followed by a data descriptor. When in use
|
227
|
+
# @param unix_permissions[Fixnum?] which UNIX permissions to set, normally the default should be used
|
225
228
|
# @return [Integer] the offset the output IO is at after writing the entry header
|
226
|
-
def add_stored_entry(filename:, modification_time: Time.now.utc, size: 0, crc32: 0, use_data_descriptor: false)
|
229
|
+
def add_stored_entry(filename:, modification_time: Time.now.utc, size: 0, crc32: 0, unix_permissions: nil, use_data_descriptor: false)
|
227
230
|
add_file_and_write_local_header(filename: filename,
|
228
231
|
modification_time: modification_time,
|
229
232
|
crc32: crc32,
|
230
233
|
storage_mode: STORED,
|
231
234
|
compressed_size: size,
|
232
235
|
uncompressed_size: size,
|
236
|
+
unix_permissions: unix_permissions,
|
233
237
|
use_data_descriptor: use_data_descriptor)
|
234
238
|
@out.tell
|
235
239
|
end
|
@@ -238,14 +242,16 @@ class ZipTricks::Streamer
|
|
238
242
|
#
|
239
243
|
# @param dirname [String] the name of the directory in the archive
|
240
244
|
# @param modification_time [Time] the modification time of the directory in the archive
|
245
|
+
# @param unix_permissions[Fixnum?] which UNIX permissions to set, normally the default should be used
|
241
246
|
# @return [Integer] the offset the output IO is at after writing the entry header
|
242
|
-
def add_empty_directory(dirname:, modification_time: Time.now.utc)
|
247
|
+
def add_empty_directory(dirname:, modification_time: Time.now.utc, unix_permissions: nil)
|
243
248
|
add_file_and_write_local_header(filename: dirname.to_s + '/',
|
244
249
|
modification_time: modification_time,
|
245
250
|
crc32: 0,
|
246
251
|
storage_mode: STORED,
|
247
252
|
compressed_size: 0,
|
248
253
|
uncompressed_size: 0,
|
254
|
+
unix_permissions: unix_permissions,
|
249
255
|
use_data_descriptor: false)
|
250
256
|
@out.tell
|
251
257
|
end
|
@@ -283,14 +289,16 @@ class ZipTricks::Streamer
|
|
283
289
|
#
|
284
290
|
# @param filename[String] the name of the file in the archive
|
285
291
|
# @param modification_time [Time] the modification time of the file in the archive
|
292
|
+
# @param unix_permissions[Fixnum?] which UNIX permissions to set, normally the default should be used
|
286
293
|
# @yield [#<<, #write] an object that the file contents must be written to that will be automatically closed
|
287
294
|
# @return [#<<, #write, #close] an object that the file contents must be written to, has to be closed manually
|
288
|
-
def write_stored_file(filename, modification_time: Time.now.utc)
|
295
|
+
def write_stored_file(filename, modification_time: Time.now.utc, unix_permissions: nil)
|
289
296
|
add_stored_entry(filename: filename,
|
290
297
|
modification_time: modification_time,
|
291
298
|
use_data_descriptor: true,
|
292
299
|
crc32: 0,
|
293
|
-
size: 0
|
300
|
+
size: 0,
|
301
|
+
unix_permissions: unix_permissions)
|
294
302
|
|
295
303
|
writable = Writable.new(self, StoredWriter.new(@out))
|
296
304
|
if block_given?
|
@@ -335,14 +343,16 @@ class ZipTricks::Streamer
|
|
335
343
|
#
|
336
344
|
# @param filename[String] the name of the file in the archive
|
337
345
|
# @param modification_time [Time] the modification time of the file in the archive
|
346
|
+
# @param unix_permissions[Fixnum?] which UNIX permissions to set, normally the default should be used
|
338
347
|
# @yield [#<<, #write] an object that the file contents must be written to
|
339
|
-
def write_deflated_file(filename, modification_time: Time.now.utc)
|
348
|
+
def write_deflated_file(filename, modification_time: Time.now.utc, unix_permissions: nil)
|
340
349
|
add_deflated_entry(filename: filename,
|
341
350
|
modification_time: modification_time,
|
342
351
|
use_data_descriptor: true,
|
343
352
|
crc32: 0,
|
344
353
|
compressed_size: 0,
|
345
|
-
uncompressed_size: 0
|
354
|
+
uncompressed_size: 0,
|
355
|
+
unix_permissions: unix_permissions)
|
346
356
|
|
347
357
|
writable = Writable.new(self, DeflatedWriter.new(@out))
|
348
358
|
if block_given?
|
@@ -375,7 +385,8 @@ class ZipTricks::Streamer
|
|
375
385
|
uncompressed_size: entry.uncompressed_size,
|
376
386
|
mtime: entry.mtime,
|
377
387
|
crc32: entry.crc32,
|
378
|
-
filename: entry.filename
|
388
|
+
filename: entry.filename,
|
389
|
+
unix_permissions: entry.unix_permissions)
|
379
390
|
end
|
380
391
|
|
381
392
|
# Record the central directory size, for the EOCDR
|
@@ -462,7 +473,8 @@ EMS
|
|
462
473
|
storage_mode:,
|
463
474
|
compressed_size:,
|
464
475
|
uncompressed_size:,
|
465
|
-
use_data_descriptor
|
476
|
+
use_data_descriptor:,
|
477
|
+
unix_permissions:)
|
466
478
|
|
467
479
|
# Clean backslashes
|
468
480
|
filename = remove_backslash(filename)
|
@@ -498,7 +510,8 @@ EMS
|
|
498
510
|
use_data_descriptor,
|
499
511
|
_local_file_header_offset = local_header_starts_at,
|
500
512
|
_bytes_used_for_local_header = 0,
|
501
|
-
_bytes_used_for_data_descriptor = 0
|
513
|
+
_bytes_used_for_data_descriptor = 0,
|
514
|
+
unix_permissions)
|
502
515
|
|
503
516
|
@writer.write_local_file_header(io: @out,
|
504
517
|
gp_flags: e.gp_flags,
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# Normally you will not have to use this class directly
|
5
5
|
class ZipTricks::Streamer::Entry < Struct.new(:filename, :crc32, :compressed_size,
|
6
6
|
:uncompressed_size, :storage_mode, :mtime,
|
7
|
-
:use_data_descriptor, :local_header_offset, :bytes_used_for_local_header, :bytes_used_for_data_descriptor)
|
7
|
+
:use_data_descriptor, :local_header_offset, :bytes_used_for_local_header, :bytes_used_for_data_descriptor, :unix_permissions)
|
8
8
|
def initialize(*)
|
9
9
|
super
|
10
10
|
filename.force_encoding(Encoding::UTF_8)
|
data/lib/zip_tricks/version.rb
CHANGED
@@ -31,22 +31,10 @@ class ZipTricks::ZipWriter
|
|
31
31
|
VERSION_MADE_BY = 52
|
32
32
|
VERSION_NEEDED_TO_EXTRACT = 20
|
33
33
|
VERSION_NEEDED_TO_EXTRACT_ZIP64 = 45
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
# zipinfo.external_attr = 0644 << 16L # permissions -r-wr--r--.
|
39
|
-
# We snatch the incantations from Rubyzip for this.
|
40
|
-
unix_perms = 0o644
|
41
|
-
file_type_file = 0o10
|
42
|
-
(file_type_file << 12 | (unix_perms & 0o7777)) << 16
|
43
|
-
end
|
44
|
-
EMPTY_DIRECTORY_EXTERNAL_ATTRS = begin
|
45
|
-
# Applies permissions to an empty directory.
|
46
|
-
unix_perms = 0o755
|
47
|
-
file_type_dir = 0o04
|
48
|
-
(file_type_dir << 12 | (unix_perms & 0o7777)) << 16
|
49
|
-
end
|
34
|
+
DEFAULT_FILE_UNIX_PERMISSIONS = 0o644
|
35
|
+
DEFAULT_DIRECTORY_UNIX_PERMISSIONS = 0o755
|
36
|
+
FILE_TYPE_FILE = 0o10
|
37
|
+
FILE_TYPE_DIRECTORY = 0o04
|
50
38
|
MADE_BY_SIGNATURE = begin
|
51
39
|
# A combination of the VERSION_MADE_BY low byte and the OS type high byte
|
52
40
|
os_type = 3 # UNIX
|
@@ -64,7 +52,8 @@ class ZipTricks::ZipWriter
|
|
64
52
|
:VERSION_MADE_BY,
|
65
53
|
:VERSION_NEEDED_TO_EXTRACT,
|
66
54
|
:VERSION_NEEDED_TO_EXTRACT_ZIP64,
|
67
|
-
:
|
55
|
+
:FILE_TYPE_FILE,
|
56
|
+
:FILE_TYPE_DIRECTORY,
|
68
57
|
:MADE_BY_SIGNATURE,
|
69
58
|
:C_UINT4,
|
70
59
|
:C_UINT2,
|
@@ -136,6 +125,7 @@ class ZipTricks::ZipWriter
|
|
136
125
|
# @param crc32[Fixnum] The CRC32 checksum of the file
|
137
126
|
# @param mtime[Time] the modification time to be recorded in the ZIP
|
138
127
|
# @param gp_flags[Fixnum] bit-packed general purpose flags
|
128
|
+
# @param unix_permissions[Fixnum?] the permissions for the file, or nil for the default to be used
|
139
129
|
# @return [void]
|
140
130
|
def write_central_directory_file_header(io:,
|
141
131
|
local_file_header_location:,
|
@@ -145,7 +135,9 @@ class ZipTricks::ZipWriter
|
|
145
135
|
uncompressed_size:,
|
146
136
|
mtime:,
|
147
137
|
crc32:,
|
148
|
-
filename
|
138
|
+
filename:,
|
139
|
+
unix_permissions: nil
|
140
|
+
)
|
149
141
|
# At this point if the header begins somewhere beyound 0xFFFFFFFF we _have_ to record the offset
|
150
142
|
# of the local file header as a zip64 extra field, so we give up, give in, you loose, love will always win...
|
151
143
|
add_zip64 = (local_file_header_location > FOUR_BYTE_MAX_UINT) ||
|
@@ -200,11 +192,15 @@ class ZipTricks::ZipWriter
|
|
200
192
|
|
201
193
|
# Because the add_empty_directory method will create a directory with a trailing "/",
|
202
194
|
# this check can be used to assign proper permissions to the created directory.
|
203
|
-
|
204
|
-
|
195
|
+
# external file attributes 4 bytes
|
196
|
+
external_attrs = if filename.end_with?('/')
|
197
|
+
unix_permissions ||= DEFAULT_DIRECTORY_UNIX_PERMISSIONS
|
198
|
+
generate_external_attrs(unix_permissions, FILE_TYPE_DIRECTORY)
|
205
199
|
else
|
206
|
-
|
200
|
+
unix_permissions ||= DEFAULT_FILE_UNIX_PERMISSIONS
|
201
|
+
generate_external_attrs(unix_permissions, FILE_TYPE_FILE)
|
207
202
|
end
|
203
|
+
io << [external_attrs].pack(C_UINT4)
|
208
204
|
|
209
205
|
io << if add_zip64 # relative offset of local header 4 bytes
|
210
206
|
[FOUR_BYTE_MAX_UINT].pack(C_UINT4)
|
@@ -434,4 +430,8 @@ class ZipTricks::ZipWriter
|
|
434
430
|
values, packspecs = values_to_packspecs.partition.each_with_index { |_, i| i.even? }
|
435
431
|
values.pack(packspecs.join)
|
436
432
|
end
|
433
|
+
|
434
|
+
def generate_external_attrs(unix_permissions_int, file_type_int)
|
435
|
+
(file_type_int << 12 | (unix_permissions_int & 0o7777)) << 16
|
436
|
+
end
|
437
437
|
end
|
data/zip_tricks.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'zip_tricks/version'
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'zip_tricks'
|
7
7
|
spec.version = ZipTricks::VERSION
|
8
|
-
spec.authors = ['Julik Tarkhanov', 'Noah Berman', 'Dmitry Tymchuk', 'David Bosveld']
|
8
|
+
spec.authors = ['Julik Tarkhanov', 'Noah Berman', 'Dmitry Tymchuk', 'David Bosveld', 'Felix Bünemann']
|
9
9
|
spec.email = ['me@julik.nl']
|
10
10
|
|
11
11
|
spec.licenses = ['MIT (Hippocratic)']
|
@@ -32,10 +32,8 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
spec.add_development_dependency 'bundler'
|
34
34
|
spec.add_development_dependency 'rubyzip', '~> 1'
|
35
|
-
spec.add_development_dependency 'terminal-table'
|
36
|
-
spec.add_development_dependency 'range_utils'
|
37
35
|
|
38
|
-
spec.add_development_dependency 'rack', '~> 1.6' # For
|
36
|
+
spec.add_development_dependency 'rack', '~> 1.6' # For tests, where we spin up a server
|
39
37
|
spec.add_development_dependency 'rake', '~> 12.2'
|
40
38
|
spec.add_development_dependency 'rspec', '~> 3'
|
41
39
|
spec.add_development_dependency 'complexity_assert'
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zip_tricks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julik Tarkhanov
|
8
8
|
- Noah Berman
|
9
9
|
- Dmitry Tymchuk
|
10
10
|
- David Bosveld
|
11
|
-
|
11
|
+
- Felix Bünemann
|
12
|
+
autorequire:
|
12
13
|
bindir: exe
|
13
14
|
cert_chain: []
|
14
|
-
date:
|
15
|
+
date: 2021-06-05 00:00:00.000000000 Z
|
15
16
|
dependencies:
|
16
17
|
- !ruby/object:Gem::Dependency
|
17
18
|
name: bundler
|
@@ -41,34 +42,6 @@ dependencies:
|
|
41
42
|
- - "~>"
|
42
43
|
- !ruby/object:Gem::Version
|
43
44
|
version: '1'
|
44
|
-
- !ruby/object:Gem::Dependency
|
45
|
-
name: terminal-table
|
46
|
-
requirement: !ruby/object:Gem::Requirement
|
47
|
-
requirements:
|
48
|
-
- - ">="
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: '0'
|
51
|
-
type: :development
|
52
|
-
prerelease: false
|
53
|
-
version_requirements: !ruby/object:Gem::Requirement
|
54
|
-
requirements:
|
55
|
-
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: '0'
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: range_utils
|
60
|
-
requirement: !ruby/object:Gem::Requirement
|
61
|
-
requirements:
|
62
|
-
- - ">="
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '0'
|
65
|
-
type: :development
|
66
|
-
prerelease: false
|
67
|
-
version_requirements: !ruby/object:Gem::Requirement
|
68
|
-
requirements:
|
69
|
-
- - ">="
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
version: '0'
|
72
45
|
- !ruby/object:Gem::Dependency
|
73
46
|
name: rack
|
74
47
|
requirement: !ruby/object:Gem::Requirement
|
@@ -218,10 +191,10 @@ extra_rdoc_files: []
|
|
218
191
|
files:
|
219
192
|
- ".codeclimate.yml"
|
220
193
|
- ".document"
|
194
|
+
- ".github/workflows/ci.yml"
|
221
195
|
- ".gitignore"
|
222
196
|
- ".rspec"
|
223
197
|
- ".rubocop.yml"
|
224
|
-
- ".travis.yml"
|
225
198
|
- ".yardopts"
|
226
199
|
- CHANGELOG.md
|
227
200
|
- CODE_OF_CONDUCT.md
|
@@ -268,7 +241,7 @@ licenses:
|
|
268
241
|
- MIT (Hippocratic)
|
269
242
|
metadata:
|
270
243
|
allowed_push_host: https://rubygems.org
|
271
|
-
post_install_message:
|
244
|
+
post_install_message:
|
272
245
|
rdoc_options: []
|
273
246
|
require_paths:
|
274
247
|
- lib
|
@@ -284,7 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
284
257
|
version: '0'
|
285
258
|
requirements: []
|
286
259
|
rubygems_version: 3.0.3
|
287
|
-
signing_key:
|
260
|
+
signing_key:
|
288
261
|
specification_version: 4
|
289
262
|
summary: Stream out ZIP files from Ruby
|
290
263
|
test_files: []
|