diff --git a/Library/Homebrew/bintray.rb b/Library/Homebrew/bintray.rb index d9b8512876..5d4b05f36a 100644 --- a/Library/Homebrew/bintray.rb +++ b/Library/Homebrew/bintray.rb @@ -4,6 +4,8 @@ require "utils/curl" require "json" class Bintray + include Context + API_URL = "https://api.bintray.com" class Error < RuntimeError @@ -32,8 +34,8 @@ class Bintray end curl(*args, url, - show_output: Homebrew.args.verbose?, - secrets: @bintray_key) + show_output: verbose?, + secrets: key) end def upload(local_file, repo:, package:, version:, remote_file:, sha256: nil) diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb index ca89004014..d33b6948ab 100644 --- a/Library/Homebrew/brew.rb +++ b/Library/Homebrew/brew.rb @@ -59,7 +59,9 @@ begin ARGV.delete_at(help_cmd_index) if help_cmd_index - Homebrew.args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true) + args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true) + Homebrew.args = args + Context.current = args.context path = PATH.new(ENV["PATH"]) homebrew_path = PATH.new(ENV["HOMEBREW_PATH"]) @@ -102,8 +104,8 @@ begin # - if cmd is Cask, let Cask handle the help command instead if (empty_argv || help_flag) && cmd != "cask" require "help" - Homebrew::Help.help cmd, empty_argv: empty_argv - # `Homebrew.help` never returns, except for unknown commands. + Homebrew::Help.help cmd, remaining_args: args.remaining, empty_argv: empty_argv + # `Homebrew::Help.help` never returns, except for unknown commands. end if internal_cmd || Commands.external_ruby_v2_cmd_path(cmd) @@ -138,17 +140,17 @@ begin end rescue UsageError => e require "help" - Homebrew::Help.help cmd, usage_error: e.message + Homebrew::Help.help cmd, remaining_args: args.remaining, usage_error: e.message rescue SystemExit => e - onoe "Kernel.exit" if Homebrew.args.debug? && !e.success? - $stderr.puts e.backtrace if Homebrew.args.debug? + onoe "Kernel.exit" if args.debug? && !e.success? + $stderr.puts e.backtrace if args.debug? raise rescue Interrupt $stderr.puts # seemingly a newline is typical exit 130 rescue BuildError => e Utils::Analytics.report_build_error(e) - e.dump + e.dump(verbose: args.verbose?) if e.formula.head? || e.formula.deprecated? || e.formula.disabled? $stderr.puts <<~EOS @@ -162,7 +164,7 @@ rescue RuntimeError, SystemCallError => e raise if e.message.empty? onoe e - $stderr.puts e.backtrace if Homebrew.args.debug? + $stderr.puts e.backtrace if args.debug? exit 1 rescue MethodDeprecatedError => e @@ -171,7 +173,7 @@ rescue MethodDeprecatedError => e $stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):" $stderr.puts " #{Formatter.url(e.issues_url)}" end - $stderr.puts e.backtrace if Homebrew.args.debug? + $stderr.puts e.backtrace if args.debug? exit 1 rescue Exception => e # rubocop:disable Lint/RescueException onoe e diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index d0ec6dacf7..51b20093da 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -139,7 +139,11 @@ class Build formula.update_head_version - formula.brew(fetch: false, keep_tmp: args.keep_tmp?, interactive: args.interactive?) do |_formula, _staging| + formula.brew( + fetch: false, + keep_tmp: args.keep_tmp?, + interactive: args.interactive?, + ) do # For head builds, HOMEBREW_FORMULA_PREFIX should include the commit, # which is not known until after the formula has been staged. ENV["HOMEBREW_FORMULA_PREFIX"] = formula.prefix @@ -201,16 +205,15 @@ class Build else raise end - Keg.new(path).optlink + Keg.new(path).optlink(verbose: args.verbose?) rescue raise "#{f.opt_prefix} not present or broken\nPlease reinstall #{f.full_name}. Sorry :(" end end begin - Homebrew.args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true) - args = Homebrew.install_args.parse + Context.current = args.context error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io) error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) diff --git a/Library/Homebrew/cask/cmd.rb b/Library/Homebrew/cask/cmd.rb index 63ae4c5fa1..b3d4b5e33a 100644 --- a/Library/Homebrew/cask/cmd.rb +++ b/Library/Homebrew/cask/cmd.rb @@ -35,6 +35,8 @@ require "cask/cmd/internal_stanza" module Cask class Cmd + include Context + ALIASES = { "ls" => "list", "homepage" => "home", @@ -154,7 +156,7 @@ module Cask end rescue CaskError, MethodDeprecatedError, ArgumentError, OptionParser::InvalidOption => e onoe e.message - $stderr.puts e.backtrace if Homebrew.args.debug? + $stderr.puts e.backtrace if debug? exit 1 rescue StandardError, ScriptError, NoMemoryError => e onoe e.message diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index cbf5dc389b..5ad75d01ce 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -367,11 +367,10 @@ module Cask force: false, ).install else - FormulaInstaller.new(cask_or_formula).yield_self do |fi| + FormulaInstaller.new(cask_or_formula, verbose: verbose?).yield_self do |fi| fi.installed_as_dependency = true fi.installed_on_request = false fi.show_header = true - fi.verbose = verbose? fi.prelude fi.fetch fi.install diff --git a/Library/Homebrew/cleaner.rb b/Library/Homebrew/cleaner.rb index cf962341f7..651662a7c9 100644 --- a/Library/Homebrew/cleaner.rb +++ b/Library/Homebrew/cleaner.rb @@ -10,6 +10,8 @@ # * sets permissions on executables # * removes unresolved symlinks class Cleaner + include Context + # Create a cleaner for the given formula def initialize(f) @f = f @@ -58,7 +60,7 @@ class Cleaner # actual files gets removed correctly. dirs.reverse_each do |d| if d.children.empty? - puts "rmdir: #{d} (empty)" if Homebrew.args.verbose? + puts "rmdir: #{d} (empty)" if verbose? d.rmdir end end @@ -109,7 +111,7 @@ class Cleaner else 0444 end - if Homebrew.args.debug? + if debug? old_perms = path.stat.mode & 0777 odebug "Fixing #{path} permissions from #{old_perms.to_s(8)} to #{perms.to_s(8)}" if perms != old_perms end diff --git a/Library/Homebrew/cli/args.rb b/Library/Homebrew/cli/args.rb index f9d7adef1f..a67d0e7d10 100644 --- a/Library/Homebrew/cli/args.rb +++ b/Library/Homebrew/cli/args.rb @@ -188,6 +188,10 @@ module Homebrew flag_with_value.delete_prefix(arg_prefix) end + def context + Context::ContextStruct.new(debug: debug?, quiet: quiet?, verbose: verbose?) + end + private def option_to_name(option) diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index 7d414e07d0..c034f63024 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -88,9 +88,7 @@ module Homebrew def env?(env) return false if env.blank? - Homebrew::EnvConfig.send("#{env}?") - rescue NoMethodError - false + Homebrew::EnvConfig.try(:"#{env}?") end def usage_banner(text) diff --git a/Library/Homebrew/cmd/help.rb b/Library/Homebrew/cmd/help.rb index d75c424e1c..acd6849ca5 100644 --- a/Library/Homebrew/cmd/help.rb +++ b/Library/Homebrew/cmd/help.rb @@ -3,7 +3,7 @@ require "help" module Homebrew - def help(cmd = nil, flags = {}) - Help.help(cmd, flags) + def help + Help.help end end diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 607e69ec92..efb73358d6 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -325,7 +325,8 @@ module Homebrew fi = FormulaInstaller.new(f, force_bottle: args.force_bottle?, include_test_formulae: args.include_test_formulae, - build_from_source_formulae: args.build_from_source_formulae) + build_from_source_formulae: args.build_from_source_formulae, + debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?) fi.options = build_options.used_options fi.env = args.env fi.force = args.force? diff --git a/Library/Homebrew/cmd/link.rb b/Library/Homebrew/cmd/link.rb index 25719e29a8..412135f55e 100644 --- a/Library/Homebrew/cmd/link.rb +++ b/Library/Homebrew/cmd/link.rb @@ -31,10 +31,11 @@ module Homebrew def link args = link_args.parse - mode = OpenStruct.new - - mode.overwrite = true if args.overwrite? - mode.dry_run = true if args.dry_run? + options = { + overwrite: args.overwrite?, + dry_run: args.dry_run?, + verbose: args.verbose?, + } args.kegs.each do |keg| keg_only = Formulary.keg_only?(keg.rack) @@ -53,13 +54,13 @@ module Homebrew next end - if mode.dry_run - if mode.overwrite + if args.dry_run? + if args.overwrite? puts "Would remove:" else puts "Would link:" end - keg.link(mode) + keg.link(**options) puts_keg_only_path_message(keg) if keg_only next end @@ -89,7 +90,7 @@ module Homebrew puts if args.verbose? begin - n = keg.link(mode) + n = keg.link(**options) rescue Keg::LinkError puts raise diff --git a/Library/Homebrew/cmd/outdated.rb b/Library/Homebrew/cmd/outdated.rb index a3366b7564..c6fe50c200 100644 --- a/Library/Homebrew/cmd/outdated.rb +++ b/Library/Homebrew/cmd/outdated.rb @@ -94,7 +94,7 @@ module Homebrew if formula_or_cask.is_a?(Formula) f = formula_or_cask - if verbose? args: args + if verbose? outdated_kegs = f.outdated_kegs(fetch_head: args.fetch_HEAD?) current_version = if f.alias_changed? @@ -122,7 +122,7 @@ module Homebrew else c = formula_or_cask - puts c.outdated_info(args.greedy?, verbose?(args: args), false) + puts c.outdated_info(args.greedy?, verbose?, false) end end end @@ -147,13 +147,13 @@ module Homebrew else c = formula_or_cask - c.outdated_info(args.greedy?, verbose?(args: args), true) + c.outdated_info(args.greedy?, verbose?, true) end end end - def verbose?(args:) - ($stdout.tty? || args.verbose?) && !args.quiet? + def verbose? + ($stdout.tty? || super) && !quiet? end def json_version(version) diff --git a/Library/Homebrew/cmd/postinstall.rb b/Library/Homebrew/cmd/postinstall.rb index e0ac1d548c..a9da23695f 100644 --- a/Library/Homebrew/cmd/postinstall.rb +++ b/Library/Homebrew/cmd/postinstall.rb @@ -24,7 +24,7 @@ module Homebrew args.resolved_formulae.each do |f| ohai "Postinstalling #{f}" - fi = FormulaInstaller.new(f) + fi = FormulaInstaller.new(f, debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?) fi.post_install end end diff --git a/Library/Homebrew/cmd/switch.rb b/Library/Homebrew/cmd/switch.rb index 06feb4badc..33a15d1c1f 100644 --- a/Library/Homebrew/cmd/switch.rb +++ b/Library/Homebrew/cmd/switch.rb @@ -49,7 +49,7 @@ module Homebrew # Link new version, if not keg-only if Formulary.keg_only?(rack) - keg.optlink + keg.optlink(verbose: args.verbose?) puts "Opt link created for #{keg}" else puts "#{keg.link} links created for #{keg}" diff --git a/Library/Homebrew/cmd/unlink.rb b/Library/Homebrew/cmd/unlink.rb index e31bde919a..7dfb9d7f7b 100644 --- a/Library/Homebrew/cmd/unlink.rb +++ b/Library/Homebrew/cmd/unlink.rb @@ -26,20 +26,19 @@ module Homebrew def unlink args = unlink_args.parse - mode = OpenStruct.new - mode.dry_run = true if args.dry_run? + options = { dry_run: args.dry_run?, verbose: args.verbose? } args.kegs.each do |keg| - if mode.dry_run + if args.dry_run? puts "Would remove:" - keg.unlink(mode) + keg.unlink(**options) next end keg.lock do print "Unlinking #{keg}... " puts if args.verbose? - puts "#{keg.unlink(mode)} symlinks removed" + puts "#{keg.unlink(**options)} symlinks removed" end end end diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index b35f1462d3..6760897cc1 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -120,7 +120,7 @@ module Homebrew else hub.dump(updated_formula_report: !args.preinstall?) hub.reporters.each(&:migrate_tap_migration) - hub.reporters.each { |r| r.migrate_formula_rename(force: args.force?) } + hub.reporters.each { |r| r.migrate_formula_rename(force: args.force?, verbose: args.verbose?) } CacheStoreDatabase.use(:descriptions) do |db| DescriptionCacheStore.new(db) .update_from_report!(hub) @@ -371,7 +371,7 @@ class Reporter end end - def migrate_formula_rename(force:) + def migrate_formula_rename(force:, verbose:) Formula.installed.each do |formula| next unless Migrator.needs_migration?(formula) diff --git a/Library/Homebrew/compat.rb b/Library/Homebrew/compat.rb index bc254d9e1c..d14810694a 100644 --- a/Library/Homebrew/compat.rb +++ b/Library/Homebrew/compat.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "compat/dependencies_helpers" +require "compat/cli/parser" require "compat/extend/nil" require "compat/extend/string" require "compat/formula" diff --git a/Library/Homebrew/compat/cli/parser.rb b/Library/Homebrew/compat/cli/parser.rb new file mode 100644 index 0000000000..ec330bb23c --- /dev/null +++ b/Library/Homebrew/compat/cli/parser.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Homebrew + module CLI + class Parser + module Compat + module DeprecatedArgs + def respond_to_missing?(*) + super + end + + def method_missing(method, *) + if ![:debug?, :quiet?, :verbose?, :value].include?(method) && !@printed_args_warning + odeprecated "Homebrew.args", "`args = _args.parse` and pass `args` along the call chain" + @printed_args_warning = true + end + + super + end + end + + def parse(*) + args = super + Homebrew.args = args.dup.extend(DeprecatedArgs) + args + end + end + + prepend Compat + end + end +end diff --git a/Library/Homebrew/compat/dependencies_helpers.rb b/Library/Homebrew/compat/dependencies_helpers.rb new file mode 100644 index 0000000000..095c891011 --- /dev/null +++ b/Library/Homebrew/compat/dependencies_helpers.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require "cli/args" + +module DependenciesHelpers + module Compat + def argv_includes_ignores(argv = nil) + unless @printed_includes_ignores_warning + odeprecated "Homebrew.argv_includes_ignores", "Homebrew.args_includes_ignores" + @printed_includes_ignores_warning = true + end + args_includes_ignores(argv ? Homebrew::CLI::Args.new : Homebrew.args) + end + end + + prepend Compat +end diff --git a/Library/Homebrew/context.rb b/Library/Homebrew/context.rb new file mode 100644 index 0000000000..c8c70ac7b8 --- /dev/null +++ b/Library/Homebrew/context.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require "monitor" + +module Context + extend MonitorMixin + + def self.current=(context) + synchronize do + @current = context + end + end + + def self.current + if current_context = Thread.current[:context] + return current_context + end + + synchronize do + @current ||= ContextStruct.new + end + end + + class ContextStruct + def initialize(debug: nil, quiet: nil, verbose: nil) + @debug = debug + @quiet = quiet + @verbose = verbose + end + + def debug? + @debug + end + + def quiet? + @quiet + end + + def verbose? + @verbose + end + end + + def debug? + Context.current.debug? + end + + def quiet? + Context.current.quiet? + end + + def verbose? + Context.current.verbose? + end + + def with_context(**options) + old_context = Thread.current[:context] + + new_context = ContextStruct.new( + debug: options.fetch(:debug, old_context&.debug?), + quiet: options.fetch(:quiet, old_context&.quiet?), + verbose: options.fetch(:verbose, old_context&.verbose?), + ) + + Thread.current[:context] = new_context + + yield + ensure + Thread.current[:context] = old_context + end +end diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 45b24c293d..599c770802 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -103,7 +103,7 @@ module Homebrew only_cops = args.only_cops except_cops = args.except_cops - options = { fix: args.fix? } + options = { fix: args.fix?, debug: args.debug?, verbose: args.verbose? } if only_cops options[:only_cops] = only_cops diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index 28ae197fac..052e5dbdbc 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -116,7 +116,7 @@ module Homebrew # git cherry-pick unfortunately has no quiet option ohai "Cherry-picking #{commit_count} commit#{"s" unless commit_count == 1} from ##{pr}" cherry_pick_args = "git", "-C", path, "cherry-pick", "--ff", "--allow-empty", "#{merge_base}..FETCH_HEAD" - result = Homebrew.args.verbose? ? system(*cherry_pick_args) : quiet_system(*cherry_pick_args) + result = args.verbose? ? system(*cherry_pick_args) : quiet_system(*cherry_pick_args) unless result if args.resolve? diff --git a/Library/Homebrew/dev-cmd/style.rb b/Library/Homebrew/dev-cmd/style.rb index 7bb6fe8e75..3c05b73778 100644 --- a/Library/Homebrew/dev-cmd/style.rb +++ b/Library/Homebrew/dev-cmd/style.rb @@ -50,7 +50,9 @@ module Homebrew only_cops = args.only_cops except_cops = args.except_cops - options = { fix: args.fix?, display_cop_names: args.display_cop_names? } + options = { + fix: args.fix?, display_cop_names: args.display_cop_names?, debug: args.debug?, verbose: args.verbose? + } if only_cops options[:only_cops] = only_cops elsif except_cops diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index ce99d2845c..7afadb9c85 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -13,6 +13,7 @@ require "mechanize/http/content_disposition_parser" class AbstractDownloadStrategy extend Forwardable include FileUtils + include Context module Pourable def stage @@ -21,9 +22,9 @@ class AbstractDownloadStrategy end end - attr_reader :cache, :cached_location, :url, :meta, :name, :version, :shutup + attr_reader :cache, :cached_location, :url, :meta, :name, :version - private :meta, :name, :version, :shutup + private :meta, :name, :version def initialize(url, name, version, **meta) @url = url @@ -31,24 +32,18 @@ class AbstractDownloadStrategy @version = version @cache = meta.fetch(:cache, HOMEBREW_CACHE) @meta = meta - @shutup = false extend Pourable if meta[:bottle] end # Download and cache the resource as {#cached_location}. def fetch; end - # Suppress output - def shutup! - @shutup = true - end - def puts(*args) - super(*args) unless shutup + super(*args) unless quiet? end def ohai(*args) - super(*args) unless shutup + super(*args) unless quiet? end # Unpack {#cached_location} into the current working directory, and possibly @@ -60,7 +55,7 @@ class AbstractDownloadStrategy ref_type: @ref_type, ref: @ref) .extract_nestedly(basename: basename, prioritise_extension: true, - verbose: Homebrew.args.verbose? && !shutup) + verbose: verbose? && !quiet?) chdir end @@ -102,9 +97,9 @@ class AbstractDownloadStrategy def system_command!(*args, **options) super( *args, - print_stdout: !shutup, - print_stderr: !shutup, - verbose: Homebrew.args.verbose? && !shutup, + print_stdout: !quiet?, + print_stderr: !quiet?, + verbose: verbose? && !quiet?, env: env, **options, ) @@ -498,7 +493,7 @@ class NoUnzipCurlDownloadStrategy < CurlDownloadStrategy def stage UnpackStrategy::Uncompressed.new(cached_location) .extract(basename: basename, - verbose: Homebrew.args.verbose? && !shutup) + verbose: verbose? && !quiet?) end end @@ -553,7 +548,7 @@ class SubversionDownloadStrategy < VCSDownloadStrategy # This saves on bandwidth and will have a similar effect to verifying the # cache as it will make any changes to get the right revision. args = [] - args << "--quiet" unless Homebrew.args.verbose? + args << "--quiet" unless verbose? if revision ohai "Checking out #{@ref}" @@ -897,7 +892,7 @@ class CVSDownloadStrategy < VCSDownloadStrategy end def quiet_flag - "-Q" unless Homebrew.args.verbose? + "-Q" unless verbose? end def clone_repo diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index 49e05e0484..f3fb93c6f0 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -356,10 +356,10 @@ class BuildError < RuntimeError [] end - def dump + def dump(verbose: false) puts - if Homebrew.args.verbose? + if verbose require "system_config" require "build_environment" diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index 63023593ca..fb3ddd9659 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -419,6 +419,8 @@ require "extend/os/pathname" # @private module ObserverPathnameExtension class << self + include Context + attr_accessor :n, :d def reset_counts! @@ -437,8 +439,8 @@ module ObserverPathnameExtension MAXIMUM_VERBOSE_OUTPUT = 100 def verbose? - return Homebrew.args.verbose? unless ENV["CI"] - return false unless Homebrew.args.verbose? + return super unless ENV["CI"] + return false unless super if total < MAXIMUM_VERBOSE_OUTPUT true diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 10ab763470..5849baaa20 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -54,9 +54,11 @@ class Formula include Utils::Inreplace include Utils::Shebang include Utils::Shell + include Context extend Enumerable extend Forwardable extend Cachable + extend Predicable # @!method inreplace(paths, before = nil, after = nil) # Actually implemented in {Utils::Inreplace.inreplace}. @@ -536,8 +538,10 @@ class Formula return false unless head&.downloader.is_a?(VCSDownloadStrategy) downloader = head.downloader - downloader.shutup! unless Homebrew.args.verbose? - downloader.commit_outdated?(version.version.commit) + + with_context quiet: true do + downloader.commit_outdated?(version.version.commit) + end end # The latest prefix for this formula. Checks for {#head}, then {#devel} @@ -1182,7 +1186,7 @@ class Formula begin yield self, staging rescue - staging.retain! if interactive || Homebrew.args.debug? + staging.retain! if interactive || debug? raise ensure cp Dir["config.log", "CMakeCache.txt"], logs @@ -1831,13 +1835,13 @@ class Formula end end rescue Exception # rubocop:disable Lint/RescueException - staging.retain! if Homebrew.args.debug? + staging.retain! if debug? raise end end ensure - @testpath = nil @prefix_returns_versioned_prefix = false + @testpath = nil end # @private @@ -1927,13 +1931,12 @@ class Formula # # If there is a "make", "install" available, please use it! # system "make", "install" def system(cmd, *args) - verbose = Homebrew.args.verbose? verbose_using_dots = Homebrew::EnvConfig.verbose_using_dots? # remove "boring" arguments so that the important ones are more likely to # be shown considering that we trim long ohai lines to the terminal width pretty_args = args.dup - unless verbose + unless verbose? case cmd when "./configure" pretty_args -= %w[--disable-dependency-tracking --disable-debug --disable-silent-rules] @@ -1961,7 +1964,7 @@ class Formula log.puts Time.now, "", cmd, args, "" log.flush - if verbose + if verbose? rd, wr = IO.pipe begin pid = fork do @@ -2004,7 +2007,7 @@ class Formula log_lines = Homebrew::EnvConfig.fail_log_lines log.flush - if !verbose || verbose_using_dots + if !verbose? || verbose_using_dots puts "Last #{log_lines} lines from #{logfn}:" Kernel.system "/usr/bin/tail", "-n", log_lines, logfn end diff --git a/Library/Homebrew/formula_assertions.rb b/Library/Homebrew/formula_assertions.rb index acb428ae98..55592f2214 100644 --- a/Library/Homebrew/formula_assertions.rb +++ b/Library/Homebrew/formula_assertions.rb @@ -2,6 +2,8 @@ module Homebrew module Assertions + include Context + require "test/unit/assertions" include ::Test::Unit::Assertions @@ -12,7 +14,7 @@ module Homebrew assert_equal result, $CHILD_STATUS.exitstatus output rescue Test::Unit::AssertionFailedError - puts output if Homebrew.args.verbose? + puts output if verbose? raise end @@ -28,7 +30,7 @@ module Homebrew assert_equal result, $CHILD_STATUS.exitstatus unless result.nil? output rescue Test::Unit::AssertionFailedError - puts output if Homebrew.args.verbose? + puts output if verbose? raise end end diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index e70d60089e..06d5db08b8 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -51,7 +51,8 @@ class FormulaInstaller force_bottle: false, include_test_formulae: [], build_from_source_formulae: [], - cc: nil) + cc: nil, + debug: false, quiet: false, verbose: false) @formula = formula @env = nil @force = false @@ -68,9 +69,9 @@ class FormulaInstaller @interactive = false @git = false @cc = cc - @verbose = Homebrew.args.verbose? - @quiet = Homebrew.args.quiet? - @debug = Homebrew.args.debug? + @verbose = verbose + @quiet = quiet + @debug = debug @installed_as_dependency = false @installed_on_request = true @options = Options.new @@ -601,15 +602,13 @@ class FormulaInstaller def fetch_dependency(dep) df = dep.to_formula - fi = FormulaInstaller.new(df, force_bottle: false, + fi = FormulaInstaller.new(df, force_bottle: false, include_test_formulae: include_test_formulae, - build_from_source_formulae: build_from_source_formulae) + build_from_source_formulae: build_from_source_formulae, + debug: debug?, quiet: quiet?, verbose: verbose?) fi.force = force? fi.keep_tmp = keep_tmp? - fi.verbose = verbose? - fi.quiet = quiet? - fi.debug = debug? # When fetching we don't need to recurse the dependency tree as it's already # been done for us in `compute_dependencies` and there's no requirement to # fetch in a particular order. @@ -642,9 +641,10 @@ class FormulaInstaller EOS end - fi = FormulaInstaller.new(df, force_bottle: false, + fi = FormulaInstaller.new(df, force_bottle: false, include_test_formulae: include_test_formulae, - build_from_source_formulae: build_from_source_formulae) + build_from_source_formulae: build_from_source_formulae, + debug: debug?, quiet: quiet?, verbose: verbose?) fi.options |= tab.used_options fi.options |= Tab.remap_deprecated_options(df.deprecated_options, dep.options) @@ -652,9 +652,6 @@ class FormulaInstaller fi.options &= df.options fi.force = force? fi.keep_tmp = keep_tmp? - fi.verbose = verbose? - fi.quiet = quiet? - fi.debug = debug? fi.link_keg ||= keg_was_linked if keg_had_linked_keg fi.installed_as_dependency = true fi.installed_on_request = df.any_version_installed? && tab.installed_on_request @@ -665,7 +662,7 @@ class FormulaInstaller rescue Exception => e # rubocop:disable Lint/RescueException ignore_interrupts do tmp_keg.rename(installed_keg) if tmp_keg && !installed_keg.directory? - linked_keg.link if keg_was_linked + linked_keg.link(verbose: verbose?) if keg_was_linked end raise unless e.is_a? FormulaInstallationAlreadyAttemptedError @@ -845,7 +842,7 @@ class FormulaInstaller def link(keg) unless link_keg begin - keg.optlink + keg.optlink(verbose: verbose?) Formula.clear_cache rescue Keg::LinkError => e onoe "Failed to create #{formula.opt_prefix}" @@ -876,7 +873,7 @@ class FormulaInstaller backup_dir = HOMEBREW_CACHE/"Backup" begin - keg.link + keg.link(verbose: verbose?) rescue Keg::ConflictError => e conflict_file = e.dst if formula.link_overwrite?(conflict_file) && !link_overwrite_backup.key?(conflict_file) @@ -891,8 +888,7 @@ class FormulaInstaller puts e puts puts "Possible conflicting files are:" - mode = OpenStruct.new(dry_run: true, overwrite: true) - keg.link(mode) + keg.link(dry_run: true, overwrite: true, verbose: verbose?) @show_summary_heading = true Homebrew.failed = true rescue Keg::LinkError => e @@ -939,7 +935,7 @@ class FormulaInstaller log.mkpath if formula.plist.include? log.to_s rescue Exception => e # rubocop:disable Lint/RescueException onoe "Failed to install plist file" - ohai e, e.backtrace if debug? + odebug e, e.backtrace Homebrew.failed = true end @@ -949,7 +945,7 @@ class FormulaInstaller onoe "Failed to fix install linkage" puts "The formula built, but you may encounter issues using it or linking other" puts "formulae against it." - ohai e, e.backtrace if debug? + odebug e, e.backtrace Homebrew.failed = true @show_summary_heading = true end @@ -960,7 +956,7 @@ class FormulaInstaller rescue Exception => e # rubocop:disable Lint/RescueException opoo "The cleaning step did not complete successfully" puts "Still, the installation was successful, so we will link it into your prefix" - ohai e, e.backtrace if debug? + odebug e, e.backtrace Homebrew.failed = true @show_summary_heading = true end @@ -996,7 +992,7 @@ class FormulaInstaller rescue Exception => e # rubocop:disable Lint/RescueException opoo "The post-install step did not complete successfully" puts "You can try again using `brew postinstall #{formula.full_name}`" - ohai e, e.backtrace if debug? || Homebrew::EnvConfig.developer? + odebug e, e.backtrace, always_display: Homebrew::EnvConfig.developer? Homebrew.failed = true @show_summary_heading = true end diff --git a/Library/Homebrew/formula_versions.rb b/Library/Homebrew/formula_versions.rb index 5805213c8b..d6503bd22b 100644 --- a/Library/Homebrew/formula_versions.rb +++ b/Library/Homebrew/formula_versions.rb @@ -3,6 +3,8 @@ require "formula" class FormulaVersions + include Context + IGNORED_EXCEPTIONS = [ ArgumentError, NameError, SyntaxError, TypeError, FormulaSpecificationError, FormulaValidationError, @@ -44,7 +46,7 @@ class FormulaVersions rescue *IGNORED_EXCEPTIONS => e # We rescue these so that we can skip bad versions and # continue walking the history - odebug "#{e} in #{name} at revision #{rev}", e.backtrace if Homebrew.args.debug? + odebug "#{e} in #{name} at revision #{rev}", e.backtrace if debug? rescue FormulaUnavailableError nil ensure diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 80600d7e34..ce3d098cf9 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -109,6 +109,8 @@ module Formulary # A FormulaLoader returns instances of formulae. # Subclasses implement loaders for particular sources of formulae. class FormulaLoader + include Context + # The formula's name attr_reader :name # The formula's ruby file's path or filename @@ -138,7 +140,7 @@ module Formulary private def load_file(flags:) - $stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if Homebrew.args.debug? + $stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if debug? raise FormulaUnavailableError, name unless path.file? Formulary.load_formula_from_path(name, path, flags: flags) @@ -314,7 +316,7 @@ module Formulary end def klass(flags:) - $stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if Homebrew.args.debug? + $stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if debug? namespace = "FormulaNamespace#{Digest::MD5.hexdigest(contents.to_s)}" Formulary.load_formula(name, path, contents, namespace, flags: flags) end diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index b100822fc0..9276582221 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -37,7 +37,6 @@ require "config" require "os" require "cli/args" require "messages" -require "system_command" HOMEBREW_PRODUCT = ENV["HOMEBREW_PRODUCT"] HOMEBREW_VERSION = ENV["HOMEBREW_VERSION"] @@ -116,6 +115,7 @@ end.compact.freeze require "set" +require "context" require "extend/pathname" require "extend/module" @@ -125,6 +125,7 @@ require "active_support/core_ext/object/blank" require "active_support/core_ext/hash/deep_merge" require "active_support/core_ext/file/atomic" +require "system_command" require "exceptions" require "utils" diff --git a/Library/Homebrew/help.rb b/Library/Homebrew/help.rb index 53c3e46d56..12283523d8 100644 --- a/Library/Homebrew/help.rb +++ b/Library/Homebrew/help.rb @@ -40,7 +40,7 @@ module Homebrew module Help module_function - def help(cmd = nil, empty_argv: false, usage_error: nil) + def help(cmd = nil, empty_argv: false, usage_error: nil, remaining_args: []) if cmd.nil? # Handle `brew` (no arguments). if empty_argv @@ -58,7 +58,7 @@ module Homebrew # Display command-specific (or generic) help in response to `UsageError`. if usage_error - $stderr.puts path ? command_help(cmd, path) : HOMEBREW_HELP + $stderr.puts path ? command_help(cmd, path, remaining_args: remaining_args) : HOMEBREW_HELP $stderr.puts onoe usage_error exit 1 @@ -68,16 +68,16 @@ module Homebrew return if path.nil? # Display help for internal command (or generic help if undocumented). - puts command_help(cmd, path) + puts command_help(cmd, path, remaining_args: remaining_args) exit 0 end - def command_help(cmd, path) + def command_help(cmd, path, remaining_args:) # Only some types of commands can have a parser. output = if Commands.valid_internal_cmd?(cmd) || Commands.valid_internal_dev_cmd?(cmd) || Commands.external_ruby_v2_cmd_path(cmd) - parser_help(path) + parser_help(path, remaining_args: remaining_args) end output ||= comment_help(path) @@ -90,13 +90,13 @@ module Homebrew output end - def parser_help(path) + def parser_help(path, remaining_args:) # Let OptionParser generate help text for commands which have a parser. cmd_parser = CLI::Parser.from_cmd_path(path) return unless cmd_parser # Try parsing arguments here in order to show formula options in help output. - cmd_parser.parse(Homebrew.args.remaining, ignore_invalid_options: true) + cmd_parser.parse(remaining_args, ignore_invalid_options: true) cmd_parser.generate_help_text end diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index ccf250e6df..fc15f00546 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -323,7 +323,7 @@ class Keg EOS end - def unlink(mode = OpenStruct.new) + def unlink(**options) ObserverPathnameExtension.reset_counts! dirs = [] @@ -341,7 +341,7 @@ class Keg next unless dst.symlink? next if src != dst.resolved_path - if mode.dry_run + if options[:dry_run] puts dst Find.prune if src.directory? next @@ -354,7 +354,7 @@ class Keg end end - unless mode.dry_run + unless options[:dry_run] remove_linked_keg_record if linked? dirs.reverse_each(&:rmdir_if_possible) end @@ -436,21 +436,21 @@ class Keg end end - def link(mode = OpenStruct.new) + def link(**options) raise AlreadyLinkedError, self if linked_keg_record.directory? ObserverPathnameExtension.reset_counts! - optlink(mode) unless mode.dry_run + optlink(**options) unless options[:dry_run] # yeah indeed, you have to force anything you need in the main tree into # these dirs REMEMBER that *NOT* everything needs to be in the main tree - link_dir("etc", mode) { :mkpath } - link_dir("bin", mode) { :skip_dir } - link_dir("sbin", mode) { :skip_dir } - link_dir("include", mode) { :link } + link_dir("etc", **options) { :mkpath } + link_dir("bin", **options) { :skip_dir } + link_dir("sbin", **options) { :skip_dir } + link_dir("include", **options) { :link } - link_dir("share", mode) do |relative_path| + link_dir("share", **options) do |relative_path| case relative_path.to_s when "locale/locale.alias" then :skip_file when INFOFILE_RX then :info @@ -468,7 +468,7 @@ class Keg end end - link_dir("lib", mode) do |relative_path| + link_dir("lib", **options) do |relative_path| case relative_path.to_s when "charset.alias" then :skip_file # pkg-config database gets explicitly created @@ -494,7 +494,7 @@ class Keg end end - link_dir("Frameworks", mode) do |relative_path| + link_dir("Frameworks", **options) do |relative_path| # Frameworks contain symlinks pointing into a subdir, so we have to use # the :link strategy. However, for Foo.framework and # Foo.framework/Versions we have to use :mkpath so that multiple formulae @@ -506,9 +506,9 @@ class Keg end end - make_relative_symlink(linked_keg_record, path, mode) unless mode.dry_run + make_relative_symlink(linked_keg_record, path, **options) unless options[:dry_run] rescue LinkError - unlink + unlink(verbose: options[:verbose]) raise else ObserverPathnameExtension.n @@ -536,19 +536,19 @@ class Keg tab.aliases || [] end - def optlink(mode = OpenStruct.new) + def optlink(**options) opt_record.delete if opt_record.symlink? || opt_record.exist? - make_relative_symlink(opt_record, path, mode) + make_relative_symlink(opt_record, path, **options) aliases.each do |a| alias_opt_record = opt_record.parent/a alias_opt_record.delete if alias_opt_record.symlink? || alias_opt_record.exist? - make_relative_symlink(alias_opt_record, path, mode) + make_relative_symlink(alias_opt_record, path, **options) end return unless oldname_opt_record oldname_opt_record.delete - make_relative_symlink(oldname_opt_record, path, mode) + make_relative_symlink(oldname_opt_record, path, **options) end def delete_pyc_files! @@ -558,7 +558,7 @@ class Keg private - def resolve_any_conflicts(dst, mode) + def resolve_any_conflicts(dst, **options) return unless dst.symlink? src = dst.resolved_path @@ -571,7 +571,7 @@ class Keg stat = src.lstat rescue Errno::ENOENT # dst is a broken symlink, so remove it. - dst.unlink unless mode.dry_run + dst.unlink unless options[:dry_run] return end @@ -580,25 +580,23 @@ class Keg begin keg = Keg.for(src) rescue NotAKegError - if Homebrew.args.verbose? - puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar" - end + puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar" if options[:verbose] return end - dst.unlink unless mode.dry_run - keg.link_dir(src, mode) { :mkpath } + dst.unlink unless options[:dry_run] + keg.link_dir(src, **options) { :mkpath } true end - def make_relative_symlink(dst, src, mode) + def make_relative_symlink(dst, src, **options) if dst.symlink? && src == dst.resolved_path - puts "Skipping; link already exists: #{dst}" if Homebrew.args.verbose? + puts "Skipping; link already exists: #{dst}" if options[:verbose] return end # cf. git-clean -n: list files to delete, don't really link or delete - if mode.dry_run && mode.overwrite + if options[:dry_run] && options[:overwrite] if dst.symlink? puts "#{dst} -> #{dst.resolved_path}" elsif dst.exist? @@ -608,12 +606,12 @@ class Keg end # list all link targets - if mode.dry_run + if options[:dry_run] puts dst return end - dst.delete if mode.overwrite && (dst.exist? || dst.symlink?) + dst.delete if options[:overwrite] && (dst.exist? || dst.symlink?) dst.make_relative_symlink(src) rescue Errno::EEXIST => e raise ConflictError.new(self, src.relative_path_from(path), dst, e) if dst.exist? @@ -631,7 +629,7 @@ class Keg protected # symlinks the contents of path+relative_dir recursively into #{HOMEBREW_PREFIX}/relative_dir - def link_dir(relative_dir, mode) + def link_dir(relative_dir, **options) root = path/relative_dir return unless root.exist? @@ -655,10 +653,10 @@ class Keg when :info next if File.basename(src) == "dir" # skip historical local 'dir' files - make_relative_symlink dst, src, mode + make_relative_symlink dst, src, **options dst.install_info else - make_relative_symlink dst, src, mode + make_relative_symlink dst, src, **options end elsif src.directory? # if the dst dir already exists, then great! walk the rest of the tree tho @@ -672,10 +670,10 @@ class Keg when :skip_dir Find.prune when :mkpath - dst.mkpath unless resolve_any_conflicts(dst, mode) + dst.mkpath unless resolve_any_conflicts(dst, **options) else - unless resolve_any_conflicts(dst, mode) - make_relative_symlink dst, src, mode + unless resolve_any_conflicts(dst, **options) + make_relative_symlink dst, src, **options Find.prune end end diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb index 30d0603b0e..e0903aa48f 100644 --- a/Library/Homebrew/migrator.rb +++ b/Library/Homebrew/migrator.rb @@ -5,6 +5,8 @@ require "keg" require "tab" class Migrator + include Context + class MigrationNeededError < RuntimeError def initialize(formula) super <<~EOS @@ -209,7 +211,7 @@ class Migrator rescue Exception => e # rubocop:disable Lint/RescueException onoe "Error occurred while migrating." puts e - puts e.backtrace if Homebrew.args.debug? + puts e.backtrace if debug? puts "Backing up..." ignore_interrupts { backup_oldname } ensure @@ -267,7 +269,7 @@ class Migrator oh1 "Unlinking #{Formatter.identifier(oldname)}" old_cellar.subdirs.each do |d| keg = Keg.new(d) - keg.unlink + keg.unlink(verbose: verbose?) end end @@ -275,7 +277,7 @@ class Migrator oh1 "Temporarily unlinking #{Formatter.identifier(newname)}" new_cellar.subdirs.each do |d| keg = Keg.new(d) - keg.unlink + keg.unlink(verbose: verbose?) end end @@ -288,7 +290,7 @@ class Migrator # If formula is keg-only we also optlink it. if formula.keg_only? || !old_linked_keg_record begin - new_keg.optlink + new_keg.optlink(verbose: verbose?) rescue Keg::LinkError => e onoe "Failed to create #{formula.opt_prefix}" raise @@ -299,15 +301,13 @@ class Migrator new_keg.remove_linked_keg_record if new_keg.linked? begin - mode = OpenStruct.new(overwrite: true) - new_keg.link(mode) + new_keg.link(overwrite: true, verbose: verbose?) rescue Keg::ConflictError => e onoe "Error while executing `brew link` step on #{newname}" puts e puts puts "Possible conflicting files are:" - mode = OpenStruct.new(dry_run: true, overwrite: true) - new_keg.link(mode) + new_keg.link(dry_run: true, overwrite: true, verbose: verbose?) raise rescue Keg::LinkError => e onoe "Error while linking" @@ -318,8 +318,8 @@ class Migrator rescue Exception => e # rubocop:disable Lint/RescueException onoe "An unexpected error occurred during linking" puts e - puts e.backtrace if Homebrew.args.debug? - ignore_interrupts { new_keg.unlink } + puts e.backtrace if debug? + ignore_interrupts { new_keg.unlink(verbose: verbose?) } raise end end @@ -384,7 +384,7 @@ class Migrator if new_cellar.exist? new_cellar.subdirs.each do |d| newname_keg = Keg.new(d) - newname_keg.unlink + newname_keg.unlink(verbose: verbose?) newname_keg.uninstall if new_cellar_existed end end @@ -396,16 +396,16 @@ class Migrator # create a keg using its old path if old_linked_keg_record begin - old_linked_keg.link + old_linked_keg.link(verbose: verbose?) rescue Keg::LinkError - old_linked_keg.unlink + old_linked_keg.unlink(verbose: verbose?) raise rescue Keg::AlreadyLinkedError - old_linked_keg.unlink + old_linked_keg.unlink(verbose: verbose?) retry end else - old_linked_keg.optlink + old_linked_keg.optlink(verbose: verbose?) end end diff --git a/Library/Homebrew/os/mac/keg.rb b/Library/Homebrew/os/mac/keg.rb index 90593712ff..0782226c00 100644 --- a/Library/Homebrew/os/mac/keg.rb +++ b/Library/Homebrew/os/mac/keg.rb @@ -5,7 +5,7 @@ class Keg return if file.dylib_id == id @require_relocation = true - odebug "Changing dylib ID of #{file}\n from #{file.dylib_id}\n to #{id}" if Homebrew.args.debug? + odebug "Changing dylib ID of #{file}\n from #{file.dylib_id}\n to #{id}" MachO::Tools.change_dylib_id(file, id, strict: false) rescue MachO::MachOError onoe <<~EOS @@ -20,7 +20,7 @@ class Keg return if old == new @require_relocation = true - odebug "Changing install name in #{file}\n from #{old}\n to #{new}" if Homebrew.args.debug? + odebug "Changing install name in #{file}\n from #{old}\n to #{new}" MachO::Tools.change_install_name(file, old, new, strict: false) rescue MachO::MachOError onoe <<~EOS diff --git a/Library/Homebrew/postinstall.rb b/Library/Homebrew/postinstall.rb index 557fd3387a..d6ae171797 100644 --- a/Library/Homebrew/postinstall.rb +++ b/Library/Homebrew/postinstall.rb @@ -17,7 +17,7 @@ begin trap("INT", old_trap) formula = args.resolved_formulae.first - formula.extend(Debrew::Formula) if Homebrew.args.debug? + formula.extend(Debrew::Formula) if args.debug? formula.run_post_install rescue Exception => e # rubocop:disable Lint/RescueException error_pipe.puts e.to_json diff --git a/Library/Homebrew/reinstall.rb b/Library/Homebrew/reinstall.rb index 77645bf7c0..96234cb04f 100644 --- a/Library/Homebrew/reinstall.rb +++ b/Library/Homebrew/reinstall.rb @@ -24,7 +24,8 @@ module Homebrew options &= f.options fi = FormulaInstaller.new(f, force_bottle: args.force_bottle?, - build_from_source_formulae: args.build_from_source_formulae) + build_from_source_formulae: args.build_from_source_formulae, + debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?) fi.options = options fi.force = args.force? fi.keep_tmp = args.keep_tmp? @@ -48,7 +49,7 @@ module Homebrew rescue FormulaInstallationAlreadyAttemptedError nil rescue Exception # rubocop:disable Lint/RescueException - ignore_interrupts { restore_backup(keg, keg_was_linked) } + ignore_interrupts { restore_backup(keg, keg_was_linked, verbose: args.verbose?) } raise else begin @@ -81,7 +82,7 @@ module Homebrew Pathname.new(keg).rmtree if keg.exist? path.rename keg - keg.link if keg_was_linked + keg.link(verbose: verbose) if keg_was_linked end def backup_path(path) diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index 4b00e4ea3a..b76bd703fa 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -9,6 +9,7 @@ require "mktemp" # primary formula download, along with other declared resources, are instances # of this class. class Resource + include Context include FileUtils attr_reader :mirrors, :specs, :using, :source_modified_time, :patches, :owner @@ -140,7 +141,7 @@ class Resource def verify_download_integrity(fn) if fn.file? - ohai "Verifying #{fn.basename} checksum" if Homebrew.args.verbose? + ohai "Verifying #{fn.basename} checksum" if verbose? fn.verify_checksum(checksum) end rescue ChecksumMissingError diff --git a/Library/Homebrew/rubocops/lines.rb b/Library/Homebrew/rubocops/lines.rb index 552225fb5b..7996601dea 100644 --- a/Library/Homebrew/rubocops/lines.rb +++ b/Library/Homebrew/rubocops/lines.rb @@ -284,9 +284,7 @@ module RuboCop end end - find_instance_call(body_node, "ARGV") do |method_node| - next if [:debug?, :verbose?, :value].index(method_node.method_name) - + find_instance_call(body_node, "ARGV") do |_method_node| problem "Use build instead of ARGV to check options" end diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index 170b4e5d8f..91ff124c09 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -240,7 +240,7 @@ class HeadSoftwareSpec < SoftwareSpec end def verify_download_integrity(_fn) - nil + # no-op end end diff --git a/Library/Homebrew/style.rb b/Library/Homebrew/style.rb index c7a94df76b..be40a4dd41 100644 --- a/Library/Homebrew/style.rb +++ b/Library/Homebrew/style.rb @@ -16,7 +16,9 @@ module Homebrew check_style_impl(files, :json, **options) end - def check_style_impl(files, output_type, fix: false, except_cops: nil, only_cops: nil, display_cop_names: false) + def check_style_impl(files, output_type, + fix: false, except_cops: nil, only_cops: nil, display_cop_names: false, + debug: false, verbose: false) Homebrew.install_bundler_gems! require "rubocop" require "rubocops" @@ -30,7 +32,8 @@ module Homebrew "--parallel" end - args += ["--extra-details", "--display-cop-names"] if Homebrew.args.verbose? + args += ["--extra-details"] if verbose + args += ["--display-cop-names"] if display_cop_names || verbose if except_cops except_cops.map! { |cop| RuboCop::Cop::Cop.registry.qualified_cop_name(cop.to_s, "") } @@ -77,15 +80,13 @@ module Homebrew case output_type when :print - args << "--debug" if Homebrew.args.debug? - args << "--display-cop-names" if display_cop_names + args << "--debug" if debug args << "--format" << "simple" if files.present? system(cache_env, "rubocop", *args) rubocop_success = $CHILD_STATUS.success? when :json json, err, status = - Open3.capture3(cache_env, "rubocop", - "--format", "json", *args) + Open3.capture3(cache_env, "rubocop", "--format", "json", *args) # exit status of 1 just means violations were found; other numbers mean # execution errors. # exitstatus can also be nil if RuboCop process crashes, e.g. due to diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index 3db2429ab0..c0e91059a1 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -8,7 +8,6 @@ require "shellwords" require "extend/io" require "extend/hash_validator" using HashValidator -require "extend/predicable" module Kernel def system_command(*args) @@ -21,6 +20,7 @@ module Kernel end class SystemCommand + include Context extend Predicable attr_reader :pid @@ -34,7 +34,7 @@ class SystemCommand end def run! - puts redact_secrets(command.shelljoin.gsub('\=', "="), @secrets) if verbose? || Homebrew.args.debug? + puts redact_secrets(command.shelljoin.gsub('\=', "="), @secrets) if verbose? || debug? @output = [] @@ -84,7 +84,13 @@ class SystemCommand attr_reader :executable, :args, :input, :options, :env - attr_predicate :sudo?, :print_stdout?, :print_stderr?, :verbose?, :must_succeed? + attr_predicate :sudo?, :print_stdout?, :print_stderr?, :must_succeed? + + def verbose? + return super if @verbose.nil? + + @verbose + end def env_args set_variables = env.reject { |_, value| value.nil? } @@ -160,6 +166,8 @@ class SystemCommand end class Result + include Context + attr_accessor :command, :status, :exit_status def initialize(command, output, status, secrets:) @@ -222,7 +230,7 @@ class SystemCommand end def warn_plist_garbage(garbage) - return unless Homebrew.args.verbose? + return unless verbose? return unless garbage.match?(/\S/) opoo "Received non-XML output from #{Formatter.identifier(command.first)}:" diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb index 2936c20715..a175ca0637 100644 --- a/Library/Homebrew/test.rb +++ b/Library/Homebrew/test.rb @@ -16,9 +16,9 @@ require "dev-cmd/test" TEST_TIMEOUT_SECONDS = 5 * 60 begin - Homebrew.args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true) - args = Homebrew.test_args.parse + Context.current = args.context + error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io) error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) diff --git a/Library/Homebrew/test/download_strategies_spec.rb b/Library/Homebrew/test/download_strategies_spec.rb index f24857652e..07a3f7bc8d 100644 --- a/Library/Homebrew/test/download_strategies_spec.rb +++ b/Library/Homebrew/test/download_strategies_spec.rb @@ -121,7 +121,6 @@ describe GitDownloadStrategy do git_commit_all end - subject.shutup! expect(subject.fetch_last_commit).to eq("f68266e") end end diff --git a/Library/Homebrew/test/keg_spec.rb b/Library/Homebrew/test/keg_spec.rb index 2df44f9b1e..060ceb2d42 100644 --- a/Library/Homebrew/test/keg_spec.rb +++ b/Library/Homebrew/test/keg_spec.rb @@ -21,7 +21,6 @@ describe Keg do let(:dst) { HOMEBREW_PREFIX/"bin"/"helloworld" } let(:nonexistent) { Pathname.new("/some/nonexistent/path") } - let(:mode) { OpenStruct.new } let!(:keg) { setup_test_keg("foo", "1.0") } let(:kegs) { [] } @@ -84,11 +83,11 @@ describe Keg do end context "with dry run set to true" do - it "only prints what would be done" do - mode.dry_run = true + let(:options) { { dry_run: true } } + it "only prints what would be done" do expect { - expect(keg.link(mode)).to eq(0) + expect(keg.link(**options)).to eq(0) }.to output(<<~EOF).to_stdout #{HOMEBREW_PREFIX}/bin/goodbye_cruel_world #{HOMEBREW_PREFIX}/bin/helloworld @@ -119,27 +118,27 @@ describe Keg do end context "with overwrite set to true" do + let(:options) { { overwrite: true } } + it "overwrite existing files" do touch dst - mode.overwrite = true - expect(keg.link(mode)).to eq(3) + expect(keg.link(**options)).to eq(3) expect(keg).to be_linked end it "overwrites broken symlinks" do dst.make_symlink "nowhere" - mode.overwrite = true - expect(keg.link(mode)).to eq(3) + expect(keg.link(**options)).to eq(3) expect(keg).to be_linked end it "still supports dryrun" do touch dst - mode.overwrite = true - mode.dry_run = true + + options[:dry_run] = true expect { - expect(keg.link(mode)).to eq(0) + expect(keg.link(**options)).to eq(0) }.to output(<<~EOF).to_stdout #{dst} EOF diff --git a/Library/Homebrew/test/rubocops/lines_spec.rb b/Library/Homebrew/test/rubocops/lines_spec.rb index 46d24fab94..404617524b 100644 --- a/Library/Homebrew/test/rubocops/lines_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_spec.rb @@ -821,18 +821,6 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do RUBY end - it "Using ARGV to check options" do - expect_no_offenses(<<~RUBY) - class Foo < Formula - desc "foo" - url 'https://brew.sh/foo-1.0.tgz' - def install - verbose = Homebrew.args.verbose? - end - end - RUBY - end - it 'man+"man8" usage' do expect_offense(<<~RUBY) class Foo < Formula diff --git a/Library/Homebrew/test/system_command_result_spec.rb b/Library/Homebrew/test/system_command_result_spec.rb index a424661c39..bc48fcdd75 100644 --- a/Library/Homebrew/test/system_command_result_spec.rb +++ b/Library/Homebrew/test/system_command_result_spec.rb @@ -120,7 +120,7 @@ describe SystemCommand::Result do context "when verbose" do before do - allow(Homebrew).to receive(:args).and_return(OpenStruct.new("verbose?" => true)) + allow(Context).to receive(:current).and_return(Context::ContextStruct.new(verbose: true)) end it "warns about garbage" do @@ -144,7 +144,7 @@ describe SystemCommand::Result do context "when verbose" do before do - allow(Homebrew).to receive(:args).and_return(OpenStruct.new("verbose?" => true)) + allow(Context).to receive(:current).and_return(Context::ContextStruct.new(verbose: true)) end it "warns about garbage" do diff --git a/Library/Homebrew/upgrade.rb b/Library/Homebrew/upgrade.rb index d447331884..06e314380f 100644 --- a/Library/Homebrew/upgrade.rb +++ b/Library/Homebrew/upgrade.rb @@ -63,9 +63,8 @@ module Homebrew options |= f.build.used_options options &= f.options - fi = FormulaInstaller.new(f, force_bottle: args.force_bottle?, - include_test_formulae: args.include_test_formulae, - build_from_source_formulae: args.build_from_source_formulae) + fi = FormulaInstaller.new(f, force_bottle: args.force_bottle?, + debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?) fi.options = options fi.force = args.force? fi.keep_tmp = args.keep_tmp? @@ -102,7 +101,7 @@ module Homebrew rescue CannotInstallFormulaError => e ofail e rescue BuildError => e - e.dump + e.dump(verbose: args.verbose?) puts Homebrew.failed = true rescue DownloadError => e @@ -225,7 +224,7 @@ module Homebrew rescue CannotInstallFormulaError => e ofail e rescue BuildError => e - e.dump + e.dump(verbose: args.verbose?) puts Homebrew.failed = true rescue DownloadError => e diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 254ac11ea1..0c4068c89e 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -16,6 +16,8 @@ require "tap_constants" require "time" module Homebrew + extend Context + module_function def _system(cmd, *args, **options) @@ -34,7 +36,7 @@ module Homebrew end def system(cmd, *args, **options) - if Homebrew.args.verbose? + if verbose? puts "#{cmd} #{args * " "}".gsub(RUBY_PATH, "ruby") .gsub($LOAD_PATH.join(File::PATH_SEPARATOR).to_s, "$LOAD_PATH") end @@ -86,7 +88,13 @@ module Kernel end def ohai_title(title) - title = Tty.truncate(title) if $stdout.tty? && !Homebrew.args.verbose? + verbose = if respond_to?(:verbose?) + verbose? + else + Context.current.verbose? + end + + title = Tty.truncate(title) if $stdout.tty? && !verbose Formatter.headline(title, color: :blue) end @@ -95,15 +103,27 @@ module Kernel puts sput end - def odebug(title, *sput) - return unless Homebrew.args.debug? + def odebug(title, *sput, always_display: false) + debug = if respond_to?(:debug) + debug? + else + Context.current.debug? + end + + return unless debug || always_display puts Formatter.headline(title, color: :magenta) puts sput unless sput.empty? end - def oh1(title, options = {}) - title = Tty.truncate(title) if $stdout.tty? && !Homebrew.args.verbose? && options.fetch(:truncate, :auto) == :auto + def oh1(title, truncate: :auto) + verbose = if respond_to?(:verbose?) + verbose? + else + Context.current.verbose? + end + + title = Tty.truncate(title) if $stdout.tty? && !verbose && truncate == :auto puts Formatter.headline(title, color: :green) end @@ -369,12 +389,12 @@ module Kernel end def nostdout - if Homebrew.args.verbose? + if verbose? yield else begin out = $stdout.dup - $stdout.reopen("/dev/null") + $stdout.reopen(File::NULL) yield ensure $stdout.reopen(out) diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index 7921136a5c..8f0e7e0e4d 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -5,6 +5,8 @@ require "erb" module Utils module Analytics class << self + include Context + def report(type, metadata = {}) return if not_this_run? return if disabled? @@ -148,7 +150,7 @@ module Utils end def get_analytics(json, args:) - full_analytics = args.analytics? || Homebrew.args.verbose? + full_analytics = args.analytics? || verbose? ohai "Analytics" json["analytics"].each do |category, value| diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb index e28265867e..2318579ee0 100644 --- a/Library/Homebrew/utils/curl.rb +++ b/Library/Homebrew/utils/curl.rb @@ -34,7 +34,7 @@ def curl_args(*extra_args, show_output: false, user_agent: :default) unless show_output args << "--fail" - args << "--progress-bar" unless Homebrew.args.verbose? + args << "--progress-bar" unless Context.current.verbose? args << "--verbose" if Homebrew::EnvConfig.curl_verbose? args << "--silent" unless $stdout.tty? end