Merge pull request #7509 from MikeMcQuaid/cli_refactoring
Refactor CLI to remove `unless args_parsed`
This commit is contained in:
commit
be5bbcd78a
@ -5,56 +5,44 @@ require "ostruct"
|
||||
module Homebrew
|
||||
module CLI
|
||||
class Args < OpenStruct
|
||||
attr_reader :processed_options, :args_parsed
|
||||
# undefine tap to allow --tap argument
|
||||
undef tap
|
||||
|
||||
def initialize
|
||||
super
|
||||
def initialize(argv = ARGV.dup.freeze, set_default_args: false)
|
||||
super()
|
||||
|
||||
self[:remaining] = []
|
||||
self[:argv] = ARGV.dup.freeze
|
||||
|
||||
@args_parsed = false
|
||||
@processed_options = []
|
||||
|
||||
# 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")
|
||||
self[:named_args] = argv.reject { |arg| arg.start_with?("-") }
|
||||
end
|
||||
|
||||
def freeze_named_args!(named_args)
|
||||
self[:named_args] = named_args
|
||||
self[:named_args].freeze
|
||||
end
|
||||
|
||||
def freeze_processed_options!(processed_options)
|
||||
@processed_options += processed_options
|
||||
@processed_options.freeze
|
||||
@args_parsed = true
|
||||
end
|
||||
|
||||
def option_to_name(option)
|
||||
option.sub(/\A--?/, "")
|
||||
.tr("-", "_")
|
||||
end
|
||||
|
||||
def cli_args
|
||||
return @cli_args if @cli_args
|
||||
|
||||
@cli_args = []
|
||||
processed_options.each do |short, long|
|
||||
option = long || short
|
||||
switch = "#{option_to_name(option)}?".to_sym
|
||||
flag = option_to_name(option).to_sym
|
||||
if @table[switch] == true || @table[flag] == true
|
||||
@cli_args << option
|
||||
elsif @table[flag].instance_of? String
|
||||
@cli_args << option + "=" + @table[flag]
|
||||
elsif @table[flag].instance_of? Array
|
||||
@cli_args << option + "=" + @table[flag].join(",")
|
||||
end
|
||||
end
|
||||
@cli_args
|
||||
end
|
||||
|
||||
def options_only
|
||||
@options_only ||= cli_args.select { |arg| arg.start_with?("-") }
|
||||
.freeze
|
||||
end
|
||||
|
||||
def flags_only
|
||||
@flags_only ||= cli_args.select { |arg| arg.start_with?("--") }
|
||||
.freeze
|
||||
end
|
||||
|
||||
def passthrough
|
||||
@ -62,7 +50,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def named
|
||||
remaining
|
||||
named_args || []
|
||||
end
|
||||
|
||||
def no_named?
|
||||
@ -74,16 +62,17 @@ module Homebrew
|
||||
def collect_build_args
|
||||
build_flags = []
|
||||
|
||||
build_flags << "--HEAD" if head
|
||||
build_flags << "--universal" if build_universal
|
||||
build_flags << "--build-bottle" if build_bottle
|
||||
build_flags << "--build-from-source" if build_from_source
|
||||
build_flags << "--HEAD" if HEAD?
|
||||
build_flags << "--universal" if build_universal?
|
||||
build_flags << "--build-bottle" if build_bottle?
|
||||
build_flags << "--build-from-source" if build_from_source?
|
||||
|
||||
build_flags
|
||||
end
|
||||
|
||||
def formulae
|
||||
require "formula"
|
||||
|
||||
@formulae ||= (downcased_unique_named - casks).map do |name|
|
||||
if name.include?("/") || File.exist?(name)
|
||||
Formulary.factory(name, spec)
|
||||
@ -91,29 +80,35 @@ module Homebrew
|
||||
Formulary.find_with_priority(name, spec)
|
||||
end
|
||||
end.uniq(&:name)
|
||||
.freeze
|
||||
end
|
||||
|
||||
def resolved_formulae
|
||||
require "formula"
|
||||
|
||||
@resolved_formulae ||= (downcased_unique_named - casks).map do |name|
|
||||
Formulary.resolve(name, spec: spec(nil))
|
||||
end.uniq(&:name)
|
||||
.freeze
|
||||
end
|
||||
|
||||
def formulae_paths
|
||||
@formulae_paths ||= (downcased_unique_named - casks).map do |name|
|
||||
Formulary.path(name)
|
||||
end.uniq
|
||||
.freeze
|
||||
end
|
||||
|
||||
def casks
|
||||
@casks ||= downcased_unique_named.grep HOMEBREW_CASK_TAP_CASK_REGEX
|
||||
@casks ||= downcased_unique_named.grep(HOMEBREW_CASK_TAP_CASK_REGEX)
|
||||
.freeze
|
||||
end
|
||||
|
||||
def kegs
|
||||
require "keg"
|
||||
require "formula"
|
||||
require "missing_formula"
|
||||
|
||||
@kegs ||= downcased_unique_named.map do |name|
|
||||
raise UsageError if name.empty?
|
||||
|
||||
@ -158,7 +153,7 @@ module Homebrew
|
||||
Please delete (with rm -rf!) all but one and then try again.
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end.freeze
|
||||
end
|
||||
|
||||
def build_stable?
|
||||
@ -168,39 +163,40 @@ module Homebrew
|
||||
# Whether a given formula should be built from source during the current
|
||||
# installation run.
|
||||
def build_formula_from_source?(f)
|
||||
return false if !build_from_source && !build_bottle
|
||||
return false if !build_from_source? && !build_bottle?
|
||||
|
||||
formulae.any? { |args_f| args_f.full_name == f.full_name }
|
||||
end
|
||||
|
||||
def build_from_source
|
||||
return argv.include?("--build-from-source") || argv.include?("-s") unless args_parsed
|
||||
|
||||
build_from_source? || s?
|
||||
end
|
||||
|
||||
def build_bottle
|
||||
return argv.include?("--build-bottle") unless args_parsed
|
||||
|
||||
build_bottle?
|
||||
end
|
||||
|
||||
def force_bottle
|
||||
return argv.include?("--force-bottle") unless args_parsed
|
||||
|
||||
force_bottle?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def option_to_name(option)
|
||||
option.sub(/\A--?/, "")
|
||||
.tr("-", "_")
|
||||
end
|
||||
|
||||
def cli_args
|
||||
return @cli_args if @cli_args
|
||||
|
||||
@cli_args = []
|
||||
@processed_options.each do |short, long|
|
||||
option = long || short
|
||||
switch = "#{option_to_name(option)}?".to_sym
|
||||
flag = option_to_name(option).to_sym
|
||||
if @table[switch] == true || @table[flag] == true
|
||||
@cli_args << option
|
||||
elsif @table[flag].instance_of? String
|
||||
@cli_args << option + "=" + @table[flag]
|
||||
elsif @table[flag].instance_of? Array
|
||||
@cli_args << option + "=" + @table[flag].join(",")
|
||||
end
|
||||
end
|
||||
@cli_args.freeze
|
||||
end
|
||||
|
||||
def downcased_unique_named
|
||||
# Only lowercase names, not paths, bottle filenames or URLs
|
||||
arguments = if args_parsed
|
||||
named
|
||||
else
|
||||
argv.reject { |arg| arg.start_with?("-") }
|
||||
end
|
||||
arguments.map do |arg|
|
||||
named.map do |arg|
|
||||
if arg.include?("/") || arg.end_with?(".tar.gz") || File.exist?(arg)
|
||||
arg
|
||||
else
|
||||
@ -209,28 +205,10 @@ module Homebrew
|
||||
end.uniq
|
||||
end
|
||||
|
||||
def head
|
||||
return argv.include?("--HEAD") unless args_parsed
|
||||
|
||||
HEAD?
|
||||
end
|
||||
|
||||
def devel
|
||||
return argv.include?("--devel") unless args_parsed
|
||||
|
||||
devel?
|
||||
end
|
||||
|
||||
def build_universal
|
||||
return argv.include?("--universal") unless args_parsed
|
||||
|
||||
universal?
|
||||
end
|
||||
|
||||
def spec(default = :stable)
|
||||
if head
|
||||
if HEAD?
|
||||
:head
|
||||
elsif devel
|
||||
elsif devel?
|
||||
:devel
|
||||
else
|
||||
default
|
||||
|
@ -12,8 +12,8 @@ module Homebrew
|
||||
class Parser
|
||||
attr_reader :processed_options, :hide_from_man_page
|
||||
|
||||
def self.parse(args = ARGV, allow_no_named_args: false, &block)
|
||||
new(args, &block).parse(args, allow_no_named_args: allow_no_named_args)
|
||||
def self.parse(argv = ARGV.dup.freeze, allow_no_named_args: false, &block)
|
||||
new(argv, &block).parse(allow_no_named_args: allow_no_named_args)
|
||||
end
|
||||
|
||||
def self.from_cmd_path(cmd_path)
|
||||
@ -37,9 +37,10 @@ module Homebrew
|
||||
}
|
||||
end
|
||||
|
||||
def initialize(&block)
|
||||
def initialize(argv = ARGV.dup.freeze, &block)
|
||||
@parser = OptionParser.new
|
||||
@args = Homebrew::CLI::Args.new
|
||||
@argv = argv
|
||||
@args = Homebrew::CLI::Args.new(@argv)
|
||||
|
||||
@constraints = []
|
||||
@conflicts = []
|
||||
@ -152,7 +153,7 @@ module Homebrew
|
||||
@parser.to_s
|
||||
end
|
||||
|
||||
def parse(argv = ARGV, allow_no_named_args: false)
|
||||
def parse(argv = @argv, allow_no_named_args: false)
|
||||
raise "Arguments were already parsed!" if @args_parsed
|
||||
|
||||
begin
|
||||
@ -161,12 +162,14 @@ module Homebrew
|
||||
$stderr.puts generate_help_text
|
||||
raise e
|
||||
end
|
||||
|
||||
check_constraint_violations
|
||||
check_named_args(named_args, allow_no_named_args: allow_no_named_args)
|
||||
@args[:remaining] = named_args
|
||||
@args.freeze_named_args!(named_args)
|
||||
parse_formula_options
|
||||
@args.freeze_processed_options!(@processed_options)
|
||||
Homebrew.args = @args
|
||||
argv.freeze
|
||||
|
||||
@args_parsed = true
|
||||
@parser
|
||||
end
|
||||
@ -186,21 +189,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def formula_options
|
||||
@args.formulae.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
|
||||
[]
|
||||
@parse_formula_options = true
|
||||
end
|
||||
|
||||
def max_named(count)
|
||||
@ -239,6 +228,26 @@ module Homebrew
|
||||
|
||||
private
|
||||
|
||||
def parse_formula_options
|
||||
return unless @parse_formula_options
|
||||
|
||||
@args.formulae.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
|
||||
[]
|
||||
end
|
||||
|
||||
def enable_switch(*names, from:)
|
||||
names.each do |name|
|
||||
@switch_sources[option_to_name(name)] = from
|
||||
|
@ -152,7 +152,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
# --HEAD, fail with no head defined
|
||||
raise "No head is defined for #{f.full_name}" if args.head? && f.head.nil?
|
||||
raise "No head is defined for #{f.full_name}" if args.HEAD? && f.head.nil?
|
||||
|
||||
# --devel, fail with no devel defined
|
||||
raise "No devel block is defined for #{f.full_name}" if args.devel? && f.devel.nil?
|
||||
|
@ -18,7 +18,8 @@ module Homebrew
|
||||
module_function
|
||||
|
||||
def irb_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
# work around IRB modifying ARGV.
|
||||
Homebrew::CLI::Parser.new(ARGV.dup) do
|
||||
usage_banner <<~EOS
|
||||
`irb` [<options>]
|
||||
|
||||
@ -33,8 +34,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def irb
|
||||
# work around IRB modifying ARGV.
|
||||
irb_args.parse(ARGV.dup)
|
||||
irb_args.parse
|
||||
|
||||
if args.examples?
|
||||
puts "'v8'.f # => instance of the v8 formula"
|
||||
|
@ -268,7 +268,7 @@ module SharedEnvExtension
|
||||
|
||||
# @private
|
||||
def effective_arch
|
||||
if Homebrew.args.build_bottle && ARGV.bottle_arch
|
||||
if Homebrew.args.build_bottle? && ARGV.bottle_arch
|
||||
ARGV.bottle_arch
|
||||
else
|
||||
Hardware.oldest_cpu
|
||||
|
@ -5,7 +5,7 @@ module Homebrew
|
||||
module_function
|
||||
|
||||
def fetch_bottle?(f)
|
||||
return true if Homebrew.args.force_bottle && f.bottle
|
||||
return true if Homebrew.args.force_bottle? && f.bottle
|
||||
return false unless f.bottle && f.pour_bottle?
|
||||
return false if Homebrew.args.build_formula_from_source?(f)
|
||||
return false unless f.bottle.compatible_cellar?
|
||||
|
@ -49,9 +49,9 @@ class FormulaInstaller
|
||||
@show_header = false
|
||||
@ignore_deps = false
|
||||
@only_deps = false
|
||||
@build_from_source = Homebrew.args.build_from_source
|
||||
@build_from_source = Homebrew.args.build_from_source?
|
||||
@build_bottle = false
|
||||
@force_bottle = Homebrew.args.force_bottle
|
||||
@force_bottle = Homebrew.args.force_bottle?
|
||||
@include_test = ARGV.include?("--include-test")
|
||||
@interactive = false
|
||||
@git = false
|
||||
|
@ -85,7 +85,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def args
|
||||
@args ||= CLI::Args.new
|
||||
@args ||= CLI::Args.new(set_default_args: true)
|
||||
end
|
||||
|
||||
def messages
|
||||
|
@ -25,7 +25,7 @@ module Homebrew
|
||||
|
||||
fi = FormulaInstaller.new(f)
|
||||
fi.options = options
|
||||
fi.build_bottle = Homebrew.args.build_bottle
|
||||
fi.build_bottle = Homebrew.args.build_bottle?
|
||||
fi.interactive = Homebrew.args.interactive?
|
||||
fi.git = Homebrew.args.git?
|
||||
fi.link_keg ||= keg_was_linked if keg_had_linked_opt
|
||||
|
@ -95,7 +95,7 @@ class SoftwareSpec
|
||||
|
||||
def bottled?
|
||||
bottle_specification.tag?(Utils::Bottles.tag) && \
|
||||
(bottle_specification.compatible_cellar? || Homebrew.args.force_bottle)
|
||||
(bottle_specification.compatible_cellar? || Homebrew.args.force_bottle?)
|
||||
end
|
||||
|
||||
def bottle(disable_type = nil, disable_reason = nil, &block)
|
||||
|
Loading…
x
Reference in New Issue
Block a user