Replace Homebrew.args with Context.

This commit is contained in:
Markus Reiter 2020-08-02 14:32:31 +02:00
parent 9d6350037f
commit 490e503b1b
38 changed files with 203 additions and 135 deletions

View File

@ -4,6 +4,8 @@ require "utils/curl"
require "json" require "json"
class Bintray class Bintray
include Context
API_URL = "https://api.bintray.com" API_URL = "https://api.bintray.com"
class Error < RuntimeError class Error < RuntimeError
@ -13,9 +15,8 @@ class Bintray
"#<Bintray: org=#{@bintray_org}>" "#<Bintray: org=#{@bintray_org}>"
end end
def initialize(org: "homebrew", verbose: false) def initialize(org: "homebrew")
@bintray_org = org @bintray_org = org
@verbose = verbose
raise UsageError, "Must set a Bintray organisation!" unless @bintray_org raise UsageError, "Must set a Bintray organisation!" unless @bintray_org
@ -33,8 +34,8 @@ class Bintray
end end
curl(*args, url, curl(*args, url,
show_output: @verbose, show_output: verbose?,
secrets: @bintray_key) secrets: key)
end end
def upload(local_file, repo:, package:, version:, remote_file:, sha256: nil) def upload(local_file, repo:, package:, version:, remote_file:, sha256: nil)

View File

@ -61,6 +61,7 @@ begin
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 Homebrew.args = args
Context.current = args.context
path = PATH.new(ENV["PATH"]) path = PATH.new(ENV["PATH"])
homebrew_path = PATH.new(ENV["HOMEBREW_PATH"]) homebrew_path = PATH.new(ENV["HOMEBREW_PATH"])

View File

@ -143,8 +143,6 @@ class Build
fetch: false, fetch: false,
keep_tmp: args.keep_tmp?, keep_tmp: args.keep_tmp?,
interactive: args.interactive?, interactive: args.interactive?,
debug: args.debug?,
verbose: args.verbose?,
) do ) do
# For head builds, HOMEBREW_FORMULA_PREFIX should include the commit, # For head builds, HOMEBREW_FORMULA_PREFIX should include the commit,
# which is not known until after the formula has been staged. # which is not known until after the formula has been staged.
@ -214,9 +212,8 @@ class Build
end end
begin begin
Homebrew.args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true)
args = Homebrew.install_args.parse args = Homebrew.install_args.parse
Context.current = args.context
error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io) error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io)
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)

View File

