From 66155ea3706ce89c2b1c15ef25ad708942f1cdc5 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Wed, 4 Mar 2020 17:27:25 +0000 Subject: [PATCH] cli/parser: add named/min_named helpers. --- Library/Homebrew/cli/parser.rb | 71 ++++++++++++++++--- .../test/cmd/shared_examples/args_parse.rb | 2 +- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index acf67aaf46..2c87d54d4d 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -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,7 +148,7 @@ 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 @@ -156,7 +158,7 @@ module Homebrew raise e end 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.freeze_processed_options!(@processed_options) Homebrew.args = @args @@ -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 diff --git a/Library/Homebrew/test/cmd/shared_examples/args_parse.rb b/Library/Homebrew/test/cmd/shared_examples/args_parse.rb index 6230b9e43b..9cc16d455a 100644 --- a/Library/Homebrew/test/cmd/shared_examples/args_parse.rb +++ b/Library/Homebrew/test/cmd/shared_examples/args_parse.rb @@ -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