lib/archive/tar_external.rb in archive-tar-external-1.2.0 vs lib/archive/tar_external.rb in archive-tar-external-1.2.1

- old
+ new

@@ -1,277 +1,287 @@ -if RUBY_PLATFORM.match("mswin") - require "win32/open3" +if RUBY_PLATFORM.match('mswin') + require 'win32/open3' else - require "open3" + require 'open3' end +# The Archive module serves as a namespace only. module Archive - class TarError < StandardError; end - class CompressError < StandardError; end - class Tar; end # Dummy, so our nesting/scoping works properly. + # The Tar class serves as a toplevel class namespace only. + class Tar - class Tar::External - VERSION = '1.2.0' + # Raised if something goes wrong during the execution of any methods + # which use the tar command internally. + class Error < StandardError; end - # The name of the archive file to be used, e.g. "test.tar" - attr_accessor :archive_name + # Raised if something goes wrong during the Tar#compress_archive or + # Tar#uncompress_archive methods. + class CompressError < StandardError; end - # The name of the tar program you wish to use. The default is "tar". - attr_accessor :tar_program + # This class encapsulates tar & zip operations. + class Tar::External + VERSION = '1.2.1' - # The name of the archive file after compression, e.g. "test.tar.gz" - attr_reader :compressed_archive_name + # The name of the archive file to be used, e.g. "test.tar" + attr_accessor :archive_name - # Returns an Archive::Tar::External object. The +archive_name+ is the - # name of the tarball. While a .tar extension is recommended based on - # years of convention, it is not enforced. - # - # Note that this does not actually create the archive unless you - # pass a value to +file_pattern+. This then becomes a shortcut for - # Archive::Tar::External.new + Archive::Tar::External#create_archive. - # - # If +program+ is provided, then it compresses the archive as well by - # calling Archive::Tar::External#compress_archive internally. - # - def initialize(archive_name, file_pattern=nil, program=nil) - @archive_name = archive_name.to_s - @compressed_archive_name = nil - @tar_program = "tar" + # The name of the tar program you wish to use. The default is "tar". + attr_accessor :tar_program - if file_pattern - create_archive(file_pattern) - end + # The name of the archive file after compression, e.g. "test.tar.gz" + attr_reader :compressed_archive_name - if program - compress_archive(program) - end - end + # Returns an Archive::Tar::External object. The +archive_name+ is the + # name of the tarball. While a .tar extension is recommended based on + # years of convention, it is not enforced. + # + # Note that this does not actually create the archive unless you + # pass a value to +file_pattern+. This then becomes a shortcut for + # Archive::Tar::External.new + Archive::Tar::External#create_archive. + # + # If +program+ is provided, then it compresses the archive as well by + # calling Archive::Tar::External#compress_archive internally. + # + def initialize(archive_name, file_pattern=nil, program=nil) + @archive_name = archive_name.to_s + @compressed_archive_name = nil + @tar_program = "tar" - # Assign a compressed archive name. This autogenerates the archive_name - # based on the extension of the name provided, unless you provide the - # extension yourself. If the extension is '.tgz', then the base of the - # name + '.tar' will be the new archive name. - # - # This should only be used if you have a pre-existing, compressed archive - # that you want to uncompress, and want to have a Tar::External object - # around. Otherwise, use the class method Tar::External.uncompress. - # - def compressed_archive_name=(name, ext=File.extname(name)) - if ext == '.tgz' || ext == '.TGZ' - @archive_name = File.basename(name, ext.downcase) + '.tar' - else - @archive_name = File.basename(name, ext) - end - @compressed_archive_name = name - end - - # Creates the archive using +file_pattern+. Any errors that occur - # here will raise a TarError. - # - def create_archive(file_pattern) - cmd = "#{@tar_program} cf #{@archive_name} #{file_pattern}" - Open3.popen3(cmd){ |tar_in, tar_out, tar_err| - err = tar_err.gets - if err - raise TarError, err.chomp + if file_pattern + create_archive(file_pattern) end - } - self - end - alias :create :create_archive - # Compresses the archive with +program+, or gzip if no program is - # provided. If you want to pass arguments to +program+, merely include - # them as part of the program name, e.g. "gzip -f". - # - # Any errors that occur here will raise a CompressError. - # - def compress_archive(program="gzip") - cmd = "#{program} #{@archive_name}" - Open3.popen3(cmd){ |prog_in, prog_out, prog_err| - err = prog_err.gets - if err - raise CompressError, err.chomp + if program + compress_archive(program) end + end - # Find the new file name with the extension. There's probably a more - # reliable way to do this, but this should work 99% of the time. - name = Dir["#{@archive_name}.{gz,bz2,cpio,zip}"].first + # Assign a compressed archive name. This autogenerates the archive_name + # based on the extension of the name provided, unless you provide the + # extension yourself. If the extension is '.tgz', then the base of the + # name + '.tar' will be the new archive name. + # + # This should only be used if you have a pre-existing, compressed archive + # that you want to uncompress, and want to have a Tar::External object + # around. Otherwise, use the class method Tar::External.uncompress. + # + def compressed_archive_name=(name, ext=File.extname(name)) + if ext == '.tgz' || ext == '.TGZ' + @archive_name = File.basename(name, ext.downcase) + '.tar' + else + @archive_name = File.basename(name, ext) + end @compressed_archive_name = name - } - self - end - alias :compress :compress_archive + end - # Uncompresses the tarball using the program you pass to this method. The - # default is "gunzip". Just as for +compress_archive+, you can pass - # arguments along as part of the argument. - # - # Note that this is only for use with archives that have been zipped up - # with gunzip, or whatever. If you want to *extract* the files from the - # tarball, use Tar::External#extract instead. - # - # Any errors that occur here will raise a CompressError. - # - def uncompress_archive(program="gunzip") - unless @compressed_archive_name - raise CompressError, "no compressed file found" + # Creates the archive using +file_pattern+. Any errors that occur + # here will raise a Error. + # + def create_archive(file_pattern) + cmd = "#{@tar_program} cf #{@archive_name} #{file_pattern}" + Open3.popen3(cmd){ |tar_in, tar_out, tar_err| + err = tar_err.gets + if err + raise Error, err.chomp + end + } + self end - - cmd = "#{program} #{@compressed_archive_name}" + alias :create :create_archive - Open3.popen3(cmd){ |prog_in, prog_out, prog_err| - err = prog_err.gets - if err - raise CompressError, err.chomp - end - @compressed_archive_name = nil - } - self - end - alias :uncompress :uncompress_archive + # Compresses the archive with +program+, or gzip if no program is + # provided. If you want to pass arguments to +program+, merely include + # them as part of the program name, e.g. "gzip -f". + # + # Any errors that occur here will raise a Tar::CompressError. + # + def compress_archive(program="gzip") + cmd = "#{program} #{@archive_name}" + Open3.popen3(cmd){ |prog_in, prog_out, prog_err| + err = prog_err.gets + if err + raise CompressError, err.chomp + end - # Uncompress an existing archive, using +program+ to uncompress it. - # The default decompression program is gunzip. - # - def self.uncompress_archive(archive, program='gunzip') - cmd = "#{program} #{archive}" + # Find the new file name with the extension. There's probably a more + # reliable way to do this, but this should work 99% of the time. + name = Dir["#{@archive_name}.{gz,bz2,cpio,zip}"].first + @compressed_archive_name = name + } + self + end + alias :compress :compress_archive - Open3.popen3(cmd){ |prog_in, prog_out, prog_err| - err = prog_err.gets - if err - raise CompressError, err.chomp + # Uncompresses the tarball using the program you pass to this method. The + # default is "gunzip". Just as for +compress_archive+, you can pass + # arguments along as part of the argument. + # + # Note that this is only for use with archives that have been zipped up + # with gunzip, or whatever. If you want to *extract* the files from the + # tarball, use Tar::External#extract instead. + # + # Any errors that occur here will raise a Tar::CompressError. + # + def uncompress_archive(program="gunzip") + unless @compressed_archive_name + raise CompressError, "no compressed file found" end - } - end + + cmd = "#{program} #{@compressed_archive_name}" - # An alias for Tar::External.uncompress_archive. - # - def self.uncompress(file, program='gunzip') - self.uncompress_archive(file, program) - end + Open3.popen3(cmd){ |prog_in, prog_out, prog_err| + err = prog_err.gets + if err + raise CompressError, err.chomp + end + @compressed_archive_name = nil + } + self + end + alias :uncompress :uncompress_archive - # Returns an array of file names that are included within the tarball. - # This method does not extract the archive. - # - def archive_info - result = [] - cmd = "#{@tar_program} tf #{@archive_name}" - Open3.popen3(cmd){ |ain, aout, aerr| - err = aerr.gets - if err - raise TarError, err.chomp - end + # Uncompress an existing archive, using +program+ to uncompress it. + # The default decompression program is gunzip. + # + def self.uncompress_archive(archive, program='gunzip') + cmd = "#{program} #{archive}" - while output = aout.gets - result << output.chomp - end - } - result - end - alias :info :archive_info + Open3.popen3(cmd){ |prog_in, prog_out, prog_err| + err = prog_err.gets + if err + raise CompressError, err.chomp + end + } + end - # Adds +files+ to an already existing archive. - # - def add_to_archive(*files) - if files.empty? - raise TarError, "there must be at least one file specified" + # An alias for Tar::External.uncompress_archive. + # + def self.uncompress(file, program='gunzip') + self.uncompress_archive(file, program) end - cmd = "#{@tar_program} rf #{@archive_name} #{files.join(" ")}" - Open3.popen3(cmd){ |ain, aout, aerr| - err = aerr.gets + # Returns an array of file names that are included within the tarball. + # This method does not extract the archive. + # + def archive_info + result = [] + cmd = "#{@tar_program} tf #{@archive_name}" + Open3.popen3(cmd){ |ain, aout, aerr| + err = aerr.gets + if err + raise Error, err.chomp + end - if err - raise TarError, err.chomp + while output = aout.gets + result << output.chomp + end + } + result + end + alias :info :archive_info + + # Adds +files+ to an already existing archive. + # + def add_to_archive(*files) + if files.empty? + raise Error, "there must be at least one file specified" end - } - self - end - alias :add :add_to_archive - # Updates the given +files+ in the archive, i.e. they are added if they - # are not already in the archive or have been modified. - # - def update_archive(*files) - if files.empty? - raise TarError, "there must be at least one file specified" + cmd = "#{@tar_program} rf #{@archive_name} #{files.join(" ")}" + Open3.popen3(cmd){ |ain, aout, aerr| + err = aerr.gets + + if err + raise Error, err.chomp + end + } + self end + alias :add :add_to_archive - cmd = "#{@tar_program} uf #{@archive_name} #{files.join(" ")}" - - Open3.popen3(cmd){ |ain, aout, aerr| - err = aerr.gets - if err - raise TarError, err.chomp + # Updates the given +files+ in the archive, i.e. they are added if they + # are not already in the archive or have been modified. + # + def update_archive(*files) + if files.empty? + raise Error, "there must be at least one file specified" end - } - self - end - alias :update :update_archive - # Expands the contents of the tarball. It does NOT delete the tarball. - # If +files+ are provided, then only those files are extracted. - # Otherwise, all files are extracted. - # - # Note that some tar programs, notably the tar program shipped by Sun, - # does not issue any sort of warning or error if you try to extract a - # file that does not exist in the archive. - # - def extract_archive(*files) - cmd = "#{@tar_program} xf #{@archive_name}" + cmd = "#{@tar_program} uf #{@archive_name} #{files.join(" ")}" - unless files.empty? - cmd << " " << files.join(" ") + Open3.popen3(cmd){ |ain, aout, aerr| + err = aerr.gets + if err + raise Error, err.chomp + end + } + self end + alias :update :update_archive - Open3.popen3(cmd){ |ain, aout, aerr| - err = aerr.gets + # Expands the contents of the tarball. It does NOT delete the tarball. + # If +files+ are provided, then only those files are extracted. + # Otherwise, all files are extracted. + # + # Note that some tar programs, notably the tar program shipped by Sun, + # does not issue any sort of warning or error if you try to extract a + # file that does not exist in the archive. + # + def extract_archive(*files) + cmd = "#{@tar_program} xf #{@archive_name}" - if err - raise TarError, err.chomp + unless files.empty? + cmd << " " << files.join(" ") end - } - self - end - alias :expand_archive :extract_archive - alias :extract :extract_archive - alias :expand :extract_archive - # A class method that behaves identically to the equivalent instance - # method, except that you must specifiy that tarball as the first - # argument. Also, the tar program is hard coded to 'tar xf'. - # - def self.extract_archive(archive, *files) - cmd = "tar xf #{archive}" + Open3.popen3(cmd){ |ain, aout, aerr| + err = aerr.gets - unless files.empty? - cmd << " " << files.join(" ") + if err + raise Error, err.chomp + end + } + self end + alias :expand_archive :extract_archive + alias :extract :extract_archive + alias :expand :extract_archive - Open3.popen3(cmd){ |ain, aout, aerr| - err = aerr.gets + # A class method that behaves identically to the equivalent instance + # method, except that you must specifiy that tarball as the first + # argument. Also, the tar program is hard coded to 'tar xf'. + # + def self.extract_archive(archive, *files) + cmd = "tar xf #{archive}" - if err - raise TarError, err.chomp + unless files.empty? + cmd << " " << files.join(" ") end - } - self - end - # Alias for self.extract_archive - def self.expand_archive(*args) - self.extract_archive(*args) - end + Open3.popen3(cmd){ |ain, aout, aerr| + err = aerr.gets - # Alias for self.extract_archive - def self.extract(*args) - self.extract_archive(*args) - end + if err + raise Error, err.chomp + end + } + self + end - # Alias for self.extract_archive - def self.expand(*args) - self.extract_archive(*args) + # Alias for self.extract_archive + def self.expand_archive(*args) + self.extract_archive(*args) + end + + # Alias for self.extract_archive + def self.extract(*args) + self.extract_archive(*args) + end + + # Alias for self.extract_archive + def self.expand(*args) + self.extract_archive(*args) + end end end end