@ -35,6 +35,8 @@ require "cask/cmd/internal_stanza"
module Cask module Cask
class Cmd class Cmd
include Context
ALIASES = { ALIASES = {
"ls" => "list", "ls" => "list",
"homepage" => "home", "homepage" => "home",
@ -154,7 +156,7 @@ module Cask
end end
rescue CaskError, MethodDeprecatedError, ArgumentError, OptionParser::InvalidOption => e rescue CaskError, MethodDeprecatedError, ArgumentError, OptionParser::InvalidOption => e
onoe e.message onoe e.message
$stderr.puts e.backtrace if Homebrew.args.debug? $stderr.puts e.backtrace if debug?
exit 1 exit 1
rescue StandardError, ScriptError, NoMemoryError => e rescue StandardError, ScriptError, NoMemoryError => e
onoe e.message onoe e.message

View File

@ -10,15 +10,11 @@
# * sets permissions on executables # * sets permissions on executables
# * removes unresolved symlinks # * removes unresolved symlinks
class Cleaner class Cleaner
extend Predicable include Context
attr_predicate :verbose?, :debug?
# Create a cleaner for the given formula # Create a cleaner for the given formula
def initialize(f, verbose: false, debug: false) def initialize(f)
@f = f @f = f
@verbose = verbose
@debug = debug
end end
# Clean the keg of formula @f # Clean the keg of formula @f

View File

@ -188,6 +188,10 @@ module Homebrew
flag_with_value.delete_prefix(arg_prefix) flag_with_value.delete_prefix(arg_prefix)
end end
def context
Context::ContextStruct.new(debug: debug?, quiet: quiet?, verbose: verbose?)
end
private private
def option_to_name(option) def option_to_name(option)

View File

@ -133,7 +133,7 @@ module Homebrew
already_fetched = f.cached_download.exist? already_fetched = f.cached_download.exist?
begin begin
download = f.fetch(verify_download_integrity: false, verbose: args.verbose?) download = f.fetch(verify_download_integrity: false)
rescue DownloadError rescue DownloadError
retry if retry_fetch?(f, args: args) retry if retry_fetch?(f, args: args)
raise raise
@ -144,6 +144,6 @@ module Homebrew
puts "Downloaded to: #{download}" unless already_fetched puts "Downloaded to: #{download}" unless already_fetched
puts Checksum::TYPES.map { |t| "#{t.to_s.upcase}: #{download.send(t)}" } puts Checksum::TYPES.map { |t| "#{t.to_s.upcase}: #{download.send(t)}" }
f.verify_download_integrity(download, verbose: args.verbose?) f.verify_download_integrity(download)
end end
end end

View File

@ -258,7 +258,7 @@ module Homebrew
Install.perform_preinstall_checks(cc: args.cc) Install.perform_preinstall_checks(cc: args.cc)
formulae.each do |f| formulae.each do |f|
Migrator.migrate_if_needed(f, force: args.force?, verbose: args.verbose?) Migrator.migrate_if_needed(f, force: args.force?)
install_formula(f, args: args) install_formula(f, args: args)
Cleanup.install_formula_clean!(f) Cleanup.install_formula_clean!(f)
end end

View File

@ -33,7 +33,7 @@ module Homebrew
raise "#{rack} is a symlink" if rack.symlink? raise "#{rack} is a symlink" if rack.symlink?
end end
migrator = Migrator.new(f, force: args.force?, verbose: args.verbose?) migrator = Migrator.new(f, force: args.force?)
migrator.migrate migrator.migrate
end end
end end

View File

@ -94,7 +94,7 @@ module Homebrew
if formula_or_cask.is_a?(Formula) if formula_or_cask.is_a?(Formula)
f = formula_or_cask f = formula_or_cask
if verbose? args: args if verbose?
outdated_kegs = f.outdated_kegs(fetch_head: args.fetch_HEAD?) outdated_kegs = f.outdated_kegs(fetch_head: args.fetch_HEAD?)
current_version = if f.alias_changed? current_version = if f.alias_changed?
@ -122,7 +122,7 @@ module Homebrew
else else
c = formula_or_cask 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 end
end end
@ -147,13 +147,13 @@ module Homebrew
else else
c = formula_or_cask c = formula_or_cask
c.outdated_info(args.greedy?, verbose?(args: args), true) c.outdated_info(args.greedy?, verbose?, true)
end end
end end
end end
def verbose?(args:) def verbose?
($stdout.tty? || args.verbose?) && !args.quiet? ($stdout.tty? || super) && !quiet?
end end
def json_version(version) def json_version(version)

View File

@ -67,7 +67,7 @@ module Homebrew
onoe "#{f.full_name} is pinned. You must unpin it to reinstall." onoe "#{f.full_name} is pinned. You must unpin it to reinstall."
next next
end end
Migrator.migrate_if_needed(f, force: args.force?, verbose: args.verbose?) Migrator.migrate_if_needed(f, force: args.force?)
reinstall_formula(f, args: args) reinstall_formula(f, args: args)
Cleanup.install_formula_clean!(f) Cleanup.install_formula_clean!(f)
end end

View File

@ -395,7 +395,7 @@ class Reporter
next next
end end
Migrator.migrate_if_needed(f, force: force, verbose: verbose) Migrator.migrate_if_needed(f, force: force)
end end
end end

View File

@ -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

View File

@ -31,7 +31,7 @@ module Homebrew
bintray_org = args.bintray_org || "homebrew" bintray_org = args.bintray_org || "homebrew"
bintray_repo = args.bintray_repo || "mirror" bintray_repo = args.bintray_repo || "mirror"
bintray = Bintray.new(org: bintray_org, verbose: args.verbose?) bintray = Bintray.new(org: bintray_org)
args.formulae.each do |formula| args.formulae.each do |formula|
mirror_url = bintray.mirror_formula(formula, repo: bintray_repo, publish_package: !args.no_publish?) mirror_url = bintray.mirror_formula(formula, repo: bintray_repo, publish_package: !args.no_publish?)

View File

@ -116,7 +116,7 @@ module Homebrew
# git cherry-pick unfortunately has no quiet option # git cherry-pick unfortunately has no quiet option
ohai "Cherry-picking #{commit_count} commit#{"s" unless commit_count == 1} from ##{pr}" 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" 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 unless result
if args.resolve? if args.resolve?

View File

@ -49,7 +49,7 @@ module Homebrew
args = pr_upload_args.parse args = pr_upload_args.parse
bintray_org = args.bintray_org || "homebrew" bintray_org = args.bintray_org || "homebrew"
bintray = Bintray.new(org: bintray_org, verbose: args.verbose?) bintray = Bintray.new(org: bintray_org)
json_files = Dir["*.json"] json_files = Dir["*.json"]
odie "No JSON files found in the current working directory" if json_files.empty? odie "No JSON files found in the current working directory" if json_files.empty?

View File

@ -57,7 +57,7 @@ module Homebrew
# show messages about tar # show messages about tar
with_env VERBOSE: "1" do with_env VERBOSE: "1" do
f.brew(debug: args.debug?) do f.brew do
f.patch if args.patch? f.patch if args.patch?
cp_r getwd, stage_dir, preserve: true cp_r getwd, stage_dir, preserve: true
end end

View File

@ -13,6 +13,7 @@ require "mechanize/http/content_disposition_parser"
class AbstractDownloadStrategy class AbstractDownloadStrategy
extend Forwardable extend Forwardable
include FileUtils include FileUtils
include Context
module Pourable module Pourable
def stage def stage
@ -21,9 +22,9 @@ class AbstractDownloadStrategy
end end
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) def initialize(url, name, version, **meta)
@url = url @url = url
@ -31,24 +32,18 @@ class AbstractDownloadStrategy
@version = version @version = version
@cache = meta.fetch(:cache, HOMEBREW_CACHE) @cache = meta.fetch(:cache, HOMEBREW_CACHE)
@meta = meta @meta = meta
@shutup = false
extend Pourable if meta[:bottle] extend Pourable if meta[:bottle]
end end
# Download and cache the resource as {#cached_location}. # Download and cache the resource as {#cached_location}.
def fetch; end def fetch; end
# Suppress output
def shutup!
@shutup = true
end
def puts(*args) def puts(*args)
super(*args) unless shutup super(*args) unless quiet?
end end
def ohai(*args) def ohai(*args)
super(*args) unless shutup super(*args) unless quiet?
end end
# Unpack {#cached_location} into the current working directory, and possibly # Unpack {#cached_location} into the current working directory, and possibly
@ -60,7 +55,7 @@ class AbstractDownloadStrategy
ref_type: @ref_type, ref: @ref) ref_type: @ref_type, ref: @ref)
.extract_nestedly(basename: basename, .extract_nestedly(basename: basename,
prioritise_extension: true, prioritise_extension: true,
verbose: Homebrew.args.verbose? && !shutup) verbose: verbose? && !quiet?)
chdir chdir
end end
@ -102,9 +97,9 @@ class AbstractDownloadStrategy
def system_command!(*args, **options) def system_command!(*args, **options)
super( super(
*args, *args,
print_stdout: !shutup, print_stdout: !quiet?,
print_stderr: !shutup, print_stderr: !quiet?,
verbose: Homebrew.args.verbose? && !shutup, verbose: verbose? && !quiet?,
env: env, env: env,
**options, **options,
) )
@ -498,7 +493,7 @@ class NoUnzipCurlDownloadStrategy < CurlDownloadStrategy
def stage def stage
UnpackStrategy::Uncompressed.new(cached_location) UnpackStrategy::Uncompressed.new(cached_location)
.extract(basename: basename, .extract(basename: basename,
verbose: Homebrew.args.verbose? && !shutup) verbose: verbose? && !quiet?)
end end
end end
@ -553,7 +548,7 @@ class SubversionDownloadStrategy < VCSDownloadStrategy
# This saves on bandwidth and will have a similar effect to verifying the # 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. # cache as it will make any changes to get the right revision.
args = [] args = []
args << "--quiet" unless Homebrew.args.verbose? args << "--quiet" unless verbose?
if revision if revision
ohai "Checking out #{@ref}" ohai "Checking out #{@ref}"
@ -897,7 +892,7 @@ class CVSDownloadStrategy < VCSDownloadStrategy
end end
def quiet_flag def quiet_flag
"-Q" unless Homebrew.args.verbose? "-Q" unless verbose?
end end
def clone_repo def clone_repo

