From cf169e527018b1728a7d511f827506c6af7e4239 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 23 Nov 2020 17:31:17 +0100 Subject: [PATCH 01/19] Fix type errors in `Sandbox`. --- Library/Homebrew/os.rb | 5 +++ Library/Homebrew/sandbox.rb | 73 +++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/Library/Homebrew/os.rb b/Library/Homebrew/os.rb index 2c3199b81b..7f0472ace9 100644 --- a/Library/Homebrew/os.rb +++ b/Library/Homebrew/os.rb @@ -5,9 +5,12 @@ # # @api private module OS + extend T::Sig + # Check if the operating system is macOS. # # @api public + sig { returns(T::Boolean) } def self.mac? return false if ENV["HOMEBREW_TEST_GENERIC_OS"] @@ -17,6 +20,7 @@ module OS # Check if the operating system is Linux. # # @api public + sig { returns(T::Boolean) } def self.linux? return false if ENV["HOMEBREW_TEST_GENERIC_OS"] @@ -26,6 +30,7 @@ module OS # Get the kernel version. # # @api public + sig { returns(Version) } def self.kernel_version @kernel_version ||= Version.new(Utils.safe_popen_read("uname", "-r").chomp) end diff --git a/Library/Homebrew/sandbox.rb b/Library/Homebrew/sandbox.rb index 2f79ae6a86..f2c0dcabf0 100644 --- a/Library/Homebrew/sandbox.rb +++ b/Library/Homebrew/sandbox.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "erb" @@ -56,12 +56,12 @@ class Sandbox end def allow_cvs - allow_write_path "#{Dir.home(ENV["USER"])}/.cvspass" + allow_write_path "#{Dir.home(ENV.fetch("USER"))}/.cvspass" end def allow_fossil - allow_write_path "#{Dir.home(ENV["USER"])}/.fossil" - allow_write_path "#{Dir.home(ENV["USER"])}/.fossil-journal" + allow_write_path "#{Dir.home(ENV.fetch("USER"))}/.fossil" + allow_write_path "#{Dir.home(ENV.fetch("USER"))}/.fossil-journal" end def allow_write_cellar(formula) @@ -72,7 +72,7 @@ class Sandbox # Xcode projects expect access to certain cache/archive dirs. def allow_write_xcode - allow_write_path "#{Dir.home(ENV["USER"])}/Library/Developer" + allow_write_path "#{Dir.home(ENV.fetch("USER"))}/Library/Developer" end def allow_write_log(formula) @@ -94,40 +94,43 @@ class Sandbox seatbelt.write(@profile.dump) seatbelt.close @start = Time.now - safe_system SANDBOX_EXEC, "-f", seatbelt.path, *args - rescue - @failed = true - raise - ensure - seatbelt.unlink - sleep 0.1 # wait for a bit to let syslog catch up the latest events. - syslog_args = %W[ - -F $((Time)(local))\ $(Sender)[$(PID)]:\ $(Message) - -k Time ge #{@start.to_i} - -k Message S deny - -k Sender kernel - -o - -k Time ge #{@start.to_i} - -k Message S deny - -k Sender sandboxd - ] - logs = Utils.popen_read("syslog", *syslog_args) - # These messages are confusing and non-fatal, so don't report them. - logs = logs.lines.reject { |l| l.match(/^.*Python\(\d+\) deny file-write.*pyc$/) }.join + begin + T.unsafe(self).safe_system SANDBOX_EXEC, "-f", seatbelt.path, *args + rescue + @failed = true + raise + ensure + seatbelt.unlink + sleep 0.1 # wait for a bit to let syslog catch up the latest events. + syslog_args = %W[ + -F $((Time)(local))\ $(Sender)[$(PID)]:\ $(Message) + -k Time ge #{@start.to_i} + -k Message S deny + -k Sender kernel + -o + -k Time ge #{@start.to_i} + -k Message S deny + -k Sender sandboxd + ] + logs = Utils.popen_read("syslog", *syslog_args) - unless logs.empty? - if @logfile - File.open(@logfile, "w") do |log| - log.write logs - log.write "\nWe use time to filter sandbox log. Therefore, unrelated logs may be recorded.\n" + # These messages are confusing and non-fatal, so don't report them. + logs = logs.lines.reject { |l| l.match(/^.*Python\(\d+\) deny file-write.*pyc$/) }.join + + unless logs.empty? + if @logfile + File.open(@logfile, "w") do |log| + log.write logs + log.write "\nWe use time to filter sandbox log. Therefore, unrelated logs may be recorded.\n" + end end - end - if @failed && Homebrew::EnvConfig.verbose? - ohai "Sandbox log" - puts logs - $stdout.flush # without it, brew test-bot would fail to catch the log + if @failed && Homebrew::EnvConfig.verbose? + ohai "Sandbox log" + puts logs + $stdout.flush # without it, brew test-bot would fail to catch the log + end end end end From 6750448d9556dff88e795cbcbc11fa31827df557 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 23 Nov 2020 18:15:48 +0100 Subject: [PATCH 02/19] Fix some auto-correctable type errors. --- Library/Homebrew/build.rb | 2 +- Library/Homebrew/cask/cmd/doctor.rb | 2 +- Library/Homebrew/cmd/--env.rb | 2 +- Library/Homebrew/dev-cmd/bottle.rb | 6 ++--- Library/Homebrew/dev-cmd/typecheck.rb | 9 +++++++- Library/Homebrew/migrator.rb | 2 +- Library/Homebrew/missing_formula.rb | 2 +- Library/Homebrew/postinstall.rb | 2 +- Library/Homebrew/readall.rb | 8 +++---- .../Homebrew/rubocops/deprecate_disable.rb | 2 +- Library/Homebrew/test.rb | 2 +- Library/Homebrew/utils.rb | 23 +++++++++++-------- Library/Homebrew/utils/analytics.rb | 2 +- Library/Homebrew/utils/fork.rb | 6 ++--- 14 files changed, 40 insertions(+), 30 deletions(-) diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index 94b928211c..41dce0eb2b 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -213,7 +213,7 @@ begin args = Homebrew.install_args.parse Context.current = args.context - error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io) + error_pipe = UNIXSocket.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io) error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) trap("INT", old_trap) diff --git a/Library/Homebrew/cask/cmd/doctor.rb b/Library/Homebrew/cask/cmd/doctor.rb index c2565191ad..d0d5cb0ba1 100644 --- a/Library/Homebrew/cask/cmd/doctor.rb +++ b/Library/Homebrew/cask/cmd/doctor.rb @@ -23,7 +23,7 @@ module Cask def run require "diagnostic" - success = true + success = T.let(true, T::Boolean) checks = Homebrew::Diagnostic::Checks.new(verbose: true) checks.cask_checks.each do |check| diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb index a7eec71143..0181ad0f3a 100644 --- a/Library/Homebrew/cmd/--env.rb +++ b/Library/Homebrew/cmd/--env.rb @@ -51,7 +51,7 @@ module Homebrew BuildEnvironment.dump ENV else BuildEnvironment.keys(ENV).each do |key| - puts Utils::Shell.export_value(key, ENV[key], shell) + puts Utils::Shell.export_value(key, ENV.fetch(key), shell) end end end diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 7bb127367f..0645087e47 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -261,8 +261,8 @@ module Homebrew formula_and_runtime_deps_names = [f.name] + f.runtime_dependencies.map(&:name) keg = Keg.new(f.prefix) - relocatable = false - skip_relocation = false + relocatable = T.let(false, T::Boolean) + skip_relocation = T.let(false, T::Boolean) keg.lock do original_tab = nil @@ -472,7 +472,7 @@ module Homebrew if args.write? path = Pathname.new((HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"]).to_s) - update_or_add = nil + update_or_add = T.let(nil, T.nilable(String)) Utils::Inreplace.inreplace(path) do |s| if s.inreplace_string.include? "bottle do" diff --git a/Library/Homebrew/dev-cmd/typecheck.rb b/Library/Homebrew/dev-cmd/typecheck.rb index b544af5c10..88e7f8321b 100644 --- a/Library/Homebrew/dev-cmd/typecheck.rb +++ b/Library/Homebrew/dev-cmd/typecheck.rb @@ -93,7 +93,14 @@ module Homebrew srb_exec = %w[bundle exec srb tc] srb_exec << "--error-black-list" << "5061" srb_exec << "--quiet" if args.quiet? - srb_exec << "--autocorrect" if args.fix? + + if args.fix? + # Auto-correcting method names is almost always wrong. + srb_exec << "--error-black-list" << "7003" + + srb_exec << "--autocorrect" + end + srb_exec += ["--ignore", args.ignore] if args.ignore.present? if args.file.present? || args.dir.present? cd("sorbet") diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb index 688a743bbf..778a41ea4e 100644 --- a/Library/Homebrew/migrator.rb +++ b/Library/Homebrew/migrator.rb @@ -234,7 +234,7 @@ class Migrator return unless old_cellar.exist? if new_cellar.exist? - conflicted = false + conflicted = T.let(false, T::Boolean) old_cellar.each_child do |c| next unless (new_cellar/c.basename).exist? diff --git a/Library/Homebrew/missing_formula.rb b/Library/Homebrew/missing_formula.rb index cb044513ea..949b0a86b9 100644 --- a/Library/Homebrew/missing_formula.rb +++ b/Library/Homebrew/missing_formula.rb @@ -94,7 +94,7 @@ module Homebrew alias generic_disallowed_reason disallowed_reason def tap_migration_reason(name) - message = nil + message = T.let(nil, T.nilable(String)) Tap.each do |old_tap| new_tap = old_tap.tap_migrations[name] diff --git a/Library/Homebrew/postinstall.rb b/Library/Homebrew/postinstall.rb index 575a27eedd..1c6d5df21d 100644 --- a/Library/Homebrew/postinstall.rb +++ b/Library/Homebrew/postinstall.rb @@ -12,7 +12,7 @@ require "cmd/postinstall" begin args = Homebrew.postinstall_args.parse - error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io) + error_pipe = UNIXSocket.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io) error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) trap("INT", old_trap) diff --git a/Library/Homebrew/readall.rb b/Library/Homebrew/readall.rb index 5075767249..47d493d848 100644 --- a/Library/Homebrew/readall.rb +++ b/Library/Homebrew/readall.rb @@ -10,7 +10,7 @@ require "cask/cask_loader" module Readall class << self def valid_ruby_syntax?(ruby_files) - failed = false + failed = T.let(false, T::Boolean) ruby_files.each do |ruby_file| # As a side effect, print syntax errors/warnings to `$stderr`. failed = true if syntax_errors_or_warnings?(ruby_file) @@ -21,7 +21,7 @@ module Readall def valid_aliases?(alias_dir, formula_dir) return true unless alias_dir.directory? - failed = false + failed = T.let(false, T::Boolean) alias_dir.each_child do |f| if !f.symlink? onoe "Non-symlink alias: #{f}" @@ -40,7 +40,7 @@ module Readall end def valid_formulae?(formulae) - success = true + success = T.let(true, T::Boolean) formulae.each do |file| Formulary.factory(file) rescue Interrupt @@ -54,7 +54,7 @@ module Readall end def valid_casks?(casks) - success = true + success = T.let(true, T::Boolean) casks.each do |file| Cask::CaskLoader.load(file) rescue Interrupt diff --git a/Library/Homebrew/rubocops/deprecate_disable.rb b/Library/Homebrew/rubocops/deprecate_disable.rb index a073092ef1..2c8cc4b7db 100644 --- a/Library/Homebrew/rubocops/deprecate_disable.rb +++ b/Library/Homebrew/rubocops/deprecate_disable.rb @@ -46,7 +46,7 @@ module RuboCop next if node.nil? - reason_found = false + reason_found = T.let(false, T::Boolean) reason(node) do |reason_node| reason_found = true next if reason_node.sym_type? diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb index 82cc34e692..9e01cf13a7 100644 --- a/Library/Homebrew/test.rb +++ b/Library/Homebrew/test.rb @@ -20,7 +20,7 @@ begin args = Homebrew.test_args.parse Context.current = args.context - error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io) + error_pipe = UNIXSocket.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io) error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) trap("INT", old_trap) diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index a66263ac4e..02eb03a879 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -34,7 +34,7 @@ module Homebrew end exit! 1 # never gets here unless exec failed end - Process.wait(pid) + Process.wait(T.must(pid)) $CHILD_STATUS.success? end @@ -58,10 +58,13 @@ module Homebrew method = instance_method(name) define_method(name) do |*args, &block| time = Time.now - method.bind(self).call(*args, &block) - ensure - $times[name] ||= 0 - $times[name] += Time.now - time + + begin + method.bind(self).call(*args, &block) + ensure + $times[name] ||= 0 + $times[name] += Time.now - time + end end end end @@ -190,7 +193,7 @@ module Kernel line.include?("/.metadata/") end - tap_message = nil + tap_message = T.let(nil, T.nilable(String)) backtrace.each do |line| next unless match = line.match(HOMEBREW_TAP_PATH_REGEX) @@ -263,12 +266,12 @@ module Kernel ENV["HOMEBREW_DEBUG_INSTALL"] = f.full_name end - if ENV["SHELL"].include?("zsh") && ENV["HOME"].start_with?(HOMEBREW_TEMP.resolved_path.to_s) - FileUtils.mkdir_p ENV["HOME"] - FileUtils.touch "#{ENV["HOME"]}/.zshrc" + if ENV["SHELL"].include?("zsh") && (home = ENV["HOME"])&.start_with?(HOMEBREW_TEMP.resolved_path.to_s) + FileUtils.mkdir_p home + FileUtils.touch "#{home}/.zshrc" end - Process.wait fork { exec ENV["SHELL"] } + Process.wait fork { exec ENV.fetch("SHELL") } return if $CHILD_STATUS.success? raise "Aborted due to non-zero exit status (#{$CHILD_STATUS.exitstatus})" if $CHILD_STATUS.exited? diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index 89dda53098..fa1b6cc2b5 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -58,7 +58,7 @@ module Utils "--silent", "--output", "/dev/null", "https://www.google-analytics.com/collect" end - Process.detach pid + Process.detach T.must(pid) end end diff --git a/Library/Homebrew/utils/fork.rb b/Library/Homebrew/utils/fork.rb index f7c16566c0..6b858996b6 100644 --- a/Library/Homebrew/utils/fork.rb +++ b/Library/Homebrew/utils/fork.rb @@ -64,7 +64,7 @@ module Utils begin socket = server.accept_nonblock rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR - retry unless Process.waitpid(pid, Process::WNOHANG) + retry unless Process.waitpid(T.must(pid), Process::WNOHANG) else socket.send_io(write) socket.close @@ -72,7 +72,7 @@ module Utils write.close data = read.read read.close - Process.wait(pid) unless socket.nil? + Process.wait(T.must(pid)) unless socket.nil? # 130 is the exit status for a process interrupted via Ctrl-C. # We handle it here because of the possibility of an interrupted process terminating @@ -80,7 +80,7 @@ module Utils raise Interrupt if $CHILD_STATUS.exitstatus == 130 if data && !data.empty? - error_hash = JSON.parse(data.lines.first) + error_hash = JSON.parse(T.must(data.lines.first)) e = ChildProcessError.new(error_hash) From 1b9002c04a0f88dceca26a5dcd01d68ce423f37b Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 23 Nov 2020 18:45:40 +0100 Subject: [PATCH 03/19] Fix type errors in `postinstall`. --- Library/Homebrew/cli/args.rbi | 6 ++++++ Library/Homebrew/cli/named_args.rb | 2 ++ Library/Homebrew/cli/parser.rb | 1 + Library/Homebrew/cmd/--env.rb | 1 + Library/Homebrew/cmd/uninstall.rb | 4 ++-- Library/Homebrew/postinstall.rb | 4 ++-- Library/Homebrew/sorbet/rbi/upstream.rbi | 19 +++++++++++-------- 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/Library/Homebrew/cli/args.rbi b/Library/Homebrew/cli/args.rbi index b072016115..b719d78fa4 100644 --- a/Library/Homebrew/cli/args.rbi +++ b/Library/Homebrew/cli/args.rbi @@ -59,6 +59,12 @@ module Homebrew sig { returns(T.nilable(T::Boolean)) } def formula?; end + + sig { returns(T.nilable(T::Boolean)) } + def zap?; end + + sig { returns(T.nilable(T::Boolean)) } + def ignore_dependencies?; end end end end diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index 87663712c9..9e848f8a29 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -5,6 +5,7 @@ require "delegate" require "cask/cask_loader" require "cli/args" +require "formula" require "formulary" require "keg" require "missing_formula" @@ -99,6 +100,7 @@ module Homebrew end private :resolve_formula + sig { returns(T::Array[Formula]) } def to_resolved_formulae @to_resolved_formulae ||= to_formulae_and_casks(only: :formula, method: :resolve) .freeze diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index 331bc71416..ee00aef2b4 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -264,6 +264,7 @@ module Homebrew [remaining, non_options] end + sig { params(argv: T::Array[String], ignore_invalid_options: T::Boolean).returns(Args) } def parse(argv = ARGV.freeze, ignore_invalid_options: false) raise "Arguments were already parsed!" if @args_parsed diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb index 0181ad0f3a..b8c9107e05 100644 --- a/Library/Homebrew/cmd/--env.rb +++ b/Library/Homebrew/cmd/--env.rb @@ -30,6 +30,7 @@ module Homebrew end end + sig { void } def __env args = __env_args.parse diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb index bb7968a9bf..dac06da9ee 100644 --- a/Library/Homebrew/cmd/uninstall.rb +++ b/Library/Homebrew/cmd/uninstall.rb @@ -61,13 +61,13 @@ module Homebrew ) if args.zap? - Cask::Cmd::Zap.zap_casks( + T.unsafe(Cask::Cmd::Zap).zap_casks( *casks, verbose: args.verbose?, force: args.force?, ) else - Cask::Cmd::Uninstall.uninstall_casks( + T.unsafe(Cask::Cmd::Uninstall).uninstall_casks( *casks, binaries: EnvConfig.cask_opts_binaries?, verbose: args.verbose?, diff --git a/Library/Homebrew/postinstall.rb b/Library/Homebrew/postinstall.rb index 1c6d5df21d..6856fa07ed 100644 --- a/Library/Homebrew/postinstall.rb +++ b/Library/Homebrew/postinstall.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: strict # frozen_string_literal: true old_trap = trap("INT") { exit! 130 } @@ -17,7 +17,7 @@ begin trap("INT", old_trap) - formula = args.named.to_resolved_formulae.first + formula = T.must(args.named.to_resolved_formulae.first) formula.extend(Debrew::Formula) if args.debug? formula.run_post_install rescue Exception => e # rubocop:disable Lint/RescueException diff --git a/Library/Homebrew/sorbet/rbi/upstream.rbi b/Library/Homebrew/sorbet/rbi/upstream.rbi index 4a77637e5a..d36710b7e2 100644 --- a/Library/Homebrew/sorbet/rbi/upstream.rbi +++ b/Library/Homebrew/sorbet/rbi/upstream.rbi @@ -1,13 +1,16 @@ # typed: strict -class Pathname - # https://github.com/sorbet/sorbet/pull/3676 - sig { params(p1: T.any(String, Pathname), p2: String).returns(T::Array[Pathname]) } - def self.glob(p1, p2 = T.unsafe(nil)); end - - # https://github.com/sorbet/sorbet/pull/3678 - sig { params(with_directory: T::Boolean).returns(T::Array[Pathname]) } - def children(with_directory = true); end +class IO + # https://github.com/sorbet/sorbet/pull/3722 + sig do + type_parameters(:U).params( + fd: T.any(String, Integer), + mode: T.any(Integer, String), + opt: T.nilable(T::Hash[Symbol, T.untyped]), + blk: T.proc.params(io: T.attached_class).returns(T.type_parameter(:U)) + ).returns(T.type_parameter(:U)) + end + def self.open(fd, mode='r', opt=nil, &blk); end end module FileUtils From 38ec7b684d27ada5df87e9cd42656de57587609a Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 23 Nov 2020 19:18:15 +0100 Subject: [PATCH 04/19] Add note in `upstream.rbi`. --- Library/Homebrew/sorbet/rbi/upstream.rbi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Library/Homebrew/sorbet/rbi/upstream.rbi b/Library/Homebrew/sorbet/rbi/upstream.rbi index d36710b7e2..45188d9d68 100644 --- a/Library/Homebrew/sorbet/rbi/upstream.rbi +++ b/Library/Homebrew/sorbet/rbi/upstream.rbi @@ -1,5 +1,8 @@ # typed: strict +# This file contains temporary definitions for fixes that have +# been submitted upstream to https://github.com/sorbet/sorbet. + class IO # https://github.com/sorbet/sorbet/pull/3722 sig do From 650ec514c1df30809cd9d416cbff34bac9227356 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Tue, 24 Nov 2020 09:55:48 +0100 Subject: [PATCH 05/19] Fix type errors in `test`. --- Library/Homebrew/cli/args.rbi | 3 +++ Library/Homebrew/test.rb | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/cli/args.rbi b/Library/Homebrew/cli/args.rbi index b719d78fa4..51e9ccadb9 100644 --- a/Library/Homebrew/cli/args.rbi +++ b/Library/Homebrew/cli/args.rbi @@ -65,6 +65,9 @@ module Homebrew sig { returns(T.nilable(T::Boolean)) } def ignore_dependencies?; end + + sig { returns(T.nilable(T::Boolean)) } + def keep_tmp?; end end end end diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb index 9e01cf13a7..6ef080962d 100644 --- a/Library/Homebrew/test.rb +++ b/Library/Homebrew/test.rb @@ -30,13 +30,13 @@ begin raise "cannot kill child processes without `pkill`, please install!" unless which("pkill") end - formula = args.named.to_resolved_formulae.first + formula = T.must(args.named.to_resolved_formulae.first) formula.extend(Homebrew::Assertions) formula.extend(Homebrew::FreePort) formula.extend(Debrew::Formula) if args.debug? ENV.extend(Stdenv) - ENV.setup_build_environment(formula: formula) + T.cast(ENV, Stdenv).setup_build_environment(formula: formula) # tests can also return false to indicate failure Timeout.timeout TEST_TIMEOUT_SECONDS do From 580d915cb4e4b00298d9341ff27bc746cbc7cc16 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Tue, 24 Nov 2020 11:27:12 +0100 Subject: [PATCH 06/19] Add type signatures for `Pathname` extensions. --- Library/Homebrew/extend/pathname.rb | 77 ++++++++++++++++++++---- Library/Homebrew/extend/pathname.rbi | 19 ++++++ Library/Homebrew/sorbet/rbi/upstream.rbi | 12 ++++ 3 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 Library/Homebrew/extend/pathname.rbi diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index c237a7133b..f2e00e41c6 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "resource" @@ -7,15 +7,17 @@ require "metafiles" module DiskUsageExtension extend T::Sig + sig { returns(Integer) } def disk_usage - return @disk_usage if @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 @file_count + return @file_count if defined?(@file_count) compute_disk_usage @file_count @@ -32,6 +34,7 @@ module DiskUsageExtension private + sig { void } def compute_disk_usage if symlink? && !exist? @file_count = 1 @@ -82,6 +85,12 @@ class Pathname BOTTLE_EXTNAME_RX = /(\.[a-z0-9_]+\.bottle\.(\d+\.)?tar\.gz)$/.freeze # Moves a file from the original location to the {Pathname}'s. + sig do + params(sources: T.any( + Resource, Resource::Partial, String, Pathname, + T::Array[T.any(String, Pathname)], T::Hash[T.any(String, Pathname), String] + )).void + end def install(*sources) sources.each do |src| case src @@ -107,6 +116,7 @@ class Pathname end end + sig { params(src: T.any(String, Pathname), new_basename: String).void } def install_p(src, new_basename) raise Errno::ENOENT, src.to_s unless File.symlink?(src) || File.exist?(src) @@ -130,6 +140,11 @@ class Pathname private :install_p # Creates symlinks to sources in this folder. + sig do + params( + sources: T.any(String, Pathname, T::Array[T.any(String, Pathname)], T::Hash[T.any(String, Pathname), String]), + ).void + end def install_symlink(*sources) sources.each do |src| case src @@ -156,21 +171,25 @@ class Pathname alias old_write write # We assume this pathname object is a file, obviously. - def write(content, *open_args) + sig { params(content: String, offset: Integer, open_args: T::Hash[Symbol, T.untyped]).returns(Integer) } + def write(content, offset = 0, open_args = {}) raise "Will not overwrite #{self}" if exist? dirname.mkpath - open("w", *open_args) { |f| f.write(content) } + + old_write(content, offset, open_args) end # Only appends to a file that is already created. - def append_lines(content, *open_args) + sig { params(content: String, open_args: T.untyped).void } + def append_lines(content, **open_args) raise "Cannot append file that doesn't exist: #{self}" unless exist? - open("a", *open_args) { |f| f.puts(content) } + T.unsafe(self).open("a", **open_args) { |f| f.puts(content) } end # @note This always overwrites. + sig { params(content: String).void } def atomic_write(content) old_stat = stat if exist? File.atomic_write(self) do |file| @@ -220,8 +239,9 @@ class Pathname alias extname_old extname # Extended to support common double extensions. - def extname(path = to_s) - basename = File.basename(path) + sig { returns(String) } + def extname + basename = File.basename(self) bottle_ext = basename[BOTTLE_EXTNAME_RX, 1] return bottle_ext if bottle_ext @@ -236,14 +256,16 @@ class Pathname end # For filetypes we support, returns basename without extension. + sig { returns(String) } def stem - File.basename((path = to_s), extname(path)) + File.basename(self, extname) end # I don't trust the children.length == 0 check particularly, not to mention # it is slow to enumerate the whole directory just to see if it is empty, # instead rely on good ol' libc and the filesystem # @private + sig { returns(T::Boolean) } def rmdir_if_possible rmdir true @@ -259,21 +281,25 @@ class Pathname end # @private + sig { returns(Version) } def version require "version" Version.parse(basename) end # @private + sig { returns(T::Boolean) } def text_executable? - /^#!\s*\S+/ =~ open("r") { |f| f.read(1024) } + /^#!\s*\S+/.match?(open("r") { |f| f.read(1024) }) end + sig { returns(String) } def sha256 require "digest/sha2" Digest::SHA256.file(self).hexdigest end + sig { params(expected: T.nilable(Checksum)).void } def verify_checksum(expected) raise ChecksumMissingError if expected.nil? || expected.empty? @@ -283,7 +309,12 @@ class Pathname alias to_str to_s - def cd + sig do + type_parameters(:U).params( + _block: T.proc.params(path: Pathname).returns(T.type_parameter(:U)), + ).returns(T.type_parameter(:U)) + end + def cd(&_block) Dir.chdir(self) { yield self } end @@ -382,6 +413,14 @@ class Pathname end # Writes an exec script that invokes a Java jar. + sig do + params( + target_jar: T.any(String, Pathname), + script_name: T.any(String, Pathname), + java_opts: String, + java_version: T.nilable(String), + ).returns(Integer) + end def write_jar_script(target_jar, script_name, java_opts = "", java_version: nil) (self/script_name).write <<~EOS #!/bin/bash @@ -431,11 +470,14 @@ require "extend/os/pathname" # @private module ObserverPathnameExtension + extend T::Sig + class << self extend T::Sig include Context + sig { returns(Integer) } attr_accessor :n, :d sig { void } @@ -444,16 +486,21 @@ module ObserverPathnameExtension @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 @@ -470,34 +517,40 @@ module ObserverPathnameExtension 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? diff --git a/Library/Homebrew/extend/pathname.rbi b/Library/Homebrew/extend/pathname.rbi new file mode 100644 index 0000000000..12a94cd3eb --- /dev/null +++ b/Library/Homebrew/extend/pathname.rbi @@ -0,0 +1,19 @@ +# typed: strict + +module DiskUsageExtension + include Kernel + + def exist?; end + + def symlink?; end + + def resolved_path; end +end + +module ObserverPathnameExtension + include Kernel + + def dirname; end + + def basename; end +end diff --git a/Library/Homebrew/sorbet/rbi/upstream.rbi b/Library/Homebrew/sorbet/rbi/upstream.rbi index 45188d9d68..904b997019 100644 --- a/Library/Homebrew/sorbet/rbi/upstream.rbi +++ b/Library/Homebrew/sorbet/rbi/upstream.rbi @@ -16,6 +16,18 @@ class IO def self.open(fd, mode='r', opt=nil, &blk); end end +class Pathname + # https://github.com/sorbet/sorbet/pull/3729 + sig do + params( + owner: T.nilable(Integer), + group: T.nilable(Integer), + ) + .returns(Integer) + end + def chown(owner, group); end +end + module FileUtils # https://github.com/sorbet/sorbet/pull/3730 module_function From 4560c06b7eaecb9d59bb97d1c7b6032a21436d2e Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:34:36 +0100 Subject: [PATCH 07/19] Add more method signatures for `CLI::Args`. --- Library/Homebrew/cli/args.rbi | 149 ++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/Library/Homebrew/cli/args.rbi b/Library/Homebrew/cli/args.rbi index 51e9ccadb9..b9d3416f46 100644 --- a/Library/Homebrew/cli/args.rbi +++ b/Library/Homebrew/cli/args.rbi @@ -66,8 +66,157 @@ module Homebrew sig { returns(T.nilable(T::Boolean)) } def ignore_dependencies?; end + sig { returns(T.nilable(T::Boolean)) } + def aliases?; end + + sig { returns(T.nilable(T::Boolean)) } + def fix?; end + sig { returns(T.nilable(T::Boolean)) } def keep_tmp?; end + + sig { returns(T.nilable(T::Boolean)) } + def overwrite?; end + + sig { returns(T.nilable(T::Boolean)) } + def silent?; end + + sig { returns(T.nilable(T::Boolean)) } + def repair?; end + + sig { returns(T.nilable(T::Boolean)) } + def prune_prefix?; end + + sig { returns(T.nilable(T::Boolean)) } + def upload?; end + + sig { returns(T.nilable(T::Boolean)) } + def total?; end + + sig { returns(T.nilable(T::Boolean)) } + def dependents?; end + + sig { returns(T.nilable(T::Boolean)) } + def installed?; end + + sig { returns(T.nilable(T::Boolean)) } + def all?; end + + sig { returns(T.nilable(T::Boolean)) } + def full?; end + + sig { returns(T.nilable(T::Boolean)) } + def list_pinned?; end + + sig { returns(T.nilable(T::Boolean)) } + def display_cop_names?; end + + sig { returns(T.nilable(T::Boolean)) } + def syntax?; end + + sig { returns(T.nilable(T::Boolean)) } + def ignore_non_pypi_packages?; end + + sig { returns(T.nilable(T::Boolean)) } + def test?; end + + sig { returns(T.nilable(T::Boolean)) } + def reverse?; end + + sig { returns(T.nilable(T::Boolean)) } + def print_only?; end + + sig { returns(T.nilable(T::Boolean)) } + def markdown?; end + + sig { returns(T.nilable(String)) } + def tag; end + + sig { returns(T.nilable(String)) } + def tap; end + + sig { returns(T.nilable(String)) } + def macos; end + + sig { returns(T.nilable(T::Array[String])) } + def hide; end + + sig { returns(T.nilable(String)) } + def version; end + + sig { returns(T.nilable(String)) } + def name; end + + sig { returns(T.nilable(T::Boolean)) } + def no_publish?; end + + sig { returns(T.nilable(T::Boolean)) } + def shallow?; end + + sig { returns(T.nilable(T::Boolean)) } + def fail_if_not_changed?; end + + sig { returns(T.nilable(String)) } + def limit; end + + sig { returns(T.nilable(String)) } + def message; end + + sig { returns(T.nilable(String)) } + def issue; end + + sig { returns(T.nilable(String)) } + def workflow; end + + sig { returns(T.nilable(String)) } + def bintray_org; end + + sig { returns(T.nilable(String)) } + def bintray_repo; end + sig { returns(T.nilable(String)) } + def package_name; end + + sig { returns(T.nilable(String)) } + def prune; end + + sig { returns(T.nilable(T::Array[String])) } + def only_cops; end + + sig { returns(T.nilable(T::Array[String])) } + def except_cops; end + + sig { returns(T.nilable(T::Array[String])) } + def only; end + + sig { returns(T.nilable(T::Array[String])) } + def except; end + + sig { returns(T.nilable(T::Array[String])) } + def mirror; end + + sig { returns(T.nilable(T::Array[String])) } + def without_labels; end + + sig { returns(T.nilable(T::Array[String])) } + def workflows; end + + sig { returns(T.nilable(T::Array[String])) } + def ignore_missing_artifacts; end + + sig { returns(T.nilable(T::Array[String])) } + def language; end + + sig { returns(T.nilable(T::Array[String])) } + def extra_packages; end + + sig { returns(T.nilable(T::Array[String])) } + def exclude_packages; end + + sig { returns(T.nilable(T::Array[String])) } + def update; end + + sig { returns(T.nilable(T::Boolean)) } + def s?; end end end end From 1baf98ea69c0a33dea17174ddc0ea0e321771a6b Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:34:53 +0100 Subject: [PATCH 08/19] Add signatures for `cmd/--cache`. --- Library/Homebrew/cmd/--cache.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Library/Homebrew/cmd/--cache.rb b/Library/Homebrew/cmd/--cache.rb index d21f3bd8cd..4a9d93889e 100644 --- a/Library/Homebrew/cmd/--cache.rb +++ b/Library/Homebrew/cmd/--cache.rb @@ -35,6 +35,7 @@ module Homebrew end end + sig { void } def __cache args = __cache_args.parse @@ -60,6 +61,7 @@ module Homebrew end end + sig { params(formula: Formula, args: CLI::Args).void } def print_formula_cache(formula, args:) if fetch_bottle?(formula, args: args) puts formula.bottle.cached_download @@ -68,6 +70,7 @@ module Homebrew end end + sig { params(cask: Cask::Cask).void } def print_cask_cache(cask) puts Cask::Download.new(cask).downloader.cached_location end From a0d6f45bd7e6ab3911eaf20b3bf5a18147a7e595 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:35:10 +0100 Subject: [PATCH 09/19] Add signatures for `cmd/tap`. --- Library/Homebrew/cmd/tap.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/cmd/tap.rb b/Library/Homebrew/cmd/tap.rb index 8dab836970..8fe4f1a5be 100644 --- a/Library/Homebrew/cmd/tap.rb +++ b/Library/Homebrew/cmd/tap.rb @@ -45,6 +45,7 @@ module Homebrew end end + sig { void } def tap args = tap_args.parse From 749199632b2e5824d6c5d09c7bc83b856c13d273 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:35:24 +0100 Subject: [PATCH 10/19] Add signatures for `dev-cmd/unbottled`. --- Library/Homebrew/dev-cmd/unbottled.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Library/Homebrew/dev-cmd/unbottled.rb b/Library/Homebrew/dev-cmd/unbottled.rb index 8ec75447c3..777ff7536d 100644 --- a/Library/Homebrew/dev-cmd/unbottled.rb +++ b/Library/Homebrew/dev-cmd/unbottled.rb @@ -33,11 +33,7 @@ module Homebrew Formulary.enable_factory_cache! - @bottle_tag = if args.tag.present? - args.tag.to_sym - else - Utils::Bottles.tag - end + @bottle_tag = args.tag.presence&.to_sym || Utils::Bottles.tag if args.named.blank? ohai "Getting formulae..." From 6fb5315deb71b4df257d710fa8e979757da8d8d0 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:35:45 +0100 Subject: [PATCH 11/19] Fix unconditionally true condition. --- Library/Homebrew/dev-cmd/style.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/style.rb b/Library/Homebrew/dev-cmd/style.rb index c0112ef519..efa36925a4 100644 --- a/Library/Homebrew/dev-cmd/style.rb +++ b/Library/Homebrew/dev-cmd/style.rb @@ -57,7 +57,7 @@ module Homebrew options[:only_cops] = only_cops elsif except_cops options[:except_cops] = except_cops - elsif only_cops.nil? && except_cops.nil? + else options[:except_cops] = %w[FormulaAuditStrict] end From 323cfbca4125e811bc2b2d608387e5b1b2b9b089 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:36:06 +0100 Subject: [PATCH 12/19] Fix type error in `dev-cmd/dispatch-build-bottle`. --- Library/Homebrew/dev-cmd/dispatch-build-bottle.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb b/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb index 21d5af7617..e5b325c918 100644 --- a/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb +++ b/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb @@ -35,14 +35,14 @@ module Homebrew def dispatch_build_bottle args = dispatch_build_bottle_args.parse - odie "Must specify --macos option" unless args.macos - - macos = begin - MacOS::Version.from_symbol(args.macos.to_sym) + macos = args.macos&.yield_self do |s| + MacOS::Version.from_symbol(s.to_sym) rescue MacOSVersionError - MacOS::Version.new(args.macos) + MacOS::Version.new(s) end + raise UsageError, "Must specify --macos option" unless macos + tap = Tap.fetch(args.tap || CoreTap.instance.name) user, repo = tap.full_name.split("/") From 307724d5cdf6a6d989eab327827e1f47cd2dc05e Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:36:24 +0100 Subject: [PATCH 13/19] Fix type error in `cmd/cleanup`. --- Library/Homebrew/cmd/cleanup.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/cmd/cleanup.rb b/Library/Homebrew/cmd/cleanup.rb index 786c28eee3..2900e3e2da 100644 --- a/Library/Homebrew/cmd/cleanup.rb +++ b/Library/Homebrew/cmd/cleanup.rb @@ -1,4 +1,4 @@ -# typed: true +# typed: false # frozen_string_literal: true require "cleanup" @@ -37,11 +37,18 @@ module Homebrew def cleanup args = cleanup_args.parse - if args.prune.present? && !Integer(args.prune, exception: false) && args.prune != "all" - raise UsageError, "--prune= expects an integer or 'all'." + days = args.prune.presence&.yield_self do |prune| + case prune + when /\A\d+\Z/ + prune.to_i + when "all" + 0 + else + raise UsageError, "--prune= expects an integer or 'all'." + end end - cleanup = Cleanup.new(*args.named, dry_run: args.dry_run?, scrub: args.s?, days: args.prune&.to_i) + cleanup = Cleanup.new(*args.named, dry_run: args.dry_run?, scrub: args.s?, days: days) if args.prune_prefix? cleanup.prune_prefix_symlinks_and_directories return From 3541ede9275af4714dce0659723a69456c4643a0 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:36:40 +0100 Subject: [PATCH 14/19] Fix signature for `update_python_resources!`. --- Library/Homebrew/utils/pypi.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/utils/pypi.rb b/Library/Homebrew/utils/pypi.rb index 30e5dbbe54..8473c38f51 100644 --- a/Library/Homebrew/utils/pypi.rb +++ b/Library/Homebrew/utils/pypi.rb @@ -122,9 +122,9 @@ module PyPI package_name: T.nilable(String), extra_packages: T.nilable(T::Array[String]), exclude_packages: T.nilable(T::Array[String]), - print_only: T::Boolean, - silent: T::Boolean, - ignore_non_pypi_packages: T::Boolean, + print_only: T.nilable(T::Boolean), + silent: T.nilable(T::Boolean), + ignore_non_pypi_packages: T.nilable(T::Boolean), ).returns(T.nilable(T::Boolean)) end def update_python_resources!(formula, version: nil, package_name: nil, extra_packages: nil, exclude_packages: nil, From 2ad7f5317cb373e76fe3bb2c0a13b48a665b014a Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 22:36:54 +0100 Subject: [PATCH 15/19] Add signatures for `Fetch` module. --- Library/Homebrew/fetch.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/fetch.rb b/Library/Homebrew/fetch.rb index 6297b5d628..f7bb7517e0 100644 --- a/Library/Homebrew/fetch.rb +++ b/Library/Homebrew/fetch.rb @@ -4,11 +4,16 @@ module Homebrew # @api private module Fetch + extend T::Sig + + sig { params(f: Formula, args: CLI::Args).returns(T::Boolean) } def fetch_bottle?(f, args:) - return true if args.force_bottle? && f.bottle - return false unless f.bottle && f.pour_bottle? + bottle = f.bottle + + return true if args.force_bottle? && bottle + return false unless bottle && f.pour_bottle? return false if args.build_from_source_formulae.include?(f.full_name) - return false unless f.bottle.compatible_cellar? + return false unless bottle.compatible_cellar? true end From 73481853472efb771bb6395f4c6ecb3786b50d58 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 29 Nov 2020 21:23:44 +0100 Subject: [PATCH 16/19] Reorder `global`. --- Library/Homebrew/cli/args.rb | 3 +- Library/Homebrew/global.rb | 44 +++++++++++++++-------------- Library/Homebrew/os/linux/global.rb | 4 ++- Library/Homebrew/tap_constants.rb | 2 ++ Library/Homebrew/utils/tty.rb | 2 ++ 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/Library/Homebrew/cli/args.rb b/Library/Homebrew/cli/args.rb index 2e878ceed8..d105a43d9b 100644 --- a/Library/Homebrew/cli/args.rb +++ b/Library/Homebrew/cli/args.rb @@ -1,7 +1,6 @@ # typed: true # frozen_string_literal: true -require "cli/named_args" require "ostruct" module Homebrew @@ -16,6 +15,8 @@ module Homebrew sig { void } def initialize + require "cli/named_args" + super() @processed_options = [] diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index 73013b002f..44b8616dfa 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -9,6 +9,11 @@ require "ostruct" require "pp" require "forwardable" +require "rbconfig" + +RUBY_PATH = Pathname.new(RbConfig.ruby).freeze +RUBY_BIN = RUBY_PATH.dirname.freeze + require_relative "load_path" require "rubygems" @@ -41,26 +46,11 @@ HOMEBREW_DEFAULT_CACHE = ENV["HOMEBREW_DEFAULT_CACHE"] HOMEBREW_DEFAULT_LOGS = ENV["HOMEBREW_DEFAULT_LOGS"] HOMEBREW_DEFAULT_TEMP = ENV["HOMEBREW_DEFAULT_TEMP"] HOMEBREW_REQUIRED_RUBY_VERSION = ENV["HOMEBREW_REQUIRED_RUBY_VERSION"] -require "env_config" - -require "config" -require "os" -require "context" -require "extend/pathname" -require "extend/predicable" -require "extend/module" -require "cli/args" -require "messages" HOMEBREW_PRODUCT = ENV["HOMEBREW_PRODUCT"] HOMEBREW_VERSION = ENV["HOMEBREW_VERSION"] HOMEBREW_WWW = "https://brew.sh" -require "rbconfig" - -RUBY_PATH = Pathname.new(RbConfig.ruby).freeze -RUBY_BIN = RUBY_PATH.dirname.freeze - HOMEBREW_USER_AGENT_CURL = ENV["HOMEBREW_USER_AGENT_CURL"] HOMEBREW_USER_AGENT_RUBY = "#{ENV["HOMEBREW_USER_AGENT"]} ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}" @@ -72,8 +62,18 @@ HOMEBREW_DEFAULT_PREFIX = "/usr/local" HOMEBREW_MACOS_ARM_DEFAULT_PREFIX = "/opt/homebrew" HOMEBREW_LINUX_DEFAULT_PREFIX = "/home/linuxbrew/.linuxbrew" +HOMEBREW_PULL_API_REGEX = + %r{https://api\.github\.com/repos/([\w-]+)/([\w-]+)?/pulls/(\d+)}.freeze +HOMEBREW_PULL_OR_COMMIT_URL_REGEX = + %r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})].freeze +HOMEBREW_RELEASES_URL_REGEX = + %r{https://github\.com/([\w-]+)/([\w-]+)?/releases/download/(.+)}.freeze + require "fileutils" + +require "os" require "os/global" +require "messages" module Homebrew extend FileUtils @@ -111,12 +111,14 @@ module Homebrew end end -HOMEBREW_PULL_API_REGEX = - %r{https://api\.github\.com/repos/([\w-]+)/([\w-]+)?/pulls/(\d+)}.freeze -HOMEBREW_PULL_OR_COMMIT_URL_REGEX = - %r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})].freeze -HOMEBREW_RELEASES_URL_REGEX = - %r{https://github\.com/([\w-]+)/([\w-]+)?/releases/download/(.+)}.freeze +require "env_config" + +require "config" +require "context" +require "extend/pathname" +require "extend/predicable" +require "extend/module" +require "cli/args" require "PATH" diff --git a/Library/Homebrew/os/linux/global.rb b/Library/Homebrew/os/linux/global.rb index 891d5a24c7..c73ffa8135 100644 --- a/Library/Homebrew/os/linux/global.rb +++ b/Library/Homebrew/os/linux/global.rb @@ -1,6 +1,8 @@ # typed: false # frozen_string_literal: true +require "env_config" + # Enables experimental `patchelf.rb` write support. HOMEBREW_PATCHELF_RB_WRITE = ( ENV["HOMEBREW_NO_PATCHELF_RB_WRITE"].blank? && @@ -9,7 +11,7 @@ HOMEBREW_PATCHELF_RB_WRITE = ( ).freeze module Homebrew - DEFAULT_PREFIX ||= if Homebrew::EnvConfig.force_homebrew_on_linux? + DEFAULT_PREFIX ||= if EnvConfig.force_homebrew_on_linux? HOMEBREW_DEFAULT_PREFIX else HOMEBREW_LINUX_DEFAULT_PREFIX diff --git a/Library/Homebrew/tap_constants.rb b/Library/Homebrew/tap_constants.rb index b9edb7afeb..10e167b2a2 100644 --- a/Library/Homebrew/tap_constants.rb +++ b/Library/Homebrew/tap_constants.rb @@ -1,6 +1,8 @@ # typed: true # frozen_string_literal: true +require "config" + # Match taps' formulae, e.g. `someuser/sometap/someformula` HOMEBREW_TAP_FORMULA_REGEX = %r{^([\w-]+)/([\w-]+)/([\w+-.@]+)$}.freeze # Match taps' casks, e.g. `someuser/sometap/somecask` diff --git a/Library/Homebrew/utils/tty.rb b/Library/Homebrew/utils/tty.rb index 01ebc1b214..ddb7da3824 100644 --- a/Library/Homebrew/utils/tty.rb +++ b/Library/Homebrew/utils/tty.rb @@ -1,6 +1,8 @@ # typed: true # frozen_string_literal: true +require "env_config" + # Various helper functions for interacting with TTYs. # # @api private From 6e20d2758281a9f331edecc56b6dd4f8df86f277 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 30 Nov 2020 00:49:07 +0100 Subject: [PATCH 17/19] Remove some unneeded `require`s. --- Library/Homebrew/extend/os/linux/system_config.rb | 3 +-- Library/Homebrew/uninstall.rb | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Library/Homebrew/extend/os/linux/system_config.rb b/Library/Homebrew/extend/os/linux/system_config.rb index 6c93d2a4fa..2f07c89b18 100644 --- a/Library/Homebrew/extend/os/linux/system_config.rb +++ b/Library/Homebrew/extend/os/linux/system_config.rb @@ -1,7 +1,6 @@ # typed: true # frozen_string_literal: true -require "formula" require "os/linux/glibc" require "system_command" @@ -48,7 +47,7 @@ module SystemConfig out.puts "/usr/bin/gcc: #{host_gcc_version}" out.puts "/usr/bin/ruby: #{host_ruby_version}" if RUBY_PATH != HOST_RUBY_PATH ["glibc", "gcc", "xorg"].each do |f| - out.puts "#{f}: #{formula_linked_version f}" + out.puts "#{f}: #{formula_linked_version(f)}" end end end diff --git a/Library/Homebrew/uninstall.rb b/Library/Homebrew/uninstall.rb index cd3140e2bb..156d74478e 100644 --- a/Library/Homebrew/uninstall.rb +++ b/Library/Homebrew/uninstall.rb @@ -2,7 +2,6 @@ # frozen_string_literal: true require "keg" -require "formula" module Homebrew # Helper module for uninstalling kegs. From fddd589bc3f38378500bea962c2805e9db2c79fe Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 30 Nov 2020 00:54:27 +0100 Subject: [PATCH 18/19] Make more `require`s in `NamedArgs` lazy. --- Library/Homebrew/cli/named_args.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index 9e848f8a29..def392761b 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -3,12 +3,7 @@ require "delegate" -require "cask/cask_loader" require "cli/args" -require "formula" -require "formulary" -require "keg" -require "missing_formula" module Homebrew module CLI @@ -19,6 +14,12 @@ module Homebrew extend T::Sig def initialize(*args, parent: Args.new, override_spec: nil, force_bottle: false, flags: []) + require "cask/cask" + require "cask/cask_loader" + require "formulary" + require "keg" + require "missing_formula" + @args = args @override_spec = override_spec @force_bottle = force_bottle @@ -159,7 +160,7 @@ module Homebrew @to_kegs ||= begin to_formulae_and_casks(only: :formula, method: :keg).freeze rescue NoSuchKegError => e - if (reason = Homebrew::MissingFormula.suggest_command(e.name, "uninstall")) + if (reason = MissingFormula.suggest_command(e.name, "uninstall")) $stderr.puts reason end raise e From 47b8f96efbf96be4e5ae415377ec51bad856eb99 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 30 Nov 2020 04:18:23 +0100 Subject: [PATCH 19/19] Require `formula` for named arguments. --- Library/Homebrew/cli/args.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/cli/args.rb b/Library/Homebrew/cli/args.rb index d105a43d9b..8ca8dea7d1 100644 --- a/Library/Homebrew/cli/args.rb +++ b/Library/Homebrew/cli/args.rb @@ -56,6 +56,7 @@ module Homebrew sig { returns(NamedArgs) } def named + require "formula" self[:named] end