class PoiseArchive::ArchiveProviders::Tar

The `tar` provider class for `poise_archive` to install from tar archives.

@see PoiseArchive::Resources::PoiseArchive::Resource @provides poise_archive

Constants

Hack that GNU tar uses for paths over 100 bytes.

@api private @see unpack_tar

Private Instance Methods

chown_entries() click to toggle source
# File lib/poise_archive/archive_providers/tar.rb, line 144
def chown_entries
  paths = @tar_entry_paths
  notifying_block do
    paths.each do |type, path|
      send(type, path) do
        group new_resource.group
        owner new_resource.user
      end
    end
  end
end
close_file!() click to toggle source

Close all the various file handles.

@return [void]

# File lib/poise_archive/archive_providers/tar.rb, line 129
def close_file!
  if @tar_reader
    @tar_reader.close
    @tar_reader = nil
  end
  if @file
    @file.close
    @file = nil
  end
  if @raw_file
    @raw_file.close unless @raw_file.closed?
    @raw_file = nil
  end
end
open_file!() click to toggle source

Open a file handle of the correct flavor.

@return [void]

# File lib/poise_archive/archive_providers/tar.rb, line 110
def open_file!
  @raw_file = ::File.open(new_resource.absolute_path, 'rb')
  @file = case new_resource.absolute_path
  when /\.tar$/
    nil # So it uses @raw_file instead.
  when /\.t?gz/
    Zlib::GzipReader.wrap(@raw_file)
  when /\.t?bz/
    # This can't take a block, hence the gross non-block forms for everything.
    PoiseArchive::Bzip2::Decompressor.new(@raw_file)
  else
    raise RuntimeError.new("Unknown or unsupported file extension for #{new_resource.path}")
  end
  @tar_reader = Gem::Package::TarReader.new(@file || @raw_file)
end
tar_each(&block) click to toggle source

Sequence the opening, iteration, and closing.

@param block [Proc] Block to process each tar entry. @return [void]

# File lib/poise_archive/archive_providers/tar.rb, line 98
def tar_each(&block)
  # In case of extreme weirdness where this happens twice.
  close_file!
  open_file!
  @tar_reader.each(&block)
ensure
  close_file!
end
unpack_archive() click to toggle source
# File lib/poise_archive/archive_providers/tar.rb, line 41
def unpack_archive
  unpack_tar
  chown_entries if new_resource.user || new_resource.group
end
unpack_tar() click to toggle source

Unpack the archive.

@return [void]

# File lib/poise_archive/archive_providers/tar.rb, line 49
def unpack_tar
  @tar_entry_paths = []
  tar_each_with_longlink do |entry|
    entry_name = entry.full_name.split(/\//).drop(new_resource.strip_components).join('/')
    # If strip_components wiped out the name, don't process this entry.
    next if entry_name.empty?
    dest = ::File.join(new_resource.destination, entry_name)
    if entry.directory?
      Dir.mkdir(dest, entry.header.mode)
      @tar_entry_paths << [:directory, dest]
    elsif entry.file?
      ::File.open(dest, 'wb', entry.header.mode) do |dest_f|
        while buf = entry.read(4096)
          dest_f.write(buf)
        end
      end
      @tar_entry_paths << [:file, dest]
    elsif entry.header.typeflag == '2' # symlink? is new in Ruby 2.0, apparently.
      ::File.symlink(entry.header.linkname, dest)
      @tar_entry_paths << [:link, dest]
    else
      raise RuntimeError.new("Unknown tar entry type #{entry.header.typeflag.inspect} in #{new_resource.path}")
    end
  end
end