opt-simple 0.7.4 → 0.7.5
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 +148 -40
- data/lib/opt_simple.rb +91 -77
- data/test/test_usage.rb +21 -2
- metadata +1 -1
data/README
CHANGED
@@ -37,6 +37,66 @@ It is recommended to install OptSimple using RubyGems:
|
|
37
37
|
|
38
38
|
== Examples
|
39
39
|
|
40
|
+
=== One example that shows a lot of the behavior you might use
|
41
|
+
|
42
|
+
require 'opt_simple'
|
43
|
+
|
44
|
+
min = 5
|
45
|
+
max = 15
|
46
|
+
|
47
|
+
options,arguments = OptSimple.new.parse_opts! do
|
48
|
+
argument %w[-i --infile], "Infile, multiple allowed", "FILE" do | arg |
|
49
|
+
accumulate_opt arg
|
50
|
+
end
|
51
|
+
|
52
|
+
option %w[-p --pattern --glob-pattern], "glob pattern","PATTERN"
|
53
|
+
|
54
|
+
option %w[-n -num --num-values],"Number of val","VAL" do |arg|
|
55
|
+
set_opt arg.to_i
|
56
|
+
end
|
57
|
+
|
58
|
+
option "--range", "range: min,max (both >0) default is #{min},#{max}" do | arg1,arg2 |
|
59
|
+
min = arg1.to_i
|
60
|
+
max = arg2.to_i
|
61
|
+
|
62
|
+
error "max must be greater than min" unless max > min
|
63
|
+
error "both must be >=0" if min < 0
|
64
|
+
end
|
65
|
+
|
66
|
+
flag %w[-v --verbose],"Verbosity. the more you set, the more we give" do
|
67
|
+
accumulate_opt
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
puts "Options"
|
73
|
+
puts options.inspect
|
74
|
+
|
75
|
+
puts "Arguments"
|
76
|
+
puts arguments.inspect
|
77
|
+
|
78
|
+
puts "ARGV"
|
79
|
+
puts ARGV
|
80
|
+
|
81
|
+
It prints out an automatic usage statement:
|
82
|
+
|
83
|
+
Usage: opt_ex.rb [options]
|
84
|
+
|
85
|
+
MANDATORY ARGS:
|
86
|
+
-i, --infile FILE Infile, multiple allowed
|
87
|
+
|
88
|
+
OPTIONS:
|
89
|
+
-p, --pattern, --glob-pattern PATTERN glob pattern
|
90
|
+
|
91
|
+
-n, -num, --num-values VAL Number of val
|
92
|
+
|
93
|
+
--range ARG range: min,max (both >0) default is 5,15
|
94
|
+
|
95
|
+
-v, --verbose Verbosity. the more you set, the more we give
|
96
|
+
|
97
|
+
-h, --help (for this help message)
|
98
|
+
|
99
|
+
|
40
100
|
=== A very simple example with no error checking. Use at your own risk!
|
41
101
|
|
42
102
|
require 'opt_simple'
|
@@ -46,7 +106,7 @@ It is recommended to install OptSimple using RubyGems:
|
|
46
106
|
}
|
47
107
|
|
48
108
|
options,arguments = OptSimple.new(defaults).parse_opts!
|
49
|
-
|
109
|
+
|
50
110
|
puts "Options"
|
51
111
|
puts options.inspect
|
52
112
|
|
@@ -107,46 +167,46 @@ It is recommended to install OptSimple using RubyGems:
|
|
107
167
|
|
108
168
|
=== An example that shows how to use 'accumulate_opt' on an option to create a list, and on a flag to increment a counter
|
109
169
|
|
110
|
-
require 'opt_simple'
|
111
|
-
|
112
|
-
verbosity = 0
|
113
|
-
|
114
|
-
options,arguments = OptSimple.new.parse_opts! do
|
115
|
-
option %w[-i --infile], "Infile, multiple allowed", "INFILE" do | arg |
|
116
|
-
accumulate_opt arg
|
117
|
-
end
|
118
|
-
|
119
|
-
flag %w[-v --verbose],"Verbosity. the more you set, the more we give" do
|
120
|
-
verbosity += 1
|
121
|
-
end
|
122
|
-
|
123
|
-
flag %w[-m --more-cow-bell], "I've got a fever" do
|
124
|
-
accumulate_opt
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
puts "Options"
|
129
|
-
puts options.inspect
|
130
|
-
|
131
|
-
puts "Arguments"
|
132
|
-
puts arguments.inspect
|
133
|
-
|
134
|
-
puts "Verbosity"
|
135
|
-
puts verbosity
|
136
|
-
|
137
|
-
puts "ARGV"
|
138
|
-
puts ARGV
|
139
|
-
|
140
|
-
|
141
|
-
=== An example that shows that you can easily set your defaults in normal Ruby variables and provide your own help.
|
142
|
-
|
143
170
|
require 'opt_simple'
|
144
171
|
|
172
|
+
verbosity = 0
|
173
|
+
|
174
|
+
options,arguments = OptSimple.new.parse_opts! do
|
175
|
+
option %w[-i --infile], "Infile, multiple allowed", "FILE" do | arg |
|
176
|
+
accumulate_opt arg
|
177
|
+
end
|
178
|
+
|
179
|
+
flag %w[-v --verbose],"Verbosity. the more you set, the more we give" do
|
180
|
+
verbosity += 1
|
181
|
+
end
|
182
|
+
|
183
|
+
flag %w[-m --more-cow-bell], "I've got a fever" do
|
184
|
+
accumulate_opt
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
puts "Options"
|
189
|
+
puts options.inspect
|
190
|
+
|
191
|
+
puts "Arguments"
|
192
|
+
puts arguments.inspect
|
193
|
+
|
194
|
+
puts "Verbosity"
|
195
|
+
puts verbosity
|
196
|
+
|
197
|
+
puts "ARGV"
|
198
|
+
puts ARGV
|
199
|
+
|
200
|
+
|
201
|
+
=== An example that shows that you can easily set your defaults in normal Ruby variables and provide your own help.
|
202
|
+
|
203
|
+
require 'opt_simple'
|
204
|
+
|
145
205
|
in_file = nil
|
146
206
|
min = 0
|
147
207
|
max = 10
|
148
208
|
pattern = "*"
|
149
|
-
|
209
|
+
|
150
210
|
usage_string = <<-UL
|
151
211
|
Usage: $0 [options]
|
152
212
|
|
@@ -155,12 +215,12 @@ puts ARGV
|
|
155
215
|
[-p, --pattern, --glob-pattern (default #{pattern})]
|
156
216
|
[-v (verbose)]
|
157
217
|
[-h, --help (help)]
|
158
|
-
|
218
|
+
|
159
219
|
UL
|
160
|
-
|
220
|
+
|
161
221
|
OptSimple.new.parse_opts! do
|
162
222
|
help usage_string
|
163
|
-
|
223
|
+
|
164
224
|
argument %w[-i --infile],"inFile" do |arg|
|
165
225
|
in_file = arg
|
166
226
|
error "inFile must exist and be readable" unless(File.readable?(in_file))
|
@@ -188,8 +248,56 @@ puts ARGV
|
|
188
248
|
|
189
249
|
puts "ARGV"
|
190
250
|
puts ARGV
|
251
|
+
|
252
|
+
=== An example showing how to register parms in multiple places before parsing the command line
|
253
|
+
|
254
|
+
require 'opt_simple'
|
255
|
+
|
256
|
+
min = 5
|
257
|
+
max = 15
|
258
|
+
|
259
|
+
os = OptSimple.new
|
260
|
+
|
261
|
+
os.register_opts do
|
262
|
+
argument %w[-i --infile], "Infile, multiple allowed", "FILE" do | arg |
|
263
|
+
accumulate_opt arg
|
264
|
+
end
|
265
|
+
|
266
|
+
option %w[-p --pattern --glob-pattern], "glob pattern","PATTERN"
|
267
|
+
end
|
268
|
+
|
269
|
+
os.register_opts do
|
270
|
+
option %w[-n -num --num-values],"Number of val","VAL" do |arg|
|
271
|
+
set_opt arg.to_i
|
272
|
+
end
|
273
|
+
|
274
|
+
option "--range", "range: min,max (both >0) default is #{min},#{max}" do | arg1,arg2 |
|
275
|
+
min = arg1.to_i
|
276
|
+
max = arg2.to_i
|
277
|
+
|
278
|
+
error "max must be greater than min" unless max > min
|
279
|
+
error "both must be >=0" if min < 0
|
280
|
+
end
|
281
|
+
|
282
|
+
flag %w[-v --verbose],"Verbosity. the more you set, the more we give" do
|
283
|
+
accumulate_opt
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
options,arguments = os.parse_opts!
|
288
|
+
|
289
|
+
puts "Options"
|
290
|
+
puts options.inspect
|
291
|
+
|
292
|
+
puts "Arguments"
|
293
|
+
puts arguments.inspect
|
294
|
+
|
295
|
+
puts "ARGV"
|
296
|
+
puts ARGV
|
297
|
+
|
191
298
|
|
192
299
|
== Questions and/or Comments
|
193
|
-
|
300
|
+
|
194
301
|
email {Ethan Stryker}[mailto:e.stryker@gmail.com]
|
195
|
-
|
302
|
+
|
303
|
+
|
data/lib/opt_simple.rb
CHANGED
@@ -57,94 +57,108 @@ class OptSimple
|
|
57
57
|
@banner = str
|
58
58
|
end
|
59
59
|
|
60
|
-
#
|
61
|
-
#
|
62
|
-
def
|
63
|
-
|
64
|
-
if block_given?
|
60
|
+
# Simply register options without actually parsing them.
|
61
|
+
# This allows registering parms in multiple places in your code.
|
62
|
+
def register_opts(&block)
|
63
|
+
begin
|
65
64
|
# call the block to register all the parameters and
|
66
65
|
# their corresponding code blocks
|
67
66
|
# We use instance_exec so that the API is cleaner.
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
67
|
+
instance_exec(@options,@positional_arguments,&block)
|
68
|
+
ensure
|
69
|
+
# we are ensuring that the options that occur before any break statement
|
70
|
+
# actually get parsed.
|
71
|
+
|
72
|
+
# add the help option at the end the first time register_opts is called
|
73
|
+
unless(@parameters.find {|p| p.switches.include?('-h')})
|
75
74
|
flag %w[-h --help] ,"(for this help message)"
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
$stdout.puts self.to_s
|
80
|
-
exit(0)
|
81
|
-
end
|
82
|
-
|
83
|
-
mandatory_check = mandatory_opts.map {|m| m.switches}
|
84
|
-
|
85
|
-
if(loc = @args.index('--'))
|
86
|
-
#remove the '--', but don't include it w/ positional arguments
|
87
|
-
@positional_arguments += @args.slice!(loc..-1)[1..-1]
|
88
|
-
end
|
89
|
-
|
90
|
-
# Handle the case where a user specifies --foo=bar, or --foo=bar,baz
|
91
|
-
equal_args = @args.find_all {|arg| arg.include?('=') }
|
92
|
-
@args.delete_if {|arg| arg.include?('=') }
|
93
|
-
equal_args.each do | e |
|
94
|
-
switch,list = e.split('=')
|
95
|
-
@args << switch
|
96
|
-
list.split(',').each {|val| @args << val }
|
97
|
-
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
98
78
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
chunks = []
|
114
|
-
arg_locations.sort.reverse.each do |loc|
|
115
|
-
chunks.unshift @args.slice!(loc .. loc + parm.block.arity)[1..-1]
|
116
|
-
end
|
79
|
+
# Parse the options, destructively pulling them out of the args array as it goes.
|
80
|
+
# If no block is given, then a default parser with no error checking will be run.
|
81
|
+
def parse_opts!(&block)
|
82
|
+
|
83
|
+
if block_given?
|
84
|
+
register_opts(&block)
|
85
|
+
end
|
86
|
+
|
87
|
+
if @parameters.empty?
|
88
|
+
#parse the @args array by looking for switches/args by regex
|
89
|
+
default_arg_parser
|
90
|
+
else
|
91
|
+
# go through the registered parameters, and pull out
|
92
|
+
# the specified parms from @arg
|
117
93
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
94
|
+
# first look for a call for help
|
95
|
+
unless (%w[-h --help] & @args).empty?
|
96
|
+
$stdout.puts self.to_s
|
97
|
+
exit(0)
|
98
|
+
end
|
99
|
+
|
100
|
+
mandatory_check = mandatory_opts.map {|m| m.switches}
|
101
|
+
|
102
|
+
if(loc = @args.index('--'))
|
103
|
+
#remove the '--', but don't include it w/ positional arguments
|
104
|
+
@positional_arguments += @args.slice!(loc..-1)[1..-1]
|
105
|
+
end
|
106
|
+
|
107
|
+
# Handle the case where a user specifies --foo=bar, or --foo=bar,baz
|
108
|
+
equal_args = @args.find_all {|arg| arg.include?('=') }
|
109
|
+
@args.delete_if {|arg| arg.include?('=') }
|
110
|
+
equal_args.each do | e |
|
111
|
+
switch,list = e.split('=')
|
112
|
+
@args << switch
|
113
|
+
list.split(',').each {|val| @args << val }
|
114
|
+
end
|
115
|
+
|
116
|
+
# now actually parse the args, and call all the stored up blocks from the options
|
117
|
+
@parameters.each do | parm |
|
118
|
+
intersection = @args & parm.switches
|
119
|
+
unless intersection.empty?
|
120
|
+
mandatory_check.delete(parm.switches)
|
121
|
+
|
122
|
+
arg_locations = []
|
123
|
+
@args.each_with_index {|arg,i| arg_locations << i if intersection.include?(arg) }
|
124
|
+
|
125
|
+
# we want to process the args in order to provide predictable behavior
|
126
|
+
# in the case of switch duplication.
|
127
|
+
# We do pull them out in reverse so that the slicing removes pieces from the end
|
128
|
+
# of @args, so we don't disrupt the other locations, but put them into 'chunks'
|
129
|
+
# backwards to restore their order.
|
130
|
+
chunks = []
|
131
|
+
arg_locations.sort.reverse.each do |loc|
|
132
|
+
chunks.unshift @args.slice!(loc .. loc + parm.block.arity)[1..-1]
|
133
|
+
end
|
134
|
+
|
135
|
+
chunks.each do | pieces |
|
136
|
+
if pieces.length < parm.block.arity or
|
137
|
+
pieces.any? {|p| p.start_with?('-')}
|
138
|
+
raise OptSimple::ParameterUsageError.new "Not enough args following #{intersection}",self
|
129
139
|
end
|
130
140
|
|
131
|
-
|
141
|
+
begin
|
142
|
+
parm.instance_exec(*pieces,&parm.block)
|
143
|
+
rescue OptSimple::Error => e
|
144
|
+
raise OptSimple::Error.new e.message,self
|
145
|
+
end
|
132
146
|
end
|
147
|
+
|
148
|
+
@options.merge!(parm.param_options)
|
133
149
|
end
|
134
|
-
|
135
|
-
unless mandatory_check.empty?
|
136
|
-
raise MissingArgument.new "Must set the following parameters: #{mandatory_check.map {|a| a.join(' OR ')}.join(', ')}",self
|
137
|
-
end
|
138
|
-
|
139
|
-
extra_switches = @args.find_all {|a| a.start_with?('-') }
|
140
|
-
raise OptSimple::InvalidOption.new "Unknown options: #{extra_switches.join(' ')}",self unless extra_switches.empty?
|
141
|
-
|
142
|
-
@positional_arguments += @args.slice!(0..-1)
|
143
150
|
end
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
151
|
+
|
152
|
+
unless mandatory_check.empty?
|
153
|
+
raise MissingArgument.new "Must set the following parameters: #{mandatory_check.map {|a| a.join(' OR ')}.join(', ')}",self
|
154
|
+
end
|
155
|
+
|
156
|
+
extra_switches = @args.find_all {|a| a.start_with?('-') }
|
157
|
+
raise OptSimple::InvalidOption.new "Unknown options: #{extra_switches.join(' ')}",self unless extra_switches.empty?
|
158
|
+
|
159
|
+
@positional_arguments += @args.slice!(0..-1)
|
160
|
+
end
|
161
|
+
|
148
162
|
return [@options,@positional_arguments]
|
149
163
|
end
|
150
164
|
|
data/test/test_usage.rb
CHANGED
@@ -55,7 +55,7 @@ class TestHelpStatement < Test::Unit::TestCase
|
|
55
55
|
must "accumulate lists of args when asked" do
|
56
56
|
os = OptSimple.new({},%w[-i foo.bar --infile bar.in])
|
57
57
|
o,a = os.parse_opts! do
|
58
|
-
option %w[-i --infile], "Infile, multiple allowed", "
|
58
|
+
option %w[-i --infile], "Infile, multiple allowed", "FILE" do | arg |
|
59
59
|
accumulate_opt arg
|
60
60
|
end
|
61
61
|
end
|
@@ -78,7 +78,7 @@ class TestHelpStatement < Test::Unit::TestCase
|
|
78
78
|
must "set last arg when duplicated when accumulate opt isn't used" do
|
79
79
|
os = OptSimple.new({},%w[-i foo.bar --infile bar.in -i baz])
|
80
80
|
o,a = os.parse_opts! do
|
81
|
-
option %w[-i --infile], "Infile, multiple allowed", "
|
81
|
+
option %w[-i --infile], "Infile, multiple allowed", "FILE" do | arg |
|
82
82
|
set_opt arg
|
83
83
|
end
|
84
84
|
end
|
@@ -86,5 +86,24 @@ class TestHelpStatement < Test::Unit::TestCase
|
|
86
86
|
assert_equal o['i'],'baz'
|
87
87
|
assert_equal o['infile'],'baz'
|
88
88
|
end
|
89
|
+
|
90
|
+
must "allow parameters to be registered in multiple spots" do
|
91
|
+
os = OptSimple.new({},%w[-i foo.bar --outfile bar.out])
|
92
|
+
os.register_opts do
|
93
|
+
option %w[-i --infile], "Infile", "FILE" do | arg |
|
94
|
+
set_opt arg
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
os.register_opts do
|
99
|
+
option %w[-o --outfile], "outfile", "FILE" do | arg |
|
100
|
+
set_opt arg
|
101
|
+
end
|
102
|
+
end
|
103
|
+
o,a = os.parse_opts!
|
104
|
+
|
105
|
+
assert_equal o['i'],'foo.bar'
|
106
|
+
assert_equal o['o'],'bar.out'
|
107
|
+
end
|
89
108
|
end
|
90
109
|
|