mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Cleanup extend/
directory usage.
- move some things out of `extend` that don't really fit there e.g. `Module`s that are included but not doing any overriding/monkeypatching - move some code into `extend/os` to fix all remaining `rubocop:todo Homebrew/MoveToExtendOS`s - remove some unneeded `bundle` skipper code that doesn't really make sense given our current bottling strategy - extract some `Pathname` extensions to `extend/pathname` for separate files - move a `ENV` `Kernel` extension into `kernel.rb` - `odeprecate` a seemingly unused backwards compatibility method - move `readline_nonblock` from a monkeypatch to a `ReadlineNonblock.read` method as its only used in one place - fix up a link in documentation
This commit is contained in:
parent
8ebb2cd65b
commit
dc71b7c8f6
@ -1,7 +1,7 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
require "api/download"
|
||||
|
||||
module Homebrew
|
||||
|
@ -1,7 +1,7 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
require "api/download"
|
||||
|
||||
module Homebrew
|
||||
|
@ -130,6 +130,9 @@ module Homebrew
|
||||
@formula_versions_from_env[formula_env_name]
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def prepend_pkgconf_path_if_needed!; end
|
||||
|
||||
sig { void }
|
||||
def reset!
|
||||
@mas_installed = T.let(nil, T.nilable(T::Boolean))
|
||||
|
@ -64,14 +64,8 @@ module Homebrew
|
||||
ENV.prepend_path "PATH", Pathname.new(dep_root)/"shims"
|
||||
end
|
||||
|
||||
# Setup pkg-config, if present, to help locate packages
|
||||
# Only need this on Linux as Homebrew provides a shim on macOS
|
||||
# TODO: use extend/OS here
|
||||
# rubocop:todo Homebrew/MoveToExtendOS
|
||||
if OS.linux? && (pkgconf = Formulary.factory("pkgconf")) && pkgconf.any_version_installed?
|
||||
ENV.prepend_path "PATH", pkgconf.opt_bin.to_s
|
||||
end
|
||||
# rubocop:enable Homebrew/MoveToExtendOS
|
||||
# Setup pkgconf, if needed, to help locate packages
|
||||
Bundle.prepend_pkgconf_path_if_needed!
|
||||
|
||||
# For commands which aren't either absolute or relative
|
||||
# Add the command directory to PATH, since it may get blown away by superenv
|
||||
|
@ -11,19 +11,6 @@ module Homebrew
|
||||
def skip?(entry, silent: false)
|
||||
require "bundle/brew_dumper"
|
||||
|
||||
# TODO: use extend/OS here
|
||||
# rubocop:todo Homebrew/MoveToExtendOS
|
||||
if (Hardware::CPU.arm? || OS.linux?) &&
|
||||
Homebrew.default_prefix? &&
|
||||
entry.type == :brew && entry.name.exclude?("/") &&
|
||||
(formula = BrewDumper.formulae_by_full_name(entry.name)) &&
|
||||
formula[:official_tap] &&
|
||||
!formula[:bottled]
|
||||
reason = Hardware::CPU.arm? ? "Apple Silicon" : "Linux"
|
||||
puts Formatter.warning "Skipping #{entry.name} (no bottle for #{reason})" unless silent
|
||||
return true
|
||||
end
|
||||
# rubocop:enable Homebrew/MoveToExtendOS
|
||||
return true if @failed_taps&.any? do |tap|
|
||||
prefix = "#{tap}/"
|
||||
entry.name.start_with?(prefix) || entry.options[:full_name]&.start_with?(prefix)
|
||||
|
@ -8,7 +8,7 @@ require "cask/dsl"
|
||||
require "cask/metadata"
|
||||
require "cask/tab"
|
||||
require "utils/bottles"
|
||||
require "extend/api_hashable"
|
||||
require "api_hashable"
|
||||
|
||||
module Cask
|
||||
# An instance of a cask.
|
||||
|
@ -26,7 +26,7 @@ require "cask/dsl/version"
|
||||
require "cask/url"
|
||||
require "cask/utils"
|
||||
|
||||
require "extend/on_system"
|
||||
require "on_system"
|
||||
|
||||
module Cask
|
||||
# Class representing the domain-specific language used for casks.
|
||||
|
@ -2,7 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/utils"
|
||||
require "extend/on_system"
|
||||
require "on_system"
|
||||
|
||||
module Cask
|
||||
class DSL
|
||||
|
@ -5,7 +5,7 @@ require "dependency"
|
||||
require "dependencies"
|
||||
require "requirement"
|
||||
require "requirements"
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
|
||||
# A dependency is a formula that another formula needs to install.
|
||||
# A requirement is something other than a formula that another formula
|
||||
|
@ -227,7 +227,7 @@ module Homebrew
|
||||
private
|
||||
|
||||
sig {
|
||||
params(string: String, keg: Keg, ignores: T::Array[String],
|
||||
params(string: String, keg: Keg, ignores: T::Array[Regexp],
|
||||
formula_and_runtime_deps_names: T.nilable(T::Array[String])).returns(T::Boolean)
|
||||
}
|
||||
def keg_contain?(string, keg, ignores, formula_and_runtime_deps_names = nil)
|
||||
@ -373,35 +373,17 @@ module Homebrew
|
||||
[gnu_tar(gnu_tar_formula), reproducible_gnutar_args(mtime)].freeze
|
||||
end
|
||||
|
||||
sig { params(formula: T.untyped).returns(T::Array[T.untyped]) }
|
||||
sig { params(formula: Formula).returns(T::Array[Regexp]) }
|
||||
def formula_ignores(formula)
|
||||
ignores = []
|
||||
cellar_regex = Regexp.escape(HOMEBREW_CELLAR)
|
||||
prefix_regex = Regexp.escape(HOMEBREW_PREFIX)
|
||||
|
||||
# Ignore matches to go keg, because all go binaries are statically linked.
|
||||
any_go_deps = formula.deps.any? do |dep|
|
||||
Version.formula_optionally_versioned_regex(:go).match?(dep.name)
|
||||
end
|
||||
if any_go_deps
|
||||
go_regex = Version.formula_optionally_versioned_regex(:go, full: false)
|
||||
ignores << %r{#{cellar_regex}/#{go_regex}/[\d.]+/libexec}
|
||||
end
|
||||
return [] unless any_go_deps
|
||||
|
||||
# TODO: Refactor and move to extend/os
|
||||
# rubocop:disable Homebrew/MoveToExtendOS
|
||||
ignores << case formula.name
|
||||
# On Linux, GCC installation can be moved so long as the whole directory tree is moved together:
|
||||
# https://gcc-help.gcc.gnu.narkive.com/GnwuCA7l/moving-gcc-from-the-installation-path-is-it-allowed.
|
||||
when Version.formula_optionally_versioned_regex(:gcc)
|
||||
Regexp.union(%r{#{cellar_regex}/gcc}, %r{#{prefix_regex}/opt/gcc}) if OS.linux?
|
||||
# binutils is relocatable for the same reason: https://github.com/Homebrew/brew/pull/11899#issuecomment-906804451.
|
||||
when Version.formula_optionally_versioned_regex(:binutils)
|
||||
%r{#{cellar_regex}/binutils} if OS.linux?
|
||||
end
|
||||
# rubocop:enable Homebrew/MoveToExtendOS
|
||||
|
||||
ignores.compact
|
||||
cellar_regex = Regexp.escape(HOMEBREW_CELLAR)
|
||||
go_regex = Version.formula_optionally_versioned_regex(:go, full: false)
|
||||
Array(%r{#{cellar_regex}/#{go_regex}/[\d.]+/libexec})
|
||||
end
|
||||
|
||||
sig { params(formula: Formula).void }
|
||||
|
@ -120,31 +120,14 @@ module Homebrew
|
||||
]
|
||||
bundle_args << "--fail-fast" if args.fail_fast?
|
||||
bundle_args << "--profile" << args.profile if args.profile
|
||||
|
||||
# TODO: Refactor and move to extend/os
|
||||
# rubocop:disable Homebrew/MoveToExtendOS
|
||||
unless OS.mac?
|
||||
bundle_args << "--tag" << "~needs_macos" << "--tag" << "~cask"
|
||||
bundle_args << "--tag" << "~needs_homebrew_core" if ENV["CI"]
|
||||
bundle_args << "--tag" << "~needs_svn" unless args.online?
|
||||
|
||||
files = files.grep_v(%r{^test/(os/mac|cask)(/.*|_spec\.rb)$})
|
||||
end
|
||||
|
||||
unless OS.linux?
|
||||
bundle_args << "--tag" << "~needs_linux" << "--tag" << "~needs_systemd"
|
||||
files = files.grep_v(%r{^test/os/linux(/.*|_spec\.rb)$})
|
||||
end
|
||||
# rubocop:enable Homebrew/MoveToExtendOS
|
||||
|
||||
bundle_args << "--tag" << "~needs_arm" unless Hardware::CPU.arm?
|
||||
|
||||
bundle_args << "--tag" << "~needs_intel" unless Hardware::CPU.intel?
|
||||
|
||||
bundle_args << "--tag" << "~needs_network" unless args.online?
|
||||
|
||||
bundle_args << "--tag" << "~needs_ci" unless ENV["CI"]
|
||||
|
||||
bundle_args = os_bundle_args(bundle_args)
|
||||
files = os_files(files)
|
||||
|
||||
puts "Randomized with seed #{seed}"
|
||||
|
||||
ENV["HOMEBREW_DEBUG"] = "1" if args.debug? # Used in spec_helper.rb to require the "debug" gem.
|
||||
@ -171,6 +154,41 @@ module Homebrew
|
||||
|
||||
private
|
||||
|
||||
sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) }
|
||||
def os_bundle_args(bundle_args)
|
||||
# for generic tests, remove macOS or Linux specific tests
|
||||
non_linux_bundle_args(non_macos_bundle_args(bundle_args))
|
||||
end
|
||||
|
||||
sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) }
|
||||
def non_macos_bundle_args(bundle_args)
|
||||
bundle_args << "--tag" << "~needs_homebrew_core" if ENV["CI"]
|
||||
bundle_args << "--tag" << "~needs_svn" unless args.online?
|
||||
|
||||
bundle_args << "--tag" << "~needs_macos" << "--tag" << "~cask"
|
||||
end
|
||||
|
||||
sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) }
|
||||
def non_linux_bundle_args(bundle_args)
|
||||
bundle_args << "--tag" << "~needs_linux" << "--tag" << "~needs_systemd"
|
||||
end
|
||||
|
||||
sig { params(files: T::Array[String]).returns(T::Array[String]) }
|
||||
def os_files(files)
|
||||
# for generic tests, remove macOS or Linux specific files
|
||||
non_linux_files(non_macos_files(files))
|
||||
end
|
||||
|
||||
sig { params(files: T::Array[String]).returns(T::Array[String]) }
|
||||
def non_macos_files(files)
|
||||
files.grep_v(%r{^test/(os/mac|cask)(/.*|_spec\.rb)$})
|
||||
end
|
||||
|
||||
sig { params(files: T::Array[String]).returns(T::Array[String]) }
|
||||
def non_linux_files(files)
|
||||
files.grep_v(%r{^test/os/linux(/.*|_spec\.rb)$})
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def changed_test_files
|
||||
changed_files = Utils.popen_read("git", "diff", "--name-only", "master")
|
||||
@ -250,3 +268,5 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require "extend/os/dev-cmd/tests"
|
||||
|
@ -7,16 +7,6 @@ require "extend/ENV/shared"
|
||||
require "extend/ENV/std"
|
||||
require "extend/ENV/super"
|
||||
|
||||
module Kernel
|
||||
sig { params(env: T.nilable(String)).returns(T::Boolean) }
|
||||
def superenv?(env)
|
||||
return false if env == "std"
|
||||
|
||||
!Superenv.bin.nil?
|
||||
end
|
||||
private :superenv?
|
||||
end
|
||||
|
||||
# <!-- vale off -->
|
||||
# @!parse
|
||||
# # `ENV` is not actually a class, but this makes YARD happy
|
||||
|
@ -5,6 +5,14 @@
|
||||
# TODO: move these out of `Kernel`.
|
||||
|
||||
module Kernel
|
||||
sig { params(env: T.nilable(String)).returns(T::Boolean) }
|
||||
def superenv?(env)
|
||||
return false if env == "std"
|
||||
|
||||
!Superenv.bin.nil?
|
||||
end
|
||||
private :superenv?
|
||||
|
||||
def require?(path)
|
||||
return false if path.nil?
|
||||
|
||||
|
5
Library/Homebrew/extend/os/dev-cmd/tests.rb
Normal file
5
Library/Homebrew/extend/os/dev-cmd/tests.rb
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/os/linux/dev-cmd/tests" if OS.linux?
|
||||
require "extend/os/mac/dev-cmd/tests" if OS.mac?
|
@ -9,6 +9,16 @@ module OS
|
||||
def mas_installed?
|
||||
false
|
||||
end
|
||||
|
||||
# Setup pkg-config, if present, to help locate packages
|
||||
# Only need this on Linux as Homebrew provides a shim on macOS
|
||||
sig { void }
|
||||
def prepend_pkgconf_path_if_needed!
|
||||
pkgconf = Formulary.factory("pkgconf")
|
||||
return unless pkgconf.any_version_installed?
|
||||
|
||||
ENV.prepend_path "PATH", pkgconf.opt_bin.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
23
Library/Homebrew/extend/os/linux/dev-cmd/tests.rb
Normal file
23
Library/Homebrew/extend/os/linux/dev-cmd/tests.rb
Normal file
@ -0,0 +1,23 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OS
|
||||
module Linux
|
||||
module DevCmd
|
||||
module Tests
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Homebrew::DevCmd::Tests }
|
||||
|
||||
private
|
||||
|
||||
sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) }
|
||||
def os_bundle_args(bundle_args)
|
||||
non_macos_bundle_args(bundle_args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Homebrew::DevCmd::Tests.prepend(OS::Linux::DevCmd::Tests)
|
@ -18,6 +18,26 @@ module OS
|
||||
def gnu_tar(gnu_tar_formula)
|
||||
"#{gnu_tar_formula.opt_bin}/gtar"
|
||||
end
|
||||
|
||||
sig { params(formula: Formula).returns(T::Array[Regexp]) }
|
||||
def formula_ignores(formula)
|
||||
ignores = super
|
||||
|
||||
cellar_regex = Regexp.escape(HOMEBREW_CELLAR)
|
||||
prefix_regex = Regexp.escape(HOMEBREW_PREFIX)
|
||||
|
||||
ignores << case formula.name
|
||||
# On Linux, GCC installation can be moved so long as the whole directory tree is moved together:
|
||||
# https://gcc-help.gcc.gnu.narkive.com/GnwuCA7l/moving-gcc-from-the-installation-path-is-it-allowed.
|
||||
when Version.formula_optionally_versioned_regex(:gcc)
|
||||
Regexp.union(%r{#{cellar_regex}/gcc}, %r{#{prefix_regex}/opt/gcc}) if OS.linux?
|
||||
# binutils is relocatable for the same reason: https://github.com/Homebrew/brew/pull/11899#issuecomment-906804451.
|
||||
when Version.formula_optionally_versioned_regex(:binutils)
|
||||
%r{#{cellar_regex}/binutils} if OS.linux?
|
||||
end
|
||||
|
||||
ignores.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
23
Library/Homebrew/extend/os/mac/dev-cmd/tests.rb
Normal file
23
Library/Homebrew/extend/os/mac/dev-cmd/tests.rb
Normal file
@ -0,0 +1,23 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OS
|
||||
module Mac
|
||||
module DevCmd
|
||||
module Tests
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Homebrew::DevCmd::Tests }
|
||||
|
||||
private
|
||||
|
||||
sig { params(bundle_args: T::Array[String]).returns(T::Array[String]) }
|
||||
def os_bundle_args(bundle_args)
|
||||
non_linux_bundle_args(bundle_args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Homebrew::DevCmd::Tests.prepend(OS::Mac::DevCmd::Tests)
|
@ -425,8 +425,8 @@ module OS
|
||||
end
|
||||
|
||||
def check_deprecated_caskroom_taps
|
||||
tapped_caskroom_taps = Tap.select { |t| t.user == "caskroom" || t.name == "phinze/cask" }
|
||||
.map(&:name)
|
||||
tapped_caskroom_taps = ::Tap.select { |t| t.user == "caskroom" || t.name == "phinze/cask" }
|
||||
.map(&:name)
|
||||
return if tapped_caskroom_taps.empty?
|
||||
|
||||
<<~EOS
|
||||
|
@ -8,7 +8,7 @@ module OS
|
||||
|
||||
requires_ancestor { Kernel }
|
||||
|
||||
sig { params(tap: Tap, os_name: T.nilable(Symbol), arch: T.nilable(Symbol)).returns(T::Boolean) }
|
||||
sig { params(tap: ::Tap, os_name: T.nilable(Symbol), arch: T.nilable(Symbol)).returns(T::Boolean) }
|
||||
def valid_casks?(tap, os_name: nil, arch: ::Hardware::CPU.type)
|
||||
return true if os_name == :linux
|
||||
|
||||
|
17
Library/Homebrew/extend/os/mac/tap.rb
Normal file
17
Library/Homebrew/extend/os/mac/tap.rb
Normal file
@ -0,0 +1,17 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OS
|
||||
module Mac
|
||||
module Tap
|
||||
module ClassMethods
|
||||
sig { returns(T::Array[::Tap]) }
|
||||
def core_taps
|
||||
[CoreTap.instance, CoreCaskTap.instance].freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Tap.singleton_class.prepend(OS::Mac::Tap::ClassMethods)
|
4
Library/Homebrew/extend/os/tap.rb
Normal file
4
Library/Homebrew/extend/os/tap.rb
Normal file
@ -0,0 +1,4 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/os/mac/tap" if OS.mac?
|
@ -1,79 +1,9 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
module DiskUsageExtension
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Pathname }
|
||||
|
||||
sig { returns(Integer) }
|
||||
def disk_usage
|
||||
return @disk_usage if defined?(@disk_usage)
|
||||
|
||||
compute_disk_usage
|
||||
@disk_usage
|
||||
end
|
||||
|
||||
sig { returns(Integer) }
|
||||
def file_count
|
||||
return @file_count if defined?(@file_count)
|
||||
|
||||
compute_disk_usage
|
||||
@file_count
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def abv
|
||||
out = +""
|
||||
compute_disk_usage
|
||||
out << "#{number_readable(@file_count)} files, " if @file_count > 1
|
||||
out << disk_usage_readable(@disk_usage).to_s
|
||||
out.freeze
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
sig { void }
|
||||
def compute_disk_usage
|
||||
if symlink? && !exist?
|
||||
@file_count = 1
|
||||
@disk_usage = 0
|
||||
return
|
||||
end
|
||||
|
||||
path = if symlink?
|
||||
resolved_path
|
||||
else
|
||||
self
|
||||
end
|
||||
|
||||
if path.directory?
|
||||
scanned_files = Set.new
|
||||
@file_count = 0
|
||||
@disk_usage = 0
|
||||
path.find do |f|
|
||||
if f.directory?
|
||||
@disk_usage += f.lstat.size
|
||||
else
|
||||
@file_count += 1 if f.basename.to_s != ".DS_Store"
|
||||
# use Pathname#lstat instead of Pathname#stat to get info of symlink itself.
|
||||
stat = f.lstat
|
||||
file_id = [stat.dev, stat.ino]
|
||||
# count hardlinks only once.
|
||||
unless scanned_files.include?(file_id)
|
||||
@disk_usage += stat.size
|
||||
scanned_files.add(file_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
@file_count = 1
|
||||
@disk_usage = path.lstat.size
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require "system_command"
|
||||
require "extend/pathname/disk_usage_extension"
|
||||
require "extend/pathname/observer_pathname_extension"
|
||||
|
||||
# Homebrew extends Ruby's `Pathname` to make our code more readable.
|
||||
# @see https://ruby-doc.org/stdlib-2.6.3/libdoc/pathname/rdoc/Pathname.html Ruby's Pathname API
|
||||
@ -524,92 +454,3 @@ class Pathname
|
||||
end
|
||||
end
|
||||
require "extend/os/pathname"
|
||||
|
||||
require "context"
|
||||
|
||||
module ObserverPathnameExtension
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Pathname }
|
||||
|
||||
class << self
|
||||
include Context
|
||||
|
||||
sig { returns(Integer) }
|
||||
attr_accessor :n, :d
|
||||
|
||||
sig { void }
|
||||
def reset_counts!
|
||||
@n = @d = 0
|
||||
@put_verbose_trimmed_warning = false
|
||||
end
|
||||
|
||||
sig { returns(Integer) }
|
||||
def total
|
||||
n + d
|
||||
end
|
||||
|
||||
sig { returns([Integer, Integer]) }
|
||||
def counts
|
||||
[n, d]
|
||||
end
|
||||
|
||||
MAXIMUM_VERBOSE_OUTPUT = 100
|
||||
private_constant :MAXIMUM_VERBOSE_OUTPUT
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def verbose?
|
||||
return super unless ENV["CI"]
|
||||
return false unless super
|
||||
|
||||
if total < MAXIMUM_VERBOSE_OUTPUT
|
||||
true
|
||||
else
|
||||
unless @put_verbose_trimmed_warning
|
||||
puts "Only the first #{MAXIMUM_VERBOSE_OUTPUT} operations were output."
|
||||
@put_verbose_trimmed_warning = true
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def unlink
|
||||
super
|
||||
puts "rm #{self}" if ObserverPathnameExtension.verbose?
|
||||
ObserverPathnameExtension.n += 1
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def mkpath
|
||||
super
|
||||
puts "mkdir -p #{self}" if ObserverPathnameExtension.verbose?
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def rmdir
|
||||
super
|
||||
puts "rmdir #{self}" if ObserverPathnameExtension.verbose?
|
||||
ObserverPathnameExtension.d += 1
|
||||
end
|
||||
|
||||
sig { params(src: Pathname).void }
|
||||
def make_relative_symlink(src)
|
||||
super
|
||||
puts "ln -s #{src.relative_path_from(dirname)} #{basename}" if ObserverPathnameExtension.verbose?
|
||||
ObserverPathnameExtension.n += 1
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def install_info
|
||||
super
|
||||
puts "info #{self}" if ObserverPathnameExtension.verbose?
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def uninstall_info
|
||||
super
|
||||
puts "uninfo #{self}" if ObserverPathnameExtension.verbose?
|
||||
end
|
||||
end
|
||||
|
74
Library/Homebrew/extend/pathname/disk_usage_extension.rb
Normal file
74
Library/Homebrew/extend/pathname/disk_usage_extension.rb
Normal file
@ -0,0 +1,74 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
module DiskUsageExtension
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Pathname }
|
||||
|
||||
sig { returns(Integer) }
|
||||
def disk_usage
|
||||
return @disk_usage if defined?(@disk_usage)
|
||||
|
||||
compute_disk_usage
|
||||
@disk_usage
|
||||
end
|
||||
|
||||
sig { returns(Integer) }
|
||||
def file_count
|
||||
return @file_count if defined?(@file_count)
|
||||
|
||||
compute_disk_usage
|
||||
@file_count
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def abv
|
||||
out = +""
|
||||
compute_disk_usage
|
||||
out << "#{number_readable(@file_count)} files, " if @file_count > 1
|
||||
out << disk_usage_readable(@disk_usage).to_s
|
||||
out.freeze
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
sig { void }
|
||||
def compute_disk_usage
|
||||
if symlink? && !exist?
|
||||
@file_count = 1
|
||||
@disk_usage = 0
|
||||
return
|
||||
end
|
||||
|
||||
path = if symlink?
|
||||
resolved_path
|
||||
else
|
||||
self
|
||||
end
|
||||
|
||||
if path.directory?
|
||||
scanned_files = Set.new
|
||||
@file_count = 0
|
||||
@disk_usage = 0
|
||||
path.find do |f|
|
||||
if f.directory?
|
||||
@disk_usage += f.lstat.size
|
||||
else
|
||||
@file_count += 1 if f.basename.to_s != ".DS_Store"
|
||||
# use Pathname#lstat instead of Pathname#stat to get info of symlink itself.
|
||||
stat = f.lstat
|
||||
file_id = [stat.dev, stat.ino]
|
||||
# count hardlinks only once.
|
||||
unless scanned_files.include?(file_id)
|
||||
@disk_usage += stat.size
|
||||
scanned_files.add(file_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
@file_count = 1
|
||||
@disk_usage = path.lstat.size
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,91 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "context"
|
||||
|
||||
module ObserverPathnameExtension
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Pathname }
|
||||
|
||||
class << self
|
||||
include Context
|
||||
|
||||
sig { returns(Integer) }
|
||||
attr_accessor :n, :d
|
||||
|
||||
sig { void }
|
||||
def reset_counts!
|
||||
@n = @d = 0
|
||||
@put_verbose_trimmed_warning = false
|
||||
end
|
||||
|
||||
sig { returns(Integer) }
|
||||
def total
|
||||
n + d
|
||||
end
|
||||
|
||||
sig { returns([Integer, Integer]) }
|
||||
def counts
|
||||
[n, d]
|
||||
end
|
||||
|
||||
MAXIMUM_VERBOSE_OUTPUT = 100
|
||||
private_constant :MAXIMUM_VERBOSE_OUTPUT
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def verbose?
|
||||
return super unless ENV["CI"]
|
||||
return false unless super
|
||||
|
||||
if total < MAXIMUM_VERBOSE_OUTPUT
|
||||
true
|
||||
else
|
||||
unless @put_verbose_trimmed_warning
|
||||
puts "Only the first #{MAXIMUM_VERBOSE_OUTPUT} operations were output."
|
||||
@put_verbose_trimmed_warning = true
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def unlink
|
||||
super
|
||||
puts "rm #{self}" if ObserverPathnameExtension.verbose?
|
||||
ObserverPathnameExtension.n += 1
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def mkpath
|
||||
super
|
||||
puts "mkdir -p #{self}" if ObserverPathnameExtension.verbose?
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def rmdir
|
||||
super
|
||||
puts "rmdir #{self}" if ObserverPathnameExtension.verbose?
|
||||
ObserverPathnameExtension.d += 1
|
||||
end
|
||||
|
||||
sig { params(src: Pathname).void }
|
||||
def make_relative_symlink(src)
|
||||
super
|
||||
puts "ln -s #{src.relative_path_from(dirname)} #{basename}" if ObserverPathnameExtension.verbose?
|
||||
ObserverPathnameExtension.n += 1
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def install_info
|
||||
super
|
||||
puts "info #{self}" if ObserverPathnameExtension.verbose?
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def uninstall_info
|
||||
super
|
||||
puts "uninfo #{self}" if ObserverPathnameExtension.verbose?
|
||||
end
|
||||
end
|
@ -5,5 +5,9 @@ require "time"
|
||||
|
||||
class Time
|
||||
# Backwards compatibility for formulae that used this ActiveSupport extension
|
||||
alias rfc3339 xmlschema
|
||||
sig { returns(String) }
|
||||
def rfc3339
|
||||
odeprecated "Time#rfc3339", "Time#xmlschema"
|
||||
xmlschema
|
||||
end
|
||||
end
|
||||
|
@ -38,9 +38,9 @@ require "tab"
|
||||
require "mktemp"
|
||||
require "find"
|
||||
require "utils/spdx"
|
||||
require "extend/on_system"
|
||||
require "on_system"
|
||||
require "api"
|
||||
require "extend/api_hashable"
|
||||
require "api_hashable"
|
||||
|
||||
# A formula provides instructions and metadata for Homebrew to install a piece
|
||||
# of software. Every Homebrew formula is a {Formula}.
|
||||
|
@ -2,7 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "digest/sha2"
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
require "tab"
|
||||
require "utils"
|
||||
require "utils/bottles"
|
||||
|
@ -138,7 +138,7 @@ require "extend/kernel"
|
||||
require "os"
|
||||
|
||||
require "extend/array"
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
require "extend/enumerable"
|
||||
require "extend/string"
|
||||
require "extend/pathname"
|
||||
|
@ -4,7 +4,7 @@
|
||||
require "keg_relocate"
|
||||
require "language/python"
|
||||
require "lock_file"
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
|
||||
# Installation prefix of a formula.
|
||||
class Keg
|
||||
|
@ -1,17 +1,17 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IO
|
||||
sig { params(sep: String).returns(String) }
|
||||
def readline_nonblock(sep = $INPUT_RECORD_SEPARATOR)
|
||||
class ReadlineNonblock
|
||||
sig { params(io: IO).returns(String) }
|
||||
def self.read(io)
|
||||
line = +""
|
||||
buffer = +""
|
||||
|
||||
begin
|
||||
loop do
|
||||
break if buffer == sep
|
||||
break if buffer == $INPUT_RECORD_SEPARATOR
|
||||
|
||||
read_nonblock(1, buffer)
|
||||
io.read_nonblock(1, buffer)
|
||||
line.concat(buffer)
|
||||
end
|
||||
|
@ -4,7 +4,7 @@
|
||||
require "downloadable"
|
||||
require "mktemp"
|
||||
require "livecheck"
|
||||
require "extend/on_system"
|
||||
require "on_system"
|
||||
|
||||
# Resource is the fundamental representation of an external resource. The
|
||||
# primary formula download, along with other declared resources, are instances
|
||||
|
@ -4,7 +4,7 @@
|
||||
require "cxxstdlib"
|
||||
require "json"
|
||||
require "development_tools"
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
require "utils/curl"
|
||||
|
||||
# Rather than calling `new` directly, use one of the class methods like {SBOM.create}.
|
||||
|
@ -2,7 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "ipaddr"
|
||||
require "extend/on_system"
|
||||
require "on_system"
|
||||
require "utils/service"
|
||||
|
||||
module Homebrew
|
||||
|
@ -12,7 +12,7 @@ require "utils/bottles"
|
||||
require "patch"
|
||||
require "compilers"
|
||||
require "macos_version"
|
||||
require "extend/on_system"
|
||||
require "on_system"
|
||||
|
||||
class SoftwareSpec
|
||||
include Downloadable
|
||||
|
@ -6,7 +6,7 @@ require "shellwords"
|
||||
require "uri"
|
||||
|
||||
require "context"
|
||||
require "extend/io"
|
||||
require "readline_nonblock"
|
||||
require "utils/timer"
|
||||
|
||||
# Class for running sub-processes and capturing their output and exit status.
|
||||
@ -361,7 +361,7 @@ class SystemCommand
|
||||
|
||||
readable_sources.each do |source|
|
||||
loop do
|
||||
line = source.readline_nonblock || ""
|
||||
line = ReadlineNonblock.read(source)
|
||||
yield(sources.fetch(source), line)
|
||||
end
|
||||
rescue EOFError
|
||||
|
@ -5,7 +5,7 @@ require "cxxstdlib"
|
||||
require "options"
|
||||
require "json"
|
||||
require "development_tools"
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
|
||||
# Rather than calling `new` directly, use one of the class methods like {Tab.create}.
|
||||
class AbstractTab
|
||||
|
@ -1079,15 +1079,12 @@ class Tap
|
||||
# All locally installed and core taps. Core taps might not be installed locally when using the API.
|
||||
sig { returns(T::Array[Tap]) }
|
||||
def self.all
|
||||
cache[:all] ||= begin
|
||||
core_taps = [
|
||||
CoreTap.instance,
|
||||
# The conditional is valid here because we only want the cask tap on macOS.
|
||||
(CoreCaskTap.instance if OS.mac?), # rubocop:disable Homebrew/MoveToExtendOS
|
||||
].compact
|
||||
cache[:all] ||= installed | core_taps
|
||||
end
|
||||
|
||||
installed | core_taps
|
||||
end
|
||||
sig { returns(T::Array[Tap]) }
|
||||
def self.core_taps
|
||||
[CoreTap.instance].freeze
|
||||
end
|
||||
|
||||
# Enumerate all available {Tap}s.
|
||||
@ -1517,3 +1514,5 @@ class TapConfig
|
||||
Homebrew::Settings.delete key, repo: tap.path
|
||||
end
|
||||
end
|
||||
|
||||
require "extend/os/tap"
|
||||
|
@ -4,7 +4,7 @@
|
||||
require "context"
|
||||
require "erb"
|
||||
require "settings"
|
||||
require "extend/cachable"
|
||||
require "cachable"
|
||||
|
||||
module Utils
|
||||
# Helper module for fetching and reporting analytics data.
|
||||
|
@ -34,7 +34,7 @@ For more information on how to express more complex types, refer to the official
|
||||
|
||||
### Ruby interface files (`.rbi`)
|
||||
|
||||
[RBI files](https://sorbet.org/docs/rbi) help Sorbet learn about constants, ancestors and methods defined in ways it doesn't understand natively. We can also create an RBI file to help Sorbet understand dynamic definitions. Some of these files are automatically generated (see the next section) and some are manually written, e.g. [`extend/on_system.rbi`](https://github.com/Homebrew/brew/blob/975fe8a83fd57a8d8e790ec6fb10c2f13f705d02/Library/Homebrew/extend/on_system.rbi).
|
||||
[RBI files](https://sorbet.org/docs/rbi) help Sorbet learn about constants, ancestors and methods defined in ways it doesn't understand natively. We can also create an RBI file to help Sorbet understand dynamic definitions. Some of these files are automatically generated (see the next section) and some are manually written, e.g. [`on_system.rbi`](https://github.com/Homebrew/brew/blob/HEAD/Library/Homebrew/on_system.rbi).
|
||||
|
||||
There are also a very small number of files that Homebrew loads before `sorbet-runtime`, such as `utils/gems.rb`. Those files cannot have type signatures alongside the code itself, so RBI files are used there instead to retain static type checking.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user