Search code examples
rubytararchive

TarWriter help adding multiple directories and files


The code in this question works, but only with a single directory. I can also make it output a file archive as well. But not both a file and a directory, or two directories. I am hoping to make it work with a list of paths, including directories and files that are all placed in the same archive. If I try to add more than one path, the tarfile becomes corrupted. I thought I could continue adding files/data to archive as long as the TarWriter object is open.

QUESTION: In addition to how I can make the above example work with multiple paths (in linked post), can someone please help explain how files and directories are added into an archive? I have looked at the directory structure/format, but I can't seem to understand why this wouldn't work with more than one directory/file.


Solution

  • You can add multiple paths to Dir object

    Dir[File.join(path1, '**/*'), File.join(path2, '**/*')]
    

    After which the code would be something like this:

    BLOCKSIZE_TO_READ = 1024 * 1000
    
    def create_tarball(path)
    
      tar_filename = Pathname.new(path).realpath.to_path + '.tar'
    
      File.open(tar_filename, 'wb') do |tarfile|
    
        Gem::Package::TarWriter.new(tarfile) do |tar|
    
          Dir[File.join(path1, '**/*'), File.join(path2, '**/*')].each do |file|
    
            mode = File.stat(file).mode
            relative_file = file.sub(/^#{ Regexp.escape(path) }\/?/, '')
    
            if File.directory?(file)
              tar.mkdir(relative_file, mode)
            else
    
              tar.add_file(relative_file, mode) do |tf|
                File.open(file, 'rb') do |f|
                  while buffer = f.read(BLOCKSIZE_TO_READ)
                    tf.write buffer
                  end
                end
              end
    
            end
          end
        end
      end
    
      tar_filename
    
    end