archive-tar-external 1.3.0 → 1.4.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.
@@ -0,0 +1,134 @@
1
+ ## Description
2
+ A simple tar interface using external system calls.
3
+
4
+ ## Synopsis
5
+ ```ruby
6
+ # Assuming we have three .txt files, t1.txt, t2.txt, t3.txt ...
7
+ require 'archive/tar/external'
8
+ include Archive
9
+
10
+ t = Tar::External.new("myfile.tar")
11
+
12
+ t.create_archive("*.txt")
13
+ t.compress_archive("bzip2") # 'myfile.tar.bz2' now exists
14
+
15
+ t.uncompress_archive("bunzip2")
16
+
17
+ t.archive_name # "myfile.tar"
18
+ t.archive_info # ["t1.txt","t2.txt","t3.txt"]
19
+
20
+ t.add_to_archive("t4.txt","t5.txt")
21
+ t.expand_archive
22
+ ```
23
+
24
+ ## Constants
25
+ `VERSION`- The current version number of this library. This is a string.
26
+
27
+ ## Singleton Methods
28
+ `.new(archive_name, pattern=nil, program=nil)`
29
+
30
+ Creates an instance of an Archive::Tar::External object. The `archive_name` is
31
+ the name of the tarball. While a '.tar' extension is recommended based on
32
+ years of convention, it is not enforced.
33
+
34
+ If `pattern` is provided, then the `create_archive` method is called internally.
35
+
36
+ If `program` is provided, then the `compress_archive` method is called internally.
37
+
38
+ Note that `archive_name` name must be a string, or a `TypeError` is raised.
39
+
40
+ `.expand_archive(archive_name, file1 [, file2, ...])`
41
+
42
+ Identical to the instance method of the same name, except that you must
43
+ specify the `archive_name`, and the tar program is hard coded to `tar xf`.
44
+
45
+ `.uncompress_archive(archive_name, program='gunzip')`
46
+
47
+ Identical to the instance method of the same name, except that you must
48
+ specify the +archive_name+ as the first argument.
49
+
50
+ ## Instance Methods
51
+ ```
52
+ #add(file1 [, file2, ...])
53
+ #add_to_archive(file1 [, file2, ...])
54
+ ```
55
+
56
+ Adds a list of files to the current archive. At least one file must be
57
+ provided or an `Archive::Tar::Error` is raised.
58
+
59
+ ```
60
+ #archive_info
61
+ #info
62
+ ```
63
+
64
+ Returns an array of file names that are included within the tarball.
65
+
66
+ `#archive_name`
67
+
68
+ Returns the current archive name.
69
+
70
+ `#archive_name=`
71
+
72
+ Sets the current archive name.
73
+
74
+ ```
75
+ #compress(program="gzip")
76
+ #compress_archive(program="gzip")
77
+ ```
78
+
79
+ Compresses the tarball using the program you pass to this method. The default is "gzip".
80
+
81
+ Note that any arguments you want to be passed along with the program can simply
82
+ be included as part of the program, e.g. "gzip -f".
83
+
84
+ ```
85
+ #create(file_pattern)
86
+ #create_archive(file_pattern, options = 'cf')
87
+ ```
88
+
89
+ Creates a new tarball, including those files which match `file_pattern`
90
+ using `options`, which are set to 'cf' (create file) by default.
91
+
92
+ ```
93
+ #expand_archive(files=nil)
94
+ #extract_archive(files=nil)
95
+ ```
96
+
97
+ Expands the contents of the tarball. Note that this method does NOT delete the tarball.
98
+
99
+ If file names are provided, then only those files are extracted.
100
+
101
+ `#tar_program`
102
+
103
+ Returns the name of the tar program used. The default is "tar".
104
+
105
+ `#tar_program=(program_name)`
106
+
107
+ Sets the name of the tar program to be used.
108
+
109
+ ```
110
+ #uncompress(program="gunzip")
111
+ #uncompress_archive(program="gunzip")
112
+ ```
113
+
114
+ Uncompresses the tarball using the program you pass to this method. The default is "gunzip".
115
+
116
+ Like the `compress_archive` method, you can pass arguments along as part of the method call.
117
+
118
+ ```
119
+ #update(files)
120
+ #update_archive(files)
121
+ ```
122
+
123
+ Updates the given `files` in the archive, i.e they are added if they
124
+ are not already in the archive or have been modified.
125
+
126
+ ## Exceptions
127
+ `Archive::Tar::Error`
128
+
129
+ Raised if something goes wrong during the execution of any methods that
130
+ use the tar command internally.
131
+
132
+ `Archive::Tar::CompressError`
133
+
134
+ Raised if something goes wrong during the `compress_archive` or `uncompress_archive` methods.
@@ -0,0 +1 @@
1
+ require_relative 'archive/tar/external'
@@ -1,281 +1,269 @@
1
- require 'rbconfig'
2
-
3
- if Config::CONFIG['host_os'] =~ /mswin|dos|win32|cygwin|mingw/i
4
- if RUBY_VERSION.to_f < 1.9 && RUBY_PLATFORM !~ /java/i
5
- require 'win32/open3'
6
- else
7
- require 'open3'
8
- end
9
- else
10
- require 'open3'
11
- end
12
-
13
- # The Archive module serves as a namespace only.
14
- module Archive
15
-
16
- # The Tar class serves as a toplevel class namespace only.
17
- class Tar
18
-
19
- # Raised if something goes wrong during the execution of any methods
20
- # which use the tar command internally.
21
- class Error < StandardError; end
22
-
23
- # Raised if something goes wrong during the Tar#compress_archive or
24
- # Tar#uncompress_archive methods.
25
- class CompressError < StandardError; end
26
-
27
- # This class encapsulates tar & zip operations.
28
- class Tar::External
29
- # The version of the archive-tar-external library.
30
- VERSION = '1.3.0'
31
-
32
- # The name of the archive file to be used, e.g. "test.tar"
33
- attr_accessor :archive_name
34
-
35
- # The name of the tar program you wish to use. The default is "tar".
36
- attr_accessor :tar_program
37
-
38
- # The name of the archive file after compression, e.g. "test.tar.gz"
39
- attr_reader :compressed_archive_name
40
-
41
- # Returns an Archive::Tar::External object. The +archive_name+ is the
42
- # name of the tarball. While a .tar extension is recommended based on
43
- # years of convention, it is not enforced.
44
- #
45
- # Note that this does not actually create the archive unless you
46
- # pass a value to +file_pattern+. This then becomes a shortcut for
47
- # Archive::Tar::External.new + Archive::Tar::External#create_archive.
48
- #
49
- # If +program+ is provided, then it compresses the archive as well by
50
- # calling Archive::Tar::External#compress_archive internally.
51
- #
52
- def initialize(archive_name, file_pattern=nil, program=nil)
53
- @archive_name = archive_name.to_s
54
- @compressed_archive_name = nil
55
- @tar_program = 'tar'
56
-
57
- if file_pattern
58
- create_archive(file_pattern)
59
- end
60
-
61
- if program
62
- compress_archive(program)
63
- end
64
- end
65
-
66
- # Assign a compressed archive name. This autogenerates the archive_name
67
- # based on the extension of the name provided, unless you provide the
68
- # extension yourself. If the extension is '.tgz', then the base of the
69
- # name + '.tar' will be the new archive name.
70
- #
71
- # This should only be used if you have a pre-existing, compressed archive
72
- # that you want to uncompress, and want to have a Tar::External object
73
- # around. Otherwise, use the class method Tar::External.uncompress.
74
- #
75
- def compressed_archive_name=(name, ext=File.extname(name))
76
- if ext.downcase == '.tgz'
77
- @archive_name = File.basename(name, ext.downcase) + '.tar'
78
- else
79
- @archive_name = File.basename(name, ext)
80
- end
81
- @compressed_archive_name = name
82
- end
83
-
84
- # Creates the archive using +file_pattern+. Any errors that occur
85
- # here will raise a Error.
86
- #
87
- def create_archive(file_pattern)
88
- cmd = "#{@tar_program} cf #{@archive_name} #{file_pattern}"
89
-
90
- Open3.popen3(cmd){ |tar_in, tar_out, tar_err|
91
- err = tar_err.gets
92
- if err
93
- raise Error, err.chomp
94
- end
95
- }
96
-
97
- self
98
- end
99
-
100
- alias :create :create_archive
101
-
102
- # Compresses the archive with +program+, or gzip if no program is
103
- # provided. If you want to pass arguments to +program+, merely include
104
- # them as part of the program name, e.g. "gzip -f".
105
- #
106
- # Any errors that occur here will raise a Tar::CompressError.
107
- #
108
- def compress_archive(program='gzip')
109
- cmd = "#{program} #{@archive_name}"
110
-
111
- Open3.popen3(cmd){ |prog_in, prog_out, prog_err|
112
- err = prog_err.gets
113
- raise CompressError, err.chomp if err
114
-
115
- # Find the new file name with the extension. There's probably a more
116
- # reliable way to do this, but this should work 99% of the time.
117
- name = Dir["#{@archive_name}.{gz,bz2,cpio,zip}"].first
118
- @compressed_archive_name = name
119
- }
120
-
121
- self
122
- end
123
-
124
- alias :compress :compress_archive
125
-
126
- # Uncompresses the tarball using the program you pass to this method. The
127
- # default is "gunzip". Just as for +compress_archive+, you can pass
128
- # arguments along as part of the argument.
129
- #
130
- # Note that this is only for use with archives that have been zipped up
131
- # with gunzip, or whatever. If you want to *extract* the files from the
132
- # tarball, use Tar::External#extract instead.
133
- #
134
- # Any errors that occur here will raise a Tar::CompressError.
135
- #
136
- def uncompress_archive(program="gunzip")
137
- unless @compressed_archive_name
138
- raise CompressError, "no compressed file found"
139
- end
140
-
141
- cmd = "#{program} #{@compressed_archive_name}"
142
-
143
- Open3.popen3(cmd){ |prog_in, prog_out, prog_err|
144
- err = prog_err.gets
145
- raise CompressError, err.chomp if err
146
- @compressed_archive_name = nil
147
- }
148
- self
149
- end
150
-
151
- alias :uncompress :uncompress_archive
152
-
153
- # Uncompress an existing archive, using +program+ to uncompress it.
154
- # The default decompression program is gunzip.
155
- #
156
- def self.uncompress_archive(archive, program='gunzip')
157
- cmd = "#{program} #{archive}"
158
-
159
- Open3.popen3(cmd){ |prog_in, prog_out, prog_err|
160
- err = prog_err.gets
161
- raise CompressError, err.chomp if err
162
- }
163
- end
164
-
165
- class << self
166
- alias uncompress uncompress_archive
167
- end
168
-
169
- # Returns an array of file names that are included within the tarball.
170
- # This method does not extract the archive.
171
- #
172
- def archive_info
173
- result = []
174
- cmd = "#{@tar_program} tf #{@archive_name}"
175
- Open3.popen3(cmd){ |ain, aout, aerr|
176
- err = aerr.gets
177
- if err
178
- raise Error, err.chomp
179
- end
180
-
181
- while output = aout.gets
182
- result << output.chomp
183
- end
184
- }
185
- result
186
- end
187
-
188
- alias :info :archive_info
189
-
190
- # Adds +files+ to an already existing archive.
191
- #
192
- def add_to_archive(*files)
193
- if files.empty?
194
- raise Error, "there must be at least one file specified"
195
- end
196
-
197
- cmd = "#{@tar_program} rf #{@archive_name} #{files.join(" ")}"
198
-
199
- Open3.popen3(cmd){ |ain, aout, aerr|
200
- err = aerr.gets
201
- raise Error, err.chomp if err
202
- }
203
- self
204
- end
205
-
206
- alias :add :add_to_archive
207
-
208
- # Updates the given +files+ in the archive, i.e. they are added if they
209
- # are not already in the archive or have been modified.
210
- #
211
- def update_archive(*files)
212
- if files.empty?
213
- raise Error, "there must be at least one file specified"
214
- end
215
-
216
- cmd = "#{@tar_program} uf #{@archive_name} #{files.join(" ")}"
217
-
218
- Open3.popen3(cmd){ |ain, aout, aerr|
219
- err = aerr.gets
220
- raise Error, err.chomp if err
221
- }
222
-
223
- self
224
- end
225
-
226
- alias :update :update_archive
227
-
228
- # Expands the contents of the tarball. It does NOT delete the tarball.
229
- # If +files+ are provided, then only those files are extracted.
230
- # Otherwise, all files are extracted.
231
- #
232
- # Note that some tar programs, notably the tar program shipped by Sun,
233
- # does not issue any sort of warning or error if you try to extract a
234
- # file that does not exist in the archive.
235
- #
236
- def extract_archive(*files)
237
- cmd = "#{@tar_program} xf #{@archive_name}"
238
-
239
- unless files.empty?
240
- cmd << " " << files.join(" ")
241
- end
242
-
243
- Open3.popen3(cmd){ |ain, aout, aerr|
244
- err = aerr.gets
245
- raise Error, err.chomp if err
246
- }
247
-
248
- self
249
- end
250
-
251
- alias :expand_archive :extract_archive
252
- alias :extract :extract_archive
253
- alias :expand :extract_archive
254
-
255
- # A class method that behaves identically to the equivalent instance
256
- # method, except that you must specifiy that tarball as the first
257
- # argument. Also, the tar program is hard coded to 'tar xf'.
258
- #
259
- def self.extract_archive(archive, *files)
260
- cmd = "tar xf #{archive}"
261
-
262
- unless files.empty?
263
- cmd << " " << files.join(" ")
264
- end
265
-
266
- Open3.popen3(cmd){ |ain, aout, aerr|
267
- err = aerr.gets
268
- raise Error, err.chomp if err
269
- }
270
-
271
- self
272
- end
273
-
274
- class << self
275
- alias expand_archive extract_archive
276
- alias extract extract_archive
277
- alias expand extract_archive
278
- end
279
- end
280
- end
281
- end
1
+ require 'open3'
2
+
3
+ # The Archive module serves as a namespace only.
4
+ module Archive
5
+
6
+ # The Tar class serves as a toplevel class namespace only.
7
+ class Tar
8
+
9
+ # Raised if something goes wrong during the execution of any methods
10
+ # which use the tar command internally.
11
+ class Error < StandardError; end
12
+
13
+ # Raised if something goes wrong during the Tar#compress_archive or
14
+ # Tar#uncompress_archive methods.
15
+ class CompressError < StandardError; end
16
+
17
+ # This class encapsulates tar & zip operations.
18
+ class Tar::External
19
+ # The version of the archive-tar-external library.
20
+ VERSION = '1.4.1'.freeze
21
+
22
+ # The name of the archive file to be used, e.g. "test.tar"
23
+ attr_accessor :archive_name
24
+
25
+ # The name of the tar program you wish to use. The default is "tar".
26
+ attr_accessor :tar_program
27
+
28
+ # The name of the archive file after compression, e.g. "test.tar.gz"
29
+ attr_reader :compressed_archive_name
30
+
31
+ # Returns an Archive::Tar::External object. The +archive_name+ is the
32
+ # name of the tarball. While a .tar extension is recommended based on
33
+ # years of convention, it is not enforced.
34
+ #
35
+ # Note that this does not actually create the archive unless you
36
+ # pass a value to +file_pattern+. This then becomes a shortcut for
37
+ # Archive::Tar::External.new + Archive::Tar::External#create_archive.
38
+ #
39
+ # If +program+ is provided, then it compresses the archive as well by
40
+ # calling Archive::Tar::External#compress_archive internally.
41
+ #
42
+ def initialize(archive_name, file_pattern=nil, program=nil)
43
+ @archive_name = archive_name.to_s
44
+ @compressed_archive_name = nil
45
+ @tar_program = 'tar'
46
+
47
+ if file_pattern
48
+ create_archive(file_pattern)
49
+ end
50
+
51
+ if program
52
+ compress_archive(program)
53
+ end
54
+ end
55
+
56
+ # Assign a compressed archive name. This autogenerates the archive_name
57
+ # based on the extension of the name provided, unless you provide the
58
+ # extension yourself. If the extension is '.tgz', then the base of the
59
+ # name + '.tar' will be the new archive name.
60
+ #
61
+ # This should only be used if you have a pre-existing, compressed archive
62
+ # that you want to uncompress, and want to have a Tar::External object
63
+ # around. Otherwise, use the class method Tar::External.uncompress.
64
+ #
65
+ def compressed_archive_name=(name, ext=File.extname(name))
66
+ if ext.downcase == '.tgz'
67
+ @archive_name = File.basename(name, ext.downcase) + '.tar'
68
+ else
69
+ @archive_name = File.basename(name, ext)
70
+ end
71
+ @compressed_archive_name = name
72
+ end
73
+
74
+ # Creates the archive using +file_pattern+ using +options+ or 'cf'
75
+ # (create file) by default.
76
+ #
77
+ # Raises an Archive::Tar::Error if a failure occurs.
78
+ #
79
+ def create_archive(file_pattern, options = 'cf')
80
+ cmd = "#{@tar_program} #{options} #{@archive_name} #{file_pattern}"
81
+
82
+ Open3.popen3(cmd){ |tar_in, tar_out, tar_err|
83
+ err = tar_err.gets
84
+ raise Error, err.chomp if err
85
+ }
86
+
87
+ self
88
+ end
89
+
90
+ alias :create :create_archive
91
+
92
+ # Compresses the archive with +program+, or gzip if no program is
93
+ # provided. If you want to pass arguments to +program+, merely include
94
+ # them as part of the program name, e.g. "gzip -f".
95
+ #
96
+ # Any errors that occur here will raise a Tar::CompressError.
97
+ #
98
+ def compress_archive(program='gzip')
99
+ cmd = "#{program} #{@archive_name}"
100
+
101
+ Open3.popen3(cmd){ |prog_in, prog_out, prog_err|
102
+ err = prog_err.gets
103
+ raise CompressError, err.chomp if err
104
+
105
+ # Find the new file name with the extension. There's probably a more
106
+ # reliable way to do this, but this should work 99% of the time.
107
+ name = Dir["#{@archive_name}.{gz,bz2,cpio,zip}"].first
108
+ @compressed_archive_name = name
109
+ }
110
+
111
+ self
112
+ end
113
+
114
+ alias :compress :compress_archive
115
+
116
+ # Uncompresses the tarball using the program you pass to this method. The
117
+ # default is "gunzip". Just as for +compress_archive+, you can pass
118
+ # arguments along as part of the argument.
119
+ #
120
+ # Note that this is only for use with archives that have been zipped up
121
+ # with gunzip, or whatever. If you want to *extract* the files from the
122
+ # tarball, use Tar::External#extract instead.
123
+ #
124
+ # Any errors that occur here will raise a Tar::CompressError.
125
+ #
126
+ def uncompress_archive(program="gunzip")
127
+ unless @compressed_archive_name
128
+ raise CompressError, "no compressed file found"
129
+ end
130
+
131
+ cmd = "#{program} #{@compressed_archive_name}"
132
+
133
+ Open3.popen3(cmd){ |prog_in, prog_out, prog_err|
134
+ err = prog_err.gets
135
+ raise CompressError, err.chomp if err
136
+ @compressed_archive_name = nil
137
+ }
138
+ self
139
+ end
140
+
141
+ alias :uncompress :uncompress_archive
142
+
143
+ # Uncompress an existing archive, using +program+ to uncompress it.
144
+ # The default decompression program is gunzip.
145
+ #
146
+ def self.uncompress_archive(archive, program='gunzip')
147
+ cmd = "#{program} #{archive}"
148
+
149
+ Open3.popen3(cmd){ |prog_in, prog_out, prog_err|
150
+ err = prog_err.gets
151
+ raise CompressError, err.chomp if err
152
+ }
153
+ end
154
+
155
+ class << self
156
+ alias uncompress uncompress_archive
157
+ end
158
+
159
+ # Returns an array of file names that are included within the tarball.
160
+ # This method does not extract the archive.
161
+ #
162
+ def archive_info
163
+ result = []
164
+ cmd = "#{@tar_program} tf #{@archive_name}"
165
+ Open3.popen3(cmd){ |ain, aout, aerr|
166
+ err = aerr.gets
167
+ raise Error, err.chomp if err
168
+
169
+ while output = aout.gets
170
+ result << output.chomp
171
+ end
172
+ }
173
+ result
174
+ end
175
+
176
+ alias :info :archive_info
177
+
178
+ # Adds +files+ to an already existing archive.
179
+ #
180
+ def add_to_archive(*files)
181
+ if files.empty?
182
+ raise Error, "there must be at least one file specified"
183
+ end
184
+
185
+ cmd = "#{@tar_program} rf #{@archive_name} #{files.join(" ")}"
186
+
187
+ Open3.popen3(cmd){ |ain, aout, aerr|
188
+ err = aerr.gets
189
+ raise Error, err.chomp if err
190
+ }
191
+ self
192
+ end
193
+
194
+ alias :add :add_to_archive
195
+
196
+ # Updates the given +files+ in the archive, i.e. they are added if they
197
+ # are not already in the archive or have been modified.
198
+ #
199
+ def update_archive(*files)
200
+ if files.empty?
201
+ raise Error, "there must be at least one file specified"
202
+ end
203
+
204
+ cmd = "#{@tar_program} uf #{@archive_name} #{files.join(" ")}"
205
+
206
+ Open3.popen3(cmd){ |ain, aout, aerr|
207
+ err = aerr.gets
208
+ raise Error, err.chomp if err
209
+ }
210
+
211
+ self
212
+ end
213
+
214
+ alias :update :update_archive
215
+
216
+ # Expands the contents of the tarball. It does NOT delete the tarball.
217
+ # If +files+ are provided, then only those files are extracted.
218
+ # Otherwise, all files are extracted.
219
+ #
220
+ # Note that some tar programs, notably the tar program shipped by Sun,
221
+ # does not issue any sort of warning or error if you try to extract a
222
+ # file that does not exist in the archive.
223
+ #
224
+ def extract_archive(*files)
225
+ cmd = "#{@tar_program} xf #{@archive_name}"
226
+
227
+ unless files.empty?
228
+ cmd << " " << files.join(" ")
229
+ end
230
+
231
+ Open3.popen3(cmd){ |ain, aout, aerr|
232
+ err = aerr.gets
233
+ raise Error, err.chomp if err
234
+ }
235
+
236
+ self
237
+ end
238
+
239
+ alias :expand_archive :extract_archive
240
+ alias :extract :extract_archive
241
+ alias :expand :extract_archive
242
+
243
+ # A class method that behaves identically to the equivalent instance
244
+ # method, except that you must specifiy that tarball as the first
245
+ # argument. Also, the tar program is hard coded to 'tar xf'.
246
+ #
247
+ def self.extract_archive(archive, *files)
248
+ cmd = "tar xf #{archive}"
249
+
250
+ unless files.empty?
251
+ cmd << " " << files.join(" ")
252
+ end
253
+
254
+ Open3.popen3(cmd){ |ain, aout, aerr|
255
+ err = aerr.gets
256
+ raise Error, err.chomp if err
257
+ }
258
+
259
+ self
260
+ end
261
+
262
+ class << self
263
+ alias expand_archive extract_archive
264
+ alias extract extract_archive
265
+ alias expand extract_archive
266
+ end
267
+ end
268
+ end
269
+ end