Class: UserInput::OptionParser
- Defined in:
- lib/user_input/option_parser.rb
Overview
Handles parsing command line options such that it terminates on the first bareword argument, ‘–’, or the end of the arguments. Uses from_user_input to validate input if requested.
Defined Under Namespace
Classes: Info
Instance Attribute Summary collapse
-
#banner ⇒ Object
returns either the banner set with banner= or a simple banner like “Usage: $0 [arguments]”.
-
#program_prefix ⇒ Object
The prefix for the program in the usage banner.
-
#saved ⇒ Object
readonly
Saved unknown barewords if save_unknown! is called, nil otherwise.
Instance Method Summary collapse
-
#argument(short_name, long_name, description, default_value, validate = nil, &block) ⇒ Object
This defines a command line argument that takes a value.
-
#flag(short_name, long_name, description, &block) ⇒ Object
This defines a command line argument that’s either on or off based on the presense of the flag.
-
#gap(count = 1) ⇒ Object
This produces a gap in the output of the help display but does not otherwise affect the argument parsing.
-
#initialize(program_prefix = $0) ⇒ OptionParser
constructor
If a block is passed in, it is given self.
- #longest ⇒ Object
- #parse(argv = ARGV) ⇒ Object
- #parse!(argv = ARGV) ⇒ Object
-
#save_unknown! ⇒ Object
Enable saving of unknown barewords.
-
#to_s ⇒ Object
Outputs a help screen.
Constructor Details
#initialize(program_prefix = $0) ⇒ OptionParser
If a block is passed in, it is given self.
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/user_input/option_parser.rb', line 39 def initialize(program_prefix = $0) @options = {} @order = [] @program_prefix = program_prefix @banner = nil @saved = nil if (block_given?) yield self end end |
Instance Attribute Details
#banner ⇒ Object
returns either the banner set with banner= or a simple banner like “Usage: $0 [arguments]”
174 175 176 |
# File 'lib/user_input/option_parser.rb', line 174 def @banner || "Usage: #{program_prefix} [arguments]" end |
#program_prefix ⇒ Object
The prefix for the program in the usage banner. Used only if banner is nil.
32 33 34 |
# File 'lib/user_input/option_parser.rb', line 32 def program_prefix @program_prefix end |
#saved ⇒ Object (readonly)
Saved unknown barewords if save_unknown! is called, nil otherwise.
36 37 38 |
# File 'lib/user_input/option_parser.rb', line 36 def saved @saved end |
Instance Method Details
#argument(short_name, long_name, description, default_value, validate = nil, &block) ⇒ Object
This defines a command line argument that takes a value.
89 90 91 |
# File 'lib/user_input/option_parser.rb', line 89 def argument(short_name, long_name, description, default_value, validate = nil, &block) return define_value(short_name, long_name, description, false, default_value, validate || block) end |
#flag(short_name, long_name, description, &block) ⇒ Object
This defines a command line argument that’s either on or off based on the presense of the flag.
95 96 97 |
# File 'lib/user_input/option_parser.rb', line 95 def flag(short_name, long_name, description, &block) return define_value(short_name, long_name, description, true, false, block) end |
#gap(count = 1) ⇒ Object
This produces a gap in the output of the help display but does not otherwise affect the argument parsing.
101 102 103 |
# File 'lib/user_input/option_parser.rb', line 101 def gap(count = 1) 1.upto(count) { @order.push(nil) } end |
#longest ⇒ Object
178 179 180 181 182 183 184 |
# File 'lib/user_input/option_parser.rb', line 178 def longest l = 0 @options.keys.each {|opt| l = (opt.length > l)? opt.length : l } return l end |
#parse(argv = ARGV) ⇒ Object
168 169 170 |
# File 'lib/user_input/option_parser.rb', line 168 def parse(argv = ARGV) self.parse!(argv.dup) end |
#parse!(argv = ARGV) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/user_input/option_parser.rb', line 105 def parse!(argv = ARGV) # this is a stack of arguments that need to have their values filled by subsequent arguments argument_stack = [] while (argv.first) arg = argv.first # if there's a node on the argument stack, we fill it in. if (argument_stack.first) argument_stack.shift.value = arg else # figure out what type of argument it is if (arg == '--') # bare -- should cause the parser to consume and then stop, unlike bare word # which should leave it in place. argv.shift return self elsif (match = arg.match(/^\-\-(.+)$/)) arg_info = @options[match[1]] if (!arg_info) raise ArgumentError, "Unrecognized option #{match[1]}" end if (arg_info.flag) arg_info.value = true else argument_stack.push(arg_info) end elsif (match = arg.match(/^-(.+)$/)) short_args = match[1].split("") short_args.each {|short_arg| arg_info = @options[short_arg] if (!arg_info) raise ArgumentError, "unrecognized option #{match[1]}" end if (arg_info.flag) arg_info.value = true else argument_stack.push(arg_info) end } else # unrecognized bareword (not part of a flag). What we do # depends on whether or not we're saving unknown barewords. if (@saved) #save it @saved << arg else # bail out and leave it to the caller to figure it out. return self end end end argv.shift end # if we got here and there are still items on the argument stack, # we didn't get all the values we expected so error out. if (argument_stack.length > 0) raise ArgumentError, "Missing value for argument #{argument_stack.first.long_name}" end return self end |
#save_unknown! ⇒ Object
Enable saving of unknown barewords. With this, the only way to terminate parsing is to hit the end of the parse or with –. You can retrieve the saved words from #saved.
84 85 86 |
# File 'lib/user_input/option_parser.rb', line 84 def save_unknown! @saved = [] end |
#to_s ⇒ Object
Outputs a help screen. Code largely taken from the awesome, but not quite right for my needs, Clip (github.com/alexvollmer/clip)
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/user_input/option_parser.rb', line 188 def to_s out = "" out << << "\n" @order.each {|option| if (option.nil?) out << "\n" next end line = sprintf("-%-2s --%-#{longest+6}s ", option.short_name, option.long_name + (option.flag ? "" : " [VAL]")) out << line if (line.length + option.description.length <= 80) out << option.description else rem = 80 - line.length desc = option.description i = 0 while (i < desc.length) out << "\n" if i > 0 j = [i + rem, desc.length].min while desc[j..j] =~ /[\w\d]/ j -= 1 end chunk = desc[i..j].strip out << " " * line.length if i > 0 out << chunk i = j + 1 end end if (!option.flag) out << " (default: #{option.default_value})" end out << "\n" } return out end |