Class: Rake::ToolkitProgram::CommandOptionParser
- Inherits:
-
OptionParser
- Object
- OptionParser
- Rake::ToolkitProgram::CommandOptionParser
- Defined in:
- lib/rake/toolkit_program/command_option_parser.rb
Constant Summary collapse
- IDENTITY =
->(v) {v}
- RUBY_GTE_2_4 =
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4')
Instance Attribute Summary collapse
-
#argument_destination ⇒ Object
readonly
Returns the value of attribute argument_destination.
Instance Method Summary collapse
-
#capture_positionals(key = nil, precapture_dest_array: false, &blk) ⇒ Object
Explicitly define capture of positional (non-option) arguments.
-
#expect_positional_cardinality(cardinality_test, explanation = nil) ⇒ Object
Constrain the number of positional arguments.
-
#initialize(arg_dest) ⇒ CommandOptionParser
constructor
A new instance of CommandOptionParser.
-
#invalid_args!(message) ⇒ Object
Convenience method for raising Rake::ToolkitProgram::InvalidCommandLine.
-
#map_positional_args(&blk) ⇒ Object
Define a mapping function for positional arguments during accumulation.
-
#no_positional_args! ⇒ Object
Disallow positional arguments.
- #order!(argv = default_args, into: nil, &nonopt) ⇒ Object
-
#parse!(argv = default_argv, into: nil) ⇒ Object
Method override, see OptionParser#parse! – though we don’t do POSIXLY_COMPLIANT.
-
#positional_arguments_allowed? ⇒ Boolean
True unless positional arguments have been prohibited.
-
#positional_cardinality ⇒ Object
Return the established test for positional cardinality (or nil).
-
#positional_cardinality_explanation ⇒ Object
String explanation of the positional cardinality, for help.
-
#positional_cardinality_ok?(n) ⇒ Boolean
Query whether a given number of positional arguments is acceptable.
Constructor Details
#initialize(arg_dest) ⇒ CommandOptionParser
Returns a new instance of CommandOptionParser.
30 31 32 33 34 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 30 def initialize(arg_dest) super() @argument_destination = arg_dest @positional_mapper = IDENTITY end |
Instance Attribute Details
#argument_destination ⇒ Object (readonly)
Returns the value of attribute argument_destination.
36 37 38 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 36 def argument_destination @argument_destination end |
Instance Method Details
#capture_positionals(key = nil, precapture_dest_array: false, &blk) ⇒ Object
Explicitly define capture of positional (non-option) arguments
When parsing into a Hash, the default is to store the Array of remaining positional arguments in the nil
key. This method overrides that behavior by either specifying a specific key to use or by specifying a block to call with the positional arguments, which is much more useful when accumulating arguments to a non-Hash object. Passing key
or a block are mutually exclusive.
precapture_dest_array
can be set to true
to cause the capture to take place before the positional arguments are accumulated. In this case, the Array object yielded to the block (if this method is called with a block) must be stored, as it will be the recipient of all positional arguments. In any case, when this option is passed to this method, capture behavior for the (empty) Array into which the positional arguments will be stored is carried out before option parsing, and values are (after any transformation dictated by #map_positional_args) stored in the positional arguments Array; there is no option to store positionals for consumption by the command task code in anything other than an Array. Note that the Array into which arguments are captured is not the same array either passed to or returned from the #parse! (or #parse, for that matter) method.
If multiple calls to this method are made, the last one is the one that defines the behavior.
key
-
Key under which positionals shall be accumulated in a Hash
precapture_dest_array
-
Capture before argument accumulation
165 166 167 168 169 170 171 172 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 165 def capture_positionals(key=nil, precapture_dest_array: false, &blk) if blk && !key.nil? raise ArgumentError, "either specify key or block" end @positionals_key = key @positionals_capture = blk @precapture_positionals_array = precapture_dest_array end |
#expect_positional_cardinality(cardinality_test, explanation = nil) ⇒ Object
Constrain the number of positional arguments
This is a declarative way of expressing how many positional (i.e. non-option) arguments should be accepted by the command. The #=== (i.e. “case match”) method of cardinality_test
is used to test the length of the positional argument Array, raising Rake::ToolkitProgram::WrongArgumentCount if #=== returns false.
A special case exists when cardinality_test
is a Symbol: because a Symbol could never match an Integer, Symbol#to_proc is called to create a useful test.
NOTE It is worth attention that Proc#=== is an alias for Proc#call, so the operator argument is passed to the Proc. This enables arbitrary computation for the validity of the positional argument count, syntactically aided by the “stabby-lambda” notation.
While this gem will do its best to explain the argument cardinality, explanation
provides an opportunity to explicitly provide a sentence to be included in the help about the allowed cardinality (i.e. count) of positional arguments.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 197 def expect_positional_cardinality(cardinality_test, explanation=nil) @positional_cardinality_explanation = explanation if cardinality_test.kind_of?(Symbol) cardinality_test.to_s.tap do |test_name| if explanation.nil? && test_name.end_with?('?') @positional_cardinality_explanation = ( "Positional argument count must be #{test_name[0..-2].gsub('_', ' ')}." ) end end cardinality_test = cardinality_test.to_proc end @positional_cardinality_test = cardinality_test end |
#invalid_args!(message) ⇒ Object
Convenience method for raising Rake::ToolkitProgram::InvalidCommandLine
The error raised is the standard error for an invalid command line when using Rake::ToolkitProgram.
228 229 230 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 228 def invalid_args!() raise InvalidCommandLine, end |
#map_positional_args(&blk) ⇒ Object
Define a mapping function for positional arguments during accumulation
The block given to this method will be called with each positional argument in turn; the return value of the block will be acculumated as the positional argument. The block’s computation may be purely functional or it may refer to outside factors in its binding such as accumulated values for options or preceding positional arguments.
241 242 243 244 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 241 def map_positional_args(&blk) raise ArgumentError, "block required" if blk.nil? @positional_mapper = blk end |
#no_positional_args! ⇒ Object
Disallow positional arguments
The command will raise Rake::ToolkitProgram::WrongArgumentCount if any positional arguments are given.
218 219 220 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 218 def no_positional_args! expect_positional_cardinality(0) end |
#order!(argv = default_args, into: nil, &nonopt) ⇒ Object
40 41 42 43 44 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 40 def order!(argv = default_argv, into: nil, &nonopt) super(argv, into: into) do |arg| nonopt.call(@positional_mapper.call(arg)) end end |
#parse!(argv = default_argv, into: nil) ⇒ Object
Method override, see OptionParser#parse! – though we don’t do POSIXLY_COMPLIANT
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 55 def parse!(argv = default_argv, into: nil) positionals = [] do_positional_capture(positionals) if @precapture_positionals_array order!(argv, into: into, &positionals.method(:<<)).tap do argv[0, 0] = positionals do_positional_capture(argv) if !@precapture_positionals_array unless positional_cardinality_ok?(positionals.length) raise WrongArgumentCount.new( @positional_cardinality_test, positionals.length ) end end return argv end |
#positional_arguments_allowed? ⇒ Boolean
True unless positional arguments have been prohibited
Technically, this test can only check that the established cardinality test is for 0, given as an Integer. If the test established by #expect_positional_cardinality is a Proc that only returns true for 0 or the Range 0..0
, this method will report incorrect results.
93 94 95 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 93 def positional_arguments_allowed? @positional_cardinality_test != 0 end |
#positional_cardinality ⇒ Object
Return the established test for positional cardinality (or nil)
If a test has been established by #expect_positional_cardinality, this method returns that test. Otherwise, it returns nil.
103 104 105 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 103 def positional_cardinality @positional_cardinality_test end |
#positional_cardinality_explanation ⇒ Object
String explanation of the positional cardinality, for help
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 110 def positional_cardinality_explanation @positional_cardinality_explanation.tap do |explicit| return explicit if explicit end obscure_answer = "A rule exists about the number of positional arguments." case (pc_test = @positional_cardinality_test) when nil, 0 then nil when 1 then "Requires 1 positional argument." when Integer then "Requires #{pc_test} positional arguments." when Range then "Requires #{pc_test.to_inclusive} (inclusive) positional arguments." when Proc then begin [pc_test.call(:explain)].map do |exp| case exp when String then exp else obscure_answer end end[0] rescue StandardError obscure_answer end else obscure_answer end end |
#positional_cardinality_ok?(n) ⇒ Boolean
Query whether a given number of positional arguments is acceptable
The result is based on the test established by #expect_positional_cardinality, and returns true if no such test has been established.
79 80 81 82 |
# File 'lib/rake/toolkit_program/command_option_parser.rb', line 79 def positional_cardinality_ok?(n) pc_test = @positional_cardinality_test !pc_test || pc_test === n end |