Module: GLI
- Extended by:
- GLI
- Included in:
- GLI
- Defined in:
- lib/gli.rb,
lib/gli/flag.rb,
lib/gli/switch.rb,
lib/gli/command.rb,
lib/support/help.rb,
lib/support/rdoc.rb,
lib/support/scaffold.rb,
lib/gli/command_line_token.rb
Overview
A means to define and parse a command line interface that works as Git’s does, in that you specify global options, a command name, command specific options, and then command arguments.
Defined Under Namespace
Classes: Command, CommandLineToken, DefaultHelpCommand, Flag, RDocCommand, Scaffold, Switch
Constant Summary collapse
- VERSION =
'0.2.1'
- @@program_name =
$0.split(/\//)[-1]
- @@post_block =
nil
- @@pre_block =
nil
- @@error_block =
nil
Instance Method Summary collapse
-
#arg_name(name) ⇒ Object
describe the argument name of the next flag.
- #clear_nexts ⇒ Object
-
#command(names) {|command| ... } ⇒ Object
(also: #c)
Define a command.
- #commands ⇒ Object
-
#default_value(val) ⇒ Object
set the default value of the next flag.
-
#desc(description) ⇒ Object
(also: #d)
describe the next switch, flag, or command.
- #find_command(name) ⇒ Object
-
#find_non_flag_index(args) ⇒ Object
Finds the index of the first non-flag argument or -1 if there wasn’t one.
-
#flag(names) ⇒ Object
(also: #f)
Create a flag, which is a switch that takes an argument.
- #flags ⇒ Object
-
#long_desc(long_desc) ⇒ Object
Provide a longer, more detailed description.
-
#on_error(&a_proc) ⇒ Object
Define a block to run if an error occurs.
-
#parse_options(args) ⇒ Object
Returns an array of four values: * global options (as a Hash) * Command * command options (as a Hash) * arguments (as an Array).
-
#parse_options_helper(args, global_options, command, command_options, arguments) ⇒ Object
Recursive helper for parsing command line options [args] the arguments that have yet to be processed [global_options] the global options hash [command] the Command that has been identified (or nil if not identified yet) [command_options] options for Command [arguments] the arguments for Command.
-
#post(&a_proc) ⇒ Object
Define a block to run after command hase been executed, only if there was not an error.
-
#pre(&a_proc) ⇒ Object
Define a block to run after command line arguments are parsed but before any command is run.
- #program_name(override = nil) ⇒ Object
-
#reset ⇒ Object
Reset the GLI module internal data structures; mostly for testing.
-
#run(args) ⇒ Object
Runs whatever command is needed based on the arguments.
-
#switch(names) ⇒ Object
(also: #s)
Create a switch.
- #switches ⇒ Object
Instance Method Details
#arg_name(name) ⇒ Object
describe the argument name of the next flag
38 |
# File 'lib/gli.rb', line 38 def arg_name(name); @@next_arg_name = name; end |
#clear_nexts ⇒ Object
147 148 149 150 151 152 |
# File 'lib/gli.rb', line 147 def clear_nexts @@next_desc = nil @@next_arg_name = nil @@next_default_value = nil @@next_long_desc = nil end |
#command(names) {|command| ... } ⇒ Object Also known as: c
Define a command.
57 58 59 60 61 62 |
# File 'lib/gli.rb', line 57 def command(names) command = Command.new(names,@@next_desc,@@next_arg_name,@@next_long_desc) commands[command.name] = command yield command clear_nexts end |
#commands ⇒ Object
158 |
# File 'lib/gli.rb', line 158 def commands; @@commands ||= {}; end |
#default_value(val) ⇒ Object
set the default value of the next flag
40 |
# File 'lib/gli.rb', line 40 def default_value(val); @@next_default_value = val; end |
#desc(description) ⇒ Object Also known as: d
describe the next switch, flag, or command. This should be a short, one-line description
31 |
# File 'lib/gli.rb', line 31 def desc(description); @@next_desc = description; end |
#find_command(name) ⇒ Object
253 254 255 256 257 258 259 260 261 |
# File 'lib/gli.rb', line 253 def find_command(name) sym = name.to_sym return commands[name.to_sym] if commands[sym] commands.keys.each do |command_name| command = commands[command_name] return command if (command.aliases && command.aliases.include?(sym)) end nil end |
#find_non_flag_index(args) ⇒ Object
Finds the index of the first non-flag argument or -1 if there wasn’t one.
134 135 136 137 138 139 140 |
# File 'lib/gli.rb', line 134 def find_non_flag_index(args) args.each_index do |i| return i if args[i] =~ /^[^\-]/; return i-1 if args[i] =~ /^\-\-$/; end -1; end |
#flag(names) ⇒ Object Also known as: f
Create a flag, which is a switch that takes an argument
43 44 45 46 47 |
# File 'lib/gli.rb', line 43 def flag(names) flag = Flag.new(names,@@next_desc,@@next_arg_name,@@next_default_value,@@next_long_desc) flags[flag.name] = flag clear_nexts end |
#flags ⇒ Object
156 |
# File 'lib/gli.rb', line 156 def flags; @@flags ||= {}; end |
#long_desc(long_desc) ⇒ Object
Provide a longer, more detailed description. This will be reformatted and wrapped to fit in 80 columns
35 |
# File 'lib/gli.rb', line 35 def long_desc(long_desc); @@next_long_desc = long_desc; end |
#on_error(&a_proc) ⇒ Object
Define a block to run if an error occurs. The block will receive any Exception that was caught. It should return false to avoid the built-in error handling (which basically just prints out a message)
85 86 87 |
# File 'lib/gli.rb', line 85 def on_error(&a_proc) @@error_block = a_proc end |
#parse_options(args) ⇒ Object
Returns an array of four values:
* global options (as a Hash)
* Command
* command options (as a Hash)
* arguments (as an Array)
125 126 127 128 129 130 |
# File 'lib/gli.rb', line 125 def (args) ,command,,arguments = (args.clone,Hash.new,nil,Hash.new,Array.new) flags.each { |name,flag| [name] = flag.default_value if ![name] } command.flags.each { |name,flag| [name] = flag.default_value if ![name] } return [,command,,arguments] end |
#parse_options_helper(args, global_options, command, command_options, arguments) ⇒ Object
Recursive helper for parsing command line options
- args
-
the arguments that have yet to be processed
- global_options
-
the global options hash
- command
-
the Command that has been identified (or nil if not identified yet)
- command_options
-
options for Command
- arguments
-
the arguments for Command
This works by finding the first non-switch/flag argument, and taking that sublist and trying to pick out flags and switches. After this is done, one of the following is true:
* the sublist is empty - in this case, go again, as there might be more flags to parse
* the sublist has a flag left in it - unknown flag; we bail
* the sublist has a non-flag left in it - this is the command (or the start of the arguments list)
This sort does the same thing in two phases; in the first phase, the command hasn’t been identified, so we are looking for global switches and flags, ending when we get the command.
Once the command has been found, we start looking for command-specific flags and switches. When those have been found, we know the rest of the argument list is arguments for the command
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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/gli.rb', line 178 def (args,,command,,arguments) non_flag_i = find_non_flag_index(args) all_flags = false if non_flag_i == 0 # no flags if !command command_name = args.shift command = find_command(command_name) raise "Unknown command '#{command_name}'" if !command return (args,,command,,arguments) else return ,command,,arguments | args end elsif non_flag_i == -1 all_flags = true end try_me = args[0..non_flag_i] rest = args[(non_flag_i+1)..args.length] if all_flags try_me = args rest = [] end # Suck up whatever options we can switch_hash = switches flag_hash = flags = if command switch_hash = command.switches flag_hash = command.flags = end switch_hash.each do |name,switch| value = switch.get_value!(try_me) [name] = value if ![name] end flag_hash.each do |name,flag| value = flag.get_value!(try_me) [name] = value if ![name] end if try_me.empty? return [,command,,arguments] if rest.empty? # If we have no more options we've parsed them all # and rest may have more return (rest,,command,,arguments) else if command check = rest check = rest | try_me if all_flags check.each() do |arg| if arg =~ /^\-\-$/ try_me.delete arg break end raise "Unknown argument #{arg}" if arg =~ /^\-/ end return [,command,,try_me | rest] else # Now we have our command name command_name = try_me.shift raise "Unknown argument #{command_name}" if command_name =~ /^\-/ command = find_command(command_name) raise "Unknown command '#{command_name}'" if !command return (rest,,command,,arguments) end end end |
#post(&a_proc) ⇒ Object
Define a block to run after command hase been executed, only if there was not an error. The block will receive the global-options,command,options, and arguments
77 78 79 |
# File 'lib/gli.rb', line 77 def post(&a_proc) @@post_block = a_proc end |
#pre(&a_proc) ⇒ Object
Define a block to run after command line arguments are parsed but before any command is run. If this block raises an exception the command specified will not be executed. The block will receive the global-options,command,options, and arguments If this block evaluates to true, the program will proceed; otherwise the program will end immediately
70 71 72 |
# File 'lib/gli.rb', line 70 def pre(&a_proc) @@pre_block = a_proc end |
#program_name(override = nil) ⇒ Object
113 114 115 116 117 118 |
# File 'lib/gli.rb', line 113 def program_name(override=nil) if override @@program_name = override end @@program_name end |
#reset ⇒ Object
Reset the GLI module internal data structures; mostly for testing
22 23 24 25 26 27 |
# File 'lib/gli.rb', line 22 def reset switches.clear flags.clear commands.clear clear_nexts end |
#run(args) ⇒ Object
Runs whatever command is needed based on the arguments.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/gli.rb', line 90 def run(args) rdoc = RDocCommand.new commands[:rdoc] = rdoc if !commands[:rdoc] commands[:help] = DefaultHelpCommand.new(rdoc) if !commands[:help] begin ,command,,arguments = (args) proceed = true proceed = @@pre_block.call(,command,,arguments) if @@pre_block if proceed command = commands[:help] if !command command.execute(,,arguments) @@post_block.call(,command,,arguments) if @@post_block end rescue Exception => ex regular_error_handling = true regular_error_handling = @@error_block.call(ex) if @@error_block if regular_error_handling puts "error: #{ex.}" end end end |
#switch(names) ⇒ Object Also known as: s
Create a switch
50 51 52 53 54 |
# File 'lib/gli.rb', line 50 def switch(names) switch = Switch.new(names,@@next_desc,@@next_long_desc) switches[switch.name] = switch clear_nexts end |
#switches ⇒ Object
157 |
# File 'lib/gli.rb', line 157 def switches; @@switches ||= {}; end |