Refactor handling of formula options in CLI::Parser.

This commit is contained in:
Markus Reiter 2020-07-31 17:37:36 +02:00
parent 05aada4333
commit be2d19fe07
6 changed files with 54 additions and 58 deletions

View File

@ -41,6 +41,7 @@ begin
empty_argv = ARGV.empty?
help_flag_list = %w[-h --help --usage -?]
help_flag = !ENV["HOMEBREW_HELP"].nil?
help_cmd_index = nil
cmd = nil
ARGV.each_with_index do |arg, i|
@ -49,13 +50,16 @@ begin
if arg == "help" && !cmd
# Command-style help: `help <cmd>` is fine, but `<cmd> help` is not.
help_flag = true
help_cmd_index = i
elsif !cmd && !help_flag_list.include?(arg)
cmd = ARGV.delete_at(i)
cmd = Commands::HOMEBREW_INTERNAL_COMMAND_ALIASES.fetch(cmd, cmd)
end
end
Homebrew.args = Homebrew::CLI::Parser.new.parse(ignore_invalid_options: true)
ARGV.delete_at(help_cmd_index) if help_cmd_index
Homebrew.args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true)
path = PATH.new(ENV["PATH"])
homebrew_path = PATH.new(ENV["HOMEBREW_PATH"])

View File

@ -10,32 +10,21 @@ module Homebrew
# undefine tap to allow --tap argument
undef tap
def initialize(argv = ARGV.dup.freeze, set_default_args: false)
def initialize
super()
@processed_options = []
@options_only = args_options_only(argv)
@flags_only = args_flags_only(argv)
@options_only = []
@flags_only = []
# Can set these because they will be overwritten by freeze_named_args!
# (whereas other values below will only be overwritten if passed).
self[:named_args] = argv.reject { |arg| arg.start_with?("-") }
self[:named_args] = []
self[:remaining] = []
# Set values needed before Parser#parse has been run.
return unless set_default_args
self[:build_from_source?] = argv.include?("--build-from-source") || argv.include?("-s")
self[:build_bottle?] = argv.include?("--build-bottle")
self[:force_bottle?] = argv.include?("--force-bottle")
self[:HEAD?] = argv.include?("--HEAD")
self[:devel?] = argv.include?("--devel")
self[:universal?] = argv.include?("--universal")
end
def freeze_remaining_args!(remaining_args)
self[:remaining] = remaining_args
self[:remaining].freeze
self[:remaining] = remaining_args.freeze
end
def freeze_named_args!(named_args)
@ -49,8 +38,7 @@ module Homebrew
@kegs = nil
@kegs_casks = nil
self[:named_args] = named_args
self[:named_args].freeze
self[:named_args] = named_args.freeze
end
def freeze_processed_options!(processed_options)
@ -60,8 +48,8 @@ module Homebrew
@processed_options += processed_options
@processed_options.freeze
@options_only = args_options_only(cli_args)
@flags_only = args_flags_only(cli_args)
@options_only = cli_args.select { |a| a.start_with?("-") }.freeze
@flags_only = cli_args.select { |a| a.start_with?("--") }.freeze
end
def named
@ -221,16 +209,6 @@ module Homebrew
@cli_args.freeze
end
def args_options_only(args)
args.select { |arg| arg.start_with?("-") }
.freeze
end
def args_flags_only(args)
args.select { |arg| arg.start_with?("--") }
.freeze
end
def downcased_unique_named
# Only lowercase names, not paths, bottle filenames or URLs
named.map do |arg|

View File

@ -33,11 +33,10 @@ module Homebrew
]
end
def initialize(argv = ARGV.dup.freeze, &block)
def initialize(&block)
@parser = OptionParser.new
@argv = argv
@args = Homebrew::CLI::Args.new(@argv)
@args = Homebrew::CLI::Args.new
@constraints = []
@conflicts = []
@ -47,6 +46,7 @@ module Homebrew
@min_named_args = nil
@min_named_type = nil
@hide_from_man_page = false
@formula_options = false
self.class.global_options.each do |short, long, desc|
switch short, long, description: desc
@ -63,7 +63,7 @@ module Homebrew
# Disable default handling of `--help` switch.
@parser.on_tail("-h", "--help", "Show this message.") do
raise OptionParser::InvalidOption
# Handled in `brew.rb`.
end
end
@ -190,9 +190,31 @@ module Homebrew
[remaining, non_options]
end
def parse(argv = @argv, ignore_invalid_options: false)
def parse(argv = ARGV.freeze, ignore_invalid_options: false)
raise "Arguments were already parsed!" if @args_parsed
# If we accept formula options, parse once allowing invalid options
# so we can get the remaining list containing formula names.
if @formula_options
remaining, non_options = parse_remaining(argv, ignore_invalid_options: true)
argv = [*remaining, "--", *non_options]
formulae(argv).each do |f|
next if f.options.empty?
f.options.each do |o|
name = o.flag
description = "`#{f.name}`: #{o.description}"
if name.end_with? "="
flag name, description: description
else
switch name, description: description
end
end
end
end
remaining, non_options = parse_remaining(argv, ignore_invalid_options: ignore_invalid_options)
named_args = if ignore_invalid_options
@ -201,8 +223,8 @@ module Homebrew
remaining + non_options
end
check_constraint_violations
check_named_args(named_args)
check_constraint_violations unless ignore_invalid_options
check_named_args(named_args) unless ignore_invalid_options
@args.freeze_named_args!(named_args)
@args.freeze_remaining_args!(non_options.empty? ? remaining : [*remaining, "--", non_options])
@args.freeze_processed_options!(@processed_options)
@ -221,21 +243,7 @@ module Homebrew
end
def formula_options
formulae(@argv).each do |f|
next if f.options.empty?
f.options.each do |o|
name = o.flag
description = "`#{f.name}`: #{o.description}"
if name.end_with? "="
flag name, description: description
else
switch name, description: description
end
end
end
rescue FormulaUnavailableError
[]
@formula_options = true
end
def max_named(count)
@ -385,9 +393,9 @@ module Homebrew
end
def formulae(argv)
argv, named_argv = split_double_dash(argv)
argv, non_options = split_double_dash(argv)
named_args = argv.reject { |arg| arg.start_with?("-") } + named_argv
named_args = argv.reject { |arg| arg.start_with?("-") } + non_options
spec = if argv.include?("--HEAD")
:head
elsif argv.include?("--devel")
@ -400,7 +408,11 @@ module Homebrew
named_args.map do |arg|
next if arg.match?(HOMEBREW_CASK_TAP_CASK_REGEX)
Formulary.factory(arg, spec, flags: @args.flags_only)
begin
Formulary.factory(arg, spec, flags: argv.select { |a| a.start_with?("--") })
rescue FormulaUnavailableError
nil
end
end.compact.uniq(&:name)
end
end

View File

@ -34,7 +34,7 @@ module Homebrew
end
def irb
args = irb_args.parse
args = irb_args.parse(ARGV.dup.freeze)
if args.examples?
puts "'v8'.f # => instance of the v8 formula"

View File

@ -82,7 +82,7 @@ module Homebrew
end
def args
@args ||= CLI::Args.new(set_default_args: true)
@args ||= CLI::Args.new
end
def messages

View File

@ -95,6 +95,8 @@ module Homebrew
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.generate_help_text
end