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.
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
-
#to_s ⇒ Object
Outputs a help screen.
Constructor Details
#initialize(program_prefix = $0) ⇒ OptionParser
If a block is passed in, it is given self.
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/user_input/option_parser.rb', line 37 def initialize(program_prefix = $0) @options = {} @order = [] @program_prefix = program_prefix @banner = 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]”
156 157 158 |
# File 'lib/user_input/option_parser.rb', line 156 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 |
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.
78 79 80 |
# File 'lib/user_input/option_parser.rb', line 78 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.
84 85 86 |
# File 'lib/user_input/option_parser.rb', line 84 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.
90 91 92 |
# File 'lib/user_input/option_parser.rb', line 90 def gap(count = 1) 1.upto(count) { @order.push(nil) } end |
#longest ⇒ Object
160 161 162 163 164 165 166 |
# File 'lib/user_input/option_parser.rb', line 160 def longest l = 0 @options.keys.each {|opt| l = (opt.length > l)? opt.length : l } return l end |
#parse(argv = ARGV) ⇒ Object
150 151 152 |
# File 'lib/user_input/option_parser.rb', line 150 def parse(argv = ARGV) self.parse!(argv.dup) end |
#parse!(argv = ARGV) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 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 |
# File 'lib/user_input/option_parser.rb', line 94 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, so bail out and leave it to the caller to figure it out. return self 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 |
#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)
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/user_input/option_parser.rb', line 170 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 |