Merge pull request #20344 from Homebrew/extend_sorbet_typing_pathname_cleanup
Cleanup some `extend/*` types/locations
This commit is contained in:
commit
46b8ef4b96
@ -2,7 +2,8 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Contains shorthand Homebrew utility methods like `ohai`, `opoo`, `odisabled`.
|
# Contains shorthand Homebrew utility methods like `ohai`, `opoo`, `odisabled`.
|
||||||
# TODO: move these out of `Kernel`.
|
# TODO: move these out of `Kernel` into `Homebrew::GlobalMethods` and add
|
||||||
|
# necessary Sorbet and global Kernel inclusions.
|
||||||
|
|
||||||
module Kernel
|
module Kernel
|
||||||
sig { params(env: T.nilable(String)).returns(T::Boolean) }
|
sig { params(env: T.nilable(String)).returns(T::Boolean) }
|
||||||
@ -13,6 +14,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
private :superenv?
|
private :superenv?
|
||||||
|
|
||||||
|
sig { params(path: T.nilable(T.any(String, Pathname))).returns(T::Boolean) }
|
||||||
def require?(path)
|
def require?(path)
|
||||||
return false if path.nil?
|
return false if path.nil?
|
||||||
|
|
||||||
@ -20,16 +22,17 @@ module Kernel
|
|||||||
# Work around require warning when done repeatedly:
|
# Work around require warning when done repeatedly:
|
||||||
# https://bugs.ruby-lang.org/issues/21091
|
# https://bugs.ruby-lang.org/issues/21091
|
||||||
Warnings.ignore(/already initialized constant/, /previous definition of/) do
|
Warnings.ignore(/already initialized constant/, /previous definition of/) do
|
||||||
require path
|
require path.to_s
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
require path
|
require path.to_s
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(title: String).returns(String) }
|
||||||
def ohai_title(title)
|
def ohai_title(title)
|
||||||
verbose = if respond_to?(:verbose?)
|
verbose = if respond_to?(:verbose?)
|
||||||
T.unsafe(self).verbose?
|
T.unsafe(self).verbose?
|
||||||
@ -42,7 +45,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
|
|
||||||
def ohai(title, *sput)
|
def ohai(title, *sput)
|
||||||
puts ohai_title(title)
|
puts ohai_title(title.to_s)
|
||||||
puts sput
|
puts sput
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -55,10 +58,11 @@ module Kernel
|
|||||||
|
|
||||||
return if !debug && !always_display
|
return if !debug && !always_display
|
||||||
|
|
||||||
$stderr.puts Formatter.headline(title, color: :magenta)
|
$stderr.puts Formatter.headline(title.to_s, color: :magenta)
|
||||||
$stderr.puts sput unless sput.empty?
|
$stderr.puts sput unless sput.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(title: String, truncate: T.any(Symbol, T::Boolean)).returns(String) }
|
||||||
def oh1_title(title, truncate: :auto)
|
def oh1_title(title, truncate: :auto)
|
||||||
verbose = if respond_to?(:verbose?)
|
verbose = if respond_to?(:verbose?)
|
||||||
T.unsafe(self).verbose?
|
T.unsafe(self).verbose?
|
||||||
@ -70,6 +74,7 @@ module Kernel
|
|||||||
Formatter.headline(title, color: :green)
|
Formatter.headline(title, color: :green)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(title: String, truncate: T.any(Symbol, T::Boolean)).void }
|
||||||
def oh1(title, truncate: :auto)
|
def oh1(title, truncate: :auto)
|
||||||
puts oh1_title(title, truncate:)
|
puts oh1_title(title, truncate:)
|
||||||
end
|
end
|
||||||
@ -134,6 +139,10 @@ module Kernel
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Output a deprecation warning/error message.
|
# Output a deprecation warning/error message.
|
||||||
|
sig {
|
||||||
|
params(method: String, replacement: T.nilable(T.any(String, Symbol)), disable: T::Boolean,
|
||||||
|
disable_on: T.nilable(Time), disable_for_developers: T::Boolean, caller: T::Array[String]).void
|
||||||
|
}
|
||||||
def odeprecated(method, replacement = nil,
|
def odeprecated(method, replacement = nil,
|
||||||
disable: false,
|
disable: false,
|
||||||
disable_on: nil,
|
disable_on: nil,
|
||||||
@ -213,12 +222,20 @@ module Kernel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def odisabled(method, replacement = nil, **options)
|
sig {
|
||||||
options = { disable: true, caller: }.merge(options)
|
params(method: String, replacement: T.nilable(T.any(String, Symbol)), disable: T::Boolean,
|
||||||
|
disable_on: T.nilable(Time), disable_for_developers: T::Boolean, caller: T::Array[String]).void
|
||||||
|
}
|
||||||
|
def odisabled(method, replacement = nil,
|
||||||
|
disable: false,
|
||||||
|
disable_on: nil,
|
||||||
|
disable_for_developers: true,
|
||||||
|
caller: send(:caller))
|
||||||
# This odeprecated should stick around indefinitely.
|
# This odeprecated should stick around indefinitely.
|
||||||
odeprecated(method, replacement, **options)
|
odeprecated(method, replacement, disable:, disable_on:, disable_for_developers:, caller:)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: T.any(String, Formula)).returns(String) }
|
||||||
def pretty_installed(formula)
|
def pretty_installed(formula)
|
||||||
if !$stdout.tty?
|
if !$stdout.tty?
|
||||||
formula.to_s
|
formula.to_s
|
||||||
@ -229,6 +246,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: T.any(String, Formula)).returns(String) }
|
||||||
def pretty_outdated(formula)
|
def pretty_outdated(formula)
|
||||||
if !$stdout.tty?
|
if !$stdout.tty?
|
||||||
formula.to_s
|
formula.to_s
|
||||||
@ -239,6 +257,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: T.any(String, Formula)).returns(String) }
|
||||||
def pretty_uninstalled(formula)
|
def pretty_uninstalled(formula)
|
||||||
if !$stdout.tty?
|
if !$stdout.tty?
|
||||||
formula.to_s
|
formula.to_s
|
||||||
@ -249,6 +268,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(seconds: T.nilable(T.any(Integer, Float))).returns(String) }
|
||||||
def pretty_duration(seconds)
|
def pretty_duration(seconds)
|
||||||
seconds = seconds.to_i
|
seconds = seconds.to_i
|
||||||
res = +""
|
res = +""
|
||||||
@ -266,9 +286,10 @@ module Kernel
|
|||||||
res.freeze
|
res.freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: T.nilable(Formula)).void }
|
||||||
def interactive_shell(formula = nil)
|
def interactive_shell(formula = nil)
|
||||||
unless formula.nil?
|
unless formula.nil?
|
||||||
ENV["HOMEBREW_DEBUG_PREFIX"] = formula.prefix
|
ENV["HOMEBREW_DEBUG_PREFIX"] = formula.prefix.to_s
|
||||||
ENV["HOMEBREW_DEBUG_INSTALL"] = formula.full_name
|
ENV["HOMEBREW_DEBUG_INSTALL"] = formula.full_name
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -295,6 +316,7 @@ module Kernel
|
|||||||
|
|
||||||
# Kernel.system but with exceptions.
|
# Kernel.system but with exceptions.
|
||||||
def safe_system(cmd, *args, **options)
|
def safe_system(cmd, *args, **options)
|
||||||
|
# TODO: migrate to utils.rb Homebrew.safe_system
|
||||||
require "utils"
|
require "utils"
|
||||||
|
|
||||||
return if Homebrew.system(cmd, *args, **options)
|
return if Homebrew.system(cmd, *args, **options)
|
||||||
@ -306,6 +328,7 @@ module Kernel
|
|||||||
#
|
#
|
||||||
# @api internal
|
# @api internal
|
||||||
def quiet_system(cmd, *args)
|
def quiet_system(cmd, *args)
|
||||||
|
# TODO: migrate to utils.rb Homebrew.quiet_system
|
||||||
require "utils"
|
require "utils"
|
||||||
|
|
||||||
Homebrew._system(cmd, *args) do
|
Homebrew._system(cmd, *args) do
|
||||||
@ -367,11 +390,13 @@ module Kernel
|
|||||||
editor
|
editor
|
||||||
end
|
end
|
||||||
|
|
||||||
def exec_editor(*args)
|
sig { params(filename: T.any(String, Pathname)).void }
|
||||||
puts "Editing #{args.join "\n"}"
|
def exec_editor(filename)
|
||||||
with_homebrew_path { safe_system(*which_editor.shellsplit, *args) }
|
puts "Editing #{filename}"
|
||||||
|
with_homebrew_path { safe_system(*which_editor.shellsplit, filename) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(args: T.any(String, Pathname)).void }
|
||||||
def exec_browser(*args)
|
def exec_browser(*args)
|
||||||
browser = Homebrew::EnvConfig.browser
|
browser = Homebrew::EnvConfig.browser
|
||||||
browser ||= OS::PATH_OPEN if defined?(OS::PATH_OPEN)
|
browser ||= OS::PATH_OPEN if defined?(OS::PATH_OPEN)
|
||||||
@ -384,7 +409,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
IGNORE_INTERRUPTS_MUTEX = Thread::Mutex.new.freeze
|
IGNORE_INTERRUPTS_MUTEX = T.let(Thread::Mutex.new.freeze, Thread::Mutex)
|
||||||
|
|
||||||
def ignore_interrupts
|
def ignore_interrupts
|
||||||
IGNORE_INTERRUPTS_MUTEX.synchronize do
|
IGNORE_INTERRUPTS_MUTEX.synchronize do
|
||||||
@ -417,6 +442,10 @@ module Kernel
|
|||||||
|
|
||||||
# Ensure the given formula is installed
|
# Ensure the given formula is installed
|
||||||
# This is useful for installing a utility formula (e.g. `shellcheck` for `brew style`)
|
# This is useful for installing a utility formula (e.g. `shellcheck` for `brew style`)
|
||||||
|
sig {
|
||||||
|
params(formula_or_name: T.any(String, Formula), reason: String, latest: T::Boolean, output_to_stderr: T::Boolean,
|
||||||
|
quiet: T::Boolean).returns(Formula)
|
||||||
|
}
|
||||||
def ensure_formula_installed!(formula_or_name, reason: "", latest: false,
|
def ensure_formula_installed!(formula_or_name, reason: "", latest: false,
|
||||||
output_to_stderr: true, quiet: false)
|
output_to_stderr: true, quiet: false)
|
||||||
if output_to_stderr || quiet
|
if output_to_stderr || quiet
|
||||||
@ -456,6 +485,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Ensure the given executable is exist otherwise install the brewed version
|
# Ensure the given executable is exist otherwise install the brewed version
|
||||||
|
sig { params(name: String, formula_name: T.nilable(String), reason: String, latest: T::Boolean).returns(T.nilable(Pathname)) }
|
||||||
def ensure_executable!(name, formula_name = nil, reason: "", latest: false)
|
def ensure_executable!(name, formula_name = nil, reason: "", latest: false)
|
||||||
formula_name ||= name
|
formula_name ||= name
|
||||||
|
|
||||||
@ -472,10 +502,12 @@ module Kernel
|
|||||||
ensure_formula_installed!(formula_name, reason:, latest:).opt_bin/name
|
ensure_formula_installed!(formula_name, reason:, latest:).opt_bin/name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Array[Pathname]) }
|
||||||
def paths
|
def paths
|
||||||
@paths ||= ORIGINAL_PATHS.uniq.map(&:to_s)
|
@paths ||= T.let(ORIGINAL_PATHS.uniq.map(&:to_s), T.nilable(T::Array[Pathname]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(size_in_bytes: T.any(Integer, Float)).returns(String) }
|
||||||
def disk_usage_readable(size_in_bytes)
|
def disk_usage_readable(size_in_bytes)
|
||||||
if size_in_bytes.abs >= 1_073_741_824
|
if size_in_bytes.abs >= 1_073_741_824
|
||||||
size = size_in_bytes.to_f / 1_073_741_824
|
size = size_in_bytes.to_f / 1_073_741_824
|
||||||
@ -509,6 +541,7 @@ module Kernel
|
|||||||
# preserving character encoding validity. The returned string will
|
# preserving character encoding validity. The returned string will
|
||||||
# be not much longer than the specified max_bytes, though the exact
|
# be not much longer than the specified max_bytes, though the exact
|
||||||
# shortfall or overrun may vary.
|
# shortfall or overrun may vary.
|
||||||
|
sig { params(str: String, max_bytes: Integer, options: T::Hash[Symbol, T.untyped]).returns(String) }
|
||||||
def truncate_text_to_approximate_size(str, max_bytes, options = {})
|
def truncate_text_to_approximate_size(str, max_bytes, options = {})
|
||||||
front_weight = options.fetch(:front_weight, 0.5)
|
front_weight = options.fetch(:front_weight, 0.5)
|
||||||
raise "opts[:front_weight] must be between 0.0 and 1.0" if front_weight < 0.0 || front_weight > 1.0
|
raise "opts[:front_weight] must be between 0.0 and 1.0" if front_weight < 0.0 || front_weight > 1.0
|
||||||
@ -530,7 +563,7 @@ module Kernel
|
|||||||
front = bytes[0..(n_front_bytes - 1)]
|
front = bytes[0..(n_front_bytes - 1)]
|
||||||
back = bytes[-n_back_bytes..]
|
back = bytes[-n_back_bytes..]
|
||||||
end
|
end
|
||||||
out = front + glue_bytes + back
|
out = T.must(front) + glue_bytes + T.must(back)
|
||||||
out.force_encoding("UTF-8")
|
out.force_encoding("UTF-8")
|
||||||
out.encode!("UTF-16", invalid: :replace)
|
out.encode!("UTF-16", invalid: :replace)
|
||||||
out.encode!("UTF-8")
|
out.encode!("UTF-8")
|
||||||
@ -568,6 +601,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T.proc.params(a: String, b: String).returns(Integer)) }
|
||||||
def tap_and_name_comparison
|
def tap_and_name_comparison
|
||||||
proc do |a, b|
|
proc do |a, b|
|
||||||
if a.include?("/") && b.exclude?("/")
|
if a.include?("/") && b.exclude?("/")
|
||||||
@ -580,6 +614,7 @@ module Kernel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(input: String, secrets: T::Array[String]).returns(String) }
|
||||||
def redact_secrets(input, secrets)
|
def redact_secrets(input, secrets)
|
||||||
secrets.compact
|
secrets.compact
|
||||||
.reduce(input) { |str, secret| str.gsub secret, "******" }
|
.reduce(input) { |str, secret| str.gsub secret, "******" }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "system_command"
|
require "system_command"
|
||||||
@ -45,30 +45,6 @@ class Pathname
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(src: T.any(String, Pathname), new_basename: String).void }
|
|
||||||
def install_p(src, new_basename)
|
|
||||||
src = Pathname(src)
|
|
||||||
raise Errno::ENOENT, src.to_s if !src.symlink? && !src.exist?
|
|
||||||
|
|
||||||
dst = join(new_basename)
|
|
||||||
dst = yield(src, dst) if block_given?
|
|
||||||
return unless dst
|
|
||||||
|
|
||||||
mkpath
|
|
||||||
|
|
||||||
# Use `FileUtils.mv` over `File.rename` to handle filesystem boundaries. If `src`
|
|
||||||
# is a symlink and its target is moved first, `FileUtils.mv` will fail
|
|
||||||
# (https://bugs.ruby-lang.org/issues/7707).
|
|
||||||
#
|
|
||||||
# In that case, use the system `mv` command.
|
|
||||||
if src.symlink?
|
|
||||||
raise unless Kernel.system "mv", src.to_s, dst
|
|
||||||
else
|
|
||||||
FileUtils.mv src, dst
|
|
||||||
end
|
|
||||||
end
|
|
||||||
private :install_p
|
|
||||||
|
|
||||||
# Creates symlinks to sources in this folder.
|
# Creates symlinks to sources in this folder.
|
||||||
#
|
#
|
||||||
# @api public
|
# @api public
|
||||||
@ -90,15 +66,6 @@ class Pathname
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def install_symlink_p(src, new_basename)
|
|
||||||
mkpath
|
|
||||||
dstdir = realpath
|
|
||||||
src = Pathname(src).expand_path(dstdir)
|
|
||||||
src = src.dirname.realpath/src.basename if src.dirname.exist?
|
|
||||||
FileUtils.ln_sf(src.relative_path_from(dstdir), dstdir/new_basename)
|
|
||||||
end
|
|
||||||
private :install_symlink_p
|
|
||||||
|
|
||||||
# Only appends to a file that is already created.
|
# Only appends to a file that is already created.
|
||||||
#
|
#
|
||||||
# @api public
|
# @api public
|
||||||
@ -146,9 +113,15 @@ class Pathname
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def cp_path_sub(pattern, replacement)
|
sig {
|
||||||
|
params(pattern: T.any(Pathname, String, Regexp), replacement: T.any(Pathname, String),
|
||||||
|
_block: T.nilable(T.proc.params(src: Pathname, dst: Pathname).returns(Pathname))).void
|
||||||
|
}
|
||||||
|
def cp_path_sub(pattern, replacement, &_block)
|
||||||
raise "#{self} does not exist" unless exist?
|
raise "#{self} does not exist" unless exist?
|
||||||
|
|
||||||
|
pattern = pattern.to_s if pattern.is_a?(Pathname)
|
||||||
|
replacement = replacement.to_s if replacement.is_a?(Pathname)
|
||||||
dst = sub(pattern, replacement)
|
dst = sub(pattern, replacement)
|
||||||
|
|
||||||
raise "#{self} is the same file as #{dst}" if self == dst
|
raise "#{self} is the same file as #{dst}" if self == dst
|
||||||
@ -269,12 +242,14 @@ class Pathname
|
|||||||
dirname.join(link).exist?
|
dirname.join(link).exist?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(src: Pathname).void }
|
||||||
def make_relative_symlink(src)
|
def make_relative_symlink(src)
|
||||||
dirname.mkpath
|
dirname.mkpath
|
||||||
File.symlink(src.relative_path_from(dirname), self)
|
File.symlink(src.relative_path_from(dirname), self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_writable
|
sig { params(_block: T.proc.void).void }
|
||||||
|
def ensure_writable(&_block)
|
||||||
saved_perms = nil
|
saved_perms = nil
|
||||||
unless writable?
|
unless writable?
|
||||||
saved_perms = stat.mode
|
saved_perms = stat.mode
|
||||||
@ -285,24 +260,18 @@ class Pathname
|
|||||||
chmod saved_perms if saved_perms
|
chmod saved_perms if saved_perms
|
||||||
end
|
end
|
||||||
|
|
||||||
def which_install_info
|
sig { void }
|
||||||
@which_install_info ||=
|
|
||||||
if File.executable?("/usr/bin/install-info")
|
|
||||||
"/usr/bin/install-info"
|
|
||||||
elsif Formula["texinfo"].any_version_installed?
|
|
||||||
Formula["texinfo"].opt_bin/"install-info"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def install_info
|
def install_info
|
||||||
quiet_system(which_install_info, "--quiet", to_s, "#{dirname}/dir")
|
quiet_system(which_install_info, "--quiet", to_s, "#{dirname}/dir")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def uninstall_info
|
def uninstall_info
|
||||||
quiet_system(which_install_info, "--delete", "--quiet", to_s, "#{dirname}/dir")
|
quiet_system(which_install_info, "--delete", "--quiet", to_s, "#{dirname}/dir")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Writes an exec script in this folder for each target pathname.
|
# Writes an exec script in this folder for each target pathname.
|
||||||
|
sig { params(targets: T::Array[Pathname]).void }
|
||||||
def write_exec_script(*targets)
|
def write_exec_script(*targets)
|
||||||
targets.flatten!
|
targets.flatten!
|
||||||
if targets.empty?
|
if targets.empty?
|
||||||
@ -320,6 +289,7 @@ class Pathname
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Writes an exec script that sets environment variables.
|
# Writes an exec script that sets environment variables.
|
||||||
|
sig { params(target: Pathname, args: T.any(T::Array[String], T::Hash[String, String]), env: T.nilable(T::Hash[String, String])).void }
|
||||||
def write_env_script(target, args, env = nil)
|
def write_env_script(target, args, env = nil)
|
||||||
unless env
|
unless env
|
||||||
env = args
|
env = args
|
||||||
@ -335,13 +305,14 @@ class Pathname
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Writes a wrapper env script and moves all files to the dst.
|
# Writes a wrapper env script and moves all files to the dst.
|
||||||
|
sig { params(dst: Pathname, env: T::Hash[String, String]).void }
|
||||||
def env_script_all_files(dst, env)
|
def env_script_all_files(dst, env)
|
||||||
dst.mkpath
|
dst.mkpath
|
||||||
Pathname.glob("#{self}/*") do |file|
|
Pathname.glob("#{self}/*") do |file|
|
||||||
next if file.directory?
|
next if file.directory?
|
||||||
|
|
||||||
new_file = dst.join(file.basename)
|
new_file = dst.join(file.basename)
|
||||||
raise Errno::EEXIST, new_file if new_file.exist?
|
raise Errno::EEXIST, new_file.to_s if new_file.exist?
|
||||||
|
|
||||||
dst.install(file)
|
dst.install(file)
|
||||||
file.write_env_script(new_file, env)
|
file.write_env_script(new_file, env)
|
||||||
@ -366,6 +337,7 @@ class Pathname
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(from: Pathname).void }
|
||||||
def install_metafiles(from = Pathname.pwd)
|
def install_metafiles(from = Pathname.pwd)
|
||||||
require "metafiles"
|
require "metafiles"
|
||||||
|
|
||||||
@ -417,6 +389,7 @@ class Pathname
|
|||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def magic_number
|
def magic_number
|
||||||
|
@magic_number ||= T.let(nil, T.nilable(String))
|
||||||
@magic_number ||= if directory?
|
@magic_number ||= if directory?
|
||||||
""
|
""
|
||||||
else
|
else
|
||||||
@ -428,16 +401,66 @@ class Pathname
|
|||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def file_type
|
def file_type
|
||||||
|
@file_type ||= T.let(nil, T.nilable(String))
|
||||||
@file_type ||= system_command("file", args: ["-b", self], print_stderr: false)
|
@file_type ||= system_command("file", args: ["-b", self], print_stderr: false)
|
||||||
.stdout.chomp
|
.stdout.chomp
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def zipinfo
|
def zipinfo
|
||||||
|
@zipinfo ||= T.let(nil, T.nilable(String))
|
||||||
@zipinfo ||= system_command("zipinfo", args: ["-1", self], print_stderr: false)
|
@zipinfo ||= system_command("zipinfo", args: ["-1", self], print_stderr: false)
|
||||||
.stdout
|
.stdout
|
||||||
.encode(Encoding::UTF_8, invalid: :replace)
|
.encode(Encoding::UTF_8, invalid: :replace)
|
||||||
.split("\n")
|
.split("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(src: T.any(String, Pathname), new_basename: String,
|
||||||
|
_block: T.nilable(T.proc.params(src: Pathname, dst: Pathname).returns(T.nilable(Pathname)))).void
|
||||||
|
}
|
||||||
|
def install_p(src, new_basename, &_block)
|
||||||
|
src = Pathname(src)
|
||||||
|
raise Errno::ENOENT, src.to_s if !src.symlink? && !src.exist?
|
||||||
|
|
||||||
|
dst = join(new_basename)
|
||||||
|
dst = yield(src, dst) if block_given?
|
||||||
|
return unless dst
|
||||||
|
|
||||||
|
mkpath
|
||||||
|
|
||||||
|
# Use `FileUtils.mv` over `File.rename` to handle filesystem boundaries. If `src`
|
||||||
|
# is a symlink and its target is moved first, `FileUtils.mv` will fail
|
||||||
|
# (https://bugs.ruby-lang.org/issues/7707).
|
||||||
|
#
|
||||||
|
# In that case, use the system `mv` command.
|
||||||
|
if src.symlink?
|
||||||
|
raise unless Kernel.system "mv", src.to_s, dst.to_s
|
||||||
|
else
|
||||||
|
FileUtils.mv src, dst
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { params(src: T.any(String, Pathname), new_basename: String).void }
|
||||||
|
def install_symlink_p(src, new_basename)
|
||||||
|
mkpath
|
||||||
|
dstdir = realpath
|
||||||
|
src = Pathname(src).expand_path(dstdir)
|
||||||
|
src = src.dirname.realpath/src.basename if src.dirname.exist?
|
||||||
|
FileUtils.ln_sf(src.relative_path_from(dstdir), dstdir/new_basename)
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { returns(T.nilable(String)) }
|
||||||
|
def which_install_info
|
||||||
|
@which_install_info ||= T.let(nil, T.nilable(String))
|
||||||
|
@which_install_info ||=
|
||||||
|
if File.executable?("/usr/bin/install-info")
|
||||||
|
"/usr/bin/install-info"
|
||||||
|
elsif Formula["texinfo"].any_version_installed?
|
||||||
|
(Formula["texinfo"].opt_bin/"install-info").to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
require "extend/os/pathname"
|
require "extend/os/pathname"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module DiskUsageExtension
|
module DiskUsageExtension
|
||||||
@ -8,24 +8,26 @@ module DiskUsageExtension
|
|||||||
|
|
||||||
sig { returns(Integer) }
|
sig { returns(Integer) }
|
||||||
def disk_usage
|
def disk_usage
|
||||||
return @disk_usage if defined?(@disk_usage)
|
@disk_usage ||= T.let(nil, T.nilable(Integer))
|
||||||
|
return @disk_usage unless @disk_usage.nil?
|
||||||
|
|
||||||
compute_disk_usage
|
@file_count, @disk_usage = compute_disk_usage
|
||||||
@disk_usage
|
@disk_usage
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(Integer) }
|
sig { returns(Integer) }
|
||||||
def file_count
|
def file_count
|
||||||
return @file_count if defined?(@file_count)
|
@file_count ||= T.let(nil, T.nilable(Integer))
|
||||||
|
return @file_count unless @file_count.nil?
|
||||||
|
|
||||||
compute_disk_usage
|
@file_count, @disk_usage = compute_disk_usage
|
||||||
@file_count
|
@file_count
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def abv
|
def abv
|
||||||
out = +""
|
out = +""
|
||||||
compute_disk_usage
|
@file_count, @disk_usage = compute_disk_usage
|
||||||
out << "#{number_readable(@file_count)} files, " if @file_count > 1
|
out << "#{number_readable(@file_count)} files, " if @file_count > 1
|
||||||
out << disk_usage_readable(@disk_usage).to_s
|
out << disk_usage_readable(@disk_usage).to_s
|
||||||
out.freeze
|
out.freeze
|
||||||
@ -33,12 +35,12 @@ module DiskUsageExtension
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
sig { void }
|
sig { returns([Integer, Integer]) }
|
||||||
def compute_disk_usage
|
def compute_disk_usage
|
||||||
if symlink? && !exist?
|
if symlink? && !exist?
|
||||||
@file_count = 1
|
file_count = 1
|
||||||
@disk_usage = 0
|
disk_usage = 0
|
||||||
return
|
return [file_count, disk_usage]
|
||||||
end
|
end
|
||||||
|
|
||||||
path = if symlink?
|
path = if symlink?
|
||||||
@ -49,26 +51,28 @@ module DiskUsageExtension
|
|||||||
|
|
||||||
if path.directory?
|
if path.directory?
|
||||||
scanned_files = Set.new
|
scanned_files = Set.new
|
||||||
@file_count = 0
|
file_count = 0
|
||||||
@disk_usage = 0
|
disk_usage = 0
|
||||||
path.find do |f|
|
path.find do |f|
|
||||||
if f.directory?
|
if f.directory?
|
||||||
@disk_usage += f.lstat.size
|
disk_usage += f.lstat.size
|
||||||
else
|
else
|
||||||
@file_count += 1 if f.basename.to_s != ".DS_Store"
|
file_count += 1 if f.basename.to_s != ".DS_Store"
|
||||||
# use Pathname#lstat instead of Pathname#stat to get info of symlink itself.
|
# use Pathname#lstat instead of Pathname#stat to get info of symlink itself.
|
||||||
stat = f.lstat
|
stat = f.lstat
|
||||||
file_id = [stat.dev, stat.ino]
|
file_id = [stat.dev, stat.ino]
|
||||||
# count hardlinks only once.
|
# count hardlinks only once.
|
||||||
unless scanned_files.include?(file_id)
|
unless scanned_files.include?(file_id)
|
||||||
@disk_usage += stat.size
|
disk_usage += stat.size
|
||||||
scanned_files.add(file_id)
|
scanned_files.add(file_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@file_count = 1
|
file_count = 1
|
||||||
@disk_usage = path.lstat.size
|
disk_usage = path.lstat.size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
[file_count, disk_usage]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1320,6 +1320,7 @@ class Formula
|
|||||||
path = Pathname.new(path)
|
path = Pathname.new(path)
|
||||||
path.extend(InstallRenamed)
|
path.extend(InstallRenamed)
|
||||||
path.cp_path_sub(bottle_prefix, HOMEBREW_PREFIX)
|
path.cp_path_sub(bottle_prefix, HOMEBREW_PREFIX)
|
||||||
|
path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -445,9 +445,11 @@ module Homebrew
|
|||||||
|
|
||||||
puts "#{::Utils.pluralize("Formula", formulae.count, plural: "e")} \
|
puts "#{::Utils.pluralize("Formula", formulae.count, plural: "e")} \
|
||||||
(#{formulae.count}): #{formulae.join(", ")}\n\n"
|
(#{formulae.count}): #{formulae.join(", ")}\n\n"
|
||||||
puts "Download Size: #{disk_usage_readable(sizes[:download])}"
|
puts "Download Size: #{disk_usage_readable(sizes.fetch(:download))}"
|
||||||
puts "Install Size: #{disk_usage_readable(sizes[:installed])}"
|
puts "Install Size: #{disk_usage_readable(sizes.fetch(:installed))}"
|
||||||
puts "Net Install Size: #{disk_usage_readable(sizes[:net])}" if sizes[:net] != 0
|
if (net_install_size = sizes[:net]) && net_install_size != 0
|
||||||
|
puts "Net Install Size: #{disk_usage_readable(net_install_size)}"
|
||||||
|
end
|
||||||
|
|
||||||
ask_input
|
ask_input
|
||||||
end
|
end
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Helper module for installing default files.
|
# Helper module for installing default files.
|
||||||
module InstallRenamed
|
module InstallRenamed
|
||||||
def install_p(_, new_basename)
|
sig {
|
||||||
|
params(src: T.any(String, Pathname), new_basename: String,
|
||||||
|
_block: T.nilable(T.proc.params(src: Pathname, dst: Pathname).returns(T.nilable(Pathname)))).void
|
||||||
|
}
|
||||||
|
def install_p(src, new_basename, &_block)
|
||||||
super do |src, dst|
|
super do |src, dst|
|
||||||
if src.directory?
|
if src.directory?
|
||||||
dst.install(src.children)
|
dst.install(src.children)
|
||||||
@ -14,22 +18,29 @@ module InstallRenamed
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def cp_path_sub(pattern, replacement)
|
sig {
|
||||||
|
params(pattern: T.any(Pathname, String, Regexp), replacement: T.any(Pathname, String),
|
||||||
|
_block: T.nilable(T.proc.params(src: Pathname, dst: Pathname).returns(Pathname))).void
|
||||||
|
}
|
||||||
|
def cp_path_sub(pattern, replacement, &_block)
|
||||||
super do |src, dst|
|
super do |src, dst|
|
||||||
append_default_if_different(src, dst)
|
append_default_if_different(src, dst)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(other: T.any(String, Pathname)).returns(Pathname) }
|
||||||
def +(other)
|
def +(other)
|
||||||
super.extend(InstallRenamed)
|
super.extend(InstallRenamed)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(other: T.any(String, Pathname)).returns(Pathname) }
|
||||||
def /(other)
|
def /(other)
|
||||||
super.extend(InstallRenamed)
|
super.extend(InstallRenamed)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { params(src: Pathname, dst: Pathname).returns(Pathname) }
|
||||||
def append_default_if_different(src, dst)
|
def append_default_if_different(src, dst)
|
||||||
if dst.file? && !FileUtils.identical?(src, dst)
|
if dst.file? && !FileUtils.identical?(src, dst)
|
||||||
Pathname.new("#{dst}.default")
|
Pathname.new("#{dst}.default")
|
||||||
|
@ -19,9 +19,11 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
exit! 1 # never gets here unless exec failed
|
exit! 1 # never gets here unless exec failed
|
||||||
end
|
end
|
||||||
Process.wait(T.must(pid))
|
Process.wait(pid)
|
||||||
$CHILD_STATUS.success?
|
$CHILD_STATUS.success?
|
||||||
end
|
end
|
||||||
|
# TODO: make private_class_method when possible
|
||||||
|
# private_class_method :_system
|
||||||
# rubocop:enable Naming/PredicateMethod
|
# rubocop:enable Naming/PredicateMethod
|
||||||
|
|
||||||
def self.system(cmd, *args, **options)
|
def self.system(cmd, *args, **options)
|
||||||
@ -37,9 +39,9 @@ module Homebrew
|
|||||||
# rubocop:disable Style/GlobalVars
|
# rubocop:disable Style/GlobalVars
|
||||||
sig { params(the_module: Module, pattern: Regexp).void }
|
sig { params(the_module: Module, pattern: Regexp).void }
|
||||||
def self.inject_dump_stats!(the_module, pattern)
|
def self.inject_dump_stats!(the_module, pattern)
|
||||||
@injected_dump_stat_modules ||= {}
|
@injected_dump_stat_modules ||= T.let({}, T.nilable(T::Hash[Module, T::Array[String]]))
|
||||||
@injected_dump_stat_modules[the_module] ||= []
|
@injected_dump_stat_modules[the_module] ||= []
|
||||||
injected_methods = @injected_dump_stat_modules[the_module]
|
injected_methods = @injected_dump_stat_modules.fetch(the_module)
|
||||||
the_module.module_eval do
|
the_module.module_eval do
|
||||||
instance_methods.grep(pattern).each do |name|
|
instance_methods.grep(pattern).each do |name|
|
||||||
next if injected_methods.include? name
|
next if injected_methods.include? name
|
||||||
|
Loading…
x
Reference in New Issue
Block a user