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
39 |
# File 'lib/gli.rb', line 39 def arg_name(name); @@next_arg_name = name; end |
#clear_nexts ⇒ Object
148 149 150 151 152 153 |
# File 'lib/gli.rb', line 148 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.
58 59 60 61 62 63 |
# File 'lib/gli.rb', line 58 def command(*names) command = Command.new([names].flatten,@@next_desc,@@next_arg_name,@@next_long_desc) commands[command.name] = command yield command clear_nexts end |
#commands ⇒ Object
159 |
# File 'lib/gli.rb', line 159 def commands; @@commands ||= {}; end |
#default_value(val) ⇒ Object
set the default value of the next flag
41 |
# File 'lib/gli.rb', line 41 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
32 |
# File 'lib/gli.rb', line 32 def desc(description); @@next_desc = description; end |
#find_command(name) ⇒ Object
254 255 256 257 258 259 260 261 262 |
# File 'lib/gli.rb', line 254 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.
135 136 137 138 139 140 141 |
# File 'lib/gli.rb', line 135 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
44 45 46 47 48 |
# File 'lib/gli.rb', line 44 def flag(*names) flag = Flag.new([names].flatten,@@next_desc,@@next_arg_name,@@next_default_value,@@next_long_desc) flags[flag.name] = flag clear_nexts end |
#flags ⇒ Object
157 |
# File 'lib/gli.rb', line 157 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
36 |
# File 'lib/gli.rb', line 36 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)
86 87 88 |
# File 'lib/gli.rb', line 86 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)
126 127 128 129 130 131 |
# File 'lib/gli.rb', line 126 def (args) ,command,,arguments = (args.clone,Options.new,nil,Options.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
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 252 |
# File 'lib/gli.rb', line 179 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
78 79 80 |
# File 'lib/gli.rb', line 78 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
71 72 73 |
# File 'lib/gli.rb', line 71 def pre(&a_proc) @@pre_block = a_proc end |
#program_name(override = nil) ⇒ Object
114 115 116 117 118 119 |
# File 'lib/gli.rb', line 114 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
23 24 25 26 27 28 |
# File 'lib/gli.rb', line 23 def reset switches.clear flags.clear commands.clear clear_nexts end |
#run(args) ⇒ Object
Runs whatever command is needed based on the arguments.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/gli.rb', line 91 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
51 52 53 54 55 |
# File 'lib/gli.rb', line 51 def switch(*names) switch = Switch.new([names].flatten,@@next_desc,@@next_long_desc) switches[switch.name] = switch clear_nexts end |
#switches ⇒ Object
158 |
# File 'lib/gli.rb', line 158 def switches; @@switches ||= {}; end |