View File

@ -419,6 +419,8 @@ require "extend/os/pathname"
# @private # @private
module ObserverPathnameExtension module ObserverPathnameExtension
class << self class << self
include Context
attr_accessor :n, :d attr_accessor :n, :d
def reset_counts! def reset_counts!
@ -437,8 +439,8 @@ module ObserverPathnameExtension
MAXIMUM_VERBOSE_OUTPUT = 100 MAXIMUM_VERBOSE_OUTPUT = 100
def verbose? def verbose?
return Homebrew.args.verbose? unless ENV["CI"] return super unless ENV["CI"]
return false unless Homebrew.args.verbose? return false unless super
if total < MAXIMUM_VERBOSE_OUTPUT if total < MAXIMUM_VERBOSE_OUTPUT
true true

View File

@ -54,6 +54,7 @@ class Formula
include Utils::Inreplace include Utils::Inreplace
include Utils::Shebang include Utils::Shebang
include Utils::Shell include Utils::Shell
include Context
extend Enumerable extend Enumerable
extend Forwardable extend Forwardable
extend Cachable extend Cachable
@ -537,8 +538,10 @@ class Formula
return false unless head&.downloader.is_a?(VCSDownloadStrategy) return false unless head&.downloader.is_a?(VCSDownloadStrategy)
downloader = head.downloader 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 end
# The latest prefix for this formula. Checks for {#head}, then {#devel} # The latest prefix for this formula. Checks for {#head}, then {#devel}
@ -1168,35 +1171,28 @@ class Formula
patchlist.each(&:apply) patchlist.each(&:apply)
end end
# @private
attr_predicate :debug?, :verbose?
# yields |self,staging| with current working directory set to the uncompressed tarball # yields |self,staging| with current working directory set to the uncompressed tarball
# where staging is a Mktemp staging context # where staging is a Mktemp staging context
# @private # @private
def brew(fetch: true, keep_tmp: false, interactive: false, debug: false, verbose: false) def brew(fetch: true, keep_tmp: false, interactive: false)
@debug = debug
@verbose = verbose
@prefix_returns_versioned_prefix = true @prefix_returns_versioned_prefix = true
active_spec.fetch if fetch active_spec.fetch if fetch
stage(interactive: interactive) do |staging| stage(interactive: interactive) do |staging|
staging.retain! if keep_tmp staging.retain! if keep_tmp
prepare_patches prepare_patches
fetch_patches(verbose: verbose) if fetch fetch_patches if fetch
begin begin
yield self, staging yield self, staging
rescue rescue
staging.retain! if interactive || debug staging.retain! if interactive || debug?
raise raise
ensure ensure
cp Dir["config.log", "CMakeCache.txt"], logs cp Dir["config.log", "CMakeCache.txt"], logs
end end
end end
ensure ensure
@debug = nil
@verbose = nil
@prefix_returns_versioned_prefix = false @prefix_returns_versioned_prefix = false
end end
@ -1801,19 +1797,17 @@ class Formula
end end
# @private # @private
def fetch(verify_download_integrity: true, verbose: false) def fetch(verify_download_integrity: true)
active_spec.fetch(verify_download_integrity: verify_download_integrity, verbose: verbose) active_spec.fetch(verify_download_integrity: verify_download_integrity)
end end
# @private # @private
def verify_download_integrity(fn, verbose: false) def verify_download_integrity(fn)
active_spec.verify_download_integrity(fn, verbose: verbose) active_spec.verify_download_integrity(fn)
end end
# @private # @private
def run_test(keep_tmp: false, debug: false, verbose: false) def run_test(keep_tmp: false)
@debug = debug
@verbose = verbose
@prefix_returns_versioned_prefix = true @prefix_returns_versioned_prefix = true
test_env = { test_env = {
@ -1841,13 +1835,11 @@ class Formula
end end
end end
rescue Exception # rubocop:disable Lint/RescueException rescue Exception # rubocop:disable Lint/RescueException
staging.retain! if debug staging.retain! if debug?
raise raise
end end
end end
ensure ensure
@debug = nil
@verbose = nil
@prefix_returns_versioned_prefix = false @prefix_returns_versioned_prefix = false
@testpath = nil @testpath = nil
end end
@ -2103,10 +2095,8 @@ class Formula
ENV.update(removed) ENV.update(removed)
end end
def fetch_patches(verbose: false) def fetch_patches
patchlist.select(&:external?).each do |p| patchlist.select(&:external?).each(&:fetch)
p.fetch(verbose: verbose)
end
end end
private private

View File

@ -2,6 +2,8 @@
module Homebrew module Homebrew
module Assertions module Assertions
include Context
require "test/unit/assertions" require "test/unit/assertions"
include ::Test::Unit::Assertions include ::Test::Unit::Assertions
@ -12,7 +14,7 @@ module Homebrew
assert_equal result, $CHILD_STATUS.exitstatus assert_equal result, $CHILD_STATUS.exitstatus
output output
rescue Test::Unit::AssertionFailedError rescue Test::Unit::AssertionFailedError
puts output if Homebrew.args.verbose? puts output if verbose?
raise raise
end end
@ -28,7 +30,7 @@ module Homebrew
assert_equal result, $CHILD_STATUS.exitstatus unless result.nil? assert_equal result, $CHILD_STATUS.exitstatus unless result.nil?
output output
rescue Test::Unit::AssertionFailedError rescue Test::Unit::AssertionFailedError
puts output if Homebrew.args.verbose? puts output if verbose?
raise raise
end end
end end

View File

@ -952,7 +952,7 @@ class FormulaInstaller
def clean def clean
ohai "Cleaning" if verbose? ohai "Cleaning" if verbose?
Cleaner.new(formula, verbose: verbose?, debug: debug?).clean Cleaner.new(formula).clean
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
opoo "The cleaning step did not complete successfully" opoo "The cleaning step did not complete successfully"
puts "Still, the installation was successful, so we will link it into your prefix" puts "Still, the installation was successful, so we will link it into your prefix"
@ -1027,10 +1027,8 @@ class FormulaInstaller
end end
return if pour_bottle? return if pour_bottle?
formula.fetch_patches(verbose: verbose?) formula.fetch_patches
formula.resources.each do |r| formula.resources.each(&:fetch)
r.fetch(verbose: verbose?)
end
downloader.fetch downloader.fetch
end end

View File

@ -3,6 +3,8 @@
require "formula" require "formula"
class FormulaVersions class FormulaVersions
include Context
IGNORED_EXCEPTIONS = [ IGNORED_EXCEPTIONS = [
ArgumentError, NameError, SyntaxError, TypeError, ArgumentError, NameError, SyntaxError, TypeError,
FormulaSpecificationError, FormulaValidationError, FormulaSpecificationError, FormulaValidationError,
@ -44,7 +46,7 @@ class FormulaVersions
rescue *IGNORED_EXCEPTIONS => e rescue *IGNORED_EXCEPTIONS => e
# We rescue these so that we can skip bad versions and # We rescue these so that we can skip bad versions and
# continue walking the history # 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 rescue FormulaUnavailableError
nil nil
ensure ensure

View File

@ -109,6 +109,8 @@ module Formulary
# A FormulaLoader returns instances of formulae. # A FormulaLoader returns instances of formulae.
# Subclasses implement loaders for particular sources of formulae. # Subclasses implement loaders for particular sources of formulae.
class FormulaLoader class FormulaLoader
include Context
# The formula's name # The formula's name
attr_reader :name attr_reader :name
# The formula's ruby file's path or filename # The formula's ruby file's path or filename
@ -138,7 +140,7 @@ module Formulary
private private
def load_file(flags:) 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? raise FormulaUnavailableError, name unless path.file?
Formulary.load_formula_from_path(name, path, flags: flags) Formulary.load_formula_from_path(name, path, flags: flags)
@ -314,7 +316,7 @@ module Formulary
end end
def klass(flags:) 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)}" namespace = "FormulaNamespace#{Digest::MD5.hexdigest(contents.to_s)}"
Formulary.load_formula(name, path, contents, namespace, flags: flags) Formulary.load_formula(name, path, contents, namespace, flags: flags)
end end

View File

@ -37,7 +37,6 @@ require "config"
require "os" require "os"
require "cli/args" require "cli/args"
require "messages" require "messages"
require "system_command"
HOMEBREW_PRODUCT = ENV["HOMEBREW_PRODUCT"] HOMEBREW_PRODUCT = ENV["HOMEBREW_PRODUCT"]
HOMEBREW_VERSION = ENV["HOMEBREW_VERSION"] HOMEBREW_VERSION = ENV["HOMEBREW_VERSION"]
@ -116,6 +115,7 @@ end.compact.freeze
require "set" require "set"
require "context"
require "extend/pathname" require "extend/pathname"
require "extend/module" 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/hash/deep_merge"
require "active_support/core_ext/file/atomic" require "active_support/core_ext/file/atomic"
require "system_command"
require "exceptions" require "exceptions"
require "utils" require "utils"

View File

@ -5,7 +5,7 @@ require "keg"
require "tab" require "tab"
class Migrator class Migrator
extend Predicable include Context
class MigrationNeededError < RuntimeError class MigrationNeededError < RuntimeError
def initialize(formula) def initialize(formula)
@ -88,8 +88,6 @@ class Migrator
# path to newname keg that will be linked if old_linked_keg isn't nil # path to newname keg that will be linked if old_linked_keg isn't nil
attr_reader :new_linked_keg_record attr_reader :new_linked_keg_record
attr_predicate :verbose?
def self.needs_migration?(formula) def self.needs_migration?(formula)
oldname = formula.oldname oldname = formula.oldname
return false unless oldname return false unless oldname
@ -101,20 +99,18 @@ class Migrator
true true
end end
def self.migrate_if_needed(formula, force:, verbose:) def self.migrate_if_needed(formula, force:)
return unless Migrator.needs_migration?(formula) return unless Migrator.needs_migration?(formula)
begin begin
migrator = Migrator.new(formula, force: force, verbose: verbose) migrator = Migrator.new(formula, force: force)
migrator.migrate migrator.migrate
rescue => e rescue => e
onoe e onoe e
end end
end end
def initialize(formula, force: false, verbose: false) def initialize(formula, force: false)
@verbose = verbose
@oldname = formula.oldname @oldname = formula.oldname
@newname = formula.name @newname = formula.name
raise MigratorNoOldnameError, formula unless oldname raise MigratorNoOldnameError, formula unless oldname
@ -215,7 +211,7 @@ class Migrator
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
onoe "Error occurred while migrating." onoe "Error occurred while migrating."
puts e puts e
puts e.backtrace if Homebrew.args.debug? puts e.backtrace if debug?
puts "Backing up..." puts "Backing up..."
ignore_interrupts { backup_oldname } ignore_interrupts { backup_oldname }
ensure ensure
@ -322,7 +318,7 @@ class Migrator
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
onoe "An unexpected error occurred during linking" onoe "An unexpected error occurred during linking"
puts e puts e
puts e.backtrace if Homebrew.args.debug? puts e.backtrace if debug?
ignore_interrupts { new_keg.unlink(verbose: verbose?) } ignore_interrupts { new_keg.unlink(verbose: verbose?) }
raise raise
end end

View File

@ -5,7 +5,7 @@ class Keg
return if file.dylib_id == id return if file.dylib_id == id
@require_relocation = true @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) MachO::Tools.change_dylib_id(file, id, strict: false)
rescue MachO::MachOError rescue MachO::MachOError
onoe <<~EOS onoe <<~EOS
@ -20,7 +20,7 @@ class Keg
return if old == new return if old == new
@require_relocation = true @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) MachO::Tools.change_install_name(file, old, new, strict: false)
rescue MachO::MachOError rescue MachO::MachOError
onoe <<~EOS onoe <<~EOS

