mini_tarball 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mini_tarball/header.rb +1 -1
- data/lib/mini_tarball/header_formatter.rb +9 -0
- data/lib/mini_tarball/header_writer.rb +2 -0
- data/lib/mini_tarball/version.rb +1 -1
- data/lib/mini_tarball/writer.rb +32 -10
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb6115ef818ae567ea4efad8646977a26cbb62f5164e656bd8d403dd1775ff38
|
4
|
+
data.tar.gz: 5364a6eece1aa623c4bb900eaf50de383017dcd4b9285f5f7b3b52423638d9b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8978adda8f400f47d37d037fc439d6d803538910aaa97a78cee3ec111b34616c0b3acd298a6a5b406a02a8e0d698e25743a5a4ff32a2e1b827835892621d186
|
7
|
+
data.tar.gz: 543abee46d1e1bd3df2abdd0b0164f2e72363d65ec63a7ac8c120302c94a0fc247315fcb7c4541774ab08ef00178e4de1df355cb2699e0056f0d984e53f532bc
|
data/lib/mini_tarball/header.rb
CHANGED
@@ -11,7 +11,7 @@ module MiniTarball
|
|
11
11
|
# rubocop:disable Layout/HashAlignment
|
12
12
|
FIELDS = {
|
13
13
|
name: { length: 100, type: :chars },
|
14
|
-
mode: { length: 8, type: :
|
14
|
+
mode: { length: 8, type: :mode },
|
15
15
|
uid: { length: 8, type: :number },
|
16
16
|
gid: { length: 8, type: :number },
|
17
17
|
size: { length: 12, type: :number },
|
@@ -4,6 +4,8 @@ module MiniTarball
|
|
4
4
|
ValueTooLargeError = Class.new(StandardError)
|
5
5
|
|
6
6
|
class HeaderFormatter
|
7
|
+
PERMISSION_BITMASK = 0007777
|
8
|
+
|
7
9
|
# @param value [Integer]
|
8
10
|
# @param length [Integer]
|
9
11
|
def self.format_number(value, length)
|
@@ -38,5 +40,12 @@ module MiniTarball
|
|
38
40
|
|
39
41
|
encoded.pack("C#{length}")
|
40
42
|
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
|
41
50
|
end
|
42
51
|
end
|
@@ -22,6 +22,8 @@ module MiniTarball
|
|
22
22
|
case field[:type]
|
23
23
|
when :number
|
24
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])
|
25
27
|
when :checksum
|
26
28
|
values_by_field[name] = " " * field[:length]
|
27
29
|
end
|
data/lib/mini_tarball/version.rb
CHANGED
data/lib/mini_tarball/writer.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'etc'
|
4
|
+
|
3
5
|
module MiniTarball
|
4
6
|
class Writer
|
5
7
|
END_OF_TAR_BLOCK_SIZE = 1024
|
@@ -27,7 +29,7 @@ module MiniTarball
|
|
27
29
|
end
|
28
30
|
|
29
31
|
def initialize(io)
|
30
|
-
|
32
|
+
ensure_valid_io!(io)
|
31
33
|
|
32
34
|
@io = io
|
33
35
|
@write_only_io = WriteOnlyStream.new(@io)
|
@@ -35,8 +37,30 @@ module MiniTarball
|
|
35
37
|
@closed = false
|
36
38
|
end
|
37
39
|
|
38
|
-
def add_file(name:, mode:
|
39
|
-
|
40
|
+
def add_file(name:, source_file_path:, mode: nil, uname: nil, gname: nil, uid: nil, gid: nil, mtime: nil)
|
41
|
+
ensure_not_closed!
|
42
|
+
|
43
|
+
file = File.open(source_file_path, "rb")
|
44
|
+
stat = File.stat(source_file_path)
|
45
|
+
|
46
|
+
@header_writer.write(Header.new(
|
47
|
+
name: name,
|
48
|
+
size: stat.size,
|
49
|
+
mode: mode || stat.mode,
|
50
|
+
uid: uid || stat.uid,
|
51
|
+
gid: gid || stat.gid,
|
52
|
+
uname: uname || Etc.getpwuid(stat.uid).name,
|
53
|
+
gname: gname || Etc.getgrgid(stat.gid).name,
|
54
|
+
mtime: mtime || stat.mtime
|
55
|
+
))
|
56
|
+
|
57
|
+
IO.copy_stream(file, @write_only_io)
|
58
|
+
write_padding
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_file_from_stream(name:, mode: 0644, uname: "nobody", gname: "nogroup", uid: nil, gid: nil, mtime: nil)
|
63
|
+
ensure_not_closed!
|
40
64
|
|
41
65
|
header_start_position = @io.pos
|
42
66
|
@header_writer.write(Header.new(name: name))
|
@@ -59,6 +83,7 @@ module MiniTarball
|
|
59
83
|
))
|
60
84
|
|
61
85
|
@io.seek(0, IO::SEEK_END)
|
86
|
+
nil
|
62
87
|
end
|
63
88
|
|
64
89
|
def closed?
|
@@ -66,7 +91,7 @@ module MiniTarball
|
|
66
91
|
end
|
67
92
|
|
68
93
|
def close
|
69
|
-
|
94
|
+
ensure_not_closed!
|
70
95
|
|
71
96
|
@io.write("\0" * END_OF_TAR_BLOCK_SIZE)
|
72
97
|
@io.close
|
@@ -75,15 +100,12 @@ module MiniTarball
|
|
75
100
|
|
76
101
|
private
|
77
102
|
|
78
|
-
def
|
103
|
+
def ensure_valid_io!(io)
|
79
104
|
raise "No IO object given" unless io.respond_to?(:pos) &&
|
80
|
-
io.respond_to?(:
|
81
|
-
|
82
|
-
io.seek(0, IO::SEEK_END)
|
83
|
-
raise "Stream must be empty" unless io.pos == 0
|
105
|
+
io.respond_to?(:write) && io.respond_to?(:close)
|
84
106
|
end
|
85
107
|
|
86
|
-
def
|
108
|
+
def ensure_not_closed!
|
87
109
|
raise IOError.new("#{self.class} is closed") if closed?
|
88
110
|
end
|
89
111
|
|
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.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Discourse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -129,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
requirements: []
|
132
|
-
rubygems_version: 3.
|
132
|
+
rubygems_version: 3.1.4
|
133
133
|
signing_key:
|
134
134
|
specification_version: 4
|
135
135
|
summary: A minimal implementation of the GNU Tar format.
|