Merge pull request #17636 from Homebrew/sorbet-strict-public-apis

This commit is contained in:
Issy Long 2024-07-12 17:25:41 +01:00 committed by GitHub
commit 1479013710
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 260 additions and 151 deletions

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require "version" require "version"
@ -16,7 +16,7 @@ class DevelopmentTools
# Don't call tools (cc, make, strip, etc.) directly! # Don't call tools (cc, make, strip, etc.) directly!
# Give the name of the binary you look for as a string to this method # Give the name of the binary you look for as a string to this method
# in order to get the full path back as a Pathname. # in order to get the full path back as a Pathname.
(@locate ||= {}).fetch(tool) do |key| (@locate ||= T.let({}, T.nilable(T::Hash[T.any(String, Symbol), T.untyped]))).fetch(tool) do |key|
@locate[key] = if File.executable?((path = "/usr/bin/#{tool}")) @locate[key] = if File.executable?((path = "/usr/bin/#{tool}"))
Pathname.new path Pathname.new path
# Homebrew GCCs most frequently; much faster to check this before xcrun # Homebrew GCCs most frequently; much faster to check this before xcrun
@ -62,12 +62,14 @@ class DevelopmentTools
# @api public # @api public
sig { returns(Version) } sig { returns(Version) }
def clang_version def clang_version
@clang_version ||= if (path = locate("clang")) && @clang_version ||= T.let(
if (path = locate("clang")) &&
(build_version = `#{path} --version`[/(?:clang|LLVM) version (\d+\.\d(?:\.\d)?)/, 1]) (build_version = `#{path} --version`[/(?:clang|LLVM) version (\d+\.\d(?:\.\d)?)/, 1])
Version.new build_version Version.new(build_version)
else else
Version::NULL Version::NULL
end end, T.nilable(Version)
)
end end
# Get the Clang build version. # Get the Clang build version.
@ -75,13 +77,14 @@ class DevelopmentTools
# @api public # @api public
sig { returns(Version) } sig { returns(Version) }
def clang_build_version def clang_build_version
@clang_build_version ||= if (path = locate("clang")) && @clang_build_version ||= T.let(
(build_version = `#{path} --version`[ if (path = locate("clang")) &&
%r{clang(-| version [^ ]+ \(tags/RELEASE_)(\d{2,})}, 2]) (build_version = `#{path} --version`[%r{clang(-| version [^ ]+ \(tags/RELEASE_)(\d{2,})}, 2])
Version.new build_version Version.new(build_version)
else else
Version::NULL Version::NULL
end end, T.nilable(Version)
)
end end
# Get the LLVM Clang build version. # Get the LLVM Clang build version.
@ -89,15 +92,14 @@ class DevelopmentTools
# @api public # @api public
sig { returns(Version) } sig { returns(Version) }
def llvm_clang_build_version def llvm_clang_build_version
@llvm_clang_build_version ||= begin @llvm_clang_build_version ||= T.let(begin
path = Formulary.factory("llvm").opt_prefix/"bin/clang" path = Formulary.factory("llvm").opt_prefix/"bin/clang"
if path.executable? && if path.executable? && (build_version = `#{path} --version`[/clang version (\d+\.\d\.\d)/, 1])
(build_version = `#{path} --version`[/clang version (\d+\.\d\.\d)/, 1]) Version.new(build_version)
Version.new build_version
else else
Version::NULL Version::NULL
end end
end end, T.nilable(Version))
end end
# Get the GCC version. # Get the GCC version.
@ -105,12 +107,12 @@ class DevelopmentTools
# @api internal # @api internal
sig { params(cc: String).returns(Version) } sig { params(cc: String).returns(Version) }
def gcc_version(cc) def gcc_version(cc)
(@gcc_version ||= {}).fetch(cc) do (@gcc_version ||= T.let({}, T.nilable(T::Hash[String, Version]))).fetch(cc) do
path = HOMEBREW_PREFIX/"opt/#{CompilerSelector.preferred_gcc}/bin"/cc path = HOMEBREW_PREFIX/"opt/#{CompilerSelector.preferred_gcc}/bin"/cc
path = locate(cc) unless path.exist? path = locate(cc) unless path.exist?
version = if path && version = if path &&
(build_version = `#{path} --version`[/gcc(?:(?:-\d+(?:\.\d)?)? \(.+\))? (\d+\.\d\.\d)/, 1]) (build_version = `#{path} --version`[/gcc(?:(?:-\d+(?:\.\d)?)? \(.+\))? (\d+\.\d\.\d)/, 1])
Version.new build_version Version.new(build_version)
else else
Version::NULL Version::NULL
end end
@ -120,8 +122,8 @@ class DevelopmentTools
sig { void } sig { void }
def clear_version_cache def clear_version_cache
@clang_version = @clang_build_version = nil @clang_version = @clang_build_version = T.let(nil, T.nilable(Version))
@gcc_version = {} @gcc_version = T.let({}, T.nilable(T::Hash[String, Version]))
end end
sig { returns(T::Boolean) } sig { returns(T::Boolean) }

View File

@ -8,7 +8,7 @@ module UnpackStrategy
module MacOSZipExtension module MacOSZipExtension
private private
sig { params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
with_env(TZ: "UTC") do with_env(TZ: "UTC") do
if merge_xattrs && contains_extended_attributes?(path) if merge_xattrs && contains_extended_attributes?(path)

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module Homebrew module Homebrew
@ -10,15 +10,18 @@ module Homebrew
require "minitest/assertions" require "minitest/assertions"
include ::Minitest::Assertions include ::Minitest::Assertions
sig { params(assertions: Integer).returns(Integer) }
attr_writer :assertions attr_writer :assertions
sig { returns(Integer) }
def assertions def assertions
@assertions ||= 0 @assertions ||= T.let(0, T.nilable(Integer))
end end
# Returns the output of running cmd and asserts the exit status. # Returns the output of running cmd and asserts the exit status.
# #
# @api public # @api public
sig { params(cmd: String, result: Integer).returns(String) }
def shell_output(cmd, result = 0) def shell_output(cmd, result = 0)
ohai cmd ohai cmd
output = `#{cmd}` output = `#{cmd}`
@ -33,6 +36,7 @@ module Homebrew
# optionally asserts the exit status. # optionally asserts the exit status.
# #
# @api public # @api public
sig { params(cmd: String, input: T.nilable(String), result: T.nilable(Integer)).returns(String) }
def pipe_output(cmd, input = nil, result = nil) def pipe_output(cmd, input = nil, result = nil)
ohai cmd ohai cmd
output = IO.popen(cmd, "w+") do |pipe| output = IO.popen(cmd, "w+") do |pipe|

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require "system_command" require "system_command"
@ -6,11 +6,30 @@ 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 include SystemCommand::Mixin
abstract!
# FIXME: Enable cop again when https://github.com/sorbet/sorbet/issues/3532 is fixed.
# rubocop:disable Style/MutableConstant
UnpackStrategyType = T.type_alias { T.all(T::Class[UnpackStrategy], UnpackStrategy::ClassMethods) }
# rubocop:enable Style/MutableConstant
module ClassMethods
extend T::Helpers
abstract!
sig { abstract.returns(T::Array[String]) }
def extensions; end
sig { abstract.params(path: Pathname).returns(T::Boolean) }
def can_extract?(path); end
end
mixes_in_class_methods(ClassMethods)
sig { returns(T.nilable(T::Array[UnpackStrategyType])) }
def self.strategies def self.strategies
@strategies ||= [ @strategies ||= T.let([
Tar, # Needs to be before Bzip2/Gzip/Xz/Lzma/Zstd. Tar, # Needs to be before Bzip2/Gzip/Xz/Lzma/Zstd.
Pax, Pax,
Gzip, Gzip,
@ -43,10 +62,11 @@ module UnpackStrategy
Sit, Sit,
Rar, Rar,
Lha, Lha,
].freeze ].freeze, T.nilable(T::Array[UnpackStrategyType]))
end end
private_class_method :strategies private_class_method :strategies
sig { params(type: Symbol).returns(T.nilable(UnpackStrategyType)) }
def self.from_type(type) def self.from_type(type)
type = { type = {
naked: :uncompressed, naked: :uncompressed,
@ -61,23 +81,31 @@ module UnpackStrategy
end end
end end
sig { params(extension: String).returns(T.nilable(UnpackStrategyType)) }
def self.from_extension(extension) def self.from_extension(extension)
strategies.sort_by { |s| s.extensions.map(&:length).max || 0 } return unless strategies
.reverse
.find { |s| s.extensions.any? { |ext| extension.end_with?(ext) } } strategies&.sort_by { |s| s.extensions.map(&:length).max || 0 }
&.reverse
&.find { |s| s.extensions.any? { |ext| extension.end_with?(ext) } }
end end
sig { params(path: Pathname).returns(T.nilable(UnpackStrategyType)) }
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
def self.detect(path, prioritize_extension: false, type: nil, ref_type: nil, ref: nil, merge_xattrs: nil) sig {
params(path: Pathname, prioritize_extension: T::Boolean, type: T.nilable(Symbol), ref_type: T.nilable(Symbol),
ref: T.nilable(String), merge_xattrs: T::Boolean).returns(T.untyped)
}
def self.detect(path, prioritize_extension: false, type: nil, ref_type: nil, ref: nil, merge_xattrs: false)
strategy = from_type(type) if type strategy = from_type(type) if type
if prioritize_extension && path.extname.present? if prioritize_extension && path.extname.present?
strategy ||= from_extension(path.extname) strategy ||= from_extension(path.extname)
strategy ||= strategies.select { |s| s < Directory || s == Fossil }
.find { |s| s.can_extract?(path) } strategy ||= strategies&.find { |s| (s < Directory || s == Fossil) && s.can_extract?(path) }
else else
strategy ||= from_magic(path) strategy ||= from_magic(path)
strategy ||= from_extension(path.extname) strategy ||= from_extension(path.extname)
@ -88,24 +116,31 @@ module UnpackStrategy
strategy.new(path, ref_type:, ref:, merge_xattrs:) strategy.new(path, ref_type:, ref:, merge_xattrs:)
end end
attr_reader :path, :merge_xattrs sig { returns(Pathname) }
attr_reader :path
def initialize(path, ref_type: nil, ref: nil, merge_xattrs: nil) sig { returns(T::Boolean) }
@path = Pathname(path).expand_path attr_reader :merge_xattrs
@ref_type = ref_type
@ref = ref sig {
@merge_xattrs = merge_xattrs params(path: T.any(String, Pathname), ref_type: T.nilable(Symbol), ref: T.nilable(String),
merge_xattrs: T::Boolean).void
}
def initialize(path, ref_type: nil, ref: nil, merge_xattrs: false)
@path = T.let(Pathname(path).expand_path, Pathname)
@ref_type = T.let(ref_type, T.nilable(Symbol))
@ref = T.let(ref, T.nilable(String))
@merge_xattrs = T.let(merge_xattrs, T::Boolean)
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).returns(T.untyped) }
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
sig { sig {
params( params(
to: T.nilable(Pathname), basename: T.nilable(T.any(String, Pathname)), verbose: T::Boolean, to: T.nilable(Pathname), basename: T.nilable(T.any(String, Pathname)), verbose: T::Boolean,
).returns(T.untyped) ).void
} }
def extract(to: nil, basename: nil, verbose: false) def extract(to: nil, basename: nil, verbose: false)
basename ||= path.basename basename ||= path.basename
@ -131,7 +166,10 @@ module UnpackStrategy
children = tmp_unpack_dir.children children = tmp_unpack_dir.children
if children.size == 1 && !children.fetch(0).directory? if children.size == 1 && !children.fetch(0).directory?
s = UnpackStrategy.detect(children.first, prioritize_extension:) first_child = children.first
next if first_child.nil?
s = UnpackStrategy.detect(first_child, prioritize_extension:)
s.extract_nestedly(to:, verbose:, prioritize_extension:) s.extract_nestedly(to:, verbose:, prioritize_extension:)
@ -149,6 +187,7 @@ module UnpackStrategy
end end
end end
sig { returns(T::Array[String]) }
def dependencies def dependencies
[] []
end end

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,18 +6,20 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
mime_type = "application/vnd.adobe.air-application-installer-package+zip" mime_type = "application/vnd.adobe.air-application-installer-package+zip"
path.magic_number.match?(/.{59}#{Regexp.escape(mime_type)}/) path.magic_number.match?(/.{59}#{Regexp.escape(mime_type)}/)
end end
sig { returns(T.nilable(T::Array[Cask::Cask])) }
def dependencies def dependencies
@dependencies ||= [Cask::CaskLoader.load("adobe-air")] @dependencies ||= T.let([Cask::CaskLoader.load("adobe-air")], T.nilable(T::Array[Cask::Cask]))
end end
AIR_APPLICATION_INSTALLER = AIR_APPLICATION_INSTALLER =
@ -27,7 +29,7 @@ module UnpackStrategy
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! AIR_APPLICATION_INSTALLER, system_command! AIR_APPLICATION_INSTALLER,
args: ["-silent", "-location", unpack_dir, path], args: ["-silent", "-location", unpack_dir, path],

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "directory" require_relative "directory"
@ -6,13 +6,14 @@ require_relative "directory"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking Bazaar archives. # Strategy for unpacking Bazaar archives.
class Bazaar < Directory class Bazaar < Directory
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
super && (path/".bzr").directory? !!(super && (path/".bzr").directory?)
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
super super

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,18 +6,19 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\ABZh/n) path.magic_number.match?(/\ABZh/n)
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true FileUtils.cp path, unpack_dir/basename, preserve: true
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,16 +6,17 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\AMSCF/n) path.magic_number.match?(/\AMSCF/n)
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "cabextract", system_command! "cabextract",
args: ["-d", unpack_dir, "--", path], args: ["-d", unpack_dir, "--", path],
@ -23,8 +24,9 @@ module UnpackStrategy
verbose: verbose:
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["cabextract"]] @dependencies ||= T.let([Formula["cabextract"]], T.nilable(T::Array[Formula]))
end end
end end
end end

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "tar" require_relative "tar"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\A\037\235/n) path.magic_number.match?(/\A\037\235/n)
end end

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "directory" require_relative "directory"
@ -6,8 +6,9 @@ require_relative "directory"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking CVS repositories. # Strategy for unpacking CVS repositories.
class Cvs < Directory class Cvs < Directory
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
super && (path/"CVS").directory? !!(super && (path/"CVS").directory?)
end end
end end
end end

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,18 +6,19 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.directory? path.directory?
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
path.children.each do |child| path.children.each do |child|
system_command! "cp", system_command! "cp",

