Introduce UnpackStrategyImpl

This commit is contained in:
Douglas Eichelberger 2024-07-05 22:29:41 -07:00 committed by Issy Long
parent 0a18f77de4
commit 4ebf1116d7
31 changed files with 63 additions and 72 deletions

View File

@ -6,47 +6,27 @@ require "system_command"
# Module containing all available strategies for unpacking archives. # Module containing all available strategies for unpacking archives.
module UnpackStrategy module UnpackStrategy
extend T::Helpers extend T::Helpers
include SystemCommand::Mixin
abstract!
# FIXME: Enable cop again when https://github.com/sorbet/sorbet/issues/3532 is fixed. # rubocop:disable Style/MutableConstant
AnyStrategy = T.type_alias do # rubocop:disable Style/MutableConstant UnpackStrategyImpl = T.type_alias { T.all(T::Class[UnpackStrategy], UnpackStrategy::ClassMethods) }
T.any( # rubocop:enable Style/MutableConstant
T.class_of(UnpackStrategy::Tar),
T.class_of(UnpackStrategy::Pax), module ClassMethods
T.class_of(UnpackStrategy::Gzip), extend T::Helpers
T.class_of(UnpackStrategy::Dmg), abstract!
T.class_of(UnpackStrategy::Lzma),
T.class_of(UnpackStrategy::Xz), sig { abstract.returns(T::Array[String]) }
T.class_of(UnpackStrategy::Zstd), def extensions; end
T.class_of(UnpackStrategy::Lzip),
T.class_of(UnpackStrategy::Air), sig { abstract.params(path: Pathname).returns(T::Boolean) }
T.class_of(UnpackStrategy::Jar), def can_extract?(path); end
T.class_of(UnpackStrategy::LuaRock),
T.class_of(UnpackStrategy::MicrosoftOfficeXml),
T.class_of(UnpackStrategy::Zip),
T.class_of(UnpackStrategy::Pkg),
T.class_of(UnpackStrategy::Xar),
T.class_of(UnpackStrategy::Ttf),
T.class_of(UnpackStrategy::Otf),
T.class_of(UnpackStrategy::Git),
T.class_of(UnpackStrategy::Mercurial),
T.class_of(UnpackStrategy::Subversion),
T.class_of(UnpackStrategy::Cvs),
T.class_of(UnpackStrategy::SelfExtractingExecutable),
T.class_of(UnpackStrategy::Cab),
T.class_of(UnpackStrategy::Executable),
T.class_of(UnpackStrategy::Bzip2),
T.class_of(UnpackStrategy::Fossil),
T.class_of(UnpackStrategy::Bazaar),
T.class_of(UnpackStrategy::P7Zip),
T.class_of(UnpackStrategy::Sit),
T.class_of(UnpackStrategy::Rar),
T.class_of(UnpackStrategy::Lha),
)
end end
include SystemCommand::Mixin mixes_in_class_methods(ClassMethods)
sig { returns(T.nilable(T::Array[AnyStrategy])) } sig { returns(T.nilable(T::Array[UnpackStrategyImpl])) }
def self.strategies def self.strategies
@strategies ||= T.let([ @strategies ||= T.let([
Tar, # Needs to be before Bzip2/Gzip/Xz/Lzma/Zstd. Tar, # Needs to be before Bzip2/Gzip/Xz/Lzma/Zstd.
@ -81,11 +61,11 @@ module UnpackStrategy
Sit, Sit,
Rar, Rar,
Lha, Lha,
].freeze, T.nilable(T::Array[AnyStrategy])) ].freeze, T.nilable(T::Array[UnpackStrategyImpl]))
end end
private_class_method :strategies private_class_method :strategies
sig { params(type: Symbol).returns(T.nilable(T.any(T.class_of(UnpackStrategy::Uncompressed), AnyStrategy))) } sig { params(type: Symbol).returns(T.nilable(UnpackStrategyImpl)) }
def self.from_type(type) def self.from_type(type)
type = { type = {
naked: :uncompressed, naked: :uncompressed,
@ -100,7 +80,7 @@ module UnpackStrategy
end end
end end
sig { params(extension: String).returns(T.nilable(AnyStrategy)) } sig { params(extension: String).returns(T.nilable(UnpackStrategyImpl)) }
def self.from_extension(extension) def self.from_extension(extension)
return unless strategies return unless strategies
@ -109,7 +89,7 @@ module UnpackStrategy
&.find { |s| s.extensions.any? { |ext| extension.end_with?(ext) } } &.find { |s| s.extensions.any? { |ext| extension.end_with?(ext) } }
end end
sig { params(path: Pathname).returns(T.nilable(AnyStrategy)) } sig { params(path: Pathname).returns(T.nilable(UnpackStrategyImpl)) }
def self.from_magic(path) def self.from_magic(path)
strategies&.find { |s| s.can_extract?(path) } strategies&.find { |s| s.can_extract?(path) }
end end
@ -152,7 +132,6 @@ module UnpackStrategy
@merge_xattrs = merge_xattrs @merge_xattrs = merge_xattrs
end end
abstract!
sig { abstract.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).void } sig { abstract.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).void }
def extract_to_dir(unpack_dir, basename:, verbose:); end def extract_to_dir(unpack_dir, basename:, verbose:); end
private :extract_to_dir private :extract_to_dir

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Air class Air
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".air"] [".air"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Bzip2 class Bzip2
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".bz2"] [".bz2"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Cab class Cab
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".cab"] [".cab"]
end end

