Merge pull request #7120 from MikeMcQuaid/args-tweaks

cli/parser: add and use more helpers.
This commit is contained in:
Mike McQuaid 2020-03-05 12:21:24 +00:00 committed by GitHub
commit 67d7697165
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 250 additions and 238 deletions

View File

@ -64,6 +64,10 @@ module Homebrew
remaining
end
def no_named?
named.blank?
end
def formulae
require "formula"
@formulae ||= (downcased_unique_named - casks).map do |name|
@ -142,7 +146,7 @@ module Homebrew
def downcased_unique_named
# Only lowercase names, not paths, bottle filenames or URLs
arguments = if args_parsed
remaining
named
else
cmdline_args.reject { |arg| arg.start_with?("-") }
end

View File

@ -12,8 +12,8 @@ module Homebrew
class Parser
attr_reader :processed_options, :hide_from_man_page
def self.parse(args = ARGV, &block)
new(args, &block).parse(args)
def self.parse(args = ARGV, allow_no_named_args: false, &block)
new(args, &block).parse(args, allow_no_named_args: allow_no_named_args)
end
def self.from_cmd_path(cmd_path)
@ -47,6 +47,8 @@ module Homebrew
@switch_sources = {}
@processed_options = []
@max_named_args = nil
@min_named_args = nil
@min_named_type = nil
@hide_from_man_page = false
instance_eval(&block)
post_initialize
@ -146,18 +148,18 @@ module Homebrew
@parser.to_s
end
def parse(cmdline_args = ARGV)
def parse(cmdline_args = ARGV, allow_no_named_args: false)
raise "Arguments were already parsed!" if @args_parsed
begin
remaining_args = @parser.parse(cmdline_args)
named_args = @parser.parse(cmdline_args)
rescue OptionParser::InvalidOption => e
$stderr.puts generate_help_text
raise e
end
check_constraint_violations
check_named_args(remaining_args)
@args[:remaining] = remaining_args
check_named_args(named_args, allow_no_named_args: allow_no_named_args)
@args[:remaining] = named_args
@args.freeze_processed_options!(@processed_options)
Homebrew.args = @args
cmdline_args.freeze
@ -198,9 +200,35 @@ module Homebrew
end
def max_named(count)
raise TypeError, "Unsupported type #{count.class.name} for max_named" unless count.is_a?(Integer)
@max_named_args = count
end
def min_named(count_or_type)
if count_or_type.is_a?(Integer)
@min_named_args = count_or_type
@min_named_type = nil
elsif count_or_type.is_a?(Symbol)
@min_named_args = 1
@min_named_type = count_or_type
else
raise TypeError, "Unsupported type #{count_or_type.class.name} for min_named"
end
end
def named(count_or_type)
if count_or_type.is_a?(Integer)
@max_named_args = @min_named_args = count_or_type
@min_named_type = nil
elsif count_or_type.is_a?(Symbol)
@max_named_args = @min_named_args = 1
@min_named_type = count_or_type
else
raise TypeError, "Unsupported type #{count_or_type.class.name} for named"
end
end
def hide_from_man_page!
@hide_from_man_page = true
end
@ -292,8 +320,17 @@ module Homebrew
check_constraints
end
def check_named_args(args)
raise NamedArgumentsError, @max_named_args if !@max_named_args.nil? && args.size > @max_named_args
def check_named_args(args, allow_no_named_args: false)
min_exception = case @min_named_type
when :formula
FormulaUnspecifiedError.new
when :keg
KegUnspecifiedError.new
else
MinNamedArgumentsError.new(@min_named_args)
end
raise min_exception if !allow_no_named_args && !@min_named_args.nil? && args.size < @min_named_args
raise MaxNamedArgumentsError, @max_named_args if !@max_named_args.nil? && args.size > @max_named_args
end
def process_option(*args)
@ -327,15 +364,29 @@ module Homebrew
end
end
class NamedArgumentsError < UsageError
class MaxNamedArgumentsError < UsageError
def initialize(maximum)
message = case maximum
when 0
"This command does not take named arguments."
"this command does not take named arguments"
when 1
"This command does not take multiple named arguments."
"this command does not take multiple named arguments"
else
"This command does not take more than #{maximum} named arguments."
"this command does not take more than #{maximum} named arguments"
end
super message
end
end
class MinNamedArgumentsError < UsageError
def initialize(minimum)
message = case minimum
when 1
"this command requires a named argument"
when 2
"this command requires multiple named arguments"
else
"this command requires at least #{minimum} named arguments"
end
super message
end

View File

@ -26,10 +26,10 @@ module Homebrew
def __cache
__cache_args.parse
if ARGV.named.empty?
if args.no_named?
puts HOMEBREW_CACHE
else
Homebrew.args.formulae.each do |f|
args.formulae.each do |f|
if Fetch.fetch_bottle?(f)
puts f.bottle.cached_download
else

View File

@ -22,10 +22,10 @@ module Homebrew
def __cellar
__cellar_args.parse
if Homebrew.args.named.blank?
if args.no_named?
puts HOMEBREW_CELLAR
else
puts Homebrew.args.resolved_formulae.map(&:rack)
puts args.resolved_formulae.map(&:rack)
end
end
end

View File

@ -30,9 +30,8 @@ module Homebrew
__env_args.parse
ENV.activate_extensions!
ENV.deps = Homebrew.args.formulae if superenv?
ENV.deps = args.formulae if superenv?
ENV.setup_build_environment
ENV.universal_binary if ARGV.build_universal?
shell = if args.plain?
nil

View File

