CommandLine 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -33,25 +33,30 @@ class Application
|
|
33
33
|
MIN_CONSOLE_WIDTH = 10
|
34
34
|
DEFAULT_BODY_INDENT = 4
|
35
35
|
|
36
|
-
#def options
|
37
|
-
# raise(OptionError,
|
38
|
-
# "Options must be over-written with a valid (or empty) options list.")
|
39
|
-
#end
|
40
|
-
|
41
36
|
def initialize
|
42
|
-
|
43
|
-
@
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@
|
37
|
+
|
38
|
+
@synopsis = ""
|
39
|
+
@arg_arity = [0,0]
|
40
|
+
@options = []
|
41
|
+
@arg_names = []
|
42
|
+
@args = []
|
43
|
+
@argv ||= ARGV
|
44
|
+
|
47
45
|
_init_format
|
48
46
|
|
49
|
-
if
|
47
|
+
__child_initialize if
|
48
|
+
self.class.private_instance_methods(false).include?("__child_initialize")
|
49
|
+
|
50
|
+
@option_parser ||= CommandLine::OptionParser.new(@options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_command_line(argv)
|
54
|
+
if argv.empty? && [0,0] != @arg_arity
|
50
55
|
puts usage
|
51
56
|
exit(0)
|
52
57
|
end
|
53
58
|
|
54
|
-
@option_data = @option_parser.parse
|
59
|
+
@option_data = @option_parser.parse(argv)
|
55
60
|
|
56
61
|
validate_args(@option_data.args)
|
57
62
|
@arg_names.each_with_index { |name, idx|
|
@@ -88,6 +93,10 @@ class Application
|
|
88
93
|
"expected #{max}.\n#{usage}") if size > max
|
89
94
|
end
|
90
95
|
|
96
|
+
def options(*opts)
|
97
|
+
opts.each { |opt| option(*[opt].flatten) }
|
98
|
+
end
|
99
|
+
|
91
100
|
def option(*args)
|
92
101
|
@options ||= []
|
93
102
|
new_list = []
|
@@ -106,43 +115,55 @@ class Application
|
|
106
115
|
end
|
107
116
|
|
108
117
|
#
|
109
|
-
#
|
118
|
+
# expected_args tells the application how many arguments (not belonging
|
110
119
|
# any option) are expected to be seen on the command line
|
111
120
|
# The names of the args are used for describing the synopsis (or usage).
|
112
121
|
# If there is an indeterminant amount of arguments, they are not
|
113
122
|
# named, but returned in an array.
|
123
|
+
# expected_args takes either a list of argument names
|
124
|
+
#
|
125
|
+
# =Usage
|
126
|
+
# expected_args :sym1
|
127
|
+
# expected_args :sym1, :sym2, ...
|
128
|
+
# expected_args n #=> arg_arity => [n,n]
|
129
|
+
# expected_args arity
|
130
|
+
#
|
131
|
+
# =Examples
|
132
|
+
#
|
114
133
|
# Many forms are valid. Some examples follow:
|
115
|
-
# args
|
116
|
-
# synopsis: Usage: app
|
117
|
-
|
118
|
-
# args :none
|
134
|
+
# expected_args 0 #=> @args = []; same as not calling expected_args
|
119
135
|
# synopsis: Usage: app
|
120
136
|
|
121
|
-
#
|
137
|
+
# expected_args 1 #=> @args is array
|
122
138
|
# synopsis: Usage: app arg
|
123
139
|
|
124
|
-
#
|
140
|
+
# expected_args 2 #=> @args is array
|
125
141
|
# synopsis: Usage: app arg1 arg2
|
126
142
|
|
127
|
-
#
|
143
|
+
# expected_args 10 #=> @args is array
|
128
144
|
# synopsis: Usage: app arg1 ... arg10
|
129
145
|
|
130
|
-
#
|
146
|
+
# expected_args :file #=> @file = <arg>
|
131
147
|
# synopsis: Usage: app file
|
132
148
|
|
133
|
-
#
|
149
|
+
# expected_args :file1, :file2 #=> @file1 = <arg1>, @file2 = <arg2>
|
134
150
|
# synopsis: Usage: app file1 file2
|
135
151
|
|
136
|
-
#
|
137
|
-
# synopsis: Usage: app [
|
152
|
+
# expected_args [0,1] #=> @args is array
|
153
|
+
# synopsis: Usage: app [arg1 [arg2]]
|
138
154
|
|
139
|
-
#
|
140
|
-
# synopsis: Usage: app
|
155
|
+
# expected_args [2,3] #=> @args is array
|
156
|
+
# synopsis: Usage: app arg1 arg2 [arg3]
|
141
157
|
|
142
|
-
#
|
143
|
-
# synopsis: Usage: app [
|
158
|
+
# expected_args [0,-1] #=> @args is array
|
159
|
+
# synopsis: Usage: app [arg1 [arg...]]
|
144
160
|
#
|
145
|
-
|
161
|
+
|
162
|
+
# expected_args :cmd
|
163
|
+
# Now, what to do if command line has more args than expected
|
164
|
+
# app --app-option cmd --cmd-option arg-for-cmd
|
165
|
+
#
|
166
|
+
def expected_args(*expected_args)
|
146
167
|
@arg_names = []
|
147
168
|
case expected_args.size
|
148
169
|
when 0 then @arg_arity = [0,0]
|
@@ -247,28 +268,45 @@ class Application
|
|
247
268
|
CommandLine::OptionParser::GET_ARG_ARRAY
|
248
269
|
end
|
249
270
|
|
250
|
-
def self.run
|
251
|
-
|
271
|
+
def self.run(argv=ARGV)
|
272
|
+
if self.private_instance_methods(false).include?("initialize")
|
273
|
+
$VERBOSE, verbose = nil, $VERBOSE
|
274
|
+
self.class_eval {
|
275
|
+
alias :__child_initialize :initialize
|
276
|
+
remove_method :initialize
|
277
|
+
}
|
278
|
+
$VERBOSE = verbose
|
279
|
+
end
|
280
|
+
obj = self.new
|
281
|
+
obj.parse_command_line(argv)
|
282
|
+
obj.main
|
283
|
+
|
284
|
+
#alias :user_init :initialize
|
285
|
+
#@@child_class.new.main if ($0 == @@appname)
|
286
|
+
obj
|
252
287
|
rescue => err
|
253
288
|
puts "ERROR: #{err}"
|
254
289
|
exit(-1)
|
255
290
|
end
|
256
291
|
|
257
|
-
def self.inherited(
|
292
|
+
def self.inherited(child_class)
|
258
293
|
@@appname = caller[0][/.*:/][0..-2]
|
259
|
-
@@
|
260
|
-
|
294
|
+
@@child_class = child_class
|
295
|
+
if @@appname == $0
|
296
|
+
at_exit { @@child_class.run }
|
297
|
+
end
|
261
298
|
end
|
262
299
|
|
263
300
|
def main
|
264
|
-
#raise(MissingMainError, "Method #main must be defined in class #{@@
|
265
|
-
@@
|
301
|
+
#raise(MissingMainError, "Method #main must be defined in class #{@@child_class}.")
|
302
|
+
@@child_class.class_eval %{ def main; end }
|
303
|
+
#self.class_eval %{ def main; end }
|
266
304
|
end
|
267
305
|
|
268
306
|
def _help
|
269
307
|
{
|
270
308
|
:names => %w(--help -h),
|
271
|
-
:
|
309
|
+
:arity => [0,0],
|
272
310
|
:opt_description => "Displays help page.",
|
273
311
|
:arg_description => "",
|
274
312
|
:opt_found => lambda { puts man; exit },
|
@@ -279,7 +317,7 @@ class Application
|
|
279
317
|
def _verbose
|
280
318
|
{
|
281
319
|
:names => %w(--verbose -v),
|
282
|
-
:
|
320
|
+
:arity => [0,0],
|
283
321
|
:opt_description => "Sets verbosity level. Subsequent "+
|
284
322
|
"flags increase verbosity level",
|
285
323
|
:arg_description => "",
|
@@ -291,7 +329,7 @@ class Application
|
|
291
329
|
def _version
|
292
330
|
{
|
293
331
|
:names => %w(--version -V),
|
294
|
-
:
|
332
|
+
:arity => [0,0],
|
295
333
|
:opt_description => "Displays application version.",
|
296
334
|
:arg_description => "",
|
297
335
|
:opt_found => lambda {
|
@@ -309,7 +347,7 @@ class Application
|
|
309
347
|
def _debug
|
310
348
|
{
|
311
349
|
:names => %w(--debug -d),
|
312
|
-
:
|
350
|
+
:arity => [0,0],
|
313
351
|
:opt_description => "Sets debug to true.",
|
314
352
|
:arg_description => "",
|
315
353
|
:opt_found => lambda { $DEBUG = true }
|
@@ -36,12 +36,12 @@ class Option
|
|
36
36
|
# need to change this to support - and --
|
37
37
|
NON_POSIX_OPTION_RE = /^(-|-{1,2}[a-zA-Z_]+[-_a-zA-Z0-9]*)/
|
38
38
|
|
39
|
-
PROPERTIES = [ :
|
39
|
+
PROPERTIES = [ :arity, :opt_description, :arg_description,
|
40
40
|
:opt_found, :opt_not_found, :posix
|
41
41
|
]
|
42
42
|
|
43
43
|
FLAG_BASE_OPTS = {
|
44
|
-
:
|
44
|
+
:arity => [0,0],
|
45
45
|
# :opt_description => nil,
|
46
46
|
:arg_description => "",
|
47
47
|
:opt_found => true,
|
@@ -50,7 +50,7 @@ class Option
|
|
50
50
|
|
51
51
|
# You get these without asking for them
|
52
52
|
DEFAULT_OPTS = {
|
53
|
-
:
|
53
|
+
:arity => [1,1],
|
54
54
|
:opt_description => "",
|
55
55
|
:arg_description => "",
|
56
56
|
:opt_found => true,
|
@@ -77,6 +77,7 @@ class Option
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
@flag = nil unless defined?(@flag)
|
80
81
|
type = @flag.nil? ? :default : :flag
|
81
82
|
merge_hash =
|
82
83
|
case type
|
@@ -84,7 +85,7 @@ class Option
|
|
84
85
|
when :default then DEFAULT_OPTS
|
85
86
|
else raise(InvalidConstructionError,
|
86
87
|
"Invalid arguments to Option.new. Must be a property hash with "+
|
87
|
-
"keys [:names, :
|
88
|
+
"keys [:names, :arity, :opt_description, :arg_description, "+
|
88
89
|
":opt_found, :opt_not_found] or "+
|
89
90
|
"an option type [:flag, :default].")
|
90
91
|
end
|
@@ -102,17 +103,17 @@ class Option
|
|
102
103
|
@properties[:names] = [@properties[:names]] unless
|
103
104
|
@properties[:names].kind_of?(Array)
|
104
105
|
|
105
|
-
arg_arity = @properties[:
|
106
|
-
@properties[:
|
106
|
+
arg_arity = @properties[:arity]
|
107
|
+
@properties[:arity] = [arg_arity, arg_arity] unless
|
107
108
|
arg_arity.kind_of?(Array)
|
108
109
|
|
109
|
-
raise "Invalid value for
|
110
|
+
raise "Invalid value for arity '#{arg_arity}'." unless
|
110
111
|
arg_arity.kind_of?(Array) || arg_arity.kind_of?(Fixnum)
|
111
112
|
|
112
113
|
raise(InvalidArgumentArityError,
|
113
114
|
"Conflicting value given to new option: :flag "+
|
114
|
-
"and :
|
115
|
-
:flag == type && [0,0] != @properties[:
|
115
|
+
"and :arity = #{@properties[:arity].inspect}.") if
|
116
|
+
:flag == type && [0,0] != @properties[:arity]
|
116
117
|
|
117
118
|
names = @properties[:names]
|
118
119
|
raise(MissingOptionNameError,
|
@@ -120,7 +121,7 @@ class Option
|
|
120
121
|
names.nil? || names.empty?
|
121
122
|
|
122
123
|
names.each { |name| check_option_name(name) }
|
123
|
-
validate_arity @properties[:
|
124
|
+
validate_arity @properties[:arity]
|
124
125
|
|
125
126
|
create_opt_description if :flag == type
|
126
127
|
end
|
@@ -149,7 +150,7 @@ class Option
|
|
149
150
|
end
|
150
151
|
|
151
152
|
def validate_arity(arity)
|
152
|
-
raise ":
|
153
|
+
raise ":arity is nil" if arity.nil?
|
153
154
|
min, max = *arity
|
154
155
|
|
155
156
|
raise(InvalidArgumentArityError, "Minimum argument arity '#{min}' must be "+
|
@@ -157,9 +158,9 @@ class Option
|
|
157
158
|
raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
|
158
159
|
"greater than or equal to -1.") if max < -1
|
159
160
|
raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
|
160
|
-
"greater than minimum
|
161
|
+
"greater than minimum arity '#{min}'.") if max < min && max != -1
|
161
162
|
if @posix
|
162
|
-
raise(InvalidArgumentArityError, "Posix options only support :
|
163
|
+
raise(InvalidArgumentArityError, "Posix options only support :arity "+
|
163
164
|
"of [0,0] or [1,1].") unless ([0,0] == arity) || ([1,1] == arity)
|
164
165
|
end
|
165
166
|
end
|
@@ -142,10 +142,10 @@ class OptionParser
|
|
142
142
|
# :
|
143
143
|
#
|
144
144
|
# add_option :names => %w(--version -v),
|
145
|
-
# :
|
145
|
+
# :arity => [0,0], # default
|
146
146
|
# :option_description => "Returns Version"
|
147
147
|
# add_option :names => %w(--file -f),
|
148
|
-
# :
|
148
|
+
# :arity => [1,:unlimited],
|
149
149
|
# :opt_description => "Define the output filename.",
|
150
150
|
# :arg_description => "Output file"
|
151
151
|
# :opt_exists => lambda {}
|
@@ -276,13 +276,13 @@ raise "Wrong data type '#{option.name}." unless Option === option
|
|
276
276
|
end
|
277
277
|
|
278
278
|
def get_opt_args(opt, user_option, args)
|
279
|
-
min, max = *opt.
|
279
|
+
min, max = *opt.arity
|
280
280
|
size = args.size
|
281
281
|
|
282
282
|
if (min == max && max > 0 && size < max) || (size < min)
|
283
283
|
raise(MissingRequiredOptionArgumentError,
|
284
284
|
"Insufficient arguments #{args.inspect}for option '#{user_option}' "+
|
285
|
-
"with :
|
285
|
+
"with :arity #{opt.arity.inspect}")
|
286
286
|
end
|
287
287
|
|
288
288
|
if 0 == min && 0 == max
|
@@ -297,7 +297,7 @@ raise "Wrong data type '#{option.name}." unless Option === option
|
|
297
297
|
flags = []
|
298
298
|
nflags = []
|
299
299
|
@options.each { |o|
|
300
|
-
if [0,0] == o.
|
300
|
+
if [0,0] == o.arity
|
301
301
|
flags << o.names[0][1..1]
|
302
302
|
else
|
303
303
|
nflags << o.names[0][1..1]
|
@@ -457,7 +457,7 @@ end
|
|
457
457
|
def to_s(sep="\n")
|
458
458
|
return "" if @options.empty?
|
459
459
|
|
460
|
-
require '
|
460
|
+
require 'text/format'
|
461
461
|
@f = Text::Format.new
|
462
462
|
@f.columns = @columns
|
463
463
|
@f.first_indent = 4
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: CommandLine
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-
|
6
|
+
version: 0.7.0
|
7
|
+
date: 2005-07-13
|
8
8
|
summary: Tools to facilitate creation of command line applications and flexible parsing of command line options.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -36,12 +36,10 @@ files:
|
|
36
36
|
- lib/commandline/application.rb
|
37
37
|
- lib/commandline/optionparser
|
38
38
|
- lib/commandline/optionparser.rb
|
39
|
-
- lib/commandline/text
|
40
39
|
- lib/commandline/utils.rb
|
41
40
|
- lib/commandline/optionparser/option.rb
|
42
41
|
- lib/commandline/optionparser/optiondata.rb
|
43
42
|
- lib/commandline/optionparser/optionparser.rb
|
44
|
-
- lib/commandline/text/format.rb
|
45
43
|
- lib/test/unit
|
46
44
|
- lib/test/unit/systemtest.rb
|
47
45
|
- README
|
@@ -54,4 +52,14 @@ extra_rdoc_files:
|
|
54
52
|
executables: []
|
55
53
|
extensions: []
|
56
54
|
requirements: []
|
57
|
-
dependencies:
|
55
|
+
dependencies:
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: text-format
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
60
|
+
requirements:
|
61
|
+
-
|
62
|
+
- "="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 1.0.0
|
65
|
+
version:
|