brew/Library/Homebrew/unpack_strategy.rb

158 lines
3.9 KiB
Ruby
Raw Normal View History

module UnpackStrategy
# length of the longest regex (currently Tar)
2018-07-01 23:35:29 +02:00
MAX_MAGIC_NUMBER_LENGTH = 262
private_constant :MAX_MAGIC_NUMBER_LENGTH
def self.strategies
@strategies ||= [
2018-07-27 11:42:34 +02:00
Air, # needs to be before Zip
2018-07-25 23:34:17 +02:00
Jar, # needs to be before Zip
LuaRock, # needs to be before Zip
MicrosoftOfficeXml, # needs to be before Zip
2018-07-27 11:42:34 +02:00
Zip, # needs to be before Tar
Pkg, # needs to be before Xar
Xar, # needs to be before Tar
2018-07-25 23:34:17 +02:00
Tar, # needs to be before Bzip2/Gzip/Xz/Lzma
Gzip,
Lzma,
Xz,
Lzip,
2018-07-27 11:42:34 +02:00
Executable,
Diff,
Git,
Mercurial,
Subversion,
Cvs,
2018-07-27 11:42:34 +02:00
Ttf,
Otf,
2018-07-25 23:34:17 +02:00
Dmg, # needs to be before Bzip2
Bzip2,
Fossil,
Bazaar,
2018-07-25 23:34:17 +02:00
SelfExtractingExecutable, # needs to be before Cab
Cab,
2018-07-27 11:42:34 +02:00
Compress,
P7Zip,
Sit,
Rar,
Lha,
2018-07-01 23:35:29 +02:00
].freeze
end
private_class_method :strategies
def self.from_type(type)
type = {
naked: :uncompressed,
seven_zip: :p7zip,
}.fetch(type, type)
begin
const_get(type.to_s.split("_").map(&:capitalize).join)
rescue NameError
nil
end
end
def self.from_path(path)
2018-07-01 23:35:29 +02:00
magic_number = if path.directory?
""
else
2018-07-09 20:04:33 +02:00
File.binread(path, MAX_MAGIC_NUMBER_LENGTH) || ""
2018-07-01 23:35:29 +02:00
end
strategy = strategies.detect do |s|
s.can_extract?(path: path, magic_number: magic_number)
end
# This is so that bad files produce good error messages.
strategy ||= case path.extname
2018-07-09 20:04:33 +02:00
when ".tar", ".tar.gz", ".tgz", ".tar.bz2", ".tbz", ".tar.xz", ".txz"
Tar
2018-07-01 23:35:29 +02:00
when ".zip"
Zip
2018-07-01 23:35:29 +02:00
else
Uncompressed
2018-07-01 23:35:29 +02:00
end
strategy
end
def self.detect(path, type: nil, ref_type: nil, ref: nil)
strategy = type ? from_type(type) : from_path(path)
strategy.new(path, ref_type: ref_type, ref: ref)
2018-07-01 23:35:29 +02:00
end
attr_reader :path
def initialize(path, ref_type: nil, ref: nil)
2018-07-01 23:35:29 +02:00
@path = Pathname(path).expand_path
@ref_type = ref_type
@ref = ref
2018-07-01 23:35:29 +02:00
end
def extract(to: nil, basename: nil, verbose: false)
2018-07-09 20:04:33 +02:00
basename ||= path.basename
2018-07-01 23:35:29 +02:00
unpack_dir = Pathname(to || Dir.pwd).expand_path
unpack_dir.mkpath
extract_to_dir(unpack_dir, basename: basename, verbose: verbose)
2018-07-01 23:35:29 +02:00
end
2018-07-16 19:00:49 +02:00
def extract_nestedly(to: nil, basename: nil, verbose: false)
2018-07-16 19:00:49 +02:00
Dir.mktmpdir do |tmp_unpack_dir|
tmp_unpack_dir = Pathname(tmp_unpack_dir)
extract(to: tmp_unpack_dir, basename: basename, verbose: verbose)
2018-07-16 19:00:49 +02:00
children = tmp_unpack_dir.children
if children.count == 1 && !children.first.directory?
s = UnpackStrategy.detect(children.first)
2018-07-16 19:00:49 +02:00
s.extract_nestedly(to: to, verbose: verbose)
2018-07-16 19:00:49 +02:00
next
end
Directory.new(tmp_unpack_dir).extract(to: to, verbose: verbose)
2018-07-16 19:00:49 +02:00
end
end
def dependencies
[]
end
2018-07-01 23:35:29 +02:00
end
require "unpack_strategy/air"
require "unpack_strategy/bazaar"
require "unpack_strategy/bzip2"
require "unpack_strategy/cab"
require "unpack_strategy/compress"
require "unpack_strategy/cvs"
2018-07-27 02:42:19 +02:00
require "unpack_strategy/diff"
require "unpack_strategy/directory"
require "unpack_strategy/dmg"
require "unpack_strategy/executable"
require "unpack_strategy/fossil"
require "unpack_strategy/generic_unar"
require "unpack_strategy/git"
require "unpack_strategy/gzip"
require "unpack_strategy/jar"
require "unpack_strategy/lha"
require "unpack_strategy/lua_rock"
require "unpack_strategy/lzip"
require "unpack_strategy/lzma"
require "unpack_strategy/mercurial"
require "unpack_strategy/microsoft_office_xml"
require "unpack_strategy/otf"
require "unpack_strategy/p7zip"
require "unpack_strategy/pkg"
require "unpack_strategy/rar"
require "unpack_strategy/self_extracting_executable"
require "unpack_strategy/sit"
require "unpack_strategy/subversion"
require "unpack_strategy/tar"
require "unpack_strategy/ttf"
require "unpack_strategy/uncompressed"
require "unpack_strategy/xar"
require "unpack_strategy/xz"
require "unpack_strategy/zip"