@ -22,10 +22,10 @@ module Homebrew
def __prefix
__prefix_args.parse
if Homebrew.args.named.blank?
if args.no_named?
puts HOMEBREW_PREFIX
else
puts Homebrew.args.resolved_formulae.map { |f|
puts args.resolved_formulae.map { |f|
f.opt_prefix.exist? ? f.opt_prefix : f.installed_prefix
}
end

View File

@ -20,10 +20,10 @@ module Homebrew
def __repository
__repository_args.parse
if ARGV.named.empty?
if args.no_named?
puts HOMEBREW_REPOSITORY
else
puts ARGV.named.map { |tap| Tap.fetch(tap).path }
puts args.named.map { |tap| Tap.fetch(tap).path }
end
end
end

View File

@ -26,7 +26,7 @@ module Homebrew
def analytics
analytics_args.parse
case args.remaining.first
case args.named.first
when nil, "state"
if Utils::Analytics.disabled?
puts "Analytics are disabled."
@ -41,7 +41,7 @@ module Homebrew
when "regenerate-uuid"
Utils::Analytics.regenerate_uuid!
else
raise UsageError, "Unknown subcommand."
raise UsageError, "unknown subcommand"
end
end
end

View File

@ -12,17 +12,12 @@ module Homebrew
Display the source of <formula>.
EOS
max_named 1
named :formula
end
end
def cat
cat_args.parse
# do not "fix" this to support multiple arguments, the output would be
# unparsable; if the user wants to cat multiple formula they can call
# `brew cat` multiple times.
formulae = Homebrew.args.formulae
raise FormulaUnspecifiedError if formulae.empty?
cd HOMEBREW_REPOSITORY
pager = if ENV["HOMEBREW_BAT"].nil?
@ -30,6 +25,6 @@ module Homebrew
else
"#{HOMEBREW_PREFIX}/bin/bat"
end
safe_system pager, formulae.first.path, *Homebrew.args.passthrough
safe_system pager, args.formulae.first.path, *args.passthrough
end
end

View File

@ -33,7 +33,7 @@ module Homebrew
def cleanup
cleanup_args.parse
cleanup = Cleanup.new(*args.remaining, dry_run: args.dry_run?, scrub: args.s?, days: args.prune&.to_i)
cleanup = Cleanup.new(*args.named, dry_run: args.dry_run?, scrub: args.s?, days: args.prune&.to_i)
if args.prune_prefix?
cleanup.prune_prefix_symlinks_and_directories
return

View File

@ -15,15 +15,14 @@ module Homebrew
EOS
switch :verbose
switch :debug
min_named 1
end
end
def command
command_args.parse
raise UsageError, "This command requires a command argument" if args.remaining.empty?
args.remaining.each do |cmd|
args.named.each do |cmd|
path = Commands.path(cmd)
odie "Unknown command: #{cmd}" unless path
puts path

View File

@ -62,7 +62,7 @@ module Homebrew
Formulary.enable_factory_cache!
recursive = !args.send("1?")
installed = args.installed? || ARGV.formulae.all?(&:opt_or_installed_prefix_keg)
installed = args.installed? || args.formulae.all?(&:opt_or_installed_prefix_keg)
@use_runtime_dependencies = installed && recursive &&
!args.include_build? &&
@ -74,27 +74,27 @@ module Homebrew
if args.installed?
puts_deps_tree Formula.installed.sort, recursive
else
raise FormulaUnspecifiedError if Homebrew.args.remaining.empty?
raise FormulaUnspecifiedError if args.no_named?
puts_deps_tree Homebrew.args.formulae, recursive
puts_deps_tree args.formulae, recursive
end
return
elsif args.all?
puts_deps Formula.sort, recursive
return
elsif !Homebrew.args.remaining.empty? && args.for_each?
puts_deps Homebrew.args.formulae, recursive
elsif !args.no_named? && args.for_each?
puts_deps args.formulae, recursive
return
end
if Homebrew.args.remaining.empty?
if args.no_named?
raise FormulaUnspecifiedError unless args.installed?
puts_deps Formula.installed.sort, recursive
return
end
all_deps = deps_for_formulae(Homebrew.args.formulae, recursive, &(args.union? ? :| : :&))
all_deps = deps_for_formulae(args.formulae, recursive, &(args.union? ? :| : :&))
all_deps = condense_requirements(all_deps)
all_deps.select!(&:installed?) if args.installed?
all_deps.map!(&method(:dep_display_name))

View File

@ -40,16 +40,16 @@ module Homebrew
search_type << :either if args.search
search_type << :name if args.name
search_type << :desc if args.description
odie "You must provide a search term." if search_type.present? && ARGV.named.empty?
odie "You must provide a search term." if search_type.present? && args.no_named?
results = if search_type.empty?
raise FormulaUnspecifiedError if ARGV.named.empty?
raise FormulaUnspecifiedError if args.no_named?
desc = {}
Homebrew.args.formulae.each { |f| desc[f.full_name] = f.desc }
args.formulae.each { |f| desc[f.full_name] = f.desc }
Descriptions.new(desc)
else
arg = ARGV.named.join(" ")
arg = args.named.join(" ")
string_or_regex = query_regexp(arg)
CacheStoreDatabase.use(:descriptions) do |db|
cache_store = DescriptionCacheStore.new(db)

View File

@ -39,14 +39,14 @@ module Homebrew
exit
end
if ARGV.named.empty?
if args.no_named?
slow_checks = %w[
check_for_broken_symlinks
check_missing_deps
]
methods = (checks.all.sort - slow_checks) + slow_checks
else
methods = ARGV.named
methods = args.named
end
first_warning = true

View File

@ -39,23 +39,22 @@ module Homebrew
switch :debug
conflicts "--devel", "--HEAD"
conflicts "--build-from-source", "--build-bottle", "--force-bottle"
min_named :formula
end
end
def fetch
fetch_args.parse
raise FormulaUnspecifiedError if ARGV.named.empty?
if args.deps?
bucket = []
Homebrew.args.formulae.each do |f|
args.formulae.each do |f|
bucket << f
bucket.concat f.recursive_dependencies.map(&:to_formula)
end
bucket.uniq!
else
bucket = Homebrew.args.formulae
bucket = args.formulae
end
puts "Fetching: #{bucket * ", "}" if bucket.size > 1

View File

@ -142,10 +142,10 @@ module Homebrew
def gist_logs
gist_logs_args.parse
raise FormulaUnspecifiedError if Homebrew.args.resolved_formulae.length != 1
raise FormulaUnspecifiedError if args.resolved_formulae.length != 1
Install.perform_preinstall_checks(all_fatal: true)
Install.perform_build_from_source_checks(all_fatal: true)
gistify_logs(Homebrew.args.resolved_formulae.first)
gistify_logs(args.resolved_formulae.first)
end
end

View File

@ -20,10 +20,10 @@ module Homebrew
def home
home_args.parse
if args.remaining.empty?
if args.no_named?
exec_browser HOMEBREW_WWW
else
exec_browser(*Homebrew.args.formulae.map(&:homepage))
exec_browser(*args.formulae.map(&:homepage))
end
end
end

View File

@ -67,7 +67,7 @@ module Homebrew
end
if args.category.present?
if Homebrew.args.named.present? && !VALID_FORMULA_CATEGORIES.include?(args.category)
if args.named.present? && !VALID_FORMULA_CATEGORIES.include?(args.category)
raise UsageError, "--category must be one of #{VALID_FORMULA_CATEGORIES.join(", ")} when querying formulae"
end
@ -77,23 +77,24 @@ module Homebrew
end
if args.json
raise UsageError, "Invalid JSON version: #{args.json}" unless ["v1", true].include? args.json
if !(args.all? || args.installed?) && Homebrew.args.named.blank?
raise UsageError, "This command's option requires a formula argument"
raise UsageError, "invalid JSON version: #{args.json}" unless ["v1", true].include? args.json
if !(args.all? || args.installed?) && args.no_named?
raise FormulaUnspecifiedError if args.no_named?
end
print_json
elsif args.github?
raise UsageError, "This command's option requires a formula argument" if Homebrew.args.named.blank?
raise FormulaUnspecifiedError if args.no_named?
exec_browser(*Homebrew.args.formulae.map { |f| github_info(f) })
exec_browser(*args.formulae.map { |f| github_info(f) })
else
print_info
end
end
def print_info
if Homebrew.args.named.blank?
if args.no_named?
if args.analytics?
Utils::Analytics.output
elsif HOMEBREW_CELLAR.exist?
@ -101,7 +102,7 @@ module Homebrew
puts "#{count} #{"keg".pluralize(count)}, #{HOMEBREW_CELLAR.dup.abv}"
end
else
Homebrew.args.named.each_with_index do |f, i|
args.named.each_with_index do |f, i|
puts unless i.zero?
begin
formula = if f.include?("/") || File.exist?(f)
@ -135,7 +136,7 @@ module Homebrew
elsif args.installed?
Formula.installed.sort
else
Homebrew.args.formulae
args.formulae
end
json = ff.map(&:to_hash)
puts JSON.generate(json)

View File

@ -88,13 +88,14 @@ module Homebrew
conflicts "--devel", "--HEAD"
conflicts "--build-from-source", "--build-bottle", "--force-bottle"
formula_options
min_named :formula
end
end
def install
install_args.parse
Homebrew.args.named.each do |name|
args.named.each do |name|
next if File.exist?(name)
next if name !~ HOMEBREW_TAP_FORMULA_REGEX && name !~ HOMEBREW_CASK_TAP_CASK_REGEX
@ -102,8 +103,6 @@ module Homebrew
tap.install unless tap.installed?
end
raise FormulaUnspecifiedError if args.remaining.empty?
if args.ignore_dependencies?
opoo <<~EOS
#{Tty.bold}--ignore-dependencies is an unsupported Homebrew developer flag!#{Tty.reset}
@ -131,9 +130,9 @@ module Homebrew
# developer tools are available, we need to stop them early on
FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?
Homebrew.args.formulae.each do |f|
args.formulae.each do |f|
# head-only without --HEAD is an error
if !Homebrew.args.HEAD? && f.stable.nil? && f.devel.nil?
if !args.HEAD? && f.stable.nil? && f.devel.nil?
raise <<~EOS
#{f.full_name} is a head-only formula
Install with `brew install --HEAD #{f.full_name}`

View File

@ -25,20 +25,19 @@ module Homebrew
description: "Allow keg-only formulae to be linked."
switch :verbose
switch :debug
min_named :keg
end
end
def link
link_args.parse
raise KegUnspecifiedError if ARGV.named.empty?
mode = OpenStruct.new
mode.overwrite = true if args.overwrite?
mode.dry_run = true if args.dry_run?
Homebrew.args.kegs.each do |keg|
args.kegs.each do |keg|
keg_only = Formulary.keg_only?(keg.rack)
if keg.linked?

View File

@ -55,14 +55,14 @@ module Homebrew
# Unbrewed uses the PREFIX, which will exist
# Things below use the CELLAR, which doesn't until the first formula is installed.
unless HOMEBREW_CELLAR.exist?
raise NoSuchKegError, Hombrew.args.named.first if Homebrew.args.named.present?
raise NoSuchKegError, Hombrew.args.named.first if args.named.present?
return
end
if args.pinned? || args.versions?
filtered_list
elsif Homebrew.args.named.blank?
elsif args.no_named?
if args.full_name?
full_names = Formula.installed.map(&:full_name).sort(&tap_and_name_comparison)
return if full_names.empty?
@ -70,12 +70,12 @@ module Homebrew
puts Formatter.columns(full_names)
else
ENV["CLICOLOR"] = nil
safe_system "ls", *Homebrew.args.passthrough << HOMEBREW_CELLAR
safe_system "ls", *args.passthrough << HOMEBREW_CELLAR
end
elsif args.verbose? || !$stdout.tty?
system_command! "find", args: Homebrew.args.kegs.map(&:to_s) + %w[-not -type d -print], print_stdout: true
system_command! "find", args: args.kegs.map(&:to_s) + %w[-not -type d -print], print_stdout: true
else
Homebrew.args.kegs.each { |keg| PrettyListing.new keg }
args.kegs.each { |keg| PrettyListing.new keg }
end
end
@ -123,10 +123,10 @@ module Homebrew
end
def filtered_list
names = if Homebrew.args.named.blank?
names = if args.no_named?
Formula.racks
else
racks = Homebrew.args.named.map { |n| Formulary.to_rack(n) }
racks = args.named.map { |n| Formulary.to_rack(n) }
racks.select do |rack|
Homebrew.failed = true unless rack.exist?
rack.exist?

View File

@ -33,10 +33,10 @@ module Homebrew
# user path, too.
ENV["PATH"] = ENV["HOMEBREW_PATH"]
if ARGV.named.empty?
if args.no_named?
git_log HOMEBREW_REPOSITORY
else
path = Formulary.path(ARGV.named.first)
path = Formulary.path(args.named.first)
tap = Tap.from_path(path)
git_log path.dirname, path, tap
end
@ -62,8 +62,8 @@ module Homebrew
git -C "#{git_cd}" fetch --unshallow
EOS
end
args = Homebrew.args.options_only
args += ["--follow", "--", path] unless path.nil?
system "git", "log", *args
system_args = args.options_only
system_args += ["--follow", "--", path] if path.present?
system "git", "log", *system_args
end
end

View File

@ -19,15 +19,14 @@ module Homebrew
"the same taps and migrate them anyway."
switch :verbose
switch :debug
min_named :formula
end
end
def migrate
migrate_args.parse
raise FormulaUnspecifiedError if Homebrew.args.named.blank?
Homebrew.args.resolved_formulae.each do |f|
args.resolved_formulae.each do |f|
if f.oldname
unless (rack = HOMEBREW_CELLAR/f.oldname).exist? && !rack.subdirs.empty?
raise NoSuchKegError, f.oldname

View File

@ -30,10 +30,10 @@ module Homebrew
return unless HOMEBREW_CELLAR.exist?
ff = if Homebrew.args.named.blank?
ff = if args.no_named?
Formula.installed.sort
else
Homebrew.args.resolved_formulae.sort
args.resolved_formulae.sort
end
ff.each do |f|

View File

@ -32,10 +32,10 @@ module Homebrew
puts_options Formula.to_a.sort
elsif args.installed?
puts_options Formula.installed.sort
elsif args.no_named?
raise FormulaUnspecifiedError
else
raise FormulaUnspecifiedError if args.remaining.empty?
puts_options Homebrew.args.formulae
puts_options args.formulae
end
end

View File

@ -35,19 +35,19 @@ module Homebrew
def outdated
outdated_args.parse
formulae = if Homebrew.args.resolved_formulae.blank?
formulae = if args.resolved_formulae.blank?
Formula.installed
else
Homebrew.args.resolved_formulae
args.resolved_formulae
end
if args.json
raise UsageError, "Invalid JSON version: #{args.json}" unless ["v1", true].include? args.json
raise UsageError, "invalid JSON version: #{args.json}" unless ["v1", true].include? args.json
outdated = print_outdated_json(formulae)
else
outdated = print_outdated(formulae)
end
Homebrew.failed = Homebrew.args.resolved_formulae.present? && !outdated.empty?
Homebrew.failed = args.resolved_formulae.present? && !outdated.empty?
end
def print_outdated(formulae)

View File

@ -15,15 +15,14 @@ module Homebrew
issuing the `brew upgrade` <formula> command. See also `unpin`.
EOS
switch :debug
min_named :formula
end
end
def pin
pin_args.parse
raise FormulaUnspecifiedError if args.remaining.empty?
Homebrew.args.resolved_formulae.each do |f|
args.resolved_formulae.each do |f|
if f.pinned?
opoo "#{f.name} already pinned"
elsif !f.pinnable?

View File

@ -17,15 +17,14 @@ module Homebrew
switch :force
switch :verbose
switch :debug
min_named :keg
end
end
def postinstall
postinstall_args.parse
raise KegUnspecifiedError if args.remaining.empty?
Homebrew.args.resolved_formulae.each do |f|
args.resolved_formulae.each do |f|
ohai "Postinstalling #{f}"
fi = FormulaInstaller.new(f)
fi.post_install

View File

@ -36,10 +36,10 @@ module Homebrew
end
options = { aliases: args.aliases? }
taps = if ARGV.named.empty?
taps = if args.no_named?
Tap
else
ARGV.named.map { |t| Tap.fetch(t) }
args.named.map { |t| Tap.fetch(t) }
end
taps.each do |tap|
Homebrew.failed = true unless Readall.valid_tap?(tap, options)

View File

@ -45,19 +45,18 @@ module Homebrew
description: "Print install times for each formula at the end of the run."
conflicts "--build-from-source", "--force-bottle"
formula_options
min_named :formula
end
end
def reinstall
reinstall_args.parse
raise FormulaUnspecifiedError if args.remaining.empty?
FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?
Install.perform_preinstall_checks
Homebrew.args.resolved_formulae.each do |f|
args.resolved_formulae.each do |f|
if f.pinned?
onoe "#{f.full_name} is pinned. You must unpin it to reinstall."
next

View File

@ -62,13 +62,13 @@ module Homebrew
if package_manager = PACKAGE_MANAGERS.find { |name,| args[:"#{name}?"] }
_, url = package_manager
exec_browser url.call(URI.encode_www_form_component(args.remaining.join(" ")))
exec_browser url.call(URI.encode_www_form_component(args.named.join(" ")))
return
end
if args.remaining.empty?
if args.no_named?
if args.casks?
raise UsageError, "specifying both --formulae and --casks requires an argument!" if args.formulae?
raise UsageError, "specifying both --formulae and --casks requires <text>" if args.formulae?
puts Formatter.columns(Cask::Cask.to_a.map(&:full_name).sort)
else
@ -78,7 +78,7 @@ module Homebrew
return
end
query = args.remaining.join(" ")
query = args.named.join(" ")
string_or_regex = query_regexp(query)
if args.desc?
@ -125,11 +125,11 @@ module Homebrew
end
return unless $stdout.tty?
return if args.remaining.empty?
return if args.no_named?
metacharacters = %w[\\ | ( ) [ ] { } ^ $ * + ?].freeze
return unless metacharacters.any? do |char|
args.remaining.any? do |arg|
args.named.any? do |arg|
arg.include?(char) && !arg.start_with?("/")
end
end

View File

@ -38,14 +38,14 @@ module Homebrew
def style
style_args.parse
target = if Homebrew.args.named.blank?
target = if args.no_named?
nil
elsif Homebrew.args.named.any? { |file| File.exist? file }
Homebrew.args.named
elsif Homebrew.args.named.any? { |tap| tap.count("/") == 1 }
Homebrew.args.named.map { |tap| Tap.fetch(tap).path }
elsif args.named.any? { |file| File.exist? file }
args.named
elsif args.named.any? { |tap| tap.count("/") == 1 }
args.named.map { |tap| Tap.fetch(tap).path }
else
Homebrew.args.formulae.map(&:path)
args.formulae.map(&:path)
end
only_cops = args.only_cops

View File

@ -16,16 +16,14 @@ module Homebrew
EOS
switch :verbose
switch :debug
max_named 2
named 2
end
end
def switch
switch_args.parse
raise FormulaUnspecifiedError if args.remaining.empty?
name = args.remaining.first
name = args.named.first
rack = Formulary.to_rack(name)
odie "#{name} not found in the Cellar." unless rack.directory?
@ -34,8 +32,7 @@ module Homebrew
.map { |d| Keg.new(d).version }
.sort
.join(", ")
version = args.remaining.second
raise UsageError, "Specify one of #{name}'s installed versions: #{versions}" unless version
version = args.named.second
odie <<~EOS unless (rack/version).directory?
#{name} does not have a version \"#{version}\" in the Cellar.

View File

@ -30,13 +30,13 @@ module Homebrew
if args.installed?
taps = Tap
else
taps = Homebrew.args.named.sort.map do |name|
taps = args.named.sort.map do |name|
Tap.fetch(name)
end
end
if args.json
raise UsageError, "Invalid JSON version: #{args.json}" unless ["v1", true].include? args.json
raise UsageError, "invalid JSON version: #{args.json}" unless ["v1", true].include? args.json
print_tap_json(taps.sort_by(&:to_s))
else

View File

@ -48,14 +48,14 @@ module Homebrew
Tap.each(&:link_completions_and_manpages)
elsif args.list_pinned?
puts Tap.select(&:pinned?).map(&:name)
elsif ARGV.named.empty?
elsif args.no_named?
puts Tap.names
else
tap = Tap.fetch(ARGV.named.first)
tap = Tap.fetch(args.named.first)
begin
tap.install clone_target: ARGV.named.second,
tap.install clone_target: args.named.second,
force_auto_update: force_auto_update?,
quiet: Homebrew.args.quiet?
quiet: args.quiet?
rescue TapRemoteMismatchError => e
odie e
rescue TapAlreadyTappedError

View File

@ -22,23 +22,22 @@ module Homebrew
description: "Don't fail uninstall, even if <formula> is a dependency of any installed "\
"formulae."
switch :debug
min_named :formula
end
end
def uninstall
uninstall_args.parse
raise KegUnspecifiedError if args.remaining.empty?
kegs_by_rack = if args.force?
Hash[ARGV.named.map do |name|
Hash[args.named.map do |name|
rack = Formulary.to_rack(name)
next unless rack.directory?
[rack, rack.subdirs.map { |d| Keg.new(d) }]
end]
else
Homebrew.args.kegs.group_by(&:rack)
args.kegs.group_by(&:rack)
end
handle_unsatisfied_dependents(kegs_by_rack)
@ -131,7 +130,7 @@ module Homebrew
protected
def sample_command
"brew uninstall --ignore-dependencies #{ARGV.named.join(" ")}"
"brew uninstall --ignore-dependencies #{Homebrew.args.named.join(" ")}"
end
def are_required_by_deps

View File

@ -20,18 +20,17 @@ module Homebrew
"deleting any files."
switch :verbose
switch :debug
min_named :keg
end
end
def unlink
unlink_args.parse
raise KegUnspecifiedError if args.remaining.empty?
mode = OpenStruct.new
mode.dry_run = true if args.dry_run?
Homebrew.args.kegs.each do |keg|
args.kegs.each do |keg|
if mode.dry_run
puts "Would remove:"
keg.unlink(mode)

View File

@ -32,7 +32,7 @@ module Homebrew
def unpack
unpack_args.parse
formulae = Homebrew.args.formulae
formulae = args.formulae
raise FormulaUnspecifiedError if formulae.empty?
if dir = args.destdir

View File

@ -22,9 +22,9 @@ module Homebrew
def unpin
unpin_args.parse
raise FormulaUnspecifiedError if args.remaining.empty?
raise FormulaUnspecifiedError if args.no_named?
Homebrew.args.resolved_formulae.each do |f|
args.resolved_formulae.each do |f|
if f.pinned?
f.unpin
elsif !f.pinnable?

View File

@ -13,15 +13,14 @@ module Homebrew
Remove a tapped formula repository.
EOS
switch :debug
min_named 1
end
end
def untap
untap_args.parse
raise UsageError, "This command requires a tap argument from `brew tap`'s list" if args.remaining.empty?
ARGV.named.each do |tapname|
args.named.each do |tapname|
tap = Tap.fetch(tapname)
odie "Untapping #{tap} is not allowed" if tap.core_tap?

View File

@ -13,7 +13,7 @@ module Homebrew
def update_preinstall_header
@update_preinstall_header ||= begin
ohai "Auto-updated Homebrew!" if ARGV.include?("--preinstall")
ohai "Auto-updated Homebrew!" if args.preinstall?
true
end
end
@ -109,7 +109,7 @@ module Homebrew
end
if !updated
puts "Already up-to-date." if !ARGV.include?("--preinstall") && !ENV["HOMEBREW_UPDATE_FAILED"]
puts "Already up-to-date." if !args.preinstall? && !ENV["HOMEBREW_UPDATE_FAILED"]
else
if hub.empty?
puts "No changes to formulae."
@ -122,7 +122,7 @@ module Homebrew
.update_from_report!(hub)
end
end
puts if ARGV.include?("--preinstall")
puts if args.preinstall?
end
link_completions_manpages_and_docs

View File

@ -65,18 +65,18 @@ module Homebrew
Install.perform_preinstall_checks
if Homebrew.args.named.blank?
if args.no_named?
outdated = Formula.installed.select do |f|
f.outdated?(fetch_head: args.fetch_HEAD?)
end
exit 0 if outdated.empty?
else
outdated = Homebrew.args.resolved_formulae.select do |f|
outdated = args.resolved_formulae.select do |f|
f.outdated?(fetch_head: args.fetch_HEAD?)
end
(Homebrew.args.resolved_formulae - outdated).each do |f|
(args.resolved_formulae - outdated).each do |f|
versions = f.installed_kegs.map(&:version)
if versions.empty?
ofail "#{f.full_specified_name} not installed"
@ -168,7 +168,7 @@ module Homebrew
tab = Tab.for_keg(keg)
end
build_options = BuildOptions.new(Options.create(Homebrew.args.flags_only), f.options)
build_options = BuildOptions.new(Options.create(args.flags_only), f.options)
options = build_options.used_options
options |= f.build.used_options
options &= f.options
@ -176,7 +176,7 @@ module Homebrew
fi = FormulaInstaller.new(f)
fi.options = options
fi.build_bottle = args.build_bottle?
fi.installed_on_request = Homebrew.args.named.present?
fi.installed_on_request = args.named.present?
fi.link_keg ||= keg_was_linked if keg_had_linked_opt
if tab
fi.build_bottle ||= tab.built_bottle?

View File

@ -38,24 +38,23 @@ module Homebrew
description: "Show usage of <formula> by HEAD builds."
switch :debug
conflicts "--devel", "--HEAD"
min_named :formula
end
end
def uses
uses_args.parse
raise FormulaUnspecifiedError if args.remaining.empty?
Formulary.enable_factory_cache!
used_formulae_missing = false
used_formulae = begin
Homebrew.args.formulae
args.formulae
rescue FormulaUnavailableError => e
opoo e
used_formulae_missing = true
# If the formula doesn't exist: fake the needed formula object name.
Homebrew.args.named.map { |name| OpenStruct.new name: name, full_name: name }
args.named.map { |name| OpenStruct.new name: name, full_name: name }
end
use_runtime_dependents = args.installed? &&

View File

@ -79,12 +79,12 @@ module Homebrew
ENV.activate_extensions!
ENV.setup_build_environment
if Homebrew.args.named.blank?
if args.no_named?
ff = Formula
files = Tap.map(&:formula_dir)
else
ff = Homebrew.args.resolved_formulae
files = Homebrew.args.resolved_formulae.map(&:path)
ff = args.resolved_formulae
files = args.resolved_formulae.map(&:path)
end
only_cops = args.only_cops

View File

@ -79,6 +79,7 @@ module Homebrew
switch :verbose
switch :debug
conflicts "--no-rebuild", "--keep-old"
min_named 1
end
end
@ -86,10 +87,9 @@ module Homebrew
bottle_args.parse
return merge if args.merge?
raise KegUnspecifiedError if args.remaining.empty?
ensure_relocation_formulae_installed! unless args.skip_relocation?
Homebrew.args.resolved_formulae.each do |f|
args.resolved_formulae.each do |f|
bottle_formula f
end
end
@ -435,10 +435,7 @@ module Homebrew
end
def merge
write = args.write?
raise UsageError, "--merge requires a JSON file path argument" if Homebrew.args.named.blank?
bottles_hash = Homebrew.args.named.reduce({}) do |hash, json_file|
bottles_hash = args.named.reduce({}) do |hash, json_file|
hash.deep_merge(JSON.parse(IO.read(json_file))) do |key, first, second|
if key == "cellar"
# Prioritize HOMEBREW_CELLAR over :any over :any_skip_relocation
@ -478,7 +475,7 @@ module Homebrew
output = bottle_output bottle
if write
if args.write?
path = Pathname.new((HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"]).to_s)
update_or_add = nil

View File

@ -116,7 +116,7 @@ module Homebrew
# Use the user's browser, too.
ENV["BROWSER"] = ENV["HOMEBREW_BROWSER"]
formula = Homebrew.args.formulae.first
formula = args.formulae.first
if formula
tap_full_name, origin_branch, previous_branch = use_correct_linux_tap(formula)
@ -315,7 +315,7 @@ module Homebrew
new_formula_version = formula_version(formula, requested_spec, new_contents)
if !new_mirrors && !formula_spec.mirrors.empty?
if Homebrew.args.force?
if args.force?
opoo "#{formula}: Removing all mirrors because a --mirror= argument was not specified."
else
odie <<~EOS
@ -433,7 +433,7 @@ module Homebrew
contents = path.open("r") { |f| Formulary.ensure_utf8_encoding(f).read }
contents.extend(StringInreplaceExtension)
replacement_pairs.each do |old, new|
ohai "replace #{old.inspect} with #{new.inspect}" unless Homebrew.args.quiet?
ohai "replace #{old.inspect} with #{new.inspect}" unless args.quiet?
raise "No old value for new value #{new}! Did you pass the wrong arguments?" unless old
contents.gsub!(old, new)
@ -445,7 +445,7 @@ module Homebrew
else
Utils::Inreplace.inreplace(path) do |s|
replacement_pairs.each do |old, new|
ohai "replace #{old.inspect} with #{new.inspect}" unless Homebrew.args.quiet?
ohai "replace #{old.inspect} with #{new.inspect}" unless args.quiet?
raise "No old value for new value #{new}! Did you pass the wrong arguments?" unless old
s.gsub!(old, new)
@ -485,11 +485,11 @@ module Homebrew
#{pull_requests.map { |pr| "#{pr["title"]} #{pr["html_url"]}" }.join("\n")}
EOS
error_message = "Duplicate PRs should not be opened. Use --force to override this error."
if Homebrew.args.force? && !Homebrew.args.quiet?
if args.force? && !args.quiet?
opoo duplicates_message
elsif !Homebrew.args.force? && Homebrew.args.quiet?
elsif !args.force? && args.quiet?
odie error_message
elsif !Homebrew.args.force?
elsif !args.force?
odie <<~EOS
#{duplicates_message.chomp}
#{error_message}

View File

@ -33,7 +33,7 @@ module Homebrew
# user path, too.
ENV["PATH"] = ENV["HOMEBREW_PATH"]
formulae = Homebrew.args.formulae
formulae = args.formulae
raise FormulaUnspecifiedError if formulae.empty?
formula = formulae.first
@ -64,7 +64,7 @@ module Homebrew
end
if args.dry_run?
ohai "replace #{old.inspect} with #{replacement.inspect}" unless Homebrew.args.quiet?
ohai "replace #{old.inspect} with #{replacement.inspect}" unless args.quiet?
else
Utils::Inreplace.inreplace(formula.path) do |s|
s.gsub!(old, replacement)

View File

@ -49,7 +49,7 @@ module Homebrew
switch :verbose
switch :debug
conflicts "--autotools", "--cmake", "--go", "--meson", "--perl", "--python", "--rust"
max_named 1
named 1
end
end
@ -57,12 +57,10 @@ module Homebrew
def create
create_args.parse
raise UsageError if ARGV.named.empty?
# Ensure that the cache exists so we can fetch the tarball
HOMEBREW_CACHE.mkpath
url = ARGV.named.first # Pull the first (and only) url from ARGV
url = args.named.first # Pull the first (and only) url from ARGV
version = args.set_version
name = args.set_name

View File

@ -32,10 +32,10 @@ module Homebrew
end
# If no brews are listed, open the project root in an editor.
paths = [HOMEBREW_REPOSITORY] if ARGV.named.empty?
paths = [HOMEBREW_REPOSITORY] if args.no_named?
# Don't use ARGV.formulae as that will throw if the file doesn't parse
paths ||= ARGV.named.map do |name|
# Don't use args.formulae as that will throw if the file doesn't parse
paths ||= args.named.map do |name|
path = Formulary.path(name)
raise FormulaUnavailableError, name if !path.file? && !args.force?

View File

@ -91,18 +91,15 @@ module Homebrew
description: "Extract the specified <version> of <formula> instead of the most recent."
switch :force
switch :debug
max_named 2
named 2
end
end
def extract
extract_args.parse
# Expect exactly two named arguments: formula and tap
raise UsageError, "This command requires formula and tap arguments" if args.remaining.length != 2
if args.remaining.first !~ HOMEBREW_TAP_FORMULA_REGEX
name = args.remaining.first.downcase
if args.named.first !~ HOMEBREW_TAP_FORMULA_REGEX
name = args.named.first.downcase
source_tap = CoreTap.instance
else
name = Regexp.last_match(3).downcase
@ -110,7 +107,7 @@ module Homebrew
raise TapFormulaUnavailableError.new(source_tap, name) unless source_tap.installed?
end
destination_tap = Tap.fetch(args.remaining.second)
destination_tap = Tap.fetch(args.named.second)
unless ARGV.homebrew_developer?
odie "Cannot extract formula to homebrew/core!" if destination_tap.core_tap?
odie "Cannot extract formula to the same tap!" if destination_tap == source_tap
@ -190,7 +187,7 @@ module Homebrew
path = destination_tap.path/"Formula/#{name}@#{version}.rb"
if path.exist?
unless Homebrew.args.force?
unless args.force?
odie <<~EOS
Destination formula already exists: #{path}
To overwrite it and continue anyways, run:

View File

@ -15,14 +15,13 @@ module Homebrew
EOS
switch :verbose
switch :debug
min_named :formula
end
end
def formula
formula_args.parse
raise FormulaUnspecifiedError if Homebrew.args.named.blank?
Homebrew.args.resolved_formulae.each { |f| puts f.path }
args.resolved_formulae.each { |f| puts f.path }
end
end

View File

@ -33,10 +33,10 @@ module Homebrew
linkage_args.parse
CacheStoreDatabase.use(:linkage) do |db|
kegs = if Homebrew.args.kegs.empty?
kegs = if args.kegs.empty?
Formula.installed.map(&:opt_or_installed_prefix_keg).reject(&:nil?)
else
Homebrew.args.kegs
args.kegs
end
kegs.each do |keg|
ohai "Checking #{keg.name} linkage" if kegs.size > 1

View File

@ -15,19 +15,18 @@ module Homebrew
switch :verbose
switch :debug
hide_from_man_page!
min_named :formula
end
end
def mirror
mirror_args.parse
raise FormulaUnspecifiedError if args.remaining.empty?
bintray_user = ENV["HOMEBREW_BINTRAY_USER"]
bintray_key = ENV["HOMEBREW_BINTRAY_KEY"]
raise "Missing HOMEBREW_BINTRAY_USER or HOMEBREW_BINTRAY_KEY variables!" if !bintray_user || !bintray_key
Homebrew.args.formulae.each do |f|
args.formulae.each do |f|
bintray_package = Utils::Bottles::Bintray.package f.name
bintray_repo_url = "https://api.bintray.com/packages/homebrew/mirror"
package_url = "#{bintray_repo_url}/#{bintray_package}"

View File

@ -62,6 +62,7 @@ module Homebrew
description: "Pull the bottle block commit from the specified <user> on GitHub."
switch :verbose
switch :debug
min_named 1
end
end
@ -70,10 +71,6 @@ module Homebrew
pull_args.parse
if ARGV.named.empty?
raise UsageError, "This command requires at least one argument containing a URL or pull request number"
end
# Passthrough Git environment variables for e.g. git am
ENV["GIT_COMMITTER_NAME"] = ENV["HOMEBREW_GIT_NAME"] if ENV["HOMEBREW_GIT_NAME"]
ENV["GIT_COMMITTER_EMAIL"] = ENV["HOMEBREW_GIT_EMAIL"] if ENV["HOMEBREW_GIT_EMAIL"]
@ -96,7 +93,7 @@ module Homebrew
tap = nil
ARGV.named.each do |arg|
args.named.each do |arg|
arg = "#{CoreTap.instance.default_remote}/pull/#{arg}" if arg.to_i.positive?
if (testing_match = arg.match %r{/job/Homebrew.*Testing/(\d+)})
tap = ARGV.value("tap")

View File

@ -23,13 +23,13 @@ module Homebrew
def release_notes
release_notes_args.parse
previous_tag = ARGV.named.first
previous_tag = args.named.first
previous_tag ||= Utils.popen_read(
"git", "-C", HOMEBREW_REPOSITORY, "tag", "--list", "--sort=-version:refname"
).lines.first.chomp
odie "Could not find any previous tags!" unless previous_tag
end_ref = ARGV.named.second || "origin/master"
end_ref = args.named.second || "origin/master"
[previous_tag, end_ref].each do |ref|
next if quiet_system "git", "-C", HOMEBREW_REPOSITORY, "rev-parse", "--verify", "--quiet", ref

View File

@ -15,16 +15,14 @@ module Homebrew
EOS
switch :verbose
switch :debug
max_named 1
named 1
end
end
def tap_new
tap_new_args.parse
raise UsageError, "This command requires a tap argument" if ARGV.named.empty?
tap = Tap.fetch(ARGV.named.first)
tap = Tap.fetch(args.named.first)
titleized_user = tap.user.dup
titleized_repo = tap.repo.dup
titleized_user[0] = titleized_user[0].upcase

View File

@ -28,17 +28,16 @@ module Homebrew
switch :verbose
switch :debug
conflicts "--devel", "--HEAD"
min_named :formula
end
end
def test
test_args.parse
raise FormulaUnspecifiedError if ARGV.named.empty?
require "formula_assertions"
Homebrew.args.resolved_formulae.each do |f|
args.resolved_formulae.each do |f|
# Cannot test uninstalled formulae
unless f.latest_version_installed?
ofail "Testing requires the latest version of #{f.full_name}"
@ -52,7 +51,7 @@ module Homebrew
end
# Don't test unlinked formulae
if !Homebrew.args.force? && !f.keg_only? && !f.linked?
if !args.force? && !f.keg_only? && !f.linked?
ofail "#{f.full_name} is not linked"
next
end
@ -75,19 +74,19 @@ module Homebrew
env = ENV.to_hash
begin
args = %W[
exec_args = %W[
#{RUBY_PATH}
-W0
-I #{$LOAD_PATH.join(File::PATH_SEPARATOR)}
--
#{HOMEBREW_LIBRARY_PATH}/test.rb
#{f.path}
].concat(Homebrew.args.options_only)
].concat(args.options_only)
if f.head?
args << "--HEAD"
exec_args << "--HEAD"
elsif f.devel?
args << "--devel"
exec_args << "--devel"
end
Utils.safe_fork do
@ -102,9 +101,9 @@ module Homebrew
sandbox.allow_write_path(HOMEBREW_PREFIX/"var/homebrew/locks")
sandbox.allow_write_path(HOMEBREW_PREFIX/"var/log")
sandbox.allow_write_path(HOMEBREW_PREFIX/"var/run")
sandbox.exec(*args)
sandbox.exec(*exec_args)
else
exec(*args)
exec(*exec_args)
end
end
rescue Exception => e # rubocop:disable Lint/RescueException

View File

@ -19,13 +19,13 @@ end
class FormulaUnspecifiedError < UsageError
def initialize
super "This command requires a formula argument"
super "this command requires a formula argument"
end
end
class KegUnspecifiedError < UsageError
def initialize
super "This command requires a keg argument"
super "this command requires a keg argument"
end
end

View File

@ -1,18 +1,12 @@
# frozen_string_literal: true
module HomebrewArgvExtension
def named
# TODO: use @instance variable to ||= cache when moving to CLI::Parser
self - options_only
end
def flags_only
select { |arg| arg.start_with?("--") }
end
def formulae
require "formula"
# TODO: use @instance variable to ||= cache when moving to CLI::Parser
(downcased_unique_named - casks).map do |name|
if name.include?("/") || File.exist?(name)
Formulary.factory(name, spec)
@ -33,10 +27,6 @@ module HomebrewArgvExtension
flag_with_value&.delete_prefix(arg_prefix)
end
def verbose?
flag?("--verbose") || !ENV["VERBOSE"].nil? || !ENV["HOMEBREW_VERBOSE"].nil?
end
def debug?
flag?("--debug") || !ENV["HOMEBREW_DEBUG"].nil?
end
@ -150,9 +140,12 @@ module HomebrewArgvExtension
end
end
def named
self - options_only
end
def downcased_unique_named
# Only lowercase names, not paths, bottle filenames or URLs
# TODO: use @instance variable to ||= cache when moving to CLI::Parser
named.map do |arg|
if arg.include?("/") || arg.end_with?(".tar.gz") || File.exist?(arg)
arg

View File

@ -31,14 +31,14 @@ describe HomebrewArgvExtension do
let(:argv) { ["foo", "--debug", "-v"] }
it "returns an array of non-option arguments" do
expect(subject.named).to eq ["foo"]
expect(subject.send(:named)).to eq ["foo"]
end
context "when there are no named arguments" do
let(:argv) { [] }
it "returns an empty array" do
expect(subject.named).to be_empty
expect(subject.send(:named)).to be_empty
end
end
end

View File

@ -13,7 +13,7 @@ shared_examples "parseable arguments" do
it "can parse arguments" do
require "dev-cmd/#{command_name}" unless require? "cmd/#{command_name}"
expect { Homebrew.send(method_name).parse({}) }
expect { Homebrew.send(method_name).parse({}, allow_no_named_args: true) }
.not_to raise_error
end
end