View File

@ -6,7 +6,7 @@ require_relative "tar"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking compress archives. # Strategy for unpacking compress archives.
class Compress < Tar class Compress < Tar
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".Z"] [".Z"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Directory class Directory
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[] []
end end

View File

@ -121,6 +121,12 @@ module UnpackStrategy
end end
end end
sig { override.returns(T::Array[String]) }
def self.extensions = []
sig { override.params(_path: Pathname).returns(T::Boolean) }
def self.can_extract?(_path) = false
private private
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
@ -165,7 +171,7 @@ module UnpackStrategy
end end
private_constant :Mount private_constant :Mount
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".dmg"] [".dmg"]
end end

View File

@ -6,7 +6,7 @@ require_relative "uncompressed"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking executables. # Strategy for unpacking executables.
class Executable < Uncompressed class Executable < Uncompressed
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".sh", ".bash"] [".sh", ".bash"]
end end

View File

@ -9,7 +9,7 @@ module UnpackStrategy
include UnpackStrategy include UnpackStrategy
extend SystemCommand::Mixin extend SystemCommand::Mixin
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[] []
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class GenericUnar class GenericUnar
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[] []
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Gzip class Gzip
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".gz"] [".gz"]
end end

View File

@ -6,7 +6,7 @@ require_relative "uncompressed"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking Java archives. # Strategy for unpacking Java archives.
class Jar < Uncompressed class Jar < Uncompressed
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".apk", ".jar"] [".apk", ".jar"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Lha class Lha
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".lha", ".lzh"] [".lha", ".lzh"]
end end

View File

@ -6,7 +6,7 @@ require_relative "uncompressed"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking LuaRock archives. # Strategy for unpacking LuaRock archives.
class LuaRock < Uncompressed class LuaRock < Uncompressed
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".rock"] [".rock"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Lzip class Lzip
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".lz"] [".lz"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Lzma class Lzma
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".lzma"] [".lzma"]
end end

View File

@ -6,7 +6,7 @@ require_relative "uncompressed"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking Microsoft Office documents. # Strategy for unpacking Microsoft Office documents.
class MicrosoftOfficeXml < Uncompressed class MicrosoftOfficeXml < Uncompressed
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[ [
".doc", ".docx", ".doc", ".docx",

View File

@ -6,7 +6,7 @@ require_relative "uncompressed"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking OpenType fonts. # Strategy for unpacking OpenType fonts.
class Otf < Uncompressed class Otf < Uncompressed
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".otf"] [".otf"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class P7Zip class P7Zip
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".7z"] [".7z"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Pax class Pax
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".pax"] [".pax"]
end end

View File

@ -6,7 +6,7 @@ require_relative "uncompressed"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking macOS package installers. # Strategy for unpacking macOS package installers.
class Pkg < Uncompressed class Pkg < Uncompressed
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".pkg", ".mkpg"] [".pkg", ".mkpg"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Rar class Rar
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".rar"] [".rar"]
end end

View File

@ -6,7 +6,7 @@ require_relative "generic_unar"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking self-extracting executables. # Strategy for unpacking self-extracting executables.
class SelfExtractingExecutable < GenericUnar class SelfExtractingExecutable < GenericUnar
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[] []
end end

View File

@ -6,7 +6,7 @@ require_relative "generic_unar"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking Stuffit archives. # Strategy for unpacking Stuffit archives.
class Sit < GenericUnar class Sit < GenericUnar
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".sit"] [".sit"]
end end

View File

@ -9,7 +9,7 @@ module UnpackStrategy
include UnpackStrategy include UnpackStrategy
extend SystemCommand::Mixin extend SystemCommand::Mixin
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[ [
".tar", ".tar",

View File

@ -6,7 +6,7 @@ require_relative "uncompressed"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking TrueType fonts. # Strategy for unpacking TrueType fonts.
class Ttf < Uncompressed class Ttf < Uncompressed
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".ttc", ".ttf"] [".ttc", ".ttf"]
end end

View File

@ -6,6 +6,12 @@ module UnpackStrategy
class Uncompressed class Uncompressed
include UnpackStrategy include UnpackStrategy
sig { override.returns(T::Array[String]) }
def self.extensions = []
sig { override.params(_path: Pathname).returns(T::Boolean) }
def self.can_extract?(_path) = false
sig { sig {
params( params(
to: T.nilable(Pathname), to: T.nilable(Pathname),

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Xar class Xar
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".xar"] [".xar"]
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Xz class Xz
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".xz"] [".xz"]
end end

View File

@ -6,12 +6,12 @@ module UnpackStrategy
class Zip class Zip
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".zip"] [".zip"]
end end
sig { params(path: Pathname).returns(T::Boolean) } sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\APK(\003\004|\005\006)/n) path.magic_number.match?(/\APK(\003\004|\005\006)/n)
end end

View File

@ -6,7 +6,7 @@ module UnpackStrategy
class Zstd class Zstd
include UnpackStrategy include UnpackStrategy
sig { returns(T::Array[String]) } sig { override.returns(T::Array[String]) }
def self.extensions def self.extensions
[".zst"] [".zst"]
end end