gli 1.2.5 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +1 -1
- data/bin/gli +1 -1
- data/gli.rdoc +0 -1
- data/lib/gli.rb +168 -71
- data/lib/gli/command.rb +48 -21
- data/lib/gli/command_line_token.rb +8 -7
- data/lib/gli/exceptions.rb +22 -5
- data/lib/gli/flag.rb +1 -1
- data/lib/gli/options.rb +3 -0
- data/lib/gli/switch.rb +3 -3
- data/lib/gli/terminal.rb +14 -7
- data/lib/gli_version.rb +1 -1
- data/lib/support/help.rb +8 -6
- data/lib/support/initconfig.rb +2 -3
- data/lib/support/rdoc.rb +40 -3
- data/lib/support/scaffold.rb +7 -6
- metadata +77 -8
data/README.rdoc
CHANGED
@@ -39,7 +39,7 @@ Though likely works on various other versions.
|
|
39
39
|
|
40
40
|
== Documentation
|
41
41
|
|
42
|
-
Extensive documentation is {available at the wiki}[https://github.com/davetron5000/gli/wiki]
|
42
|
+
Extensive documentation is {available at the wiki}[https://github.com/davetron5000/gli/wiki]. For API Documentation, start with the GLI module.
|
43
43
|
|
44
44
|
== Links
|
45
45
|
|
data/bin/gli
CHANGED
data/gli.rdoc
CHANGED
@@ -15,7 +15,6 @@ These options are available for any command and are specified before the name of
|
|
15
15
|
This is the directory where the projects directory will be made, so if you specify a project name foo and the root dir of ., the directory ./foo will be created
|
16
16
|
|
17
17
|
[<tt>-v</tt>] Be verbose
|
18
|
-
[<tt>--version</tt>] Show version
|
19
18
|
== Commands
|
20
19
|
[<tt>help</tt>] Shows list of commands or help for one command
|
21
20
|
[<tt>init</tt>] Create a new GLI-based project
|
data/lib/gli.rb
CHANGED
@@ -23,9 +23,15 @@ module GLI
|
|
23
23
|
@@config_file = nil
|
24
24
|
@@use_openstruct = false
|
25
25
|
@@version = nil
|
26
|
+
@@stderr = $stderr
|
26
27
|
|
27
|
-
#
|
28
|
-
def
|
28
|
+
# Override the device of stderr; exposed only for testing
|
29
|
+
def error_device=(e) #:nodoc:
|
30
|
+
@@stderr = e
|
31
|
+
end
|
32
|
+
|
33
|
+
# Reset the GLI module internal data structures; mostly useful for testing
|
34
|
+
def reset # :nodoc:
|
29
35
|
switches.clear
|
30
36
|
flags.clear
|
31
37
|
commands.clear
|
@@ -35,21 +41,51 @@ module GLI
|
|
35
41
|
clear_nexts
|
36
42
|
end
|
37
43
|
|
38
|
-
#
|
44
|
+
# Describe the next switch, flag, or command. This should be a
|
39
45
|
# short, one-line description
|
46
|
+
#
|
47
|
+
# +description+:: A String of the short descripiton of the switch, flag, or command following
|
40
48
|
def desc(description); @@next_desc = description; end
|
41
49
|
|
42
50
|
# Provide a longer, more detailed description. This
|
43
|
-
# will be reformatted and wrapped to fit in
|
51
|
+
# will be reformatted and wrapped to fit in the terminal's columns
|
52
|
+
#
|
53
|
+
# +long_desc+:: A String that is s longer description of the switch, flag, or command following.
|
44
54
|
def long_desc(long_desc); @@next_long_desc = long_desc; end
|
45
55
|
|
46
|
-
#
|
56
|
+
# Describe the argument name of the next flag. It's important to keep
|
57
|
+
# this VERY short and, ideally, without any spaces (see Example).
|
58
|
+
#
|
59
|
+
# +name+:: A String that *briefly* describes the argument given to the following command or flag.
|
60
|
+
#
|
61
|
+
# Example:
|
62
|
+
# desc 'Set the filename'
|
63
|
+
# arg_name 'file_name'
|
64
|
+
# flag [:f,:filename]
|
65
|
+
#
|
66
|
+
# Produces:
|
67
|
+
# -f, --filename=file_name Set the filename
|
47
68
|
def arg_name(name); @@next_arg_name = name; end
|
48
69
|
|
49
70
|
# set the default value of the next flag
|
71
|
+
#
|
72
|
+
# +val+:: A String reprensenting the default value to be used for the following flag if the user doesn't specify one
|
73
|
+
# and, when using a config file, the config also doesn't specify one
|
50
74
|
def default_value(val); @@next_default_value = val; end
|
51
75
|
|
52
76
|
# Create a flag, which is a switch that takes an argument
|
77
|
+
#
|
78
|
+
# +names+:: a String or Symbol, or an Array of String or Symbol that represent all the different names
|
79
|
+
# and aliases for this flag.
|
80
|
+
#
|
81
|
+
# Example:
|
82
|
+
#
|
83
|
+
# desc 'Set the filename'
|
84
|
+
# flag [:f,:filename,'file-name']
|
85
|
+
#
|
86
|
+
# Produces:
|
87
|
+
#
|
88
|
+
# -f, --filename, --file-name=arg Set the filename
|
53
89
|
def flag(*names)
|
54
90
|
names = [names].flatten
|
55
91
|
verify_unused(names,flags,switches,"in global options")
|
@@ -58,7 +94,10 @@ module GLI
|
|
58
94
|
clear_nexts
|
59
95
|
end
|
60
96
|
|
61
|
-
# Create a switch
|
97
|
+
# Create a switch, which is a command line flag that takes no arguments (thus, it _switches_ something on)
|
98
|
+
#
|
99
|
+
# +names+:: a String or Symbol, or an Array of String or Symbol that represent all the different names
|
100
|
+
# and aliases for this switch.
|
62
101
|
def switch(*names)
|
63
102
|
names = [names].flatten
|
64
103
|
verify_unused(names,flags,switches,"in global options")
|
@@ -67,8 +106,11 @@ module GLI
|
|
67
106
|
clear_nexts
|
68
107
|
end
|
69
108
|
|
70
|
-
# Sets
|
71
|
-
#
|
109
|
+
# Sets that this app uses a config file as well as the name of the config file.
|
110
|
+
#
|
111
|
+
# +filename+:: A String representing the path to the file to use for the config file. If it's an absolute
|
112
|
+
# path, this is treated as the path to the file. If it's *not*, it's treated as relative to the user's home
|
113
|
+
# directory as produced by <code>Etc.getpwuid.dir</code>.
|
72
114
|
def config_file(filename)
|
73
115
|
if filename =~ /^\//
|
74
116
|
@@config_file = filename
|
@@ -79,7 +121,11 @@ module GLI
|
|
79
121
|
@@config_file
|
80
122
|
end
|
81
123
|
|
82
|
-
# Define a command.
|
124
|
+
# Define a new command. This takes a block that will be given an instance of the Command that was created.
|
125
|
+
# You then may call methods on this object to define aspects of that Command.
|
126
|
+
#
|
127
|
+
# +names+:: a String or Symbol, or an Array of String or Symbol that represent all the different names and aliases for this command.
|
128
|
+
#
|
83
129
|
def command(*names)
|
84
130
|
command = Command.new([names].flatten,@@next_desc,@@next_arg_name,@@next_long_desc)
|
85
131
|
commands[command.name] = command
|
@@ -97,8 +143,8 @@ module GLI
|
|
97
143
|
@@pre_block = a_proc
|
98
144
|
end
|
99
145
|
|
100
|
-
# Define a block to run after command
|
101
|
-
# if there was not an error
|
146
|
+
# Define a block to run after the command was executed, <b>only
|
147
|
+
# if there was not an error</b>.
|
102
148
|
# The block will receive the global-options,command,options, and arguments
|
103
149
|
def post(&a_proc)
|
104
150
|
@@post_block = a_proc
|
@@ -106,65 +152,103 @@ module GLI
|
|
106
152
|
|
107
153
|
# Define a block to run if an error occurs.
|
108
154
|
# The block will receive any Exception that was caught.
|
109
|
-
# It should
|
110
|
-
# prints out a message)
|
155
|
+
# It should evaluate to false to avoid the built-in error handling (which basically just
|
156
|
+
# prints out a message). GLI uses a variety of exceptions that you can use to find out what
|
157
|
+
# errors might've occurred during command-line parsing:
|
158
|
+
# * GLI::CustomExit
|
159
|
+
# * GLI::UnknownCommandArgument
|
160
|
+
# * GLI::UnknownGlobalArgument
|
161
|
+
# * GLI::UnknownCommand
|
162
|
+
# * GLI::BadCommandLine
|
111
163
|
def on_error(&a_proc)
|
112
164
|
@@error_block = a_proc
|
113
165
|
end
|
114
166
|
|
115
167
|
# Indicate the version of your application
|
168
|
+
#
|
169
|
+
# +version+:: String containing the version of your application.
|
116
170
|
def version(version)
|
117
171
|
@@version = version
|
118
172
|
end
|
119
173
|
|
120
|
-
# Call this with
|
121
|
-
#
|
122
|
-
#
|
174
|
+
# Call this with +true+ will cause the +global_options+ and
|
175
|
+
# +options+ passed to your code to be wrapped in
|
176
|
+
# Options, which is a subclass of +OpenStruct+ that adds
|
123
177
|
# <tt>[]</tt> and <tt>[]=</tt> methods.
|
178
|
+
#
|
179
|
+
# +use_openstruct+:: a Boolean indicating if we should use OpenStruct instead of Hashes
|
124
180
|
def use_openstruct(use_openstruct)
|
125
181
|
@@use_openstruct = use_openstruct
|
126
182
|
end
|
127
183
|
|
128
184
|
# Runs whatever command is needed based on the arguments.
|
129
185
|
#
|
130
|
-
# args
|
186
|
+
# +args+:: the command line ARGV array
|
131
187
|
#
|
132
188
|
# Returns a number that would be a reasonable exit code
|
133
|
-
def run(args)
|
189
|
+
def run(args) #:nodoc:
|
134
190
|
rdoc = RDocCommand.new
|
135
191
|
commands[:rdoc] = rdoc if !commands[:rdoc]
|
136
192
|
commands[:help] = DefaultHelpCommand.new(@@version,rdoc) if !commands[:help]
|
193
|
+
exit_code = 0
|
137
194
|
begin
|
138
195
|
config = parse_config
|
139
196
|
global_options,command,options,arguments = parse_options(args,config)
|
140
197
|
copy_options_to_aliased_versions(global_options,command,options)
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
proceed = @@pre_block.call(global_options,command,options,arguments) if @@pre_block
|
145
|
-
if proceed
|
198
|
+
global_options = convert_to_openstruct?(global_options)
|
199
|
+
options = convert_to_openstruct?(options)
|
200
|
+
if proceed?(global_options,command,options,arguments)
|
146
201
|
command = commands[:help] if !command
|
147
202
|
command.execute(global_options,options,arguments)
|
148
203
|
@@post_block.call(global_options,command,options,arguments) if @@post_block
|
149
204
|
end
|
150
|
-
0
|
151
205
|
rescue Exception => ex
|
152
|
-
regular_error_handling = true
|
153
|
-
regular_error_handling = @@error_block.call(ex) if @@error_block
|
154
206
|
|
155
|
-
if regular_error_handling
|
156
|
-
$stderr.puts "error: #{ex.message}"
|
157
|
-
end
|
207
|
+
@@stderr.puts error_message(ex) if regular_error_handling?(ex)
|
158
208
|
|
159
209
|
raise ex if ENV['GLI_DEBUG'] == 'true'
|
160
210
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
else
|
211
|
+
exit_code = if ex.respond_to? :exit_code
|
212
|
+
ex.exit_code
|
213
|
+
else
|
165
214
|
-2
|
166
215
|
end
|
167
216
|
end
|
217
|
+
exit_code
|
218
|
+
end
|
219
|
+
|
220
|
+
# True if we should proceed with executing the command; this calls
|
221
|
+
# the pre block if it's defined
|
222
|
+
def proceed?(global_options,command,options,arguments) #:nodoc:
|
223
|
+
if @@pre_block
|
224
|
+
@@pre_block.call(global_options,command,options,arguments)
|
225
|
+
else
|
226
|
+
true
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Returns true if we should proceed with GLI's basic error handling.
|
231
|
+
# This calls the error block if the user provided one
|
232
|
+
def regular_error_handling?(ex) #:nodoc:
|
233
|
+
if @@error_block
|
234
|
+
@@error_block.call(ex)
|
235
|
+
else
|
236
|
+
true
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# Returns a String of the error message to show the user
|
241
|
+
# +ex+:: The exception we caught that launched the error handling routines
|
242
|
+
def error_message(ex) #:nodoc:
|
243
|
+
msg = "error: #{ex.message}"
|
244
|
+
case ex
|
245
|
+
when UnknownCommand
|
246
|
+
msg += ". Use '#{program_name} help' for a list of commands"
|
247
|
+
when UnknownCommandArgument
|
248
|
+
msg += ". Use '#{program_name} help #{ex.command.name}' for a list of command options"
|
249
|
+
when UnknownGlobalArgument
|
250
|
+
msg += ". Use '#{program_name} help' for a list of global options"
|
251
|
+
end
|
168
252
|
end
|
169
253
|
|
170
254
|
# Simpler means of exiting with a custom exit code. This will
|
@@ -174,17 +258,36 @@ module GLI
|
|
174
258
|
raise CustomExit.new(message,exit_code)
|
175
259
|
end
|
176
260
|
|
261
|
+
# Set or get the name of the program, if you don't want the default (which is
|
262
|
+
# the name of the command line program). This
|
263
|
+
# is only used currently in the help and rdoc commands.
|
264
|
+
#
|
265
|
+
# +override+:: A String that represents the name of the program to use, other than the default.
|
266
|
+
#
|
267
|
+
# Returns the current program name, as a String
|
268
|
+
def program_name(override=nil)
|
269
|
+
if override
|
270
|
+
@@program_name = override
|
271
|
+
end
|
272
|
+
@@program_name
|
273
|
+
end
|
274
|
+
|
275
|
+
alias :d :desc
|
276
|
+
alias :f :flag
|
277
|
+
alias :s :switch
|
278
|
+
alias :c :command
|
279
|
+
|
177
280
|
# Possibly returns a copy of the passed-in Hash as an instance of GLI::Option.
|
178
|
-
# By default, it will *not
|
281
|
+
# By default, it will *not*. However by putting <tt>use_openstruct true</tt>
|
179
282
|
# in your CLI definition, it will
|
180
|
-
def
|
283
|
+
def convert_to_openstruct?(options) # :nodoc:
|
181
284
|
@@use_openstruct ? Options.new(options) : options
|
182
285
|
end
|
183
286
|
|
184
287
|
# Copies all options in both global_options and options to keys for the aliases of those flags.
|
185
288
|
# For example, if a flag works with either -f or --flag, this will copy the value from [:f] to [:flag]
|
186
289
|
# to allow the user to access the options by any alias
|
187
|
-
def copy_options_to_aliased_versions(global_options,command,options)
|
290
|
+
def copy_options_to_aliased_versions(global_options,command,options) # :nodoc:
|
188
291
|
copy_options_to_aliases(global_options,self)
|
189
292
|
copy_options_to_aliases(options,command)
|
190
293
|
end
|
@@ -194,7 +297,7 @@ module GLI
|
|
194
297
|
#
|
195
298
|
# options - Hash of options parsed from command line; this is an I/O param
|
196
299
|
# gli_like - Object resonding to flags and switches in the same way that GLI or a Command instance do
|
197
|
-
def copy_options_to_aliases(options,gli_like)
|
300
|
+
def copy_options_to_aliases(options,gli_like) # :nodoc:
|
198
301
|
new_options = {}
|
199
302
|
options.each do |key,value|
|
200
303
|
if gli_like.flags[key] && gli_like.flags[key].aliases
|
@@ -210,7 +313,7 @@ module GLI
|
|
210
313
|
options.merge!(new_options)
|
211
314
|
end
|
212
315
|
|
213
|
-
def parse_config
|
316
|
+
def parse_config # :nodoc:
|
214
317
|
return nil if @@config_file.nil?
|
215
318
|
require 'yaml'
|
216
319
|
if File.exist?(@@config_file)
|
@@ -220,19 +323,12 @@ module GLI
|
|
220
323
|
end
|
221
324
|
end
|
222
325
|
|
223
|
-
def program_name(override=nil)
|
224
|
-
if override
|
225
|
-
@@program_name = override
|
226
|
-
end
|
227
|
-
@@program_name
|
228
|
-
end
|
229
|
-
|
230
326
|
# Returns an array of four values:
|
231
327
|
# * global options (as a Hash)
|
232
328
|
# * Command
|
233
329
|
# * command options (as a Hash)
|
234
330
|
# * arguments (as an Array)
|
235
|
-
def parse_options(args,config=nil)
|
331
|
+
def parse_options(args,config=nil) # :nodoc:
|
236
332
|
command_configs = {}
|
237
333
|
if config.nil?
|
238
334
|
config = {}
|
@@ -247,7 +343,7 @@ module GLI
|
|
247
343
|
|
248
344
|
# Finds the index of the first non-flag
|
249
345
|
# argument or -1 if there wasn't one.
|
250
|
-
def find_non_flag_index(args)
|
346
|
+
def find_non_flag_index(args) # :nodoc:
|
251
347
|
args.each_index do |i|
|
252
348
|
return i if args[i] =~ /^[^\-]/;
|
253
349
|
return i-1 if args[i] =~ /^\-\-$/;
|
@@ -255,12 +351,7 @@ module GLI
|
|
255
351
|
-1;
|
256
352
|
end
|
257
353
|
|
258
|
-
|
259
|
-
alias :f :flag
|
260
|
-
alias :s :switch
|
261
|
-
alias :c :command
|
262
|
-
|
263
|
-
def clear_nexts
|
354
|
+
def clear_nexts # :nodoc:
|
264
355
|
@@next_desc = nil
|
265
356
|
@@next_arg_name = nil
|
266
357
|
@@next_default_value = nil
|
@@ -269,17 +360,23 @@ module GLI
|
|
269
360
|
|
270
361
|
clear_nexts
|
271
362
|
|
272
|
-
def flags
|
273
|
-
|
274
|
-
|
363
|
+
def flags # :nodoc:
|
364
|
+
@@flags ||= {}
|
365
|
+
end
|
366
|
+
def switches # :nodoc:
|
367
|
+
@@switches ||= {}
|
368
|
+
end
|
369
|
+
def commands # :nodoc:
|
370
|
+
@@commands ||= {}
|
371
|
+
end
|
275
372
|
|
276
373
|
# Recursive helper for parsing command line options
|
277
|
-
#
|
278
|
-
#
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
282
|
-
#
|
374
|
+
# <code>args</code>:: the arguments that have yet to be processed
|
375
|
+
# <code>global_options</code>:: the global options hash
|
376
|
+
# <code>command</code>:: the Command that has been identified (or nil if not identified yet)
|
377
|
+
# <code>command_options</code>:: options for Command
|
378
|
+
# <code>arguments</code>:: the arguments for Command
|
379
|
+
# <code>command_configs</code>:: the configuration file for all commands, used as defaults
|
283
380
|
#
|
284
381
|
# This works by finding the first non-switch/flag argument, and taking that sublist and trying to pick out
|
285
382
|
# flags and switches. After this is done, one of the following is true:
|
@@ -292,7 +389,7 @@ module GLI
|
|
292
389
|
#
|
293
390
|
# Once the command has been found, we start looking for command-specific flags and switches.
|
294
391
|
# When those have been found, we know the rest of the argument list is arguments for the command
|
295
|
-
def parse_options_helper(args,global_options,command,command_options,arguments,command_configs)
|
392
|
+
def parse_options_helper(args,global_options,command,command_options,arguments,command_configs) # :nodoc:
|
296
393
|
non_flag_i = find_non_flag_index(args)
|
297
394
|
all_flags = false
|
298
395
|
if non_flag_i == 0
|
@@ -300,7 +397,7 @@ module GLI
|
|
300
397
|
if !command
|
301
398
|
command_name = args.shift
|
302
399
|
command = find_command(command_name)
|
303
|
-
raise
|
400
|
+
raise UnknownCommand.new("Unknown command '#{command_name}'") if !command
|
304
401
|
return parse_options_helper(args,
|
305
402
|
global_options,
|
306
403
|
command,
|
@@ -366,16 +463,16 @@ module GLI
|
|
366
463
|
try_me.delete arg
|
367
464
|
break
|
368
465
|
end
|
369
|
-
raise
|
466
|
+
raise UnknownCommandArgument.new("Unknown option #{arg}",command) if arg =~ /^\-/
|
370
467
|
end
|
371
468
|
return [global_options,command,command_options,try_me + rest]
|
372
469
|
else
|
373
470
|
# Now we have our command name
|
374
471
|
command_name = try_me.shift
|
375
|
-
raise
|
472
|
+
raise UnknownGlobalArgument.new("Unknown option #{command_name}") if command_name =~ /^\-/
|
376
473
|
|
377
474
|
command = find_command(command_name)
|
378
|
-
raise
|
475
|
+
raise UnknownCommand.new("Unknown command '#{command_name}'") if !command
|
379
476
|
|
380
477
|
return parse_options_helper(rest,
|
381
478
|
global_options,
|
@@ -388,11 +485,11 @@ module GLI
|
|
388
485
|
|
389
486
|
end
|
390
487
|
|
391
|
-
def default_command_options(command,command_configs)
|
488
|
+
def default_command_options(command,command_configs) # :nodoc:
|
392
489
|
options = (command_configs && command_configs[command.name.to_sym]) || {}
|
393
490
|
end
|
394
491
|
|
395
|
-
def find_command(name)
|
492
|
+
def find_command(name) # :nodoc:
|
396
493
|
sym = name.to_sym
|
397
494
|
return commands[name.to_sym] if commands[sym]
|
398
495
|
commands.keys.each do |command_name|
|
@@ -403,7 +500,7 @@ module GLI
|
|
403
500
|
end
|
404
501
|
|
405
502
|
# Checks that the names passed in have not been used in another flag or option
|
406
|
-
def verify_unused(names,flags,switches,context)
|
503
|
+
def verify_unused(names,flags,switches,context) # :nodoc:
|
407
504
|
names.each do |name|
|
408
505
|
verify_unused_in_option(name,flags,"flag",context)
|
409
506
|
verify_unused_in_option(name,switches,"switch",context)
|
@@ -412,7 +509,7 @@ module GLI
|
|
412
509
|
|
413
510
|
private
|
414
511
|
|
415
|
-
def verify_unused_in_option(name,option_like,type,context)
|
512
|
+
def verify_unused_in_option(name,option_like,type,context) # :nodoc:
|
416
513
|
raise ArgumentError.new("#{name} has already been specified as a #{type} #{context}") if option_like[name]
|
417
514
|
option_like.each do |one_option_name,one_option|
|
418
515
|
if one_option.aliases
|
data/lib/gli/command.rb
CHANGED
@@ -1,47 +1,62 @@
|
|
1
1
|
require 'gli/command_line_token.rb'
|
2
2
|
|
3
3
|
module GLI
|
4
|
-
# A command to be run, in context of global flags and switches
|
4
|
+
# A command to be run, in context of global flags and switches. You are given an instance of this class
|
5
|
+
# to the block you use for GLI#command. You then use the methods described here to describe the
|
6
|
+
# command-specific command-line arguments, much as you use the methods in GLI to describe the global
|
7
|
+
# command-line interface
|
5
8
|
class Command < CommandLineToken
|
6
9
|
|
7
10
|
# Create a new command
|
8
11
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
def initialize(names,description,arguments_name=nil,long_desc=nil)
|
12
|
+
# +names+:: A String, Symbol, or Array of String or Symbol that represents the name(s) of this command.
|
13
|
+
# +description+:: short description of this command as a Strign
|
14
|
+
# +arguments_name+:: description of the arguments as a String, or nil if this command doesn't take arguments
|
15
|
+
# +long_desc+:: a longer description of the command, possibly with multiple lines and text formatting
|
16
|
+
def initialize(names,description,arguments_name=nil,long_desc=nil) # :nodoc:
|
15
17
|
super(names,description,long_desc)
|
16
18
|
@arguments_description = arguments_name || ''
|
17
19
|
clear_nexts
|
18
20
|
end
|
19
21
|
|
20
|
-
|
22
|
+
# Return the arguments description
|
23
|
+
def arguments_description #:nodoc:
|
24
|
+
@arguments_description
|
25
|
+
end
|
21
26
|
|
22
|
-
|
27
|
+
# Return the Array of the command's names
|
28
|
+
def names #:nodoc:
|
23
29
|
all_forms
|
24
30
|
end
|
25
31
|
|
26
|
-
|
32
|
+
# Get the usage string
|
33
|
+
# CR: This should probably not be here
|
34
|
+
def usage #:nodoc:
|
27
35
|
usage = name.to_s
|
28
|
-
usage += ' [options]' if !flags.empty? || !switches.empty?
|
36
|
+
usage += ' [command options]' if !flags.empty? || !switches.empty?
|
29
37
|
usage += ' ' + @arguments_description if @arguments_description
|
30
38
|
usage
|
31
39
|
end
|
32
40
|
|
33
|
-
|
34
|
-
def
|
41
|
+
# Return the flags as a Hash
|
42
|
+
def flags #:nodoc:
|
43
|
+
@flags ||= {}
|
44
|
+
end
|
45
|
+
# Return the switches as a Hash
|
46
|
+
def switches #:nodoc:
|
47
|
+
@switches ||= {}
|
48
|
+
end
|
35
49
|
|
36
|
-
# describe the next switch or flag
|
50
|
+
# describe the next switch or flag just as GLI#desc does.
|
37
51
|
def desc(description); @next_desc = description; end
|
38
|
-
# long description of this flag/switch
|
52
|
+
# set the long description of this flag/switch, just as GLI#long_desc does.
|
39
53
|
def long_desc(long_desc); @next_long_desc = long_desc; end
|
40
|
-
# describe the argument name of the next flag
|
54
|
+
# describe the argument name of the next flag, just as GLI#arg_name does.
|
41
55
|
def arg_name(name); @next_arg_name = name; end
|
42
|
-
# set the default value of the next flag
|
56
|
+
# set the default value of the next flag, just as GLI#default_value does.
|
43
57
|
def default_value(val); @next_default_value = val; end
|
44
58
|
|
59
|
+
# Create a command-specific flag, similar to GLI#flag
|
45
60
|
def flag(*names)
|
46
61
|
names = [names].flatten
|
47
62
|
GLI.verify_unused(names,flags,switches,"in command #{name}")
|
@@ -50,7 +65,7 @@ module GLI
|
|
50
65
|
clear_nexts
|
51
66
|
end
|
52
67
|
|
53
|
-
# Create a switch
|
68
|
+
# Create a command-specific switch, similar to GLI#switch
|
54
69
|
def switch(*names)
|
55
70
|
names = [names].flatten
|
56
71
|
GLI.verify_unused(names,flags,switches,"in command #{name}")
|
@@ -59,22 +74,34 @@ module GLI
|
|
59
74
|
clear_nexts
|
60
75
|
end
|
61
76
|
|
77
|
+
# Define the action to take when the user executes this command
|
78
|
+
#
|
79
|
+
# +block+:: A block of code to execute. The block will be given 3 arguments:
|
80
|
+
# +global_options+:: A Hash (or Options, see GLI#use_openstruct) of the _global_ options specified
|
81
|
+
# by the user, with defaults set and config file values used (if using a config file, see
|
82
|
+
# GLI#config_file)
|
83
|
+
# +options+:: A Hash (or Options, see GLI#use_openstruct) of the command-specific options specified by the
|
84
|
+
# user, with defaults set and config file values used (if using a config file, see GLI#config_file)
|
85
|
+
# +arguments+:: An Array of Strings representing the unparsed command line arguments
|
86
|
+
# The block's result value is not used; raise an exception or use GLI#exit_now! if you need an early exit based
|
87
|
+
# on an error condition
|
62
88
|
def action(&block)
|
63
89
|
@action = block
|
64
90
|
end
|
65
91
|
|
66
|
-
def self.name_as_string(name)
|
92
|
+
def self.name_as_string(name) #:nodoc:
|
67
93
|
name.to_s
|
68
94
|
end
|
69
95
|
|
70
|
-
def clear_nexts
|
96
|
+
def clear_nexts #:nodoc:
|
71
97
|
@next_desc = nil
|
72
98
|
@next_arg_name = nil
|
73
99
|
@next_default_value = nil
|
74
100
|
@next_long_desc = nil
|
75
101
|
end
|
76
102
|
|
77
|
-
|
103
|
+
# Executes the command
|
104
|
+
def execute(global_options,options,arguments) #:nodoc:
|
78
105
|
@action.call(global_options,options,arguments)
|
79
106
|
end
|
80
107
|
end
|
@@ -1,22 +1,23 @@
|
|
1
1
|
module GLI
|
2
|
-
#
|
2
|
+
# Abstract base class for a logical element of a command line, mostly so that subclasses can have similar
|
3
3
|
# initialization and interface
|
4
4
|
class CommandLineToken
|
5
|
-
attr_reader :name
|
6
|
-
attr_reader :aliases
|
7
|
-
attr_reader :description
|
8
|
-
attr_reader :long_description
|
5
|
+
attr_reader :name #:ndoc:
|
6
|
+
attr_reader :aliases #:ndoc:
|
7
|
+
attr_reader :description #:ndoc:
|
8
|
+
attr_reader :long_description #:ndoc:
|
9
9
|
|
10
|
-
def initialize(names,description,long_description=nil)
|
10
|
+
def initialize(names,description,long_description=nil) #:ndoc:
|
11
11
|
@description = description
|
12
12
|
@long_description = long_description
|
13
13
|
@name,@aliases,@names = parse_names(names)
|
14
14
|
end
|
15
15
|
|
16
|
-
def usage
|
16
|
+
def usage #:nodoc:
|
17
17
|
all_forms
|
18
18
|
end
|
19
19
|
|
20
|
+
# Sort based on name
|
20
21
|
def <=>(other)
|
21
22
|
self.name.to_s <=> other.name.to_s
|
22
23
|
end
|
data/lib/gli/exceptions.rb
CHANGED
@@ -1,13 +1,30 @@
|
|
1
1
|
module GLI
|
2
2
|
# Indicates that the command line invocation was bad
|
3
3
|
class BadCommandLine < Exception
|
4
|
-
def
|
4
|
+
def exit_code; -1; end
|
5
|
+
end
|
6
|
+
|
7
|
+
# Indicates the bad command line was an unknown command
|
8
|
+
class UnknownCommand < BadCommandLine
|
9
|
+
end
|
10
|
+
|
11
|
+
# Indicates the bad command line was an unknown global argument
|
12
|
+
class UnknownGlobalArgument < BadCommandLine
|
13
|
+
end
|
14
|
+
|
15
|
+
# Indicates the bad command line was an unknown command argument
|
16
|
+
class UnknownCommandArgument < BadCommandLine
|
17
|
+
attr_reader :command
|
18
|
+
# +message+:: the error message to show the user
|
19
|
+
# +command+:: the command we were using to parse command-specific options
|
20
|
+
def initialize(message,command)
|
5
21
|
super(message)
|
22
|
+
@command = command
|
6
23
|
end
|
7
24
|
end
|
8
25
|
|
9
26
|
# Raise this if you want to use an exit status that isn't the default
|
10
|
-
# provided by GLI.
|
27
|
+
# provided by GLI. Note that GLI#exit_now! might be a bit more to your liking.
|
11
28
|
#
|
12
29
|
# Example:
|
13
30
|
#
|
@@ -15,11 +32,11 @@ module GLI
|
|
15
32
|
# raise CustomExit.new("Bad SQL",-6) unless valid_sql?(args[0])
|
16
33
|
#
|
17
34
|
class CustomExit < Exception
|
18
|
-
attr_reader :exit_code
|
35
|
+
attr_reader :exit_code #:nodoc:
|
19
36
|
# Create a custom exit exception
|
20
37
|
#
|
21
|
-
# message
|
22
|
-
# exit_code
|
38
|
+
# +message+:: String containing error message to show the user
|
39
|
+
# +exit_code+:: the exit code to use (as an Int), overridding GLI's default
|
23
40
|
def initialize(message,exit_code)
|
24
41
|
super(message)
|
25
42
|
@exit_code = exit_code
|
data/lib/gli/flag.rb
CHANGED
data/lib/gli/options.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
|
3
3
|
module GLI
|
4
|
+
# Subclass of OpenStruct that provides hash-like methods for #[] and #[]=. Note that is is *not* a Hash.
|
4
5
|
class Options < OpenStruct
|
5
6
|
|
7
|
+
# Return the value of an attribute
|
6
8
|
def[](k)
|
7
9
|
@table[k.to_sym]
|
8
10
|
end
|
9
11
|
|
12
|
+
# Set the value of an attribute
|
10
13
|
def[]=(k, v)
|
11
14
|
@table[k.to_sym] = v
|
12
15
|
end
|
data/lib/gli/switch.rb
CHANGED
@@ -2,7 +2,7 @@ require 'gli/command_line_token.rb'
|
|
2
2
|
|
3
3
|
module GLI
|
4
4
|
# Defines a command line switch
|
5
|
-
class Switch < CommandLineToken
|
5
|
+
class Switch < CommandLineToken #:nodoc:
|
6
6
|
|
7
7
|
def initialize(names,description,long_desc=nil)
|
8
8
|
super(names,description,long_desc)
|
@@ -28,8 +28,8 @@ module GLI
|
|
28
28
|
|
29
29
|
# Finds the switch in the given arg, returning the arg to keep.
|
30
30
|
# Returns an array of size 2:
|
31
|
-
#
|
32
|
-
#
|
31
|
+
# index 0:: true or false if the arg was found
|
32
|
+
# index 1:: the remaining arg to keep in the command line or nil to remove it
|
33
33
|
def find_me(arg)
|
34
34
|
if @names[arg]
|
35
35
|
return [true,nil]
|
data/lib/gli/terminal.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
module GLI
|
2
|
-
# Class to encapsulate stuff about the terminal.
|
2
|
+
# Class to encapsulate stuff about the terminal. This is useful to application developers
|
3
|
+
# as a canonical means to get information about the user's current terminal configuraiton.
|
4
|
+
# GLI uses this to determine the number of columns to use when printing to the screen.
|
5
|
+
#
|
6
|
+
# To access it, use Terminal#instance. This is a singleton mostly to facilitate testing, but
|
7
|
+
# it seems reasonable enough, since there's only one terminal in effect
|
3
8
|
#
|
4
9
|
# Example:
|
5
10
|
#
|
@@ -20,29 +25,31 @@ module GLI
|
|
20
25
|
|
21
26
|
# Set the default size of the terminal to use when we can't figure it out
|
22
27
|
#
|
23
|
-
# size
|
28
|
+
# +size+:: array of two int [cols,rows]
|
24
29
|
def self.default_size=(size)
|
25
30
|
@@default_size = size
|
26
31
|
end
|
27
32
|
|
28
|
-
# Provide access to the shared instance
|
33
|
+
# Provide access to the shared instance.
|
29
34
|
def self.instance; @@instance ||= Terminal.new; end
|
30
35
|
|
31
36
|
# Call this to cause methods to throw exceptions rather than return a sane default. You
|
32
37
|
# probably don't want to call this unless you are writing tests
|
33
|
-
def make_unsafe
|
38
|
+
def make_unsafe!
|
34
39
|
@unsafe = true
|
35
40
|
end
|
36
41
|
|
37
42
|
# Returns true if the given command exists on this system
|
38
43
|
#
|
39
|
-
# command
|
44
|
+
# +command+:: The command, as a String, to check for, without any path information.
|
40
45
|
def command_exists?(command)
|
41
46
|
ENV['PATH'].split(File::PATH_SEPARATOR).any? {|d| File.exists? File.join(d, command) }
|
42
47
|
end
|
43
48
|
|
44
|
-
#
|
45
|
-
#
|
49
|
+
# Get the size of the current terminal.
|
50
|
+
# Ripped from hirb[https://github.com/cldwalker/hirb/blob/master/lib/hirb/util.rb]
|
51
|
+
#
|
52
|
+
# Returns an Array of size two Ints representing the terminal width and height
|
46
53
|
def size
|
47
54
|
if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
|
48
55
|
[ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
|
data/lib/gli_version.rb
CHANGED
data/lib/support/help.rb
CHANGED
@@ -3,9 +3,9 @@ require 'gli/command'
|
|
3
3
|
require 'gli/terminal'
|
4
4
|
|
5
5
|
module GLI
|
6
|
-
class DefaultHelpCommand < Command
|
6
|
+
class DefaultHelpCommand < Command #:nodoc:
|
7
7
|
@@output = $stdout
|
8
|
-
# Exposed for testing
|
8
|
+
# Exposed for testing
|
9
9
|
def self.output_device=(o); @@output = o; end
|
10
10
|
|
11
11
|
def initialize(version,*omit_from_list)
|
@@ -47,18 +47,20 @@ module GLI
|
|
47
47
|
private
|
48
48
|
|
49
49
|
def list_global_flags
|
50
|
-
usage = "usage: #{GLI.program_name}
|
50
|
+
usage = "usage: #{GLI.program_name} "
|
51
51
|
all_options = GLI.switches.merge(GLI.flags)
|
52
52
|
if !all_options.empty?
|
53
|
-
|
53
|
+
usage += "[global options] "
|
54
54
|
end
|
55
|
+
usage += "command"
|
56
|
+
usage += ' [command options]'
|
55
57
|
@@output.puts usage
|
56
58
|
@@output.puts
|
57
59
|
if @version
|
58
60
|
@@output.puts "Version: #{@version}"
|
59
61
|
@@output.puts
|
60
62
|
end
|
61
|
-
@@output.puts 'Options:' if !all_options.empty?
|
63
|
+
@@output.puts 'Global Options:' if !all_options.empty?
|
62
64
|
output_command_tokens_for_help(all_options)
|
63
65
|
@@output.puts if !all_options.empty?
|
64
66
|
end
|
@@ -85,7 +87,7 @@ module GLI
|
|
85
87
|
all_options = command.switches.merge(command.flags)
|
86
88
|
if !all_options.empty?
|
87
89
|
@@output.puts
|
88
|
-
@@output.puts "Options:"
|
90
|
+
@@output.puts "Command Options:"
|
89
91
|
output_command_tokens_for_help(all_options)
|
90
92
|
end
|
91
93
|
else
|
data/lib/support/initconfig.rb
CHANGED
@@ -3,7 +3,7 @@ require 'gli/command'
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
5
|
module GLI
|
6
|
-
class InitConfig < Command
|
6
|
+
class InitConfig < Command # :nodoc:
|
7
7
|
COMMANDS_KEY = 'commands'
|
8
8
|
|
9
9
|
def initialize(config_file_name)
|
@@ -27,8 +27,7 @@ module GLI
|
|
27
27
|
YAML.dump(config,file)
|
28
28
|
end
|
29
29
|
else
|
30
|
-
|
31
|
-
puts 'Use --force to override'
|
30
|
+
raise "Not overwriting existing config file #{@filename}, use --force to override"
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
data/lib/support/rdoc.rb
CHANGED
@@ -2,13 +2,50 @@ require 'gli'
|
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
4
|
module GLI
|
5
|
-
class RDocCommand < Command
|
5
|
+
class RDocCommand < Command # :nodoc:
|
6
6
|
|
7
7
|
def initialize
|
8
|
-
super(:rdoc,'Generates RDoc for your command line interface')
|
8
|
+
super(:rdoc,'Generates RDoc (and other types of documentation) for your command line interface')
|
9
|
+
self.desc 'Create a very basic scaffold for a cheat-style cheatsheet, in addition to rdoc'
|
10
|
+
self.switch 'cheatsheet'
|
11
|
+
self.desc 'Include a manapage suitable for gem man, in addition to rdoc'
|
12
|
+
self.switch 'manpage'
|
13
|
+
self.desc 'Do not create rdoc'
|
14
|
+
self.switch 'no-rdoc'
|
9
15
|
end
|
10
16
|
|
11
|
-
def execute(g,
|
17
|
+
def execute(g,options,a)
|
18
|
+
create_rdoc unless options[:'no-rdoc']
|
19
|
+
create_manpage if options[:manpage]
|
20
|
+
create_cheatsheet if options[:cheatsheet]
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_cheatsheet
|
24
|
+
File.open("#{GLI.program_name}.cheat",'w') do |file|
|
25
|
+
file << GLI.program_name
|
26
|
+
file << "\n"
|
27
|
+
file << GLI.program_name.length.times.inject("") { |a,x| a + "=" }
|
28
|
+
file << "\n"
|
29
|
+
file << "\n"
|
30
|
+
file << "Installation:\n"
|
31
|
+
file << "$ gem install #{GLI.program_name}\n\n"
|
32
|
+
GLI.commands.values.sort.each do |command|
|
33
|
+
next if command == self
|
34
|
+
file << command.description
|
35
|
+
file << "\n"
|
36
|
+
[command.name,command.aliases].flatten.each do |name|
|
37
|
+
next unless name
|
38
|
+
file << "$ #{GLI.program_name} #{name} #{command.arguments_description}\n"
|
39
|
+
end
|
40
|
+
file << "\n"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_manpage
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_rdoc
|
12
49
|
File.open("#{GLI.program_name}.rdoc",'w') do |file|
|
13
50
|
file << "= <tt>#{GLI.program_name}</tt>\n\n"
|
14
51
|
file << " "
|
data/lib/support/scaffold.rb
CHANGED
@@ -2,7 +2,7 @@ require 'gli'
|
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
4
|
module GLI
|
5
|
-
class Scaffold
|
5
|
+
class Scaffold #:nodoc:
|
6
6
|
|
7
7
|
def self.create_scaffold(root_dir,create_test_dir,create_ext_dir,project_name,commands,force=false,dry_run=false)
|
8
8
|
dirs = [File.join(root_dir,project_name,'lib')]
|
@@ -58,6 +58,8 @@ bin/#{project_name}
|
|
58
58
|
s.rdoc_options << '--title' << '#{project_name}' << '--main' << 'README.rdoc' << '-ri'
|
59
59
|
s.bindir = 'bin'
|
60
60
|
s.executables << '#{project_name}'
|
61
|
+
s.add_development_dependency('rake')
|
62
|
+
s.add_development_dependency('rdoc')
|
61
63
|
end
|
62
64
|
EOS
|
63
65
|
end
|
@@ -137,8 +139,7 @@ EOS
|
|
137
139
|
puts "Created #{root_dir}/#{project_name}/Rakefile"
|
138
140
|
File.open("#{root_dir}/#{project_name}/Gemfile",'w') do |bundler_file|
|
139
141
|
bundler_file.puts "source :rubygems"
|
140
|
-
bundler_file.puts "
|
141
|
-
bundler_file.puts "gem: 'rdoc'"
|
142
|
+
bundler_file.puts "gemspec"
|
142
143
|
end
|
143
144
|
puts "Created #{root_dir}/#{project_name}/Gemfile"
|
144
145
|
end
|
@@ -155,7 +156,7 @@ EOS
|
|
155
156
|
# have this method, so we add it so we get resolved symlinks
|
156
157
|
# and compatibility
|
157
158
|
unless File.respond_to? :realpath
|
158
|
-
class File
|
159
|
+
class File #:nodoc:
|
159
160
|
def self.realpath path
|
160
161
|
return realpath(File.readlink(path)) if symlink?(path)
|
161
162
|
path
|
@@ -253,7 +254,7 @@ EOS
|
|
253
254
|
if !force
|
254
255
|
dirs.each do |dir|
|
255
256
|
if File.exist? dir
|
256
|
-
|
257
|
+
raise "#{dir} exists; use --force to override"
|
257
258
|
exists = true
|
258
259
|
end
|
259
260
|
end
|
@@ -262,7 +263,7 @@ EOS
|
|
262
263
|
dirs.each do |dir|
|
263
264
|
puts "Creating dir #{dir}..."
|
264
265
|
if dry_run
|
265
|
-
|
266
|
+
puts "dry-run; #{dir} not created"
|
266
267
|
else
|
267
268
|
FileUtils.mkdir_p dir
|
268
269
|
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 21
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 1
|
8
7
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
8
|
+
- 6
|
9
|
+
version: 1.2.6
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- David Copeland
|
@@ -15,10 +14,82 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
17
|
+
date: 2011-03-06 00:00:00 -05:00
|
19
18
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rake
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 8
|
31
|
+
- 7
|
32
|
+
version: 0.8.7
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rcov
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 9
|
46
|
+
- 8
|
47
|
+
version: 0.9.8
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rdoc
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 2
|
60
|
+
- 4
|
61
|
+
- 3
|
62
|
+
version: 2.4.3
|
63
|
+
type: :development
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: sdoc
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
- 2
|
76
|
+
- 20
|
77
|
+
version: 0.2.20
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: grancher
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id005
|
22
93
|
description: An application and API for describing command line interfaces that can be used to quickly create a shell for executing command-line tasks. The command line user interface is similar to Gits, in that it takes global options, a command, command-specific options, and arguments
|
23
94
|
email: davidcopeland@naildrivin5.com
|
24
95
|
executables:
|
@@ -64,7 +135,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
135
|
requirements:
|
65
136
|
- - ">="
|
66
137
|
- !ruby/object:Gem::Version
|
67
|
-
hash: 3
|
68
138
|
segments:
|
69
139
|
- 0
|
70
140
|
version: "0"
|
@@ -73,7 +143,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
143
|
requirements:
|
74
144
|
- - ">="
|
75
145
|
- !ruby/object:Gem::Version
|
76
|
-
hash: 3
|
77
146
|
segments:
|
78
147
|
- 0
|
79
148
|
version: "0"
|