clasp-ruby 0.23.0.2 → 0.23.1
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.
- checksums.yaml +4 -4
- data/examples/cr-example.rb +16 -16
- data/examples/flag_and_option_specifications.rb +15 -15
- data/examples/show_usage_and_version.rb +10 -11
- data/lib/clasp/arguments.rb +86 -87
- data/lib/clasp/clasp.rb +15 -11
- data/lib/clasp/cli.rb +135 -134
- data/lib/clasp/old_module.rb +8 -8
- data/lib/clasp/specifications.rb +325 -322
- data/lib/clasp/util/exceptions.rb +21 -22
- data/lib/clasp/util/value_parser.rb +99 -101
- data/lib/clasp/version.rb +12 -12
- data/lib/clasp-ruby.rb +8 -7
- data/lib/clasp.rb +8 -7
- data/test/scratch/test_list_command_line.rb +6 -6
- data/test/scratch/test_specifications.rb +14 -14
- data/test/scratch/test_usage.rb +5 -5
- data/test/scratch/test_usage_with_duplicate_specifications.rb +5 -5
- data/test/unit/tc_ARGV_rewrite.rb +36 -36
- data/test/unit/tc_arguments_1.rb +708 -708
- data/test/unit/tc_arguments_2.rb +43 -43
- data/test/unit/tc_arguments_3.rb +77 -77
- data/test/unit/tc_arguments_inspect.rb +55 -55
- data/test/unit/tc_cli.rb +4 -4
- data/test/unit/tc_default_value.rb +91 -91
- data/test/unit/tc_defaults_1.rb +38 -38
- data/test/unit/tc_examples_Arguments.rb +130 -130
- data/test/unit/tc_extras.rb +24 -24
- data/test/unit/tc_option_required.rb +38 -38
- data/test/unit/tc_option_value_aliases.rb +44 -44
- data/test/unit/tc_specifications.rb +7 -7
- data/test/unit/tc_typed_options.rb +200 -200
- data/test/unit/tc_usage.rb +69 -69
- data/test/unit/tc_with_action.rb +23 -23
- metadata +9 -8
data/lib/clasp/specifications.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
|
2
2
|
# ######################################################################## #
|
3
|
-
# File:
|
3
|
+
# File: clasp/specifications.rb
|
4
4
|
#
|
5
|
-
# Purpose:
|
5
|
+
# Purpose: Argument specification classes
|
6
6
|
#
|
7
|
-
# Created:
|
8
|
-
# Updated:
|
7
|
+
# Created: 25th October 2014
|
8
|
+
# Updated: 6th March 2025
|
9
9
|
#
|
10
|
-
# Home:
|
10
|
+
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
11
|
#
|
12
|
-
# Author:
|
12
|
+
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c)
|
14
|
+
# Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems
|
15
|
+
# Copyright (c) 2014-2019, Matthew Wilson and Synesis Software
|
15
16
|
# All rights reserved.
|
16
17
|
#
|
17
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -61,319 +62,319 @@ module CLASP
|
|
61
62
|
# @!visibility private
|
62
63
|
class SpecificationBase # :nodoc: all
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
65
|
+
private
|
66
|
+
# @!visibility private
|
67
|
+
def check_arity_(blk, range, label) # :nodoc:
|
67
68
|
|
68
|
-
|
69
|
+
raise ArgumentError, "block must be a #{Proc}; #{blk.class} given" unless blk.nil? || Proc === blk
|
69
70
|
|
70
|
-
|
71
|
+
if blk
|
71
72
|
|
72
|
-
|
73
|
-
|
73
|
+
case blk.arity
|
74
|
+
when range
|
74
75
|
|
75
|
-
|
76
|
-
|
76
|
+
;
|
77
|
+
else
|
77
78
|
|
78
|
-
|
79
|
+
msg = "wrong arity for #{label}"
|
79
80
|
|
80
|
-
|
81
|
+
if $DEBUG
|
81
82
|
|
82
|
-
|
83
|
-
|
83
|
+
raise ArgumentError, msg
|
84
|
+
else
|
84
85
|
|
85
|
-
|
86
|
-
end
|
87
|
-
end
|
86
|
+
warn msg
|
88
87
|
end
|
88
|
+
end
|
89
89
|
end
|
90
|
-
|
90
|
+
end
|
91
|
+
public
|
91
92
|
end
|
92
93
|
|
93
94
|
# A class that represents the specification for a command-line flag
|
94
95
|
class FlagSpecification < SpecificationBase
|
95
96
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
97
|
+
# Creates a FlagSpecification instance from the given name, aliases, and help
|
98
|
+
#
|
99
|
+
# === Signature
|
100
|
+
#
|
101
|
+
# * *Parameters*
|
102
|
+
# - +name+ (+String+) The name, or long-form, of the flag
|
103
|
+
# - +aliases+ (+Array+) 0 or more strings specifying short-form or option-value aliases
|
104
|
+
# - +help+ (+String+) The help string, which may be +nil+
|
105
|
+
# - +extras+ An application-defined additional parameter. If +nil+, it is assigned an empty +Hash+
|
106
|
+
#
|
107
|
+
# * *Block* An optional block that is called when a matching flag argument is found
|
108
|
+
#
|
109
|
+
# *NOTE:* Users should prefer the +CLASP::Flag()+ method
|
110
|
+
def initialize(name, aliases, help, extras = nil, &blk)
|
111
|
+
|
112
|
+
check_arity_(blk, 0..3, "flag")
|
113
|
+
|
114
|
+
@name = name
|
115
|
+
@aliases = (aliases || []).select { |a| a and not a.empty? }
|
116
|
+
@help = help
|
117
|
+
@extras = extras || {}
|
118
|
+
@action = blk
|
119
|
+
end
|
120
|
+
|
121
|
+
# The flag's name string
|
122
|
+
attr_reader :name
|
123
|
+
# The flag's aliases array
|
124
|
+
attr_reader :aliases
|
125
|
+
# The flag's help string
|
126
|
+
attr_reader :help
|
127
|
+
# The flag's extras
|
128
|
+
attr_reader :extras
|
129
|
+
|
130
|
+
# (Proc) The procedure
|
131
|
+
attr_reader :action
|
132
|
+
|
133
|
+
# @!visibility private
|
134
|
+
def action=(blk) # :nodoc: all
|
135
|
+
|
136
|
+
check_arity_(blk, 0..3, "flag")
|
137
|
+
|
138
|
+
@action = blk
|
139
|
+
end
|
140
|
+
|
141
|
+
# String form of the flag
|
142
|
+
def to_s
|
143
|
+
|
144
|
+
"{#{name}; aliases=#{aliases.join(', ')}; help='#{help}'; extras=#{extras}}"
|
145
|
+
end
|
146
|
+
|
147
|
+
# @!visibility private
|
148
|
+
def eql? rhs # :nodoc:
|
149
|
+
|
150
|
+
case rhs
|
151
|
+
when self.class
|
152
|
+
|
153
|
+
return true if equal?(rhs)
|
154
|
+
else
|
155
|
+
|
156
|
+
return false
|
118
157
|
end
|
119
158
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
# The flag's help string
|
125
|
-
attr_reader :help
|
126
|
-
# The flag's extras
|
127
|
-
attr_reader :extras
|
159
|
+
return false unless name == rhs.name
|
160
|
+
return false unless aliases == rhs.aliases
|
161
|
+
return false unless help == rhs.help
|
162
|
+
return false unless extras == rhs.extras
|
128
163
|
|
129
|
-
|
130
|
-
|
164
|
+
return true
|
165
|
+
end
|
131
166
|
|
132
|
-
|
133
|
-
|
167
|
+
# Compares instance against another FlagSpecification or against a name (String)
|
168
|
+
def == rhs
|
134
169
|
|
135
|
-
|
170
|
+
case rhs
|
171
|
+
when self.class
|
136
172
|
|
137
|
-
|
138
|
-
|
173
|
+
return self.eql? rhs
|
174
|
+
when String
|
139
175
|
|
140
|
-
|
141
|
-
|
176
|
+
return name == rhs
|
177
|
+
else
|
142
178
|
|
143
|
-
|
179
|
+
false
|
144
180
|
end
|
181
|
+
end
|
145
182
|
|
146
|
-
|
147
|
-
|
183
|
+
private
|
184
|
+
@@Help_ = self.new('--help', [], 'shows this help and terminates')
|
185
|
+
@@Version_ = self.new('--version', [], 'shows version and terminates')
|
186
|
+
public
|
187
|
+
# An instance of FlagSpecification that provides default '--help' information
|
188
|
+
#
|
189
|
+
# If you wish to specify +extras+ or attach a block, you may do so
|
190
|
+
def self.Help(extras = nil, &blk)
|
148
191
|
|
149
|
-
|
150
|
-
when self.class
|
192
|
+
h = @@Help_
|
151
193
|
|
152
|
-
|
153
|
-
else
|
154
|
-
|
155
|
-
return false
|
156
|
-
end
|
157
|
-
|
158
|
-
return false unless name == rhs.name
|
159
|
-
return false unless aliases == rhs.aliases
|
160
|
-
return false unless help == rhs.help
|
161
|
-
return false unless extras == rhs.extras
|
194
|
+
if extras || blk
|
162
195
|
|
163
|
-
|
196
|
+
return self.new(h.name, h.aliases, h.help, extras, &blk)
|
164
197
|
end
|
165
198
|
|
166
|
-
|
167
|
-
|
199
|
+
h
|
200
|
+
end
|
168
201
|
|
169
|
-
|
170
|
-
|
202
|
+
# An instance of FlagSpecification that provides default '--version' information
|
203
|
+
#
|
204
|
+
# If you wish to specify +extras+ or attach a block, you may do so
|
205
|
+
def self.Version(extras = nil, &blk)
|
171
206
|
|
172
|
-
|
173
|
-
when String
|
207
|
+
h = @@Version_
|
174
208
|
|
175
|
-
|
176
|
-
else
|
209
|
+
if extras || blk
|
177
210
|
|
178
|
-
|
179
|
-
end
|
211
|
+
return self.new(h.name, h.aliases, h.help, extras, &blk)
|
180
212
|
end
|
181
213
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
public
|
186
|
-
# An instance of FlagSpecification that provides default '--help' information
|
187
|
-
#
|
188
|
-
# If you wish to specify +extras+ or attach a block, you may do so
|
189
|
-
def self.Help(extras = nil, &blk)
|
190
|
-
|
191
|
-
h = @@Help_
|
214
|
+
h
|
215
|
+
end
|
216
|
+
end
|
192
217
|
|
193
|
-
|
218
|
+
# A class that represents the specification for a command-line option
|
219
|
+
class OptionSpecification < SpecificationBase
|
194
220
|
|
195
|
-
|
196
|
-
|
221
|
+
# Creates an OptionSpecification instance from the given name, aliases, help,
|
222
|
+
# values_range, and default_value
|
223
|
+
#
|
224
|
+
# === Signature
|
225
|
+
#
|
226
|
+
# * *Parameters*
|
227
|
+
# - +name+ (+String+) The name, or long-form, of the option
|
228
|
+
# - +aliases+ (+Array+) 0 or more strings specifying short-form or option-value aliases
|
229
|
+
# - +help+ (+String+) The help string, which may be +nil+
|
230
|
+
# - +values_range+ (+Array+) 0 or more strings specifying values supported by the option
|
231
|
+
# - +default_value+ (+String+) The default value of the option, which will be used in the case where an option is specified without a value. May be +nil+
|
232
|
+
# - +required+ (boolean) Whether the option is required. May be +nil+
|
233
|
+
# - +required_message+ (::String) Message to be used when reporting that a required option is missing. May be +nil+ in which case a message of the form "<option-name> not specified; use --help for usage". If begins with the nul character ("\0"), then is used in the place of the <option-name> and placed into the rest of the standard form message
|
234
|
+
# - +constraint+ (Hash) Constraint to be applied to the parsed values of options matching this specification. NOTE: only integer constraints are supported in the current version
|
235
|
+
# - +extras+ An application-defined additional parameter. If +nil+, it is assigned an empty +Hash+
|
236
|
+
#
|
237
|
+
# * *Block* An optional block that is called when a matching option argument is found
|
238
|
+
#
|
239
|
+
# *NOTE:* Users should prefer the +CLASP::Option()+ method
|
240
|
+
def initialize(name, aliases, help, values_range, default_value, required, required_message, constraint, extras = nil, &blk)
|
241
|
+
|
242
|
+
check_arity_(blk, 0..3, "option")
|
243
|
+
|
244
|
+
@name = name
|
245
|
+
@aliases = (aliases || []).select { |a| a and not a.empty? }
|
246
|
+
@help = help
|
247
|
+
@values_range = values_range || []
|
248
|
+
@default_value = default_value
|
249
|
+
@required = required
|
250
|
+
@required_message = nil
|
251
|
+
@constraint = constraint || {}
|
252
|
+
@extras = extras || {}
|
253
|
+
@action = blk
|
254
|
+
|
255
|
+
rm_name = nil
|
256
|
+
|
257
|
+
if required_message
|
258
|
+
|
259
|
+
if "\0" == required_message[0]
|
260
|
+
|
261
|
+
rm_name = required_message[1..-1]
|
262
|
+
end
|
263
|
+
else
|
197
264
|
|
198
|
-
|
265
|
+
rm_name = "'#{name}'"
|
199
266
|
end
|
200
267
|
|
201
|
-
|
202
|
-
#
|
203
|
-
# If you wish to specify +extras+ or attach a block, you may do so
|
204
|
-
def self.Version(extras = nil, &blk)
|
268
|
+
if rm_name
|
205
269
|
|
206
|
-
|
207
|
-
|
208
|
-
if extras || blk
|
209
|
-
|
210
|
-
return self.new(h.name, h.aliases, h.help, extras, &blk)
|
211
|
-
end
|
212
|
-
|
213
|
-
h
|
270
|
+
required_message = "#{rm_name} not specified; use --help for usage"
|
214
271
|
end
|
215
|
-
end
|
216
272
|
|
217
|
-
|
218
|
-
|
273
|
+
@required_message = required_message
|
274
|
+
end
|
219
275
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
# *NOTE:* Users should prefer the +CLASP::Option()+ method
|
239
|
-
def initialize(name, aliases, help, values_range, default_value, required, required_message, constraint, extras = nil, &blk)
|
240
|
-
|
241
|
-
check_arity_(blk, 0..3, "option")
|
242
|
-
|
243
|
-
@name = name
|
244
|
-
@aliases = (aliases || []).select { |a| a and not a.empty? }
|
245
|
-
@help = help
|
246
|
-
@values_range = values_range || []
|
247
|
-
@default_value = default_value
|
248
|
-
@required = required
|
249
|
-
@required_message = nil
|
250
|
-
@constraint = constraint || {}
|
251
|
-
@extras = extras || {}
|
252
|
-
@action = blk
|
253
|
-
|
254
|
-
rm_name = nil
|
255
|
-
|
256
|
-
if required_message
|
257
|
-
|
258
|
-
if "\0" == required_message[0]
|
259
|
-
|
260
|
-
rm_name = required_message[1..-1]
|
261
|
-
end
|
262
|
-
else
|
276
|
+
# The option's name string
|
277
|
+
attr_reader :name
|
278
|
+
# The option's aliases array
|
279
|
+
attr_reader :aliases
|
280
|
+
# The option's help string
|
281
|
+
attr_reader :help
|
282
|
+
# The range of values supported by the option
|
283
|
+
attr_reader :values_range
|
284
|
+
# The default value of the option
|
285
|
+
attr_reader :default_value
|
286
|
+
# Indicates whether the option is required
|
287
|
+
def required?; @required; end
|
288
|
+
# The message to be used when reporting that a required option is missing
|
289
|
+
attr_reader :required_message
|
290
|
+
# The value constraint
|
291
|
+
attr_reader :constraint
|
292
|
+
# The option's extras
|
293
|
+
attr_reader :extras
|
263
294
|
|
264
|
-
|
265
|
-
|
295
|
+
# (Proc) The procedure
|
296
|
+
attr_reader :action
|
266
297
|
|
267
|
-
|
298
|
+
# @!visibility private
|
299
|
+
def action=(blk) # :nodoc: all
|
268
300
|
|
269
|
-
|
270
|
-
end
|
301
|
+
check_arity_(blk, 0..3, "flag")
|
271
302
|
|
272
|
-
|
273
|
-
|
303
|
+
@action = blk
|
304
|
+
end
|
274
305
|
|
275
|
-
|
276
|
-
|
277
|
-
# The option's aliases array
|
278
|
-
attr_reader :aliases
|
279
|
-
# The option's help string
|
280
|
-
attr_reader :help
|
281
|
-
# The range of values supported by the option
|
282
|
-
attr_reader :values_range
|
283
|
-
# The default value of the option
|
284
|
-
attr_reader :default_value
|
285
|
-
# Indicates whether the option is required
|
286
|
-
def required?; @required; end
|
287
|
-
# The message to be used when reporting that a required option is missing
|
288
|
-
attr_reader :required_message
|
289
|
-
# The value constraint
|
290
|
-
attr_reader :constraint
|
291
|
-
# The option's extras
|
292
|
-
attr_reader :extras
|
293
|
-
|
294
|
-
# (Proc) The procedure
|
295
|
-
attr_reader :action
|
296
|
-
|
297
|
-
# @!visibility private
|
298
|
-
def action=(blk) # :nodoc: all
|
299
|
-
|
300
|
-
check_arity_(blk, 0..3, "flag")
|
301
|
-
|
302
|
-
@action = blk
|
303
|
-
end
|
304
|
-
|
305
|
-
# String form of the option
|
306
|
-
def to_s
|
306
|
+
# String form of the option
|
307
|
+
def to_s
|
307
308
|
|
308
|
-
|
309
|
-
|
309
|
+
"{#{name}; aliases=#{aliases.join(', ')}; values_range=[ #{values_range.join(', ')} ]; default_value='#{default_value}'; help='#{help}'; required?=#{required?}; required_message=#{required_message}; constraint=#{constraint}; extras=#{extras}}"
|
310
|
+
end
|
310
311
|
|
311
|
-
|
312
|
-
|
312
|
+
# @!visibility private
|
313
|
+
def eql? rhs # :nodoc:
|
313
314
|
|
314
|
-
|
315
|
-
|
315
|
+
case rhs
|
316
|
+
when self.class
|
316
317
|
|
317
|
-
|
318
|
-
|
318
|
+
return true if equal?(rhs)
|
319
|
+
else
|
319
320
|
|
320
|
-
|
321
|
-
|
321
|
+
return false
|
322
|
+
end
|
322
323
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
324
|
+
return false unless name == rhs.name
|
325
|
+
return false unless aliases == rhs.aliases
|
326
|
+
return false unless help == rhs.help
|
327
|
+
return false unless values_range == rhs.values_range
|
328
|
+
return false unless default_value == rhs.default_value
|
329
|
+
return false unless required? == rhs.required?
|
330
|
+
return false unless required_message == rhs.required_message
|
331
|
+
return false unless extras == rhs.extras
|
331
332
|
|
332
|
-
|
333
|
-
|
333
|
+
return true
|
334
|
+
end
|
334
335
|
|
335
|
-
|
336
|
-
|
336
|
+
# Compares instance against another OptionSpecification or against a name (String)
|
337
|
+
def == rhs
|
337
338
|
|
338
|
-
|
339
|
-
|
339
|
+
case rhs
|
340
|
+
when self.class
|
340
341
|
|
341
|
-
|
342
|
-
|
342
|
+
return self.eql? rhs
|
343
|
+
when String
|
343
344
|
|
344
|
-
|
345
|
-
|
345
|
+
return name == rhs
|
346
|
+
else
|
346
347
|
|
347
|
-
|
348
|
-
end
|
348
|
+
false
|
349
349
|
end
|
350
|
+
end
|
350
351
|
end
|
351
352
|
|
352
353
|
# A class that represents an explicit alias for a flag or an option
|
353
354
|
class AliasSpecification
|
354
355
|
|
355
|
-
|
356
|
+
def initialize(name, aliases)
|
356
357
|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
358
|
+
@name = name
|
359
|
+
@aliases = (aliases || []).select { |a| a and not a.empty? }
|
360
|
+
@extras = nil
|
361
|
+
@help = nil
|
362
|
+
end
|
362
363
|
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
364
|
+
# The alias' name string
|
365
|
+
attr_reader :name
|
366
|
+
# The alias' aliases array
|
367
|
+
attr_reader :aliases
|
368
|
+
# The flag's help string
|
369
|
+
attr_reader :help
|
370
|
+
# The flag's extras
|
371
|
+
attr_reader :extras
|
371
372
|
|
372
|
-
|
373
|
-
|
373
|
+
# String form of the option
|
374
|
+
def to_s
|
374
375
|
|
375
|
-
|
376
|
-
|
376
|
+
"{#{name}; aliases=#{aliases.join(', ')}}"
|
377
|
+
end
|
377
378
|
end
|
378
379
|
|
379
380
|
|
@@ -398,38 +399,39 @@ end
|
|
398
399
|
# * *Block* An optional block that is called when a matching flag argument is found
|
399
400
|
def CLASP.Flag(name, options = {}, &blk)
|
400
401
|
|
401
|
-
|
402
|
-
|
403
|
-
|
402
|
+
aliases = nil
|
403
|
+
help = nil
|
404
|
+
extras = nil
|
404
405
|
|
405
|
-
|
406
|
+
options.each do |k, v|
|
406
407
|
|
407
|
-
|
408
|
-
|
409
|
-
case k
|
410
|
-
when :alias
|
408
|
+
case k
|
409
|
+
when Symbol
|
411
410
|
|
412
|
-
|
413
|
-
|
411
|
+
case k
|
412
|
+
when :alias
|
414
413
|
|
415
|
-
|
416
|
-
|
414
|
+
aliases = [ v ] if v
|
415
|
+
when :aliases
|
417
416
|
|
418
|
-
|
419
|
-
|
417
|
+
aliases = v unless aliases
|
418
|
+
when :help
|
420
419
|
|
421
|
-
|
422
|
-
|
420
|
+
help = v
|
421
|
+
when :extras
|
423
422
|
|
424
|
-
|
425
|
-
|
426
|
-
else
|
423
|
+
extras = v
|
424
|
+
else
|
427
425
|
|
428
|
-
|
429
|
-
|
426
|
+
raise ArgumentError, "invalid option for flag: '#{k}' => '#{v}'"
|
427
|
+
end
|
428
|
+
else
|
429
|
+
|
430
|
+
raise ArgumentError, "invalid option type for flag: '#{k}' (#{k.class}) => '#{v}'"
|
430
431
|
end
|
432
|
+
end
|
431
433
|
|
432
|
-
|
434
|
+
CLASP::FlagSpecification.new(name, aliases, help, extras, &blk)
|
433
435
|
end
|
434
436
|
|
435
437
|
# Generator method that obtains a CLASP::OptionSpecification according to the given
|
@@ -458,88 +460,89 @@ end
|
|
458
460
|
# * *Block* An optional block that is called when a matching option argument is found
|
459
461
|
def CLASP.Option(name, options = {}, &blk)
|
460
462
|
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
463
|
+
aliases = nil
|
464
|
+
help = nil
|
465
|
+
values_range = nil
|
466
|
+
default_value = nil
|
467
|
+
required = false
|
468
|
+
require_message = nil
|
469
|
+
constraint = nil
|
470
|
+
extras = nil
|
469
471
|
|
470
|
-
|
472
|
+
options.each do |k, v|
|
471
473
|
|
472
|
-
|
473
|
-
|
474
|
-
case k
|
475
|
-
when :alias
|
474
|
+
case k
|
475
|
+
when Symbol
|
476
476
|
|
477
|
-
|
478
|
-
|
477
|
+
case k
|
478
|
+
when :alias
|
479
479
|
|
480
|
-
|
481
|
-
|
480
|
+
aliases = [ v ] if v
|
481
|
+
when :aliases
|
482
482
|
|
483
|
-
|
484
|
-
|
483
|
+
aliases = v unless aliases
|
484
|
+
when :help
|
485
485
|
|
486
|
-
|
487
|
-
|
486
|
+
help = v
|
487
|
+
when :values_range, :values
|
488
488
|
|
489
|
-
|
490
|
-
|
489
|
+
values_range = v
|
490
|
+
when :default_value, :default
|
491
491
|
|
492
|
-
|
493
|
-
|
492
|
+
default_value = v
|
493
|
+
when :required
|
494
494
|
|
495
|
-
|
496
|
-
|
495
|
+
required = v
|
496
|
+
when :required_message
|
497
497
|
|
498
|
-
|
499
|
-
|
498
|
+
require_message = v
|
499
|
+
when :extras
|
500
500
|
|
501
|
-
|
502
|
-
|
501
|
+
extras = v
|
502
|
+
when :constraint
|
503
503
|
|
504
|
-
|
505
|
-
|
506
|
-
else
|
504
|
+
constraint = v
|
505
|
+
else
|
507
506
|
|
508
|
-
|
509
|
-
|
507
|
+
raise ArgumentError, "invalid option for option: '#{k}' => '#{v}'"
|
508
|
+
end
|
509
|
+
else
|
510
|
+
|
511
|
+
raise ArgumentError, "invalid option type for option: '#{k}' (#{k.class}) => '#{v}'"
|
510
512
|
end
|
513
|
+
end
|
511
514
|
|
512
|
-
|
515
|
+
CLASP::OptionSpecification.new(name, aliases, help, values_range, default_value, required, require_message, constraint, extras, &blk)
|
513
516
|
end
|
514
517
|
|
515
518
|
def CLASP.Alias(name, *args)
|
516
519
|
|
517
|
-
|
518
|
-
|
520
|
+
options = args.pop if args[-1].is_a?(::Hash)
|
521
|
+
options ||= {}
|
519
522
|
|
520
|
-
|
523
|
+
if options[:alias]
|
521
524
|
|
522
|
-
|
523
|
-
|
525
|
+
aliases = [ options[:alias] ]
|
526
|
+
elsif options[:aliases]
|
524
527
|
|
525
|
-
|
526
|
-
|
528
|
+
aliases = options[:aliases]
|
529
|
+
else
|
527
530
|
|
528
|
-
|
529
|
-
|
531
|
+
aliases = args
|
532
|
+
end
|
530
533
|
|
531
|
-
|
534
|
+
CLASP::AliasSpecification.new name, aliases
|
532
535
|
end
|
533
536
|
|
534
537
|
|
535
538
|
# ######################################################################## #
|
536
539
|
# backwards-compatible
|
537
540
|
|
538
|
-
Alias =
|
539
|
-
Flag =
|
540
|
-
FlagAlias =
|
541
|
-
Option =
|
542
|
-
OptionAlias =
|
541
|
+
Alias = AliasSpecification
|
542
|
+
Flag = FlagSpecification
|
543
|
+
FlagAlias = FlagSpecification
|
544
|
+
Option = OptionSpecification
|
545
|
+
OptionAlias = OptionSpecification
|
543
546
|
|
544
547
|
|
545
548
|
# ######################################################################## #
|