View File

@ -179,12 +179,12 @@ class LegacyPatch < ExternalPatch
resource.download_strategy = CurlDownloadStrategy resource.download_strategy = CurlDownloadStrategy
end end
def fetch(verbose: false) def fetch
clear_cache clear_cache
super super
end end
def verify_download_integrity(_fn, verbose: false) def verify_download_integrity(_fn)
# no-op # no-op
end end

View File

@ -17,7 +17,7 @@ begin
trap("INT", old_trap) trap("INT", old_trap)
formula = args.resolved_formulae.first formula = args.resolved_formulae.first
formula.extend(Debrew::Formula) if Homebrew.args.debug? formula.extend(Debrew::Formula) if args.debug?
formula.run_post_install formula.run_post_install
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
error_pipe.puts e.to_json error_pipe.puts e.to_json

View File

@ -9,6 +9,7 @@ require "mktemp"
# primary formula download, along with other declared resources, are instances # primary formula download, along with other declared resources, are instances
# of this class. # of this class.
class Resource class Resource
include Context
include FileUtils include FileUtils
attr_reader :mirrors, :specs, :using, :source_modified_time, :patches, :owner attr_reader :mirrors, :specs, :using, :source_modified_time, :patches, :owner
@ -74,10 +75,9 @@ class Resource
def stage(target = nil, &block) def stage(target = nil, &block)
raise ArgumentError, "target directory or block is required" if !target && block.blank? raise ArgumentError, "target directory or block is required" if !target && block.blank?
verbose = owner.owner.verbose?
prepare_patches prepare_patches
fetch_patches(skip_downloaded: true, verbose: verbose) fetch_patches(skip_downloaded: true)
fetch(verbose: owner.owner.verbose?) unless downloaded? fetch unless downloaded?
unpack(target, &block) unpack(target, &block)
end end
@ -86,12 +86,10 @@ class Resource
patches.grep(DATAPatch) { |p| p.path = owner.owner.path } patches.grep(DATAPatch) { |p| p.path = owner.owner.path }
end end
def fetch_patches(skip_downloaded: false, verbose: false) def fetch_patches(skip_downloaded: false)
external_patches = patches.select(&:external?) external_patches = patches.select(&:external?)
external_patches.reject!(&:downloaded?) if skip_downloaded external_patches.reject!(&:downloaded?) if skip_downloaded
external_patches.each do |p| external_patches.each(&:fetch)
p.fetch(verbose: verbose)
end
end end
def apply_patches def apply_patches
@ -125,10 +123,10 @@ class Resource
Partial.new(self, files) Partial.new(self, files)
end end
def fetch(verify_download_integrity: true, verbose: false) def fetch(verify_download_integrity: true)
HOMEBREW_CACHE.mkpath HOMEBREW_CACHE.mkpath
fetch_patches(verbose: verbose) fetch_patches
begin begin
downloader.fetch downloader.fetch
@ -137,13 +135,13 @@ class Resource
end end
download = cached_download download = cached_download
verify_download_integrity(download, verbose: verbose) if verify_download_integrity verify_download_integrity(download) if verify_download_integrity
download download
end end
def verify_download_integrity(fn, verbose: false) def verify_download_integrity(fn)
if fn.file? if fn.file?
ohai "Verifying #{fn.basename} checksum" if verbose ohai "Verifying #{fn.basename} checksum" if verbose?
fn.verify_checksum(checksum) fn.verify_checksum(checksum)
end end
rescue ChecksumMissingError rescue ChecksumMissingError

