class Excavate::Archive
Constants
- TYPES
Public Class Methods
new(archive)
click to toggle source
# File lib/excavate/archive.rb, line 13 def initialize(archive) @archive = archive end
Public Instance Methods
extract(target = nil, recursive_packages: false)
click to toggle source
# File lib/excavate/archive.rb, line 28 def extract(target = nil, recursive_packages: false) source = File.expand_path(@archive) target ||= default_target(source) raise(TargetNotEmptyError, "Target directory `#{File.basename(target)}` is not empty.") unless Dir.empty?(target) if recursive_packages extract_recursively(source, target) else extract_once(source, target) end target end
files(recursive_packages: false) { |file| ... }
click to toggle source
# File lib/excavate/archive.rb, line 17 def files(recursive_packages: false) target = Dir.mktmpdir extract(target, recursive_packages: recursive_packages) all_files_in(target).map do |file| yield file end ensure FileUtils.rm_rf(target) end
Private Instance Methods
all_files_in(dir)
click to toggle source
# File lib/excavate/archive.rb, line 103 def all_files_in(dir) Dir.glob(File.join(dir, "**", "*")) end
archive?(file)
click to toggle source
# File lib/excavate/archive.rb, line 107 def archive?(file) return false unless File.file?(file) ext = normalized_extension(file) TYPES.key?(ext) end
default_target(source)
click to toggle source
# File lib/excavate/archive.rb, line 44 def default_target(source) target = File.expand_path(File.basename(source, ".*")) raise(TargetExistsError, "Target directory `#{File.basename(target)}` already exists.") if File.exist?(target) FileUtils.mkdir(target) target end
extract_and_replace(archive)
click to toggle source
# File lib/excavate/archive.rb, line 75 def extract_and_replace(archive) target = Dir.mktmpdir extract_recursively(archive, target) FileUtils.rm(archive) FileUtils.mv(target, archive) rescue FFI::NullPointerError => e FileUtils.rmdir(target) raise unless normalized_extension(archive) == "exe" && e.message.start_with?("invalid memory read at address=0x0000000000000000") end
extract_once(archive, target)
click to toggle source
# File lib/excavate/archive.rb, line 63 def extract_once(archive, target) extension = normalized_extension(archive) extractor_class = TYPES[extension] raise(UnknownArchiveError, "Could not unarchive `#{archive}`.") unless extractor_class extractor_class.new(archive).extract(target) rescue StandardError => e raise unless extension == "exe" && e.message.start_with?("Invalid file format") Extractors::CabExtractor.new(archive).extract(target) end
extract_recursively(archive, target)
click to toggle source
# File lib/excavate/archive.rb, line 53 def extract_recursively(archive, target) extract_once(archive, target) all_files_in(target).each do |file| next unless archive?(file) extract_and_replace(file) end end
fetch_extension(file)
click to toggle source
# File lib/excavate/archive.rb, line 91 def fetch_extension(file) File.extname(filename(file)).sub(/^\./, "") end
filename(file)
click to toggle source
# File lib/excavate/archive.rb, line 95 def filename(file) if file.respond_to?(:original_filename) file.original_filename else File.basename(file) end end
normalized_extension(file)
click to toggle source
# File lib/excavate/archive.rb, line 87 def normalized_extension(file) fetch_extension(file).downcase end