mini_tarball 0.2.0 → 0.3.1
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/lib/mini_tarball/header.rb +37 -4
- data/lib/mini_tarball/header_fields.rb +50 -0
- data/lib/mini_tarball/header_formatter.rb +31 -18
- data/lib/mini_tarball/header_writer.rb +7 -69
- data/lib/mini_tarball/streams/limited_size_stream.rb +28 -0
- data/lib/mini_tarball/streams/placeholder_stream.rb +17 -0
- data/lib/mini_tarball/{write_only_stream.rb → streams/write_only_stream.rb} +1 -1
- data/lib/mini_tarball/version.rb +1 -1
- data/lib/mini_tarball/writer.rb +122 -39
- data/lib/mini_tarball.rb +9 -6
- metadata +38 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 313b7544e163106d7c251eb36ace29a96c22dfe43bc198310966155c18417260
|
4
|
+
data.tar.gz: fe252395b2daa1b7a8843ff27a0f6b87d96dff09031c485c42c217ad39b9ba52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acf0381c3b1dfc12c7d3e2da19f3bf3747f3c60e4af2939718d0095fe6dbff6554bf359beaf8e2a74b2a6f44b317620eb85977360a6bce0cae88c638442b5e86
|
7
|
+
data.tar.gz: f86d7def07d9c89a5375f2428324c1b9e8f7ec2e35c57d473c35a79e42207929685410900e2e76e1e19969ac2051f3f34e9f8f2669de792c2a522a6da78e1c56
|
data/lib/mini_tarball/header.rb
CHANGED
@@ -8,7 +8,7 @@ module MiniTarball
|
|
8
8
|
TYPE_REGULAR = "0"
|
9
9
|
TYPE_LONG_LINK = "L"
|
10
10
|
|
11
|
-
#
|
11
|
+
# stree-ignore
|
12
12
|
FIELDS = {
|
13
13
|
name: { length: 100, type: :chars },
|
14
14
|
mode: { length: 8, type: :mode },
|
@@ -27,9 +27,33 @@ module MiniTarball
|
|
27
27
|
devminor: { length: 8, type: :number },
|
28
28
|
prefix: { length: 155, type: :chars }
|
29
29
|
}
|
30
|
-
# rubocop:enable Layout/HashAlignment
|
31
30
|
|
32
|
-
def
|
31
|
+
def self.long_link_header(name)
|
32
|
+
Header.new(
|
33
|
+
name: "././@LongLink",
|
34
|
+
mode: 0644,
|
35
|
+
uid: 0,
|
36
|
+
gid: 0,
|
37
|
+
size: name.bytesize + 1,
|
38
|
+
typeflag: TYPE_LONG_LINK,
|
39
|
+
uname: "root",
|
40
|
+
gname: "root",
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
# :reek:LongParameterList
|
45
|
+
def initialize(
|
46
|
+
name:,
|
47
|
+
mode: 0,
|
48
|
+
uid: nil,
|
49
|
+
gid: nil,
|
50
|
+
size: 0,
|
51
|
+
mtime: 0,
|
52
|
+
typeflag: TYPE_REGULAR,
|
53
|
+
linkname: "",
|
54
|
+
uname: nil,
|
55
|
+
gname: nil
|
56
|
+
)
|
33
57
|
@values = {
|
34
58
|
name: name,
|
35
59
|
mode: mode,
|
@@ -46,12 +70,21 @@ module MiniTarball
|
|
46
70
|
gname: gname,
|
47
71
|
devmajor: nil,
|
48
72
|
devminor: nil,
|
49
|
-
prefix: ""
|
73
|
+
prefix: "",
|
50
74
|
}
|
51
75
|
end
|
52
76
|
|
53
77
|
def value_of(key)
|
54
78
|
@values[key]
|
55
79
|
end
|
80
|
+
|
81
|
+
def to_binary
|
82
|
+
fields = HeaderFields.new(self)
|
83
|
+
fields.to_binary
|
84
|
+
end
|
85
|
+
|
86
|
+
def has_long_name?
|
87
|
+
value_of(:name).bytesize > FIELDS[:name][:length]
|
88
|
+
end
|
56
89
|
end
|
57
90
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MiniTarball
|
4
|
+
class HeaderFields
|
5
|
+
def self.pack_format
|
6
|
+
@pack_format ||= Header::FIELDS.values.map { |field| "a#{field[:length]}" }.join("")
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(header)
|
10
|
+
@header = header
|
11
|
+
@values_by_field = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_binary
|
15
|
+
Header::FIELDS.each_key do |name|
|
16
|
+
value = @header.value_of(name)
|
17
|
+
set_value(name, value)
|
18
|
+
end
|
19
|
+
|
20
|
+
update_checksum
|
21
|
+
HeaderFormatter.zero_pad(encode_fields)
|
22
|
+
end
|
23
|
+
|
24
|
+
# :reek:DuplicateMethodCall
|
25
|
+
def set_value(name, value)
|
26
|
+
field = Header::FIELDS[name]
|
27
|
+
|
28
|
+
case field[:type]
|
29
|
+
when :number
|
30
|
+
@values_by_field[name] = HeaderFormatter.format_number(value, field[:length])
|
31
|
+
when :mode
|
32
|
+
@values_by_field[name] = HeaderFormatter.format_permissions(value, field[:length])
|
33
|
+
when :checksum
|
34
|
+
@values_by_field[name] = HeaderFormatter.format_checksum(value)
|
35
|
+
else
|
36
|
+
@values_by_field[name] = value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_checksum
|
41
|
+
checksum = encode_fields.unpack("C*").sum
|
42
|
+
set_value(:checksum, checksum)
|
43
|
+
end
|
44
|
+
|
45
|
+
private def encode_fields
|
46
|
+
values = @values_by_field.values
|
47
|
+
values.pack(HeaderFields.pack_format)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -3,30 +3,50 @@
|
|
3
3
|
module MiniTarball
|
4
4
|
ValueTooLargeError = Class.new(StandardError)
|
5
5
|
|
6
|
-
|
6
|
+
module HeaderFormatter
|
7
7
|
PERMISSION_BITMASK = 0007777
|
8
8
|
|
9
9
|
# @param value [Integer]
|
10
10
|
# @param length [Integer]
|
11
11
|
def self.format_number(value, length)
|
12
|
-
return nil if value
|
12
|
+
return nil if !value
|
13
13
|
raise NotImplementedError.new("Negative numbers are not supported") if value.negative?
|
14
14
|
|
15
|
+
fits_into_octal?(value, length) ? to_octal(value, length) : to_base256(value, length)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Removes file type bitfields and returns file permissions as formatted number
|
19
|
+
# @param value [Integer]
|
20
|
+
# @param length [Integer]
|
21
|
+
def self.format_permissions(value, length)
|
22
|
+
format_number(value & PERMISSION_BITMASK, length)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.format_checksum(checksum)
|
26
|
+
length = Header::FIELDS[:checksum][:length]
|
27
|
+
|
28
|
+
checksum ? format_number(checksum, length - 1) << "\0 " : " " * length
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.zero_pad(binary)
|
32
|
+
padding_length = (Header::BLOCK_SIZE - binary.length) % Header::BLOCK_SIZE
|
33
|
+
binary << "\0" * padding_length
|
34
|
+
end
|
35
|
+
|
36
|
+
private_class_method def self.fits_into_octal?(value, length)
|
15
37
|
octal_length = length - 1
|
16
38
|
max_octal_value = ("0" + "7" * octal_length).to_i(8)
|
17
|
-
|
18
|
-
if (value <= max_octal_value)
|
19
|
-
to_octal(value, octal_length)
|
20
|
-
else
|
21
|
-
to_base256(value, length)
|
22
|
-
end
|
39
|
+
value <= max_octal_value
|
23
40
|
end
|
24
41
|
|
25
|
-
def self.to_octal(value, length)
|
26
|
-
|
42
|
+
private_class_method def self.to_octal(value, length)
|
43
|
+
octal_length = length - 1
|
44
|
+
"%0#{octal_length}o" % value
|
27
45
|
end
|
28
46
|
|
29
|
-
|
47
|
+
# :reek:TooManyStatements { max_statements: 8}
|
48
|
+
# :reek:UncommunicativeMethodName
|
49
|
+
private_class_method def self.to_base256(value, length)
|
30
50
|
encoded = Array.new(length, 0)
|
31
51
|
encoded[0] = 0x80
|
32
52
|
index = length - 1
|
@@ -40,12 +60,5 @@ module MiniTarball
|
|
40
60
|
|
41
61
|
encoded.pack("C#{length}")
|
42
62
|
end
|
43
|
-
|
44
|
-
# Removes file type bitfields and returns file permissions as formatted number
|
45
|
-
# @param value [Integer]
|
46
|
-
# @param length [Integer]
|
47
|
-
def self.format_permissions(value, length)
|
48
|
-
format_number(value & PERMISSION_BITMASK, length)
|
49
|
-
end
|
50
63
|
end
|
51
64
|
end
|
@@ -7,79 +7,17 @@ module MiniTarball
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def write(header)
|
10
|
-
write_long_name_header(header) if has_long_name?
|
11
|
-
@io.write(to_binary
|
10
|
+
write_long_name_header(header) if header.has_long_name?
|
11
|
+
@io.write(header.to_binary)
|
12
12
|
end
|
13
13
|
|
14
|
-
private
|
15
|
-
|
16
|
-
def to_binary(header)
|
17
|
-
values_by_field = {}
|
18
|
-
|
19
|
-
Header::FIELDS.each do |name, field|
|
20
|
-
value = values_by_field[name] = header.value_of(name)
|
21
|
-
|
22
|
-
case field[:type]
|
23
|
-
when :number
|
24
|
-
values_by_field[name] = HeaderFormatter.format_number(value, field[:length])
|
25
|
-
when :mode
|
26
|
-
values_by_field[name] = HeaderFormatter.format_permissions(value, field[:length])
|
27
|
-
when :checksum
|
28
|
-
values_by_field[name] = " " * field[:length]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
update_checksum(values_by_field)
|
33
|
-
add_padding(encode(values_by_field.values))
|
34
|
-
end
|
35
|
-
|
36
|
-
def update_checksum(values_by_field)
|
37
|
-
checksum = encode(values_by_field.values).unpack("C*").sum
|
38
|
-
values_by_field[:checksum] = format_checksum(checksum)
|
39
|
-
end
|
40
|
-
|
41
|
-
def format_checksum(checksum)
|
42
|
-
length = Header::FIELDS[:checksum][:length] - 1
|
43
|
-
HeaderFormatter.format_number(checksum, length) << "\0 "
|
44
|
-
end
|
45
|
-
|
46
|
-
def encode(values)
|
47
|
-
@pack_format ||= Header::FIELDS.values
|
48
|
-
.map { |field| "a#{field[:length]}" }
|
49
|
-
.join("")
|
50
|
-
|
51
|
-
values.pack(@pack_format)
|
52
|
-
end
|
53
|
-
|
54
|
-
def add_padding(binary)
|
55
|
-
padding_length = (Header::BLOCK_SIZE - binary.length) % Header::BLOCK_SIZE
|
56
|
-
binary << "\0" * padding_length
|
57
|
-
end
|
58
|
-
|
59
|
-
def has_long_name?(header)
|
60
|
-
header.value_of(:name).bytesize > Header::FIELDS[:name][:length]
|
61
|
-
end
|
62
|
-
|
63
|
-
def write_long_name_header(header)
|
14
|
+
private def write_long_name_header(header)
|
64
15
|
name = header.value_of(:name)
|
65
|
-
private_header = long_link_header(name
|
66
|
-
|
67
|
-
|
68
|
-
@io.write(to_binary(private_header))
|
69
|
-
@io.write(add_padding(data))
|
70
|
-
end
|
16
|
+
private_header = Header.long_link_header(name)
|
17
|
+
binary_data = [name].pack("Z*")
|
71
18
|
|
72
|
-
|
73
|
-
|
74
|
-
name: "././@LongLink",
|
75
|
-
mode: 0644,
|
76
|
-
uid: 0,
|
77
|
-
gid: 0,
|
78
|
-
size: name.bytesize + 1,
|
79
|
-
typeflag: type,
|
80
|
-
uname: "root",
|
81
|
-
gname: "root"
|
82
|
-
)
|
19
|
+
@io.write(private_header.to_binary)
|
20
|
+
@io.write(HeaderFormatter.zero_pad(binary_data))
|
83
21
|
end
|
84
22
|
end
|
85
23
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MiniTarball
|
4
|
+
class WriteOutOfRangeError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class LimitedSizeStream
|
8
|
+
attr_reader :start_position, :end_position
|
9
|
+
attr_reader :io
|
10
|
+
private :io # TODO change to `private attr_reader :io` after dropping support for Ruby 2.7
|
11
|
+
|
12
|
+
def initialize(io, start_position:, max_file_size:)
|
13
|
+
@io = io
|
14
|
+
@start_position = start_position
|
15
|
+
@end_position = start_position + max_file_size
|
16
|
+
end
|
17
|
+
|
18
|
+
def write(data)
|
19
|
+
current_position = io.pos
|
20
|
+
|
21
|
+
if current_position < start_position || current_position + data.bytesize > end_position
|
22
|
+
raise WriteOutOfRangeError.new("Writing outside of limits not allowed")
|
23
|
+
end
|
24
|
+
|
25
|
+
io.write(data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MiniTarball
|
4
|
+
class PlaceholderStream < LimitedSizeStream
|
5
|
+
def initialize(io, start_position:, file_size:)
|
6
|
+
super(io, start_position: start_position, max_file_size: file_size)
|
7
|
+
end
|
8
|
+
|
9
|
+
def write(data)
|
10
|
+
super(data)
|
11
|
+
|
12
|
+
if (current_position = io.pos) <= end_position
|
13
|
+
io.write("\0" * (end_position - current_position))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/mini_tarball/version.rb
CHANGED
data/lib/mini_tarball/writer.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "etc"
|
4
4
|
|
5
5
|
module MiniTarball
|
6
|
+
class NoIOLikeObjectError < StandardError
|
7
|
+
end
|
8
|
+
|
6
9
|
class Writer
|
7
10
|
END_OF_TAR_BLOCK_SIZE = 1024
|
8
11
|
|
9
12
|
# @param [String] filename
|
10
13
|
# @yieldparam [Writer]
|
14
|
+
#
|
15
|
+
# :reek:NestedIterators
|
11
16
|
def self.create(filename)
|
12
|
-
File.open(filename, "wb")
|
13
|
-
use(file) { |writer| yield(writer) }
|
14
|
-
end
|
17
|
+
File.open(filename, "wb") { |file| use(file) { |writer| yield(writer) } }
|
15
18
|
end
|
16
19
|
|
17
20
|
# @param [IO] io
|
@@ -29,38 +32,68 @@ module MiniTarball
|
|
29
32
|
end
|
30
33
|
|
31
34
|
def initialize(io)
|
32
|
-
ensure_valid_io
|
35
|
+
ensure_valid_io(io)
|
33
36
|
|
34
37
|
@io = io
|
35
38
|
@write_only_io = WriteOnlyStream.new(@io)
|
36
39
|
@header_writer = HeaderWriter.new(@write_only_io)
|
37
40
|
@closed = false
|
41
|
+
@placeholders = []
|
38
42
|
end
|
39
43
|
|
40
|
-
|
41
|
-
|
44
|
+
# :reek:ControlParameter
|
45
|
+
# :reek:DuplicateMethodCall { allow_calls: ['stat.uid', 'stat.gid'] }
|
46
|
+
# :reek:FeatureEnvy
|
47
|
+
# :reek:LongParameterList
|
48
|
+
# :reek:TooManyStatements
|
49
|
+
def add_file(
|
50
|
+
name:,
|
51
|
+
source_file_path:,
|
52
|
+
mode: nil,
|
53
|
+
uname: nil,
|
54
|
+
gname: nil,
|
55
|
+
uid: nil,
|
56
|
+
gid: nil,
|
57
|
+
mtime: nil
|
58
|
+
)
|
59
|
+
ensure_not_closed
|
42
60
|
|
43
|
-
file = File.open(source_file_path, "rb")
|
44
61
|
stat = File.stat(source_file_path)
|
45
62
|
|
46
|
-
@header_writer.write(
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
63
|
+
@header_writer.write(
|
64
|
+
Header.new(
|
65
|
+
name: name,
|
66
|
+
size: stat.size,
|
67
|
+
mode: mode || stat.mode,
|
68
|
+
uid: uid || stat.uid,
|
69
|
+
gid: gid || stat.gid,
|
70
|
+
uname: uname || Etc.getpwuid(stat.uid).name,
|
71
|
+
gname: gname || Etc.getgrgid(stat.gid).name,
|
72
|
+
mtime: mtime || stat.mtime,
|
73
|
+
),
|
74
|
+
)
|
75
|
+
|
76
|
+
File.open(source_file_path, "rb") { |file| IO.copy_stream(file, @write_only_io) }
|
77
|
+
|
58
78
|
write_padding
|
59
79
|
nil
|
60
80
|
end
|
61
81
|
|
62
|
-
|
63
|
-
|
82
|
+
# :reek:ControlParameter
|
83
|
+
# :reek:DuplicateMethodCall { allow_calls: ['@io.pos'] }
|
84
|
+
# :reek:LongParameterList
|
85
|
+
# :reek:TooManyStatements
|
86
|
+
def add_file_from_stream(
|
87
|
+
name:,
|
88
|
+
mode: 0644,
|
89
|
+
uname: "nobody",
|
90
|
+
gname: "nogroup",
|
91
|
+
uid: nil,
|
92
|
+
gid: nil,
|
93
|
+
mtime: nil
|
94
|
+
)
|
95
|
+
ensure_not_closed
|
96
|
+
ensure_seekable_io
|
64
97
|
|
65
98
|
header_start_position = @io.pos
|
66
99
|
@header_writer.write(Header.new(name: name))
|
@@ -71,18 +104,63 @@ module MiniTarball
|
|
71
104
|
write_padding
|
72
105
|
|
73
106
|
@io.seek(header_start_position)
|
74
|
-
@header_writer.write(
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
107
|
+
@header_writer.write(
|
108
|
+
Header.new(
|
109
|
+
name: name,
|
110
|
+
size: file_size,
|
111
|
+
mode: mode,
|
112
|
+
uid: uid,
|
113
|
+
gid: gid,
|
114
|
+
uname: uname,
|
115
|
+
gname: gname,
|
116
|
+
mtime: mtime || Time.now.utc,
|
117
|
+
),
|
118
|
+
)
|
119
|
+
|
120
|
+
@io.seek(0, IO::SEEK_END)
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
|
124
|
+
# :reek:DuplicateMethodCall { allow_calls: ['@io.pos'] }
|
125
|
+
# :reek:TooManyStatements
|
126
|
+
def add_file_placeholder(name:, file_size:)
|
127
|
+
ensure_not_closed
|
128
|
+
|
129
|
+
placeholder = {}
|
130
|
+
placeholder[:header_start_position] = @io.pos
|
131
|
+
@header_writer.write(Header.new(name: name, size: file_size))
|
132
|
+
|
133
|
+
placeholder[:file_start_position] = @io.pos
|
134
|
+
@io.write("\0" * file_size)
|
135
|
+
placeholder[:file_size] = file_size
|
84
136
|
|
137
|
+
write_padding
|
138
|
+
|
139
|
+
@placeholders << placeholder
|
140
|
+
@placeholders.size - 1
|
141
|
+
end
|
142
|
+
|
143
|
+
# :reek:TooManyStatements
|
144
|
+
def with_placeholder(index)
|
145
|
+
ensure_seekable_io
|
146
|
+
|
147
|
+
placeholder = @placeholders[index]
|
148
|
+
raise ArgumentError.new("Placeholder not found") if !placeholder
|
149
|
+
|
150
|
+
@io.seek(placeholder[:header_start_position])
|
151
|
+
old_write_only_io = @write_only_io
|
152
|
+
@write_only_io =
|
153
|
+
PlaceholderStream.new(
|
154
|
+
@io,
|
155
|
+
start_position: placeholder[:file_start_position],
|
156
|
+
file_size: placeholder[:file_size],
|
157
|
+
)
|
158
|
+
|
159
|
+
yield self
|
160
|
+
|
161
|
+
@write_only_io = old_write_only_io
|
85
162
|
@io.seek(0, IO::SEEK_END)
|
163
|
+
|
86
164
|
nil
|
87
165
|
end
|
88
166
|
|
@@ -91,25 +169,30 @@ module MiniTarball
|
|
91
169
|
end
|
92
170
|
|
93
171
|
def close
|
94
|
-
ensure_not_closed
|
172
|
+
ensure_not_closed
|
95
173
|
|
96
174
|
@io.write("\0" * END_OF_TAR_BLOCK_SIZE)
|
97
175
|
@io.close
|
98
176
|
@closed = true
|
99
177
|
end
|
100
178
|
|
101
|
-
|
179
|
+
# :reek:FeatureEnvy
|
180
|
+
# :reek:ManualDispatch
|
181
|
+
private def ensure_valid_io(io)
|
182
|
+
unless io.respond_to?(:pos) && io.respond_to?(:write) && io.respond_to?(:close)
|
183
|
+
raise NoIOLikeObjectError.new("No IO object given")
|
184
|
+
end
|
185
|
+
end
|
102
186
|
|
103
|
-
def
|
104
|
-
raise "No IO object given" unless io.respond_to?(:
|
105
|
-
io.respond_to?(:write) && io.respond_to?(:close)
|
187
|
+
private def ensure_seekable_io
|
188
|
+
raise NoIOLikeObjectError.new("No seekable IO object given") unless @io.respond_to?(:seek)
|
106
189
|
end
|
107
190
|
|
108
|
-
def ensure_not_closed
|
191
|
+
private def ensure_not_closed
|
109
192
|
raise IOError.new("#{self.class} is closed") if closed?
|
110
193
|
end
|
111
194
|
|
112
|
-
def write_padding
|
195
|
+
private def write_padding
|
113
196
|
padding_length = (Header::BLOCK_SIZE - @io.pos) % Header::BLOCK_SIZE
|
114
197
|
@io.write("\0" * padding_length)
|
115
198
|
end
|
data/lib/mini_tarball.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
3
|
+
require "mini_tarball/header"
|
4
|
+
require "mini_tarball/header_fields"
|
5
|
+
require "mini_tarball/header_formatter"
|
6
|
+
require "mini_tarball/header_writer"
|
7
|
+
require "mini_tarball/streams/limited_size_stream"
|
8
|
+
require "mini_tarball/streams/placeholder_stream"
|
9
|
+
require "mini_tarball/streams/write_only_stream"
|
10
|
+
require "mini_tarball/writer"
|
11
|
+
require "mini_tarball/version"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_tarball
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Discourse
|
7
|
+
- Discourse Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rubycritic
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -94,6 +94,34 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: super_diff
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: syntax_tree
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
97
125
|
description:
|
98
126
|
email:
|
99
127
|
executables: []
|
@@ -103,10 +131,13 @@ files:
|
|
103
131
|
- LICENSE.txt
|
104
132
|
- lib/mini_tarball.rb
|
105
133
|
- lib/mini_tarball/header.rb
|
134
|
+
- lib/mini_tarball/header_fields.rb
|
106
135
|
- lib/mini_tarball/header_formatter.rb
|
107
136
|
- lib/mini_tarball/header_writer.rb
|
137
|
+
- lib/mini_tarball/streams/limited_size_stream.rb
|
138
|
+
- lib/mini_tarball/streams/placeholder_stream.rb
|
139
|
+
- lib/mini_tarball/streams/write_only_stream.rb
|
108
140
|
- lib/mini_tarball/version.rb
|
109
|
-
- lib/mini_tarball/write_only_stream.rb
|
110
141
|
- lib/mini_tarball/writer.rb
|
111
142
|
homepage: https://github.com/discourse/mini_tarball
|
112
143
|
licenses:
|
@@ -122,14 +153,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
153
|
requirements:
|
123
154
|
- - ">="
|
124
155
|
- !ruby/object:Gem::Version
|
125
|
-
version: 2.
|
156
|
+
version: 2.7.0
|
126
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
158
|
requirements:
|
128
159
|
- - ">="
|
129
160
|
- !ruby/object:Gem::Version
|
130
161
|
version: '0'
|
131
162
|
requirements: []
|
132
|
-
rubygems_version: 3.1.
|
163
|
+
rubygems_version: 3.1.6
|
133
164
|
signing_key:
|
134
165
|
specification_version: 4
|
135
166
|
summary: A minimal implementation of the GNU Tar format.
|