View File

@ -239,7 +239,7 @@ class HeadSoftwareSpec < SoftwareSpec
@resource.version = Version.create("HEAD") @resource.version = Version.create("HEAD")
end end
def verify_download_integrity(_fn, verbose: false) def verify_download_integrity(_fn)
# no-op # no-op
end end
end end

View File

@ -8,7 +8,6 @@ require "shellwords"
require "extend/io" require "extend/io"
require "extend/hash_validator" require "extend/hash_validator"
using HashValidator using HashValidator
require "extend/predicable"
module Kernel module Kernel
def system_command(*args) def system_command(*args)
@ -21,6 +20,7 @@ module Kernel
end end
class SystemCommand class SystemCommand
include Context
extend Predicable extend Predicable
attr_reader :pid attr_reader :pid
@ -34,7 +34,7 @@ class SystemCommand
end end
def run! 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 = [] @output = []
@ -84,7 +84,13 @@ class SystemCommand
attr_reader :executable, :args, :input, :options, :env 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 def env_args
set_variables = env.reject { |_, value| value.nil? } set_variables = env.reject { |_, value| value.nil? }
@ -160,6 +166,8 @@ class SystemCommand
end end
class Result class Result
include Context
attr_accessor :command, :status, :exit_status attr_accessor :command, :status, :exit_status
def initialize(command, output, status, secrets:) def initialize(command, output, status, secrets:)
@ -222,7 +230,7 @@ class SystemCommand
end end
def warn_plist_garbage(garbage) def warn_plist_garbage(garbage)
return unless Homebrew.args.verbose? return unless verbose?
return unless garbage.match?(/\S/) return unless garbage.match?(/\S/)
opoo "Received non-XML output from #{Formatter.identifier(command.first)}:" opoo "Received non-XML output from #{Formatter.identifier(command.first)}:"

