Class: MiniTarball::Writer

Inherits:
Object
  • Object
show all
Defined in:
lib/mini_tarball/writer.rb

Constant Summary collapse

END_OF_TAR_BLOCK_SIZE =
1024

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io) ⇒ Writer

Returns a new instance of Writer.



34
35
36
37
38
39
40
41
42
# File 'lib/mini_tarball/writer.rb', line 34

def initialize(io)
  ensure_valid_io(io)

  @io = io
  @write_only_io = WriteOnlyStream.new(@io)
  @header_writer = HeaderWriter.new(@write_only_io)
  @closed = false
  @placeholders = []
end

Class Method Details

.create(filename) {|| ... } ⇒ Object

:reek:NestedIterators

Parameters:

  • filename (String)

Yield Parameters:



16
17
18
# File 'lib/mini_tarball/writer.rb', line 16

def self.create(filename)
  File.open(filename, "wb") { |file| use(file) { |writer| yield(writer) } }
end

.use(io) {|| ... } ⇒ Object

Parameters:

  • io (IO)

Yield Parameters:



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/mini_tarball/writer.rb', line 22

def self.use(io)
  writer = new(io)

  begin
    yield(writer)
  ensure
    writer.close
  end

  nil
end

Instance Method Details

#add_file(name:, source_file_path:, mode: nil, uname: nil, gname: nil, uid: nil, gid: nil, mtime: nil) ⇒ Object

:reek:ControlParameter :reek:DuplicateMethodCall { allow_calls: [‘stat.uid’, ‘stat.gid’] } :reek:FeatureEnvy :reek:LongParameterList :reek:TooManyStatements



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/mini_tarball/writer.rb', line 49

def add_file(
  name:,
  source_file_path:,
  mode: nil,
  uname: nil,
  gname: nil,
  uid: nil,
  gid: nil,
  mtime: nil
)
  ensure_not_closed

  stat = File.stat(source_file_path)

  @header_writer.write(
    Header.new(
      name: name,
      size: stat.size,
      mode: mode || stat.mode,
      uid: uid || stat.uid,
      gid: gid || stat.gid,
      uname: uname || Etc.getpwuid(stat.uid).name,
      gname: gname || Etc.getgrgid(stat.gid).name,
      mtime: mtime || stat.mtime,
    ),
  )

  File.open(source_file_path, "rb") { |file| IO.copy_stream(file, @write_only_io) }

  write_padding
  nil
end

#add_file_from_stream(name:, mode: 0644, uname: "nobody", gname: "nogroup", uid: nil, gid: nil, mtime: nil) {|@write_only_io| ... } ⇒ Object

:reek:ControlParameter :reek:DuplicateMethodCall { allow_calls: [‘@io.pos’] } :reek:LongParameterList :reek:TooManyStatements

Yields:

  • (@write_only_io)


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/mini_tarball/writer.rb', line 86

def add_file_from_stream(
  name:,
  mode: 0644,
  uname: "nobody",
  gname: "nogroup",
  uid: nil,
  gid: nil,
  mtime: nil
)
  ensure_not_closed
  ensure_seekable_io

  header_start_position = @io.pos
  @header_writer.write(Header.new(name: name))

  file_start_position = @io.pos
  yield @write_only_io
  file_size = @io.pos - file_start_position
  write_padding

  @io.seek(header_start_position)
  @header_writer.write(
    Header.new(
      name: name,
      size: file_size,
      mode: mode,
      uid: uid,
      gid: gid,
      uname: uname,
      gname: gname,
      mtime: mtime || Time.now.utc,
    ),
  )

  @io.seek(0, IO::SEEK_END)
  nil
end

#add_file_placeholder(name:, file_size:) ⇒ Object

:reek:DuplicateMethodCall { allow_calls: [‘@io.pos’] } :reek:TooManyStatements



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/mini_tarball/writer.rb', line 126

def add_file_placeholder(name:, file_size:)
  ensure_not_closed

  placeholder = {}
  placeholder[:header_start_position] = @io.pos
  @header_writer.write(Header.new(name: name, size: file_size))

  placeholder[:file_start_position] = @io.pos
  @io.write("\0" * file_size)
  placeholder[:file_size] = file_size

  write_padding

  @placeholders << placeholder
  @placeholders.size - 1
end

#closeObject



171
172
173
174
175
176
177
# File 'lib/mini_tarball/writer.rb', line 171

def close
  ensure_not_closed

  @io.write("\0" * END_OF_TAR_BLOCK_SIZE)
  @io.close
  @closed = true
end

#closed?Boolean

Returns:

  • (Boolean)


167
168
169
# File 'lib/mini_tarball/writer.rb', line 167

def closed?
  @closed
end

#with_placeholder(index) {|_self| ... } ⇒ Object

:reek:TooManyStatements

Yields:

  • (_self)

Yield Parameters:

Raises:

  • (ArgumentError)


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/mini_tarball/writer.rb', line 144

def with_placeholder(index)
  ensure_seekable_io

  placeholder = @placeholders[index]
  raise ArgumentError.new("Placeholder not found") if !placeholder

  @io.seek(placeholder[:header_start_position])
  old_write_only_io = @write_only_io
  @write_only_io =
    PlaceholderStream.new(
      @io,
      start_position: placeholder[:file_start_position],
      file_size: placeholder[:file_size],
    )

  yield self

  @write_only_io = old_write_only_io
  @io.seek(0, IO::SEEK_END)

  nil
end