cli/parser: add named/min_named helpers.

This commit is contained in:
Mike McQuaid 2020-03-04 17:27:25 +00:00
parent f13b0513ea
commit 66155ea370
No known key found for this signature in database
GPG Key ID: 48A898132FD8EE70
2 changed files with 62 additions and 11 deletions

View File

@ -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, &block) def self.parse(args = ARGV, allow_no_named_args: false, &block)
new(args, &block).parse(args) new(args, &block).parse(args, allow_no_named_args: allow_no_named_args)
end end
def self.from_cmd_path(cmd_path) def self.from_cmd_path(cmd_path)
@ -47,6 +47,8 @@ module Homebrew
@switch_sources = {} @switch_sources = {}
@processed_options = [] @processed_options = []
@max_named_args = nil @max_named_args = nil
@min_named_args = nil
@min_named_type = nil
@hide_from_man_page = false @hide_from_man_page = false
instance_eval(&block) instance_eval(&block)
post_initialize post_initialize
@ -146,7 +148,7 @@ module Homebrew
@parser.to_s @parser.to_s
end end
def parse(cmdline_args = ARGV) def parse(cmdline_args = ARGV, allow_no_named_args: false)
raise "Arguments were already parsed!" if @args_parsed raise "Arguments were already parsed!" if @args_parsed
begin begin
@ -156,7 +158,7 @@ module Homebrew
raise e raise e
end end
check_constraint_violations check_constraint_violations
check_named_args(named_args) check_named_args(named_args, allow_no_named_args: allow_no_named_args)
@args[:remaining] = named_args @args[:remaining] = named_args
@args.freeze_processed_options!(@processed_options) @args.freeze_processed_options!(@processed_options)
Homebrew.args = @args Homebrew.args = @args
@ -198,9 +200,35 @@ module Homebrew
end end
def max_named(count) def max_named(count)
raise TypeError, "Unsupported type #{count.class.name} for max_named" unless count.is_a?(Integer)
@max_named_args = count @max_named_args = count
end 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! def hide_from_man_page!
@hide_from_man_page = true @hide_from_man_page = true
end end
@ -292,8 +320,17 @@ module Homebrew
check_constraints check_constraints
end end
def check_named_args(args) def check_named_args(args, allow_no_named_args: false)
raise NamedArgumentsError, @max_named_args if !@max_named_args.nil? && args.size > @max_named_args 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 end
def process_option(*args) def process_option(*args)
@ -327,15 +364,29 @@ module Homebrew
end end
end end
class NamedArgumentsError < UsageError class MaxNamedArgumentsError < UsageError
def initialize(maximum) def initialize(maximum)
message = case maximum message = case maximum
when 0 when 0
"This command does not take named arguments." "this command does not take named arguments"
when 1 when 1
"This command does not take multiple named arguments." "this command does not take multiple named arguments"
else 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 end
super message super message
end end

View File

@ -13,7 +13,7 @@ shared_examples "parseable arguments" do
it "can parse arguments" do it "can parse arguments" do
require "dev-cmd/#{command_name}" unless require? "cmd/#{command_name}" 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 .not_to raise_error
end end
end end