View File

@ -16,9 +16,9 @@ require "dev-cmd/test"
TEST_TIMEOUT_SECONDS = 5 * 60 TEST_TIMEOUT_SECONDS = 5 * 60
begin begin
Homebrew.args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true)
args = Homebrew.test_args.parse args = Homebrew.test_args.parse
Context.current = args.context
error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io) error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io)
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
@ -34,9 +34,7 @@ begin
# tests can also return false to indicate failure # tests can also return false to indicate failure
Timeout.timeout TEST_TIMEOUT_SECONDS do Timeout.timeout TEST_TIMEOUT_SECONDS do
if formula.run_test(keep_tmp: args.keep_tmp?, debug: args.debug?, verbose: args.verbose?) == false raise "test returned false" if formula.run_test(keep_tmp: args.keep_tmp?) == false
raise "test returned false"
end
end end
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
error_pipe.puts e.to_json error_pipe.puts e.to_json

View File

@ -120,7 +120,7 @@ describe SystemCommand::Result do
context "when verbose" do context "when verbose" do
before 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 end
it "warns about garbage" do it "warns about garbage" do
@ -144,7 +144,7 @@ describe SystemCommand::Result do
context "when verbose" do context "when verbose" do
before 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 end
it "warns about garbage" do it "warns about garbage" do

