Class: Clin::OptionParser
- Inherits:
-
Object
- Object
- Clin::OptionParser
- Defined in:
- lib/clin/option_parser.rb
Overview
Class that handler the option parsing part of command parsing. It separate the options from the arguments
Constant Summary collapse
- LONG_OPTION_REGEX =
/\A(?<name>--[^=]*)(?:=(?<value>.*))?/m
- SHORT_OPTION_REGEX =
/\A(?<name>-.)(?<value>(=).*|.+)?/m
Instance Attribute Summary collapse
-
#arguments ⇒ Object
readonly
List of arguments(i.e. Argv segments that are not options).
-
#errors ⇒ Object
readonly
List of errors encountered.
-
#options ⇒ Object
readonly
Parsed options are store here.
-
#skipped_options ⇒ Object
readonly
Any option skipped(if the command allow it) will be listed in here.
Instance Method Summary collapse
- #add_error(err) ⇒ Object
-
#complete(value) ⇒ Object
Get the next possible argument in the list if the value is nil.
-
#handle_unknown_option(name, value) ⇒ Object
Handle the case where the option was not defined in the command.
-
#initialize(command, argv) ⇒ OptionParser
constructor
A new instance of OptionParser.
-
#parse ⇒ Hash
Parse the argument for the command.
-
#parse_compact_flag_options(options) ⇒ Object
Parse compact flag_options(e.g. For -abc it will be called with ‘bc’).
-
#parse_flag_option(option, value, short) ⇒ Object
Parse a flag option(No argument) Add [OptionUnexpectedArgumentError] If value is defined and the long version was used.
-
#parse_long(name, value) ⇒ Object
Parse a long option If the value is nil and the option allow argument it will try to use the next argument.
-
#parse_next ⇒ Boolean
Fetch the next next argument and parse the option or store it as an argument.
-
#parse_option(option, name, value, short) ⇒ Object
Parse the given option.
-
#parse_short(name, value) ⇒ Object
Parse a long option If the value is nil and the option allow argument it will try to use the next argument.
Constructor Details
#initialize(command, argv) ⇒ OptionParser
Returns a new instance of OptionParser.
21 22 23 24 25 26 27 28 29 |
# File 'lib/clin/option_parser.rb', line 21 def initialize(command, argv) @errors = [] @command = command @options = {} @original_argv = argv @argv = argv.clone @arguments = [] @skipped_options = [] end |
Instance Attribute Details
#arguments ⇒ Object (readonly)
List of arguments(i.e. Argv segments that are not options)
10 11 12 |
# File 'lib/clin/option_parser.rb', line 10 def arguments @arguments end |
#errors ⇒ Object (readonly)
List of errors encountered
13 14 15 |
# File 'lib/clin/option_parser.rb', line 13 def errors @errors end |
#options ⇒ Object (readonly)
Parsed options are store here
16 17 18 |
# File 'lib/clin/option_parser.rb', line 16 def @options end |
#skipped_options ⇒ Object (readonly)
Any option skipped(if the command allow it) will be listed in here
19 20 21 |
# File 'lib/clin/option_parser.rb', line 19 def @skipped_options end |
Instance Method Details
#add_error(err) ⇒ Object
156 157 158 |
# File 'lib/clin/option_parser.rb', line 156 def add_error(err) @errors << err end |
#complete(value) ⇒ Object
Get the next possible argument in the list if the value is nil. Only get the next argument in the list if:
-
value is nil
-
the next argument is not an option(start with ‘-’)
106 107 108 109 110 111 112 |
# File 'lib/clin/option_parser.rb', line 106 def complete(value) if value.nil? && @argv.any? && !@argv.first.start_with?('-') @argv.shift else value end end |
#handle_unknown_option(name, value) ⇒ Object
Handle the case where the option was not defined in the command. Add [UnknownOptionError] if the command doesn’t allow unknown options.
147 148 149 150 151 152 153 154 |
# File 'lib/clin/option_parser.rb', line 147 def handle_unknown_option(name, value) unless @command. add_error Clin::UnknownOptionError.new(name) return end value = complete(value) @skipped_options += [name, value] end |
#parse ⇒ Hash
Parse the argument for the command. Options can also be accessed with #options “‘ # Suppose verbose and opt are defined option for the command. parser = OptionParser.new(command, %w(arg1 arg2 -v –opt val)) parser.parse #=> true, opt: ’val’ Get the arguments parser.argv # => [‘arg1’, ‘arg2’] “‘
41 42 43 44 45 |
# File 'lib/clin/option_parser.rb', line 41 def parse while parse_next end @options end |
#parse_compact_flag_options(options) ⇒ Object
Parse compact flag_options(e.g. For -abc it will be called with ‘bc’)
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/clin/option_parser.rb', line 131 def () .each_char do |s| option = @command.find_option_by(short: "-#{s}") if option && !option.flag? = "Cannot combine short options that expect argument: #{option}" add_error Clin::OptionError.new(, option) break end parse_flag_option(option, nil, true) end end |
#parse_flag_option(option, value, short) ⇒ Object
Parse a flag option(No argument) Add [OptionUnexpectedArgumentError] If value is defined and the long version was used. Short flag option can be merged together(i.e these are equivalent: -abc, -a -b -c) In that case the value will be ‘bc’. It will then try to parse b and c as flag options.
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/clin/option_parser.rb', line 118 def parse_flag_option(option, value, short) return option.trigger(self, @options, true) if value.nil? unless short # Short can also have the format -abc return add_error Clin::OptionUnexpectedArgumentError.new(option, value) end option.trigger(self, @options, true) # The value is expected to be other flag options (value) end |
#parse_long(name, value) ⇒ Object
Parse a long option If the value is nil and the option allow argument it will try to use the next argument
70 71 72 73 |
# File 'lib/clin/option_parser.rb', line 70 def parse_long(name, value) option = @command.find_option_by(long: name) parse_option(option, name, value, false) end |
#parse_next ⇒ Boolean
Fetch the next next argument and parse the option or store it as an argument
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/clin/option_parser.rb', line 49 def parse_next return false if @argv.empty? case (arg = @argv.shift) when LONG_OPTION_REGEX name = Regexp.last_match[:name] value = Regexp.last_match[:value] parse_long(name, value) when SHORT_OPTION_REGEX name = Regexp.last_match[:name] value = Regexp.last_match[:value] parse_short(name, value) else @arguments << arg end true end |
#parse_option(option, name, value, short) ⇒ Object
Parse the given option. If the value is nil and the option allow argument it will try to use the next argument
89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/clin/option_parser.rb', line 89 def parse_option(option, name, value, short) return handle_unknown_option(name, value) if option.nil? return parse_flag_option(option, value, short) if option.flag? value = complete(value) if value.nil? && !option.argument_optional? return add_error Clin::MissingOptionArgumentError.new(option) end value ||= true option.trigger(self, @options, value) end |
#parse_short(name, value) ⇒ Object
Parse a long option If the value is nil and the option allow argument it will try to use the next argument
79 80 81 82 |
# File 'lib/clin/option_parser.rb', line 79 def parse_short(name, value) option = @command.find_option_by(short: name) parse_option(option, name, value, true) end |