archive-tar-external 1.3.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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