View File

@ -26,7 +26,7 @@ module Homebrew
end end
formulae_to_install.each do |f| formulae_to_install.each do |f|
Migrator.migrate_if_needed(f, force: args.force?, verbose: args.verbose?) Migrator.migrate_if_needed(f, force: args.force?)
begin begin
upgrade_formula(f, args: args) upgrade_formula(f, args: args)
Cleanup.install_formula_clean!(f) Cleanup.install_formula_clean!(f)

View File

@ -16,6 +16,8 @@ require "tap_constants"
require "time" require "time"
module Homebrew module Homebrew
extend Context
module_function module_function
def _system(cmd, *args, **options) def _system(cmd, *args, **options)
@ -34,7 +36,7 @@ module Homebrew
end end
def system(cmd, *args, **options) def system(cmd, *args, **options)
if Homebrew.args.verbose? if verbose?
puts "#{cmd} #{args * " "}".gsub(RUBY_PATH, "ruby") puts "#{cmd} #{args * " "}".gsub(RUBY_PATH, "ruby")
.gsub($LOAD_PATH.join(File::PATH_SEPARATOR).to_s, "$LOAD_PATH") .gsub($LOAD_PATH.join(File::PATH_SEPARATOR).to_s, "$LOAD_PATH")
end end
@ -89,7 +91,7 @@ module Kernel
verbose = if respond_to?(:verbose?) verbose = if respond_to?(:verbose?)
verbose? verbose?
else else
Homebrew.args.verbose? Context.current.verbose?
end end
title = Tty.truncate(title) if $stdout.tty? && !verbose title = Tty.truncate(title) if $stdout.tty? && !verbose
@ -102,10 +104,10 @@ module Kernel
end end
def odebug(title, *sput, always_display: false) def odebug(title, *sput, always_display: false)
debug = if respond_to?(:debug?) debug = if respond_to?(:debug)
debug? debug?
else else
Homebrew.args.debug? Context.current.debug?
end end
return unless debug || always_display return unless debug || always_display
@ -118,7 +120,7 @@ module Kernel
verbose = if respond_to?(:verbose?) verbose = if respond_to?(:verbose?)
verbose? verbose?
else else
Homebrew.args.verbose? Context.current.verbose?
end end
title = Tty.truncate(title) if $stdout.tty? && !verbose && truncate == :auto title = Tty.truncate(title) if $stdout.tty? && !verbose && truncate == :auto
@ -387,12 +389,12 @@ module Kernel
end end
def nostdout def nostdout
if Homebrew.args.verbose? if verbose?
yield yield
else else
begin begin
out = $stdout.dup out = $stdout.dup
$stdout.reopen("/dev/null") $stdout.reopen(File::NULL)
yield yield
ensure ensure
$stdout.reopen(out) $stdout.reopen(out)

View File

@ -5,6 +5,8 @@ require "erb"
module Utils module Utils
module Analytics module Analytics
class << self class << self
include Context
def report(type, metadata = {}) def report(type, metadata = {})
return if not_this_run? return if not_this_run?
return if disabled? return if disabled?
@ -148,7 +150,7 @@ module Utils
end end
def get_analytics(json, args:) def get_analytics(json, args:)
full_analytics = args.analytics? || Homebrew.args.verbose? full_analytics = args.analytics? || verbose?
ohai "Analytics" ohai "Analytics"
json["analytics"].each do |category, value| json["analytics"].each do |category, value|

View File

@ -34,7 +34,7 @@ def curl_args(*extra_args, show_output: false, user_agent: :default)
unless show_output unless show_output
args << "--fail" args << "--fail"
args << "--progress-bar" unless Homebrew.args.verbose? args << "--progress-bar" unless Context.current.verbose?
args << "--verbose" if Homebrew::EnvConfig.curl_verbose? args << "--verbose" if Homebrew::EnvConfig.curl_verbose?
args << "--silent" unless $stdout.tty? args << "--silent" unless $stdout.tty?
end end