CommandLine 0.6.0 → 0.7.0
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.
@@ -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:
|