View File

@ -121,9 +121,15 @@ 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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
tries = 3 tries = 3
bom = begin bom = begin
@ -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
@ -177,7 +183,7 @@ module UnpackStrategy
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
mount(verbose:) do |mounts| mount(verbose:) do |mounts|
raise "No mounts found in '#{path}'; perhaps this is a bad disk image?" if mounts.empty? raise "No mounts found in '#{path}'; perhaps this is a bad disk image?" if mounts.empty?

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "uncompressed" require_relative "uncompressed"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\A#!\s*\S+/n) || path.magic_number.match?(/\A#!\s*\S+/n) ||
path.magic_number.match?(/\AMZ/n) path.magic_number.match?(/\AMZ/n)

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require "system_command" require "system_command"
@ -9,11 +9,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
return false unless path.magic_number.match?(/\ASQLite format 3\000/n) return false unless path.magic_number.match?(/\ASQLite format 3\000/n)
@ -24,7 +25,7 @@ module UnpackStrategy
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
args = if @ref_type && @ref args = if @ref_type && @ref
[@ref] [@ref]

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,22 +6,24 @@ 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
sig { override.params(_path: Pathname).returns(T::Boolean) }
def self.can_extract?(_path) def self.can_extract?(_path)
false false
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["unar"]] @dependencies ||= T.let([Formula["unar"]], T.nilable(T::Array[Formula]))
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "unar", system_command! "unar",
args: [ args: [

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "directory" require_relative "directory"
@ -6,8 +6,9 @@ require_relative "directory"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking Git repositories. # Strategy for unpacking Git repositories.
class Git < Directory class Git < Directory
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
super && (path/".git").directory? !!(super && (path/".git").directory?)
end end
end end
end end

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,18 +6,19 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\A\037\213/n) path.magic_number.match?(/\A\037\213/n)
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true FileUtils.cp path, unpack_dir/basename, preserve: true
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "uncompressed" require_relative "uncompressed"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
return false unless Zip.can_extract?(path) return false unless Zip.can_extract?(path)

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,22 +6,24 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\A..-(lh0|lh1|lz4|lz5|lzs|lh\\40|lhd|lh2|lh3|lh4|lh5)-/n) path.magic_number.match?(/\A..-(lh0|lh1|lz4|lz5|lzs|lh\\40|lhd|lh2|lh3|lh4|lh5)-/n)
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["lha"]] @dependencies ||= T.let([Formula["lha"]], T.nilable(T::Array[Formula]))
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "lha", system_command! "lha",
args: ["xq2w=#{unpack_dir}", path], args: ["xq2w=#{unpack_dir}", path],

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "uncompressed" require_relative "uncompressed"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
return false unless Zip.can_extract?(path) return false unless Zip.can_extract?(path)

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,22 +6,24 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\ALZIP/n) path.magic_number.match?(/\ALZIP/n)
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["lzip"]] @dependencies ||= T.let([Formula["lzip"]], T.nilable(T::Array[Formula]))
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true FileUtils.cp path, unpack_dir/basename, preserve: true
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,22 +6,24 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\A\]\000\000\200\000/n) path.magic_number.match?(/\A\]\000\000\200\000/n)
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["xz"]] @dependencies ||= T.let([Formula["xz"]], T.nilable(T::Array[Formula]))
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true FileUtils.cp path, unpack_dir/basename, preserve: true
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "directory" require_relative "directory"
@ -6,12 +6,14 @@ require_relative "directory"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking Mercurial repositories. # Strategy for unpacking Mercurial repositories.
class Mercurial < Directory class Mercurial < Directory
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
super && (path/".hg").directory? !!(super && (path/".hg").directory?)
end end
private private
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "hg", system_command! "hg",
args: ["--cwd", path, "archive", "--subrepos", "-y", "-t", "files", unpack_dir], args: ["--cwd", path, "archive", "--subrepos", "-y", "-t", "files", unpack_dir],

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "uncompressed" require_relative "uncompressed"
@ -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",
@ -15,6 +15,7 @@ module UnpackStrategy
] ]
end end
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
return false unless Zip.can_extract?(path) return false unless Zip.can_extract?(path)

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "uncompressed" require_relative "uncompressed"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\AOTTO/n) path.magic_number.match?(/\AOTTO/n)
end end

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,22 +6,24 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\A7z\xBC\xAF\x27\x1C/n) path.magic_number.match?(/\A7z\xBC\xAF\x27\x1C/n)
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["p7zip"]] @dependencies ||= T.let([Formula["p7zip"]], T.nilable(T::Array[Formula]))
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "7zr", system_command! "7zr",
args: ["x", "-y", "-bd", "-bso0", path, "-o#{unpack_dir}"], args: ["x", "-y", "-bd", "-bso0", path, "-o#{unpack_dir}"],

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,18 +6,19 @@ 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
sig { override.params(_path: Pathname).returns(T::Boolean) }
def self.can_extract?(_path) def self.can_extract?(_path)
false false
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "pax", system_command! "pax",
args: ["-rf", path], args: ["-rf", path],

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "uncompressed" require_relative "uncompressed"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.extname.match?(/\A.m?pkg\Z/) && path.extname.match?(/\A.m?pkg\Z/) &&
(path.directory? || path.magic_number.match?(/\Axar!/n)) (path.directory? || path.magic_number.match?(/\Axar!/n))

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,22 +6,24 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\ARar!/n) path.magic_number.match?(/\ARar!/n)
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["libarchive"]] @dependencies ||= T.let([Formula["libarchive"]], T.nilable(T::Array[Formula]))
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "bsdtar", system_command! "bsdtar",
args: ["x", "-f", path, "-C", unpack_dir], args: ["x", "-f", path, "-C", unpack_dir],

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "generic_unar" require_relative "generic_unar"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\AMZ/n) && path.magic_number.match?(/\AMZ/n) &&
path.file_type.include?("self-extracting archive") path.file_type.include?("self-extracting archive")

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "generic_unar" require_relative "generic_unar"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\AStuffIt/n) path.magic_number.match?(/\AStuffIt/n)
end end

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "directory" require_relative "directory"
@ -6,12 +6,14 @@ require_relative "directory"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking Subversion repositories. # Strategy for unpacking Subversion repositories.
class Subversion < Directory class Subversion < Directory
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
super && (path/".svn").directory? !!(super && (path/".svn").directory?)
end end
private private
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "svn", system_command! "svn",
args: ["export", "--force", ".", unpack_dir], args: ["export", "--force", ".", unpack_dir],

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require "system_command" require "system_command"
@ -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",
@ -22,6 +22,7 @@ module UnpackStrategy
] ]
end end
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
return true if path.magic_number.match?(/\A.{257}ustar/n) return true if path.magic_number.match?(/\A.{257}ustar/n)
@ -34,7 +35,7 @@ module UnpackStrategy
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
Dir.mktmpdir("homebrew-tar", HOMEBREW_TEMP) do |tmpdir| Dir.mktmpdir("homebrew-tar", HOMEBREW_TEMP) do |tmpdir|
tar_path = if DependencyCollector.tar_needs_xz_dependency? && Xz.can_extract?(path) tar_path = if DependencyCollector.tar_needs_xz_dependency? && Xz.can_extract?(path)

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require_relative "uncompressed" require_relative "uncompressed"
@ -6,11 +6,12 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
# TrueType Font # TrueType Font
path.magic_number.match?(/\A\000\001\000\000\000/n) || path.magic_number.match?(/\A\000\001\000\000\000/n) ||

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),
@ -20,7 +26,7 @@ module UnpackStrategy
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).void }
def extract_to_dir(unpack_dir, basename:, verbose: false) def extract_to_dir(unpack_dir, basename:, verbose: false)
FileUtils.cp path, unpack_dir/basename.sub(/^[\da-f]{64}--/, ""), preserve: true, verbose: FileUtils.cp path, unpack_dir/basename.sub(/^[\da-f]{64}--/, ""), preserve: true, verbose:
end end

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,18 +6,19 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\Axar!/n) path.magic_number.match?(/\Axar!/n)
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
system_command! "xar", system_command! "xar",
args: ["-x", "-f", path, "-C", unpack_dir], args: ["-x", "-f", path, "-C", unpack_dir],

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,22 +6,24 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\A\xFD7zXZ\x00/n) path.magic_number.match?(/\A\xFD7zXZ\x00/n)
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["xz"]] @dependencies ||= T.let([Formula["xz"]], T.nilable(T::Array[Formula]))
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true FileUtils.cp path, unpack_dir/basename, preserve: true
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]

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
@ -23,6 +23,7 @@ module UnpackStrategy
.returns(SystemCommand::Result) .returns(SystemCommand::Result)
} }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
odebug "in unpack_strategy, zip, extract_to_dir, verbose: #{verbose.inspect}"
unzip = if which("unzip").blank? unzip = if which("unzip").blank?
begin begin
Formula["unzip"] Formula["unzip"]

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module UnpackStrategy module UnpackStrategy
@ -6,22 +6,24 @@ 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
sig { override.params(path: Pathname).returns(T::Boolean) }
def self.can_extract?(path) def self.can_extract?(path)
path.magic_number.match?(/\x28\xB5\x2F\xFD/n) path.magic_number.match?(/\x28\xB5\x2F\xFD/n)
end end
sig { returns(T.nilable(T::Array[Formula])) }
def dependencies def dependencies
@dependencies ||= [Formula["zstd"]] @dependencies ||= T.let([Formula["zstd"]], T.nilable(T::Array[Formula]))
end end
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).void }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true FileUtils.cp path, unpack_dir/basename, preserve: true
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]

View File

@ -1,4 +1,4 @@
# typed: true # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
module Utils module Utils
@ -8,13 +8,20 @@ module Utils
# Specification on how to rewrite a given shebang. # Specification on how to rewrite a given shebang.
class RewriteInfo class RewriteInfo
attr_reader :regex, :max_length, :replacement sig { returns(Regexp) }
attr_reader :regex
sig { returns(Integer) }
attr_reader :max_length
sig { returns(T.any(String, Pathname)) }
attr_reader :replacement
sig { params(regex: Regexp, max_length: Integer, replacement: T.any(String, Pathname)).void } sig { params(regex: Regexp, max_length: Integer, replacement: T.any(String, Pathname)).void }
def initialize(regex, max_length, replacement) def initialize(regex, max_length, replacement)
@regex = regex @regex = T.let(regex, Regexp)
@max_length = max_length @max_length = T.let(max_length, Integer)
@replacement = replacement @replacement = T.let(replacement, T.any(String, Pathname))
end end
end end