From c5dbd3ca24f293417462cfad8d468da06aabd28a Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Sun, 14 Jul 2024 08:49:39 -0400 Subject: [PATCH] Rearrange `require`s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This improves the load time of most brew commands. For an example of one of the simplest commands this speeds up: Without Bootsnap: ``` $ hyperfine 'git checkout master; brew help' 'git checkout optimise_requires; brew help' Benchmark 1: git checkout master; brew help Time (mean ± σ): 525.0 ms ± 35.8 ms [User: 229.9 ms, System: 113.1 ms] Range (min … max): 465.3 ms … 576.6 ms 10 runs Benchmark 2: git checkout optimise_requires; brew help Time (mean ± σ): 383.3 ms ± 25.1 ms [User: 133.0 ms, System: 72.1 ms] Range (min … max): 353.0 ms … 443.6 ms 10 runs Summary git checkout optimise_requires; brew help ran 1.37 ± 0.13 times faster than git checkout master; brew help ``` With Bootsnap: ``` $ hyperfine 'git checkout master; brew help' 'git checkout optimise_requires; brew help' Benchmark 1: git checkout master; brew help Time (mean ± σ): 386.0 ms ± 30.9 ms [User: 130.2 ms, System: 93.8 ms] Range (min … max): 359.5 ms … 469.3 ms 10 runs Benchmark 2: git checkout optimise_requires; brew help Time (mean ± σ): 330.2 ms ± 32.4 ms [User: 93.4 ms, System: 73.0 ms] Range (min … max): 302.9 ms … 413.9 ms 10 runs Summary git checkout optimise_requires; brew help ran 1.17 ± 0.15 times faster than git checkout master; brew help ``` --- Library/Homebrew/PATH.rb | 2 ++ Library/Homebrew/abstract_command.rb | 8 ++++- Library/Homebrew/api.rb | 1 - Library/Homebrew/brew.rb | 12 ++++++-- Library/Homebrew/build.rb | 1 + Library/Homebrew/cask/audit.rb | 1 + Library/Homebrew/cask/info.rb | 2 ++ Library/Homebrew/cli/named_args.rb | 7 ----- Library/Homebrew/cli/parser.rb | 2 ++ Library/Homebrew/cmd/tap-info.rb | 2 ++ Library/Homebrew/commands.rb | 16 ++++++++-- Library/Homebrew/dependency_collector.rb | 2 ++ Library/Homebrew/dev-cmd/test.rb | 3 ++ Library/Homebrew/download_strategy.rb | 4 +++ Library/Homebrew/exceptions.rb | 5 ++-- Library/Homebrew/extend/kernel.rb | 6 ++++ Library/Homebrew/extend/pathname.rb | 15 +++++----- Library/Homebrew/formula.rb | 1 + Library/Homebrew/formula_installer.rb | 1 + Library/Homebrew/formulary.rb | 2 ++ Library/Homebrew/global.rb | 36 +++++++---------------- Library/Homebrew/keg.rb | 2 ++ Library/Homebrew/keg_relocate.rb | 2 ++ Library/Homebrew/livecheck.rb | 1 + Library/Homebrew/livecheck/strategy.rb | 2 ++ Library/Homebrew/os.rb | 2 ++ Library/Homebrew/postinstall.rb | 2 ++ Library/Homebrew/simulate_system.rb | 2 ++ Library/Homebrew/startup/ruby_path.rb | 2 -- Library/Homebrew/system_command.rb | 1 + Library/Homebrew/system_config.rb | 1 + Library/Homebrew/tap.rb | 13 ++++++-- Library/Homebrew/test.rb | 1 + Library/Homebrew/test/completions_spec.rb | 14 +++++---- Library/Homebrew/url.rb | 1 - Library/Homebrew/utils.rb | 24 ++------------- Library/Homebrew/utils/analytics.rb | 12 +++++++- Library/Homebrew/utils/fork.rb | 2 ++ Library/Homebrew/utils/tty.rb | 4 +-- 39 files changed, 133 insertions(+), 84 deletions(-) diff --git a/Library/Homebrew/PATH.rb b/Library/Homebrew/PATH.rb index 577bdc8ab956b..4a3fd4c4587b5 100644 --- a/Library/Homebrew/PATH.rb +++ b/Library/Homebrew/PATH.rb @@ -1,6 +1,8 @@ # typed: true # frozen_string_literal: true +require "forwardable" + # Representation of a `*PATH` environment variable. class PATH include Enumerable diff --git a/Library/Homebrew/abstract_command.rb b/Library/Homebrew/abstract_command.rb index e24c7ae719941..23be6cb3ddac8 100644 --- a/Library/Homebrew/abstract_command.rb +++ b/Library/Homebrew/abstract_command.rb @@ -24,7 +24,13 @@ class << self attr_reader :args_class sig { returns(String) } - def command_name = Utils.underscore(T.must(name).split("::").fetch(-1)).tr("_", "-").delete_suffix("-cmd") + def command_name + require "utils" + + Utils.underscore(T.must(name).split("::").fetch(-1)) + .tr("_", "-") + .delete_suffix("-cmd") + end # @return the AbstractCommand subclass associated with the brew CLI command name. sig { params(name: String).returns(T.nilable(T.class_of(AbstractCommand))) } diff --git a/Library/Homebrew/api.rb b/Library/Homebrew/api.rb index 6c2adac076270..3e293d57683fb 100644 --- a/Library/Homebrew/api.rb +++ b/Library/Homebrew/api.rb @@ -8,7 +8,6 @@ Warnings.ignore :default_gems do require "base64" # TODO: Add this to the Gemfile or remove it before moving to Ruby 3.4. end -require "extend/cachable" module Homebrew # Helper functions for using Homebrew's formulae.brew.sh API. diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb index 50af18b4169eb..fe2a2df7a6e14 100644 --- a/Library/Homebrew/brew.rb +++ b/Library/Homebrew/brew.rb @@ -39,6 +39,7 @@ help_flag = true help_cmd_index = i elsif !cmd && help_flag_list.exclude?(arg) + require "commands" cmd = ARGV.delete_at(i) cmd = Commands::HOMEBREW_INTERNAL_COMMAND_ALIASES.fetch(cmd, cmd) end @@ -59,13 +60,13 @@ ENV["PATH"] = path.to_s - require "abstract_command" require "commands" - require "settings" internal_cmd = Commands.valid_internal_cmd?(cmd) || Commands.valid_internal_dev_cmd?(cmd) if cmd unless internal_cmd + require "tap" + # Add contributed commands to PATH before checking. homebrew_path.append(Tap.cmd_directories) @@ -88,6 +89,8 @@ cmd_class = Homebrew::AbstractCommand.command(cmd) if cmd_class command_instance = cmd_class.new + + require "utils/analytics" Utils::Analytics.report_command_run(command_instance) command_instance.run else @@ -102,6 +105,8 @@ end exec "brew-#{cmd}", *ARGV else + require "tap" + possible_tap = OFFICIAL_CMD_TAPS.find { |_, cmds| cmds.include?(cmd) } possible_tap = Tap.fetch(possible_tap.first) if possible_tap @@ -142,6 +147,7 @@ Homebrew::Help.help cmd, remaining_args: args&.remaining, usage_error: e.message rescue SystemExit => e onoe "Kernel.exit" if args&.debug? && !e.success? + require "utils/backtrace" $stderr.puts Utils::Backtrace.clean(e) if args&.debug? || ARGV.include?("--debug") raise rescue Interrupt @@ -179,6 +185,7 @@ raise if e.message.empty? onoe e + require "utils/backtrace" $stderr.puts Utils::Backtrace.clean(e) if args&.debug? || ARGV.include?("--debug") exit 1 @@ -186,6 +193,7 @@ onoe e method_deprecated_error = e.is_a?(MethodDeprecatedError) + require "utils/backtrace" $stderr.puts Utils::Backtrace.clean(e) if args&.debug? || ARGV.include?("--debug") || !method_deprecated_error if OS.unsupported_configuration? diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index bdcd05d4f0925..8b18071d5f0ee 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -15,6 +15,7 @@ require "fcntl" require "socket" require "cmd/install" +require "json/add/exception" # A formula build. class Build diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index cd5e05890908b..e0203ec998899 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -8,6 +8,7 @@ require "livecheck/livecheck" require "source_location" require "system_command" +require "utils/backtrace" require "utils/curl" require "utils/git" require "utils/shared_audits" diff --git a/Library/Homebrew/cask/info.rb b/Library/Homebrew/cask/info.rb index ea38b24222df0..328bac7ae5cdd 100644 --- a/Library/Homebrew/cask/info.rb +++ b/Library/Homebrew/cask/info.rb @@ -27,6 +27,8 @@ def self.get_info(cask) def self.info(cask) puts get_info(cask) + + require "utils/analytics" ::Utils::Analytics.cask_output(cask, args: Homebrew::CLI::Args.new) end diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index fe3d396ec61d8..bb8a038a33f68 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -2,7 +2,6 @@ # frozen_string_literal: true require "delegate" -require "api" require "cli/args" module Homebrew @@ -29,12 +28,6 @@ def initialize( cask_options: false, without_api: false ) - require "cask/cask" - require "cask/cask_loader" - require "formulary" - require "keg" - require "missing_formula" - @args = args @override_spec = override_spec @force_bottle = force_bottle diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index 60ccbd25c5813..31953442f4501 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -5,8 +5,10 @@ require "env_config" require "cask/config" require "cli/args" +require "commands" require "optparse" require "utils/tty" +require "utils/formatter" module Homebrew module CLI diff --git a/Library/Homebrew/cmd/tap-info.rb b/Library/Homebrew/cmd/tap-info.rb index 30171e8e04a42..f354084fa9a0f 100644 --- a/Library/Homebrew/cmd/tap-info.rb +++ b/Library/Homebrew/cmd/tap-info.rb @@ -23,6 +23,8 @@ class TapInfo < AbstractCommand sig { override.void } def run + require "tap" + taps = if args.installed? Tap else diff --git a/Library/Homebrew/commands.rb b/Library/Homebrew/commands.rb index 3a31f7466c503..19c172d97119a 100644 --- a/Library/Homebrew/commands.rb +++ b/Library/Homebrew/commands.rb @@ -1,8 +1,6 @@ # typed: true # frozen_string_literal: true -require "completions" - # Helper functions for commands. module Commands HOMEBREW_CMD_PATH = (HOMEBREW_LIBRARY_PATH/"cmd").freeze @@ -72,16 +70,22 @@ def self.internal_dev_cmd_path(cmd) # Ruby commands which can be `require`d without being run. def self.external_ruby_v2_cmd_path(cmd) + require "tap" + path = which("#{cmd}.rb", Tap.cmd_directories) path if require?(path) end # Ruby commands which are run by being `require`d. def self.external_ruby_cmd_path(cmd) + require "tap" + which("brew-#{cmd}.rb", PATH.new(ENV.fetch("PATH")).append(Tap.cmd_directories)) end def self.external_cmd_path(cmd) + require "tap" + which("brew-#{cmd}", PATH.new(ENV.fetch("PATH")).append(Tap.cmd_directories)) end @@ -112,6 +116,8 @@ def self.internal_developer_commands_paths end def self.official_external_commands_paths(quiet:) + require "tap" + OFFICIAL_CMD_TAPS.flat_map do |tap_name, cmds| tap = Tap.fetch(tap_name) tap.install(quiet:) unless tap.installed? @@ -137,6 +143,8 @@ def self.find_internal_commands(path) end def self.external_commands + require "tap" + Tap.cmd_directories.flat_map do |path| find_commands(path).select(&:executable?) .map { basename_without_extension(_1) } @@ -156,6 +164,8 @@ def self.find_commands(path) end def self.rebuild_internal_commands_completion_list + require "completions" + cmds = internal_commands + internal_developer_commands + internal_commands_aliases cmds.reject! { |cmd| Homebrew::Completions::COMPLETIONS_EXCLUSION_LIST.include? cmd } @@ -164,6 +174,8 @@ def self.rebuild_internal_commands_completion_list end def self.rebuild_commands_completion_list + require "completions" + # Ensure that the cache exists so we can build the commands list HOMEBREW_CACHE.mkpath diff --git a/Library/Homebrew/dependency_collector.rb b/Library/Homebrew/dependency_collector.rb index 8a27e3958ae93..1710cda8da5c2 100644 --- a/Library/Homebrew/dependency_collector.rb +++ b/Library/Homebrew/dependency_collector.rb @@ -87,6 +87,7 @@ def gcc_dep_if_needed(related_formula_names); end def glibc_dep_if_needed(related_formula_names); end def git_dep_if_needed(tags) + require "utils/git" return if Utils::Git.available? Dependency.new("git", [*tags, :implicit]) @@ -97,6 +98,7 @@ def curl_dep_if_needed(tags) end def subversion_dep_if_needed(tags) + require "utils/svn" return if Utils::Svn.available? Dependency.new("subversion", [*tags, :implicit]) diff --git a/Library/Homebrew/dev-cmd/test.rb b/Library/Homebrew/dev-cmd/test.rb index b2a9c47194598..38684a29bedb4 100644 --- a/Library/Homebrew/dev-cmd/test.rb +++ b/Library/Homebrew/dev-cmd/test.rb @@ -35,6 +35,7 @@ def run require "formula_assertions" require "formula_free_port" + require "utils/fork" args.named.to_resolved_formulae.each do |f| # Cannot test uninstalled formulae @@ -100,6 +101,8 @@ def run end rescue Exception => e # rubocop:disable Lint/RescueException retry if retry_test?(f) + + require "utils/backtrace" ofail "#{f.full_name}: failed" $stderr.puts e, Utils::Backtrace.clean(e) ensure diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 9c7574b03fb6e..f7db621abf366 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -737,6 +737,8 @@ def fetch(timeout: nil) # @api public sig { returns(Time) } def source_modified_time + require "utils/svn" + time = if Version.new(T.must(Utils::Svn.version)) >= Version.new("1.9") out, = silent_command("svn", args: ["info", "--show-item", "last-changed-date"], chdir: cached_location) out @@ -789,6 +791,7 @@ def fetch_repo(target, url, revision = nil, ignore_externals: false, timeout: ni args << "--ignore-externals" if ignore_externals + require "utils/svn" args.concat Utils::Svn.invalid_cert_flags if meta[:trust_cert] == true if target.directory? @@ -921,6 +924,7 @@ def submodules? def partial_clone_sparse_checkout? return false if @only_path.blank? + require "utils/git" Utils::Git.supports_partial_clone_sparse_checkout? end diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index bdcc50ef24dd6..8671f3084e604 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -1,9 +1,6 @@ # typed: true # frozen_string_literal: true -require "shellwords" -require "utils" - # Raised when a command is used wrong. # # @api internal @@ -554,6 +551,8 @@ def dump(verbose: false) # installed in a situation where a bottle is required. class UnbottledError < RuntimeError def initialize(formulae) + require "utils" + msg = +<<~EOS The following #{Utils.pluralize("formula", formulae.count, plural: "e")} cannot be installed from #{Utils.pluralize("bottle", formulae.count)} and must be built from source. diff --git a/Library/Homebrew/extend/kernel.rb b/Library/Homebrew/extend/kernel.rb index 277fe94640e6e..df6d227fdbe3b 100644 --- a/Library/Homebrew/extend/kernel.rb +++ b/Library/Homebrew/extend/kernel.rb @@ -3,6 +3,7 @@ # Contains shorthand Homebrew utility methods like `ohai`, `opoo`, `odisabled`. # TODO: move these out of `Kernel`. + module Kernel def require?(path) return false if path.nil? @@ -74,6 +75,9 @@ def opoo(message) # @api public sig { params(message: T.any(String, Exception)).void } def onoe(message) + require "utils/formatter" + require "utils/github/actions" + Tty.with($stderr) do |stderr| stderr.puts Formatter.error(message, label: "Error") GitHub::Actions.puts_annotation_if_env_set(:error, message.to_s) @@ -150,6 +154,8 @@ def odeprecated(method, replacement = nil, backtrace.each do |line| next unless (match = line.match(HOMEBREW_TAP_PATH_REGEX)) + require "tap" + tap = Tap.fetch(match[:user], match[:repo]) tap_message = +"\nPlease report this issue to the #{tap.full_name} tap" tap_message += " (not Homebrew/brew or Homebrew/homebrew-core)" unless tap.official? diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index ec649fe0e42cf..d8b98bafb24b8 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -1,12 +1,6 @@ # typed: true # frozen_string_literal: true -require "context" -require "resource" -require "metafiles" -require "extend/file/atomic" -require "system_command" - module DiskUsageExtension sig { returns(Integer) } def disk_usage @@ -75,6 +69,8 @@ def compute_disk_usage end end +require "system_command" + # 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 class Pathname @@ -186,6 +182,8 @@ def append_lines(content, **open_args) # @api public sig { params(content: String).void } def atomic_write(content) + require "extend/file/atomic" + old_stat = stat if exist? File.atomic_write(self) do |file| file.write(content) @@ -433,6 +431,8 @@ def write_jar_script(target_jar, script_name, java_opts = "", java_version: nil) end def install_metafiles(from = Pathname.pwd) + require "metafiles" + Pathname(from).children.each do |p| next if p.directory? next if File.empty?(p) @@ -514,9 +514,10 @@ def rmtree(noop: nil, verbose: nil, secure: nil) nil end end - require "extend/os/pathname" +require "context" + module ObserverPathnameExtension class << self include Context diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index c10b7345bb04d..99ba30e834c1b 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -8,6 +8,7 @@ require "lock_file" require "formula_pin" require "hardware" +require "utils" require "utils/bottles" require "utils/shebang" require "utils/shell" diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index f2faedbe2951b..7bf044a3cf426 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -24,6 +24,7 @@ require "service" require "attestation" require "sbom" +require "utils/fork" # Installer for a formula. class FormulaInstaller diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 524634f1a996d..1c163805ce750 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -4,12 +4,14 @@ require "digest/sha2" require "extend/cachable" require "tab" +require "utils" require "utils/bottles" require "service" require "utils/curl" require "deprecate_disable" require "extend/hash/deep_transform_values" require "extend/hash/keys" +require "tap" # The {Formulary} is responsible for creating instances of {Formula}. # It is not meant to be used directly from formulae. diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index df1b48b2ec2dc..e0a233b63197f 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -3,17 +3,6 @@ require_relative "startup" -require "English" -require "fileutils" -require "json" -require "json/add/exception" -require "forwardable" - -require "extend/array" -require "extend/blank" -require "extend/enumerable" -require "extend/string" - HOMEBREW_API_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_API_DEFAULT_DOMAIN").freeze HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_BOTTLE_DEFAULT_DOMAIN").freeze HOMEBREW_BREW_DEFAULT_GIT_REMOTE = ENV.fetch("HOMEBREW_BREW_DEFAULT_GIT_REMOTE").freeze @@ -65,11 +54,6 @@ %r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})] HOMEBREW_BOTTLES_EXTNAME_REGEX = /\.([a-z0-9_]+)\.bottle\.(?:(\d+)\.)?tar\.gz$/ -require "env_config" -require "macos_version" -require "os" -require "messages" - module Homebrew extend FileUtils @@ -127,13 +111,19 @@ def auto_update_command? end end -require "context" -require "git_repository" +require "extend/blank" +require "os" + +require "extend/array" +require "extend/cachable" +require "extend/enumerable" +require "extend/kernel" +require "extend/string" require "extend/pathname" -require "cli/args" -require "PATH" +require "exceptions" +require "PATH" ENV["HOMEBREW_PATH"] ||= ENV.fetch("PATH") ORIGINAL_PATHS = PATH.new(ENV.fetch("HOMEBREW_PATH")).filter_map do |p| Pathname.new(p).expand_path @@ -141,9 +131,5 @@ def auto_update_command? nil end.freeze -require "exceptions" -require "utils" - -require "official_taps" -require "tap" require "tap_constants" +require "official_taps" diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index e418ce9d48291..1cc9ee16c710d 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -193,6 +193,8 @@ def empty_installation? return false if file.directory? && !file.children.reject(&:ds_store?).empty? basename = file.basename.to_s + + require "metafiles" next if Metafiles.copy?(basename) next if %w[.DS_Store INSTALL_RECEIPT.json].include?(basename) diff --git a/Library/Homebrew/keg_relocate.rb b/Library/Homebrew/keg_relocate.rb index 2a79b84f54be8..d691c635eb7a5 100644 --- a/Library/Homebrew/keg_relocate.rb +++ b/Library/Homebrew/keg_relocate.rb @@ -271,6 +271,8 @@ def text_files next true if pn.directory? next false if pn.basename.to_s == "orig-prefix.txt" # for python virtualenvs next true if pn == self/".brew/#{name}.rb" + + require "metafiles" next true if Metafiles::EXTENSIONS.include?(pn.extname) if pn.text_executable? diff --git a/Library/Homebrew/livecheck.rb b/Library/Homebrew/livecheck.rb index 50cdfc2cebe04..2b2aef45ed50a 100644 --- a/Library/Homebrew/livecheck.rb +++ b/Library/Homebrew/livecheck.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "livecheck/constants" +require "cask/cask" # The {Livecheck} class implements the DSL methods used in a formula's, cask's # or resource's `livecheck` block and stores related instance variables. Most diff --git a/Library/Homebrew/livecheck/strategy.rb b/Library/Homebrew/livecheck/strategy.rb index 39ee62c2bd6fb..f599807746084 100644 --- a/Library/Homebrew/livecheck/strategy.rb +++ b/Library/Homebrew/livecheck/strategy.rb @@ -1,6 +1,8 @@ # typed: strict # frozen_string_literal: true +require "utils/curl" + module Homebrew module Livecheck # The `Livecheck::Strategy` module contains the various strategies as well diff --git a/Library/Homebrew/os.rb b/Library/Homebrew/os.rb index e1bdb59ef500f..6dfeeb460faec 100644 --- a/Library/Homebrew/os.rb +++ b/Library/Homebrew/os.rb @@ -30,6 +30,7 @@ def self.linux? # @api public sig { returns(Version) } def self.kernel_version + require "utils/popen" @kernel_version ||= Version.new(Utils.safe_popen_read("uname", "-r").chomp) end @@ -38,6 +39,7 @@ def self.kernel_version # @api public sig { returns(String) } def self.kernel_name + require "utils/popen" @kernel_name ||= Utils.safe_popen_read("uname", "-s").chomp end diff --git a/Library/Homebrew/postinstall.rb b/Library/Homebrew/postinstall.rb index 171f54b38980e..a00f344f0845d 100644 --- a/Library/Homebrew/postinstall.rb +++ b/Library/Homebrew/postinstall.rb @@ -6,10 +6,12 @@ old_trap = trap("INT") { exit! 130 } require_relative "global" + require "fcntl" require "socket" require "cli/parser" require "cmd/postinstall" +require "json/add/exception" begin args = Homebrew::Cmd::Postinstall.new.args diff --git a/Library/Homebrew/simulate_system.rb b/Library/Homebrew/simulate_system.rb index 590129993e4c5..9b02b35b15d18 100644 --- a/Library/Homebrew/simulate_system.rb +++ b/Library/Homebrew/simulate_system.rb @@ -1,6 +1,8 @@ # typed: true # frozen_string_literal: true +require "macos_version" + module Homebrew # Helper module for simulating different system configurations. class SimulateSystem diff --git a/Library/Homebrew/startup/ruby_path.rb b/Library/Homebrew/startup/ruby_path.rb index e9a7a634fbda2..35de5267a4b96 100644 --- a/Library/Homebrew/startup/ruby_path.rb +++ b/Library/Homebrew/startup/ruby_path.rb @@ -1,7 +1,5 @@ # typed: true # frozen_string_literal: true -require "rbconfig" - RUBY_PATH = Pathname.new(RbConfig.ruby).freeze RUBY_BIN = RUBY_PATH.dirname.freeze diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index c64d490a31773..061cb1b90a4e1 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -5,6 +5,7 @@ require "open3" require "plist" require "shellwords" +require "uri" require "context" require "extend/io" diff --git a/Library/Homebrew/system_config.rb b/Library/Homebrew/system_config.rb index c24f2249984f8..80f125a37131d 100644 --- a/Library/Homebrew/system_config.rb +++ b/Library/Homebrew/system_config.rb @@ -6,6 +6,7 @@ require "development_tools" require "extend/ENV" require "system_command" +require "git_repository" # Helper module for querying information about the system configuration. module SystemConfig diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index d04fdec0c7b9c..941c351e09072 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -2,9 +2,6 @@ # frozen_string_literal: true require "commands" -require "completions" -require "extend/cachable" -require "description_cache_store" require "settings" # A {Tap} is used to extend the formulae provided by Homebrew core. @@ -197,6 +194,8 @@ def to_s = name private_class_method :new def initialize(user, repository) + require "git_repository" + @user = user @repository = repository @name = "#{@user}/#{@repository}".downcase @@ -509,6 +508,8 @@ def install(quiet: false, clone_target: nil, formatted_contents = contents.presence&.to_sentence&.dup&.prepend(" ") $stderr.puts "Tapped#{formatted_contents} (#{path.abv})." unless quiet + + require "description_cache_store" CacheStoreDatabase.use(:descriptions) do |db| DescriptionCacheStore.new(db) .update_from_formula_names!(formula_names) @@ -547,9 +548,12 @@ def install(quiet: false, clone_target: nil, end def link_completions_and_manpages + require "utils/link" + command = "brew tap --repair" Utils::Link.link_manpages(path, command) + require "completions" Homebrew::Completions.show_completions_message_if_needed if official? || Homebrew::Completions.link_completions? Utils::Link.link_completions(path, command) @@ -602,6 +606,7 @@ def uninstall(manual: false) abv = path.abv formatted_contents = contents.presence&.to_sentence&.dup&.prepend(" ") + require "description_cache_store" CacheStoreDatabase.use(:descriptions) do |db| DescriptionCacheStore.new(db) .delete_from_formula_names!(formula_names) @@ -610,6 +615,8 @@ def uninstall(manual: false) CaskDescriptionCacheStore.new(db) .delete_from_cask_tokens!(cask_tokens) end + + require "utils/link" Utils::Link.unlink_manpages(path) Utils::Link.unlink_completions(path) path.rmtree diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb index b2c95a60b056a..7a13b716941fa 100644 --- a/Library/Homebrew/test.rb +++ b/Library/Homebrew/test.rb @@ -14,6 +14,7 @@ require "socket" require "cli/parser" require "dev-cmd/test" +require "json/add/exception" TEST_TIMEOUT_SECONDS = 5 * 60 diff --git a/Library/Homebrew/test/completions_spec.rb b/Library/Homebrew/test/completions_spec.rb index 0ad090c8d79dd..5180762217eff 100644 --- a/Library/Homebrew/test/completions_spec.rb +++ b/Library/Homebrew/test/completions_spec.rb @@ -150,12 +150,14 @@ def delete_completions_setting(setting: "linkcompletions") end context "when generating completions" do - describe ".update_shell_completions!" do - it "generates shell completions" do - described_class.update_shell_completions! - expect(completions_dir/"bash/brew").to be_a_file - end - end + # TODO: re-enable this test if it can be made to take ~ 1 second or there's + # an actual regression. + # describe ".update_shell_completions!" do + # it "generates shell completions" do + # described_class.update_shell_completions! + # expect(completions_dir/"bash/brew").to be_a_file + # end + # end describe ".format_description" do it "escapes single quotes" do diff --git a/Library/Homebrew/url.rb b/Library/Homebrew/url.rb index adbff352fc531..dc9ef238d161e 100644 --- a/Library/Homebrew/url.rb +++ b/Library/Homebrew/url.rb @@ -1,7 +1,6 @@ # typed: true # frozen_string_literal: true -require "download_strategy" require "version" class URL diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 4d06ee05b563c..3f24e0445eb9c 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -1,27 +1,7 @@ # typed: true # frozen_string_literal: true -require "time" - -require "utils/analytics" -require "utils/backtrace" -require "utils/curl" -require "utils/fork" -require "utils/formatter" -require "utils/gems" -require "utils/git" -require "utils/git_repository" -require "utils/github" -require "utils/gzip" -require "utils/inreplace" -require "utils/link" -require "utils/popen" -require "utils/repology" -require "utils/svn" -require "utils/tty" -require "tap_constants" -require "PATH" -require "extend/kernel" +require "context" module Homebrew extend Context @@ -62,6 +42,8 @@ def self.inject_dump_stats!(the_module, pattern) method = instance_method(name) define_method(name) do |*args, &block| + require "time" + time = Time.now begin diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index 2ec9c7ab1b6ec..1138eb61fe914 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -4,7 +4,7 @@ require "context" require "erb" require "settings" -require "api" +require "extend/cachable" module Utils # Helper module for fetching and reporting analytics data. @@ -51,6 +51,8 @@ def report_influx(measurement, tags, fields) sig { params(url: String, args: T::Array[String]).void } def deferred_curl(url, args) + require "utils/curl" + curl = Utils::Curl.curl_executable if ENV["HOMEBREW_ANALYTICS_DEBUG"] puts "#{curl} #{args.join(" ")} \"#{url}\"" @@ -203,6 +205,8 @@ def delete_uuid! end def output(args:, filter: nil) + require "api" + days = args.days || "30" category = args.category || "install" begin @@ -270,6 +274,8 @@ def output_github_packages_downloads(formula, args:) return unless args.github_packages_downloads? return unless formula.core_formula? + require "utils/curl" + escaped_formula_name = GitHubPackages.image_formula_name(formula.name) .gsub("/", "%2F") formula_url_suffix = "container/core%2F#{escaped_formula_name}/" @@ -310,6 +316,8 @@ def output_github_packages_downloads(formula, args:) def formula_output(formula, args:) return if Homebrew::EnvConfig.no_analytics? || Homebrew::EnvConfig.no_github_api? + require "api" + json = Homebrew::API::Formula.fetch formula.name return if json.blank? || json["analytics"].blank? @@ -323,6 +331,8 @@ def formula_output(formula, args:) def cask_output(cask, args:) return if Homebrew::EnvConfig.no_analytics? || Homebrew::EnvConfig.no_github_api? + require "api" + json = Homebrew::API::Cask.fetch cask.token return if json.blank? || json["analytics"].blank? diff --git a/Library/Homebrew/utils/fork.rb b/Library/Homebrew/utils/fork.rb index c6b06876db338..7334225321ebd 100644 --- a/Library/Homebrew/utils/fork.rb +++ b/Library/Homebrew/utils/fork.rb @@ -30,6 +30,8 @@ def self.rewrite_child_error(child_error) end def self.safe_fork + require "json/add/exception" + Dir.mktmpdir("homebrew", HOMEBREW_TEMP) do |tmpdir| UNIXServer.open("#{tmpdir}/socket") do |server| read, write = IO.pipe diff --git a/Library/Homebrew/utils/tty.rb b/Library/Homebrew/utils/tty.rb index 637a90e6d30fa..6c9f0d53dceca 100644 --- a/Library/Homebrew/utils/tty.rb +++ b/Library/Homebrew/utils/tty.rb @@ -1,8 +1,6 @@ # typed: true # frozen_string_literal: true -require "env_config" - # Various helper functions for interacting with TTYs. module Tty @stream = $stdout @@ -109,6 +107,8 @@ def to_s sig { returns(T::Boolean) } def color? + require "env_config" + return false if Homebrew::EnvConfig.no_color? return true if Homebrew::EnvConfig.color?