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