clasp-ruby 0.20.3 → 0.22.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 +7 -0
- data/lib/clasp/arguments.rb +65 -20
- data/lib/clasp/clasp.rb +9 -0
- data/lib/clasp/specifications.rb +106 -16
- data/lib/clasp/util/exceptions.rb +82 -0
- data/lib/clasp/util/value_parser.rb +222 -0
- data/lib/clasp/version.rb +3 -2
- data/test/unit/tc_typed_options.rb +310 -0
- data/test/unit/tc_with_action.rb +50 -0
- metadata +29 -34
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2cdf702af24b59501e6bbe93ba1985416e7793a7dd3dd2a3cfedae7847156a2a
|
4
|
+
data.tar.gz: 6efa37c0a5f2914498de32916f6d6be2fbe79ab87d0af3a32f10dc5163595309
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5660b7d456acadbbaeacbfb04f83cfb2dfe94b5918cb731a7194fe0da0efba198e1be3196870fb1ea338cf489e528b703d406e8cee949065e234764181ac2a47
|
7
|
+
data.tar.gz: 83c5cbbb81fd29695e7c00f600bcfc5812854534c5dae6d61812e9ee1d9c68e058aa21c493adced37c3121e54cf724f048b7cf7bd700cff8f91ffbb1440499de
|
data/lib/clasp/arguments.rb
CHANGED
@@ -46,7 +46,8 @@
|
|
46
46
|
|
47
47
|
|
48
48
|
|
49
|
-
require File.join(File.dirname(__FILE__), 'specifications
|
49
|
+
require File.join(File.dirname(__FILE__), 'specifications')
|
50
|
+
require File.join(File.dirname(__FILE__), 'util', 'value_parser')
|
50
51
|
|
51
52
|
require 'yaml'
|
52
53
|
|
@@ -136,17 +137,40 @@ class Arguments
|
|
136
137
|
# Class that represents a parsed option
|
137
138
|
class OptionArgument
|
138
139
|
|
140
|
+
include ::CLASP::Util::ValueParser
|
141
|
+
|
139
142
|
# @!visibility private
|
140
143
|
#
|
141
144
|
# [PRIVATE] This method is subject to changed between versions and
|
142
145
|
# should not be called directly from application code
|
143
146
|
def initialize(arg, given_index, given_name, resolved_name, argument_spec, given_hyphens, given_label, value, extras) # :nodoc:
|
144
147
|
|
145
|
-
|
148
|
+
resolved_value = nil
|
149
|
+
|
150
|
+
if argument_spec
|
151
|
+
|
152
|
+
case constraint = (argument_spec.constraint || {})
|
153
|
+
=begin
|
154
|
+
when Proc
|
155
|
+
|
156
|
+
resolved_value = value_from_Proc(constraint, value, arg, given_index, given_name, argument_spec, extras)
|
157
|
+
=end
|
158
|
+
when Hash
|
159
|
+
|
160
|
+
if constraint.empty?
|
161
|
+
|
162
|
+
resolved_value = (value || '').empty? ? argument_spec.default_value : value
|
163
|
+
else
|
164
|
+
|
165
|
+
resolved_value = value_from_Hash(constraint, value, arg, given_index, given_name, argument_spec, extras)
|
166
|
+
end
|
167
|
+
else
|
146
168
|
|
147
|
-
|
169
|
+
warn "unexpected constraint on argument specification #{argument_spec} when parsing argument '#{arg}'"
|
170
|
+
end
|
171
|
+
else
|
148
172
|
|
149
|
-
|
173
|
+
resolved_value = value
|
150
174
|
end
|
151
175
|
|
152
176
|
@arg = arg
|
@@ -155,7 +179,8 @@ class Arguments
|
|
155
179
|
@argument_specification = argument_spec
|
156
180
|
@given_hyphens = given_hyphens
|
157
181
|
@given_label = given_label
|
158
|
-
@
|
182
|
+
@given_value = value
|
183
|
+
@value = resolved_value
|
159
184
|
@name = resolved_name || given_name
|
160
185
|
@extras = extras.nil? ? {} : extras
|
161
186
|
end
|
@@ -172,7 +197,9 @@ class Arguments
|
|
172
197
|
attr_reader :given_label
|
173
198
|
# (String) The resolved name of the argument
|
174
199
|
attr_reader :name
|
175
|
-
# (String) The value of the option
|
200
|
+
# (String) The given value of the option
|
201
|
+
attr_reader :given_value
|
202
|
+
# (????) The value of the option, which may be of a type other than string subject to the option specification's constraint
|
176
203
|
attr_reader :value
|
177
204
|
# (Object, Hash) The extras associated with the argument
|
178
205
|
attr_reader :extras
|
@@ -458,7 +485,7 @@ class Arguments
|
|
458
485
|
values = []
|
459
486
|
|
460
487
|
forced_value = false
|
461
|
-
|
488
|
+
pending_option = nil
|
462
489
|
|
463
490
|
argv.each_with_index do |arg, index|
|
464
491
|
|
@@ -563,15 +590,22 @@ class Arguments
|
|
563
590
|
|
564
591
|
if argument_spec and argument_spec.is_a? CLASP::OptionSpecification and not value
|
565
592
|
|
566
|
-
|
567
|
-
|
593
|
+
pending_option = {
|
594
|
+
|
595
|
+
arg: arg,
|
596
|
+
index: index,
|
597
|
+
given_name: given_name,
|
598
|
+
resolved_name: resolved_name,
|
599
|
+
argument_spec: argument_spec,
|
600
|
+
hyphens_size: hyphens.size,
|
601
|
+
given_label: given_label,
|
602
|
+
extras: argument_spec ? argument_spec.extras : nil,
|
603
|
+
}
|
568
604
|
elsif value
|
569
605
|
|
570
|
-
want_option_value = false
|
571
606
|
options << OptionArgument.new(arg, index, given_name, resolved_name, argument_spec, hyphens.size, given_label, value, argument_spec ? argument_spec.extras : nil)
|
572
607
|
else
|
573
608
|
|
574
|
-
want_option_value = false
|
575
609
|
flags << FlagArgument.new(arg, index, given_name, resolved_name, argument_spec, hyphens.size, given_label, argument_spec ? argument_spec.extras : nil)
|
576
610
|
end
|
577
611
|
|
@@ -579,20 +613,31 @@ class Arguments
|
|
579
613
|
end
|
580
614
|
end
|
581
615
|
|
582
|
-
if
|
616
|
+
if pending_option
|
583
617
|
|
584
|
-
|
585
|
-
option.instance_eval("@value='#{arg}'")
|
586
|
-
want_option_value = false
|
587
|
-
else
|
618
|
+
value = forced_value ? nil : arg
|
588
619
|
|
589
|
-
arg
|
590
|
-
arg_ix = ::Integer === index ? index : index.dup
|
620
|
+
options << OptionArgument.new(pending_option[:arg], pending_option[:index], pending_option[:given_name], pending_option[:resolved_name], pending_option[:argument_spec], pending_option[:hyphens_size], pending_option[:given_label], value, pending_option[:extras])
|
591
621
|
|
592
|
-
|
622
|
+
pending_option = nil
|
593
623
|
|
594
|
-
|
624
|
+
next unless forced_value
|
595
625
|
end
|
626
|
+
|
627
|
+
arg = arg.dup
|
628
|
+
arg_ix = ::Integer === index ? index : index.dup
|
629
|
+
|
630
|
+
arg.define_singleton_method(:given_index) { arg_ix }
|
631
|
+
|
632
|
+
values << arg
|
633
|
+
end
|
634
|
+
|
635
|
+
if pending_option
|
636
|
+
|
637
|
+
value = nil
|
638
|
+
|
639
|
+
options << OptionArgument.new(pending_option[:arg], pending_option[:index], pending_option[:given_name], pending_option[:resolved_name], pending_option[:argument_spec], pending_option[:hyphens_size], pending_option[:given_label], value, pending_option[:extras])
|
640
|
+
|
596
641
|
end
|
597
642
|
|
598
643
|
return flags, options, values
|
data/lib/clasp/clasp.rb
CHANGED
@@ -50,6 +50,15 @@ require 'clasp/specifications'
|
|
50
50
|
require 'clasp/cli'
|
51
51
|
require 'clasp/version'
|
52
52
|
|
53
|
+
module CLASP
|
54
|
+
|
55
|
+
# TBC (but is a shorthand for calling +Arguments.new()+
|
56
|
+
def self.parse(argv = ARGV, specifications = nil, options = {})
|
57
|
+
|
58
|
+
return Arguments.new(argv, specifications, options)
|
59
|
+
end
|
60
|
+
end # module CLASP
|
61
|
+
|
53
62
|
# ############################## end of file ############################# #
|
54
63
|
|
55
64
|
|
data/lib/clasp/specifications.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Purpose: Argument specification classes
|
6
6
|
#
|
7
7
|
# Created: 25th October 2014
|
8
|
-
# Updated:
|
8
|
+
# Updated: 29th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
11
|
#
|
@@ -57,8 +57,40 @@ module CLASP
|
|
57
57
|
# ######################################################################## #
|
58
58
|
# classes
|
59
59
|
|
60
|
+
# @!visibility private
|
61
|
+
class SpecificationBase # :nodoc: all
|
62
|
+
|
63
|
+
private
|
64
|
+
# @!visibility private
|
65
|
+
def check_arity_(blk, range, label) # :nodoc:
|
66
|
+
|
67
|
+
raise ArgumentError, "block must be a #{Proc}; #{blk.class} given" unless blk.nil? || Proc === blk
|
68
|
+
|
69
|
+
if blk
|
70
|
+
|
71
|
+
case blk.arity
|
72
|
+
when range
|
73
|
+
|
74
|
+
;
|
75
|
+
else
|
76
|
+
|
77
|
+
msg = "wrong arity for #{label}"
|
78
|
+
|
79
|
+
if $DEBUG
|
80
|
+
|
81
|
+
raise ArgumentError, msg
|
82
|
+
else
|
83
|
+
|
84
|
+
warn msg
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
public
|
90
|
+
end
|
91
|
+
|
60
92
|
# A class that represents the specification for a command-line flag
|
61
|
-
class FlagSpecification
|
93
|
+
class FlagSpecification < SpecificationBase
|
62
94
|
|
63
95
|
# Creates a FlagSpecification instance from the given name, aliases, and help
|
64
96
|
#
|
@@ -69,12 +101,19 @@ class FlagSpecification
|
|
69
101
|
# - +aliases+ (+Array+) 0 or more strings specifying short-form or option-value aliases
|
70
102
|
# - +help+ (+String+) The help string, which may be +nil+
|
71
103
|
# - +extras+ An application-defined additional parameter. If +nil+, it is assigned an empty +Hash+
|
72
|
-
|
104
|
+
#
|
105
|
+
# * *Block* An optional block that is called when a matching flag argument is found
|
106
|
+
#
|
107
|
+
# *NOTE:* Users should prefer the +CLASP::Flag()+ method
|
108
|
+
def initialize(name, aliases, help, extras = nil, &blk)
|
109
|
+
|
110
|
+
check_arity_(blk, 0..3, "flag")
|
73
111
|
|
74
112
|
@name = name
|
75
113
|
@aliases = (aliases || []).select { |a| a and not a.empty? }
|
76
114
|
@help = help
|
77
115
|
@extras = extras || {}
|
116
|
+
@action = blk
|
78
117
|
end
|
79
118
|
|
80
119
|
# The flag's name string
|
@@ -86,6 +125,17 @@ class FlagSpecification
|
|
86
125
|
# The flag's extras
|
87
126
|
attr_reader :extras
|
88
127
|
|
128
|
+
# (Proc) The procedure
|
129
|
+
attr_reader :action
|
130
|
+
|
131
|
+
# @!visibility private
|
132
|
+
def action=(blk) # :nodoc: all
|
133
|
+
|
134
|
+
check_arity_(blk, 0..3, "flag")
|
135
|
+
|
136
|
+
@action = blk
|
137
|
+
end
|
138
|
+
|
89
139
|
# String form of the flag
|
90
140
|
def to_s
|
91
141
|
|
@@ -133,28 +183,38 @@ class FlagSpecification
|
|
133
183
|
@@Version_ = self.new('--version', [], 'shows version and terminates')
|
134
184
|
public
|
135
185
|
# An instance of FlagSpecification that provides default '--help' information
|
136
|
-
|
186
|
+
#
|
187
|
+
# If you wish to specify +extras+ or attach a block, you may do so
|
188
|
+
def self.Help(extras = nil, &blk)
|
137
189
|
|
138
190
|
h = @@Help_
|
139
191
|
|
140
|
-
|
192
|
+
if extras || blk
|
193
|
+
|
194
|
+
return self.new(h.name, h.aliases, h.help, extras, &blk)
|
195
|
+
end
|
141
196
|
|
142
197
|
h
|
143
198
|
end
|
144
199
|
|
145
200
|
# An instance of FlagSpecification that provides default '--version' information
|
146
|
-
|
201
|
+
#
|
202
|
+
# If you wish to specify +extras+ or attach a block, you may do so
|
203
|
+
def self.Version(extras = nil, &blk)
|
147
204
|
|
148
205
|
h = @@Version_
|
149
206
|
|
150
|
-
|
207
|
+
if extras || blk
|
208
|
+
|
209
|
+
return self.new(h.name, h.aliases, h.help, extras, &blk)
|
210
|
+
end
|
151
211
|
|
152
212
|
h
|
153
213
|
end
|
154
214
|
end
|
155
215
|
|
156
216
|
# A class that represents the specification for a command-line option
|
157
|
-
class OptionSpecification
|
217
|
+
class OptionSpecification < SpecificationBase
|
158
218
|
|
159
219
|
# Creates an OptionSpecification instance from the given name, aliases, help,
|
160
220
|
# values_range, and default_value
|
@@ -169,8 +229,15 @@ class OptionSpecification
|
|
169
229
|
# - +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+
|
170
230
|
# - +required+ (boolean) Whether the option is required. May be +nil+
|
171
231
|
# - +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
|
232
|
+
# - +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
|
172
233
|
# - +extras+ An application-defined additional parameter. If +nil+, it is assigned an empty +Hash+
|
173
|
-
|
234
|
+
#
|
235
|
+
# * *Block* An optional block that is called when a matching option argument is found
|
236
|
+
#
|
237
|
+
# *NOTE:* Users should prefer the +CLASP::Option()+ method
|
238
|
+
def initialize(name, aliases, help, values_range, default_value, required, required_message, constraint, extras = nil, &blk)
|
239
|
+
|
240
|
+
check_arity_(blk, 0..3, "option")
|
174
241
|
|
175
242
|
@name = name
|
176
243
|
@aliases = (aliases || []).select { |a| a and not a.empty? }
|
@@ -179,7 +246,9 @@ class OptionSpecification
|
|
179
246
|
@default_value = default_value
|
180
247
|
@required = required
|
181
248
|
@required_message = nil
|
249
|
+
@constraint = constraint || {}
|
182
250
|
@extras = extras || {}
|
251
|
+
@action = blk
|
183
252
|
|
184
253
|
rm_name = nil
|
185
254
|
|
@@ -214,16 +283,28 @@ class OptionSpecification
|
|
214
283
|
attr_reader :default_value
|
215
284
|
# Indicates whether the option is required
|
216
285
|
def required?; @required; end
|
217
|
-
# The message to be used when reporting that a required option is
|
218
|
-
# missing
|
286
|
+
# The message to be used when reporting that a required option is missing
|
219
287
|
attr_reader :required_message
|
288
|
+
# The value constraint
|
289
|
+
attr_reader :constraint
|
220
290
|
# The option's extras
|
221
291
|
attr_reader :extras
|
222
292
|
|
293
|
+
# (Proc) The procedure
|
294
|
+
attr_reader :action
|
295
|
+
|
296
|
+
# @!visibility private
|
297
|
+
def action=(blk) # :nodoc: all
|
298
|
+
|
299
|
+
check_arity_(blk, 0..3, "flag")
|
300
|
+
|
301
|
+
@action = blk
|
302
|
+
end
|
303
|
+
|
223
304
|
# String form of the option
|
224
305
|
def to_s
|
225
306
|
|
226
|
-
"{#{name}; aliases=#{aliases.join(', ')}; values_range=[ #{values_range.join(', ')} ]; default_value='#{default_value}'; help='#{help}'; required?=#{required?}; extras=#{extras}}"
|
307
|
+
"{#{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}}"
|
227
308
|
end
|
228
309
|
|
229
310
|
# @!visibility private
|
@@ -311,7 +392,9 @@ end
|
|
311
392
|
# - +:aliases+ (::Array) An array of aliases, e.g. [ '-v', '-verb' ]. Ignored if +:alias+ is specified
|
312
393
|
# - +:extras+ An application-defined object, usually a hash of custom attributes
|
313
394
|
# - +:help+ (::String) A help string
|
314
|
-
|
395
|
+
#
|
396
|
+
# * *Block* An optional block that is called when a matching flag argument is found
|
397
|
+
def CLASP.Flag(name, options = {}, &blk)
|
315
398
|
|
316
399
|
aliases = nil
|
317
400
|
help = nil
|
@@ -344,7 +427,7 @@ def CLASP.Flag(name, options = {})
|
|
344
427
|
end
|
345
428
|
end
|
346
429
|
|
347
|
-
CLASP::FlagSpecification.new(name, aliases, help, extras)
|
430
|
+
CLASP::FlagSpecification.new(name, aliases, help, extras, &blk)
|
348
431
|
end
|
349
432
|
|
350
433
|
# Generator method that obtains a CLASP::OptionSpecification according to the given
|
@@ -366,9 +449,12 @@ end
|
|
366
449
|
# - +required+ (boolean) Whether the option is required. May be +nil+
|
367
450
|
# - +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
|
368
451
|
# - +extras+ An application-defined additional parameter. If +nil+, it is assigned an empty +Hash+.
|
452
|
+
# - +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
|
369
453
|
# - +:values_range+ (::Array) An array defining the accepted values for the option
|
370
454
|
# - +:values+ [DEPRECATED] Alternative to +:values_range+
|
371
|
-
|
455
|
+
#
|
456
|
+
# * *Block* An optional block that is called when a matching option argument is found
|
457
|
+
def CLASP.Option(name, options = {}, &blk)
|
372
458
|
|
373
459
|
aliases = nil
|
374
460
|
help = nil
|
@@ -376,6 +462,7 @@ def CLASP.Option(name, options = {})
|
|
376
462
|
default_value = nil
|
377
463
|
required = false
|
378
464
|
require_message = nil
|
465
|
+
constraint = nil
|
379
466
|
extras = nil
|
380
467
|
|
381
468
|
options.each do |k, v|
|
@@ -407,6 +494,9 @@ def CLASP.Option(name, options = {})
|
|
407
494
|
when :extras
|
408
495
|
|
409
496
|
extras = v
|
497
|
+
when :constraint
|
498
|
+
|
499
|
+
constraint = v
|
410
500
|
else
|
411
501
|
|
412
502
|
raise ArgumentError, "invalid option for option: '#{k}' => '#{v}'"
|
@@ -417,7 +507,7 @@ def CLASP.Option(name, options = {})
|
|
417
507
|
end
|
418
508
|
end
|
419
509
|
|
420
|
-
CLASP::OptionSpecification.new(name, aliases, help, values_range, default_value, required, require_message, extras)
|
510
|
+
CLASP::OptionSpecification.new(name, aliases, help, values_range, default_value, required, require_message, constraint, extras, &blk)
|
421
511
|
end
|
422
512
|
|
423
513
|
def CLASP.Alias(name, *args)
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
# ######################################################################## #
|
3
|
+
# File: clasp/util/exceptions.rb
|
4
|
+
#
|
5
|
+
# Purpose: Exception classes
|
6
|
+
#
|
7
|
+
# Created: 20th April 2019
|
8
|
+
# Updated: 28th April 2019
|
9
|
+
#
|
10
|
+
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
|
+
#
|
12
|
+
# Author: Matthew Wilson
|
13
|
+
#
|
14
|
+
# Copyright (c) 2019, Matthew Wilson and Synesis Software
|
15
|
+
# All rights reserved.
|
16
|
+
#
|
17
|
+
# Redistribution and use in source and binary forms, with or without
|
18
|
+
# modification, are permitted provided that the following conditions are
|
19
|
+
# met:
|
20
|
+
#
|
21
|
+
# * Redistributions of source code must retain the above copyright
|
22
|
+
# notice, this list of conditions and the following disclaimer.
|
23
|
+
#
|
24
|
+
# * Redistributions in binary form must reproduce the above copyright
|
25
|
+
# notice, this list of conditions and the following disclaimer in the
|
26
|
+
# documentation and/or other materials provided with the distribution.
|
27
|
+
#
|
28
|
+
# * Neither the names of the copyright holder nor the names of its
|
29
|
+
# contributors may be used to endorse or promote products derived from
|
30
|
+
# this software without specific prior written permission.
|
31
|
+
#
|
32
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
33
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
34
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
35
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
36
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
37
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
38
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
39
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
40
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
41
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
42
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
43
|
+
#
|
44
|
+
# ######################################################################## #
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
=begin
|
49
|
+
=end
|
50
|
+
|
51
|
+
module CLASP # :nodoc:
|
52
|
+
|
53
|
+
# Exceptions
|
54
|
+
module Exceptions
|
55
|
+
|
56
|
+
# Root exception for CLASP
|
57
|
+
class CLASPException < RuntimeError; end
|
58
|
+
|
59
|
+
# Root exception for value parsing
|
60
|
+
class ValueParserException < CLASPException; end
|
61
|
+
|
62
|
+
# No value specified (and no default value) for an option
|
63
|
+
class MissingValueException < ValueParserException; end
|
64
|
+
|
65
|
+
# Exception class indicating invalid values (as opposed to types)
|
66
|
+
class InvalidValueException < ValueParserException; end
|
67
|
+
|
68
|
+
# The given value could not be recognised as a (properly-formatted) number
|
69
|
+
class InvalidNumberException < InvalidValueException; end
|
70
|
+
|
71
|
+
# The given value could not be recognised as a (properly-formatted) integer
|
72
|
+
class InvalidIntegerException < InvalidNumberException; end
|
73
|
+
|
74
|
+
# The value was a valid integer but is out of range
|
75
|
+
class IntegerOutOfRangeException < InvalidValueException; end
|
76
|
+
|
77
|
+
end # module Exceptions
|
78
|
+
end # module CLASP
|
79
|
+
|
80
|
+
# ############################## end of file ############################# #
|
81
|
+
|
82
|
+
|
@@ -0,0 +1,222 @@
|
|
1
|
+
|
2
|
+
# ######################################################################## #
|
3
|
+
# File: clasp/util/value_parser.rb
|
4
|
+
#
|
5
|
+
# Purpose: Utility component for typed values
|
6
|
+
#
|
7
|
+
# Created: 20th April 2019
|
8
|
+
# Updated: 28th April 2019
|
9
|
+
#
|
10
|
+
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
|
+
#
|
12
|
+
# Author: Matthew Wilson
|
13
|
+
#
|
14
|
+
# Copyright (c) 2019, Matthew Wilson and Synesis Software
|
15
|
+
# All rights reserved.
|
16
|
+
#
|
17
|
+
# Redistribution and use in source and binary forms, with or without
|
18
|
+
# modification, are permitted provided that the following conditions are
|
19
|
+
# met:
|
20
|
+
#
|
21
|
+
# * Redistributions of source code must retain the above copyright
|
22
|
+
# notice, this list of conditions and the following disclaimer.
|
23
|
+
#
|
24
|
+
# * Redistributions in binary form must reproduce the above copyright
|
25
|
+
# notice, this list of conditions and the following disclaimer in the
|
26
|
+
# documentation and/or other materials provided with the distribution.
|
27
|
+
#
|
28
|
+
# * Neither the names of the copyright holder nor the names of its
|
29
|
+
# contributors may be used to endorse or promote products derived from
|
30
|
+
# this software without specific prior written permission.
|
31
|
+
#
|
32
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
33
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
34
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
35
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
36
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
37
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
38
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
39
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
40
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
41
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
42
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
43
|
+
#
|
44
|
+
# ######################################################################## #
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
require File.join(File.dirname(__FILE__), 'exceptions')
|
49
|
+
|
50
|
+
=begin
|
51
|
+
=end
|
52
|
+
|
53
|
+
module CLASP # :nodoc:
|
54
|
+
module Util # :nodoc:
|
55
|
+
|
56
|
+
# @!visibility private
|
57
|
+
module ValueParser # :nodoc: all
|
58
|
+
|
59
|
+
module Internal_ # :nodoc: all
|
60
|
+
|
61
|
+
include Exceptions
|
62
|
+
|
63
|
+
def self.is_integer? type
|
64
|
+
|
65
|
+
h = {}
|
66
|
+
|
67
|
+
return true if Integer == type
|
68
|
+
return true if :integer == type
|
69
|
+
|
70
|
+
false
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.obtain_integer value, constraint, argument_spec
|
74
|
+
|
75
|
+
# If no value is given, then use the default (and don't do any
|
76
|
+
# range testing)
|
77
|
+
|
78
|
+
if (value || '').empty?
|
79
|
+
|
80
|
+
def_value = argument_spec.default_value
|
81
|
+
|
82
|
+
if (def_value || '').to_s.empty?
|
83
|
+
|
84
|
+
msg = "no value specified for the option '#{argument_spec.name}', which has no default value either"
|
85
|
+
|
86
|
+
warn msg if $DEBUG
|
87
|
+
|
88
|
+
raise MissingValueException, msg
|
89
|
+
end
|
90
|
+
|
91
|
+
begin
|
92
|
+
|
93
|
+
return Integer(def_value)
|
94
|
+
rescue ArgumentError => x
|
95
|
+
|
96
|
+
msg = "default value '#{def_value}' specified for option '#{argument_spec.name}' that requires the value to be an integer"
|
97
|
+
|
98
|
+
warn msg if $DEBUG
|
99
|
+
|
100
|
+
raise InvalidIntegerException, msg
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# obtain the integer from the value
|
105
|
+
|
106
|
+
v = nil
|
107
|
+
|
108
|
+
begin
|
109
|
+
|
110
|
+
v = Integer(value)
|
111
|
+
rescue ArgumentError => x
|
112
|
+
|
113
|
+
msg = "value '#{value}' specified for option '#{argument_spec.name}' that requires the value to be an integer"
|
114
|
+
|
115
|
+
warn msg if $DEBUG
|
116
|
+
|
117
|
+
raise InvalidIntegerException, msg
|
118
|
+
end
|
119
|
+
|
120
|
+
# Is there a value constraint?:
|
121
|
+
#
|
122
|
+
# - values (obtained from argument_spec#values)
|
123
|
+
# - range
|
124
|
+
# - minimum & maximum
|
125
|
+
|
126
|
+
values_range = argument_spec.values_range
|
127
|
+
|
128
|
+
unless values_range.empty?
|
129
|
+
|
130
|
+
v_s = v.to_s
|
131
|
+
|
132
|
+
v_s = '+' + v_s unless '-' == v_s[0]
|
133
|
+
|
134
|
+
vr_s = values_range.map { |x| x.to_s }.map { |x| '-' == x[0] ? x : '+' + x }
|
135
|
+
|
136
|
+
unless vr_s.include? v_s
|
137
|
+
|
138
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' does not fall within the required range"
|
139
|
+
|
140
|
+
raise IntegerOutOfRangeException, msg
|
141
|
+
end
|
142
|
+
else
|
143
|
+
|
144
|
+
case range = constraint[:range]
|
145
|
+
when :negative
|
146
|
+
|
147
|
+
if v >= 0
|
148
|
+
|
149
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' must be a negative integer"
|
150
|
+
|
151
|
+
raise IntegerOutOfRangeException, msg
|
152
|
+
end
|
153
|
+
when :positive
|
154
|
+
|
155
|
+
if v < 1
|
156
|
+
|
157
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' must be a positive integer"
|
158
|
+
|
159
|
+
raise IntegerOutOfRangeException, msg
|
160
|
+
end
|
161
|
+
when :non_positive
|
162
|
+
|
163
|
+
if v > 0
|
164
|
+
|
165
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' must be a non-positive integer"
|
166
|
+
|
167
|
+
raise IntegerOutOfRangeException, msg
|
168
|
+
end
|
169
|
+
when :non_negative
|
170
|
+
|
171
|
+
if v < 0
|
172
|
+
|
173
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' must be a non-negative integer"
|
174
|
+
|
175
|
+
raise IntegerOutOfRangeException, msg
|
176
|
+
end
|
177
|
+
when Range
|
178
|
+
|
179
|
+
unless range.include?
|
180
|
+
|
181
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' does not fall within the required range"
|
182
|
+
|
183
|
+
raise IntegerOutOfRangeException, msg
|
184
|
+
end
|
185
|
+
else
|
186
|
+
|
187
|
+
;
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
v
|
192
|
+
end
|
193
|
+
end # module Internal_
|
194
|
+
|
195
|
+
def value_from_Proc(constraint, value, arg, given_index, given_name, argument_spec, extras)
|
196
|
+
|
197
|
+
value
|
198
|
+
end
|
199
|
+
|
200
|
+
def value_from_Hash(constraint, value, arg, given_index, given_name, argument_spec, extras)
|
201
|
+
|
202
|
+
# Check if type is specified; if not, String is assumed
|
203
|
+
|
204
|
+
type = constraint[:type]
|
205
|
+
|
206
|
+
|
207
|
+
if Internal_.is_integer?(type)
|
208
|
+
|
209
|
+
return Internal_.obtain_integer(value, constraint, argument_spec)
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
value
|
214
|
+
end
|
215
|
+
end # module ValueParser
|
216
|
+
|
217
|
+
end # module util
|
218
|
+
end # module CLASP
|
219
|
+
|
220
|
+
# ############################## end of file ############################# #
|
221
|
+
|
222
|
+
|
data/lib/clasp/version.rb
CHANGED
@@ -5,12 +5,13 @@
|
|
5
5
|
# Purpose: Version for CLASP.Ruby library
|
6
6
|
#
|
7
7
|
# Created: 16th November 2014
|
8
|
-
# Updated:
|
8
|
+
# Updated: 26th June 2022
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
+
# Copyright (c) 2019-2022, Matthew Wilson and Synesis Information Systems
|
14
15
|
# Copyright (c) 2014-2019, Matthew Wilson and Synesis Software
|
15
16
|
# All rights reserved.
|
16
17
|
#
|
@@ -51,7 +52,7 @@
|
|
51
52
|
module CLASP
|
52
53
|
|
53
54
|
# Current version of the CLASP.Ruby library
|
54
|
-
VERSION = '0.
|
55
|
+
VERSION = '0.22.1'
|
55
56
|
|
56
57
|
private
|
57
58
|
# @!visibility private
|
@@ -0,0 +1,310 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
4
|
+
|
5
|
+
require 'clasp'
|
6
|
+
|
7
|
+
require 'xqsr3/extensions/test/unit' if RUBY_VERSION >= '2'
|
8
|
+
|
9
|
+
require 'test/unit'
|
10
|
+
|
11
|
+
class Test_TypedOptionValues < Test::Unit::TestCase
|
12
|
+
|
13
|
+
if RUBY_VERSION < '2'
|
14
|
+
|
15
|
+
def assert_raise_with_message(type_spec, message_spec, *args, &block)
|
16
|
+
|
17
|
+
assert_raise(type_spec, *args, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_Integer_no_range
|
22
|
+
|
23
|
+
specifications = [
|
24
|
+
|
25
|
+
CLASP.Option('--level', default_value: 1234, constraint: { type: Integer })
|
26
|
+
]
|
27
|
+
|
28
|
+
# with no arguments
|
29
|
+
begin
|
30
|
+
|
31
|
+
argv = []
|
32
|
+
args = CLASP.parse argv, specifications
|
33
|
+
|
34
|
+
assert_equal 0, args.flags.size
|
35
|
+
assert_equal 0, args.options.size
|
36
|
+
assert_equal 0, args.values.size
|
37
|
+
end
|
38
|
+
|
39
|
+
# with default value
|
40
|
+
begin
|
41
|
+
|
42
|
+
argv = [ '--level=' ]
|
43
|
+
|
44
|
+
args = CLASP.parse argv, specifications
|
45
|
+
|
46
|
+
assert_equal 0, args.flags.size
|
47
|
+
assert_equal 1, args.options.size
|
48
|
+
assert_equal 0, args.values.size
|
49
|
+
|
50
|
+
opt = args.options[0]
|
51
|
+
|
52
|
+
assert_equal 0, opt.given_index
|
53
|
+
assert_equal specifications[0], opt.argument_specification
|
54
|
+
assert_equal '--level', opt.name
|
55
|
+
assert_equal '', opt.given_value
|
56
|
+
assert_equal 1234, opt.value
|
57
|
+
end
|
58
|
+
|
59
|
+
# with explicit value 0
|
60
|
+
begin
|
61
|
+
|
62
|
+
argv = [ '--level=0' ]
|
63
|
+
|
64
|
+
args = CLASP.parse argv, specifications
|
65
|
+
|
66
|
+
assert_equal 0, args.flags.size
|
67
|
+
assert_equal 1, args.options.size
|
68
|
+
assert_equal 0, args.values.size
|
69
|
+
|
70
|
+
opt = args.options[0]
|
71
|
+
|
72
|
+
assert_equal 0, opt.given_index
|
73
|
+
assert_equal specifications[0], opt.argument_specification
|
74
|
+
assert_equal '--level', opt.name
|
75
|
+
assert_equal '0', opt.given_value
|
76
|
+
assert_equal 0, opt.value
|
77
|
+
end
|
78
|
+
|
79
|
+
# with explicit value -100
|
80
|
+
begin
|
81
|
+
|
82
|
+
argv = [ '--level=-100' ]
|
83
|
+
|
84
|
+
args = CLASP.parse argv, specifications
|
85
|
+
|
86
|
+
assert_equal 0, args.flags.size
|
87
|
+
assert_equal 1, args.options.size
|
88
|
+
assert_equal 0, args.values.size
|
89
|
+
|
90
|
+
opt = args.options[0]
|
91
|
+
|
92
|
+
assert_equal 0, opt.given_index
|
93
|
+
assert_equal specifications[0], opt.argument_specification
|
94
|
+
assert_equal '--level', opt.name
|
95
|
+
assert_equal '-100', opt.given_value
|
96
|
+
assert_equal -100, opt.value
|
97
|
+
end
|
98
|
+
|
99
|
+
# with explicit value 123456789
|
100
|
+
begin
|
101
|
+
|
102
|
+
argv = [ '--level=123456789' ]
|
103
|
+
|
104
|
+
args = CLASP.parse argv, specifications
|
105
|
+
|
106
|
+
assert_equal 0, args.flags.size
|
107
|
+
assert_equal 1, args.options.size
|
108
|
+
assert_equal 0, args.values.size
|
109
|
+
|
110
|
+
opt = args.options[0]
|
111
|
+
|
112
|
+
assert_equal 0, opt.given_index
|
113
|
+
assert_equal specifications[0], opt.argument_specification
|
114
|
+
assert_equal '--level', opt.name
|
115
|
+
assert_equal '123456789', opt.given_value
|
116
|
+
assert_equal 123456789, opt.value
|
117
|
+
end
|
118
|
+
|
119
|
+
# with explicit value +123456789
|
120
|
+
begin
|
121
|
+
|
122
|
+
argv = [ '--level=+123456789' ]
|
123
|
+
|
124
|
+
args = CLASP.parse argv, specifications
|
125
|
+
|
126
|
+
assert_equal 0, args.flags.size
|
127
|
+
assert_equal 1, args.options.size
|
128
|
+
assert_equal 0, args.values.size
|
129
|
+
|
130
|
+
opt = args.options[0]
|
131
|
+
|
132
|
+
assert_equal 0, opt.given_index
|
133
|
+
assert_equal specifications[0], opt.argument_specification
|
134
|
+
assert_equal '--level', opt.name
|
135
|
+
assert_equal '+123456789', opt.given_value
|
136
|
+
assert_equal 123456789, opt.value
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_Integer_positive
|
141
|
+
|
142
|
+
specifications = [
|
143
|
+
|
144
|
+
CLASP.Option('--level', default_value: 1234, constraint: { type: Integer, range: :positive })
|
145
|
+
]
|
146
|
+
|
147
|
+
# with no arguments
|
148
|
+
begin
|
149
|
+
|
150
|
+
argv = []
|
151
|
+
args = CLASP.parse argv, specifications
|
152
|
+
|
153
|
+
assert_equal 0, args.flags.size
|
154
|
+
assert_equal 0, args.options.size
|
155
|
+
assert_equal 0, args.values.size
|
156
|
+
end
|
157
|
+
|
158
|
+
# with default value
|
159
|
+
begin
|
160
|
+
|
161
|
+
argv = [ '--level=' ]
|
162
|
+
|
163
|
+
args = CLASP.parse argv, specifications
|
164
|
+
|
165
|
+
assert_equal 0, args.flags.size
|
166
|
+
assert_equal 1, args.options.size
|
167
|
+
assert_equal 0, args.values.size
|
168
|
+
|
169
|
+
opt = args.options[0]
|
170
|
+
|
171
|
+
assert_equal 0, opt.given_index
|
172
|
+
assert_equal specifications[0], opt.argument_specification
|
173
|
+
assert_equal '--level', opt.name
|
174
|
+
assert_equal '', opt.given_value
|
175
|
+
assert_equal 1234, opt.value
|
176
|
+
end
|
177
|
+
|
178
|
+
# with explicit value 0
|
179
|
+
begin
|
180
|
+
|
181
|
+
argv = [ '--level=0' ]
|
182
|
+
|
183
|
+
assert_raise_with_message(CLASP::Exceptions::IntegerOutOfRangeException, /\b0\b.*--level.*must be a positive integer/) { CLASP.parse argv, specifications }
|
184
|
+
end
|
185
|
+
|
186
|
+
# with explicit value -100
|
187
|
+
begin
|
188
|
+
|
189
|
+
argv = [ '--level=-100' ]
|
190
|
+
|
191
|
+
assert_raise_with_message(CLASP::Exceptions::IntegerOutOfRangeException, /-100\b.*--level.*must be a positive integer/) { CLASP.parse argv, specifications }
|
192
|
+
end
|
193
|
+
|
194
|
+
# with explicit value 123456789
|
195
|
+
begin
|
196
|
+
|
197
|
+
argv = [ '--level=123456789' ]
|
198
|
+
|
199
|
+
args = CLASP.parse argv, specifications
|
200
|
+
|
201
|
+
assert_equal 0, args.flags.size
|
202
|
+
assert_equal 1, args.options.size
|
203
|
+
assert_equal 0, args.values.size
|
204
|
+
|
205
|
+
opt = args.options[0]
|
206
|
+
|
207
|
+
assert_equal 0, opt.given_index
|
208
|
+
assert_equal specifications[0], opt.argument_specification
|
209
|
+
assert_equal '--level', opt.name
|
210
|
+
assert_equal '123456789', opt.given_value
|
211
|
+
assert_equal 123456789, opt.value
|
212
|
+
end
|
213
|
+
|
214
|
+
# with explicit value +123456789
|
215
|
+
begin
|
216
|
+
|
217
|
+
argv = [ '--level=+123456789' ]
|
218
|
+
|
219
|
+
args = CLASP.parse argv, specifications
|
220
|
+
|
221
|
+
assert_equal 0, args.flags.size
|
222
|
+
assert_equal 1, args.options.size
|
223
|
+
assert_equal 0, args.values.size
|
224
|
+
|
225
|
+
opt = args.options[0]
|
226
|
+
|
227
|
+
assert_equal 0, opt.given_index
|
228
|
+
assert_equal specifications[0], opt.argument_specification
|
229
|
+
assert_equal '--level', opt.name
|
230
|
+
assert_equal '+123456789', opt.given_value
|
231
|
+
assert_equal 123456789, opt.value
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_Integer_range_values_range
|
236
|
+
|
237
|
+
specifications = [
|
238
|
+
|
239
|
+
CLASP.Option('--level', default_value: 1234, values_range: [ 1234, -1234, 7, 19 ], constraint: { type: Integer })
|
240
|
+
]
|
241
|
+
|
242
|
+
# with no arguments
|
243
|
+
begin
|
244
|
+
|
245
|
+
argv = []
|
246
|
+
args = CLASP.parse argv, specifications
|
247
|
+
|
248
|
+
assert_equal 0, args.flags.size
|
249
|
+
assert_equal 0, args.options.size
|
250
|
+
assert_equal 0, args.values.size
|
251
|
+
end
|
252
|
+
|
253
|
+
# with default value
|
254
|
+
begin
|
255
|
+
|
256
|
+
argv = [ '--level=' ]
|
257
|
+
|
258
|
+
args = CLASP.parse argv, specifications
|
259
|
+
|
260
|
+
assert_equal 0, args.flags.size
|
261
|
+
assert_equal 1, args.options.size
|
262
|
+
assert_equal 0, args.values.size
|
263
|
+
|
264
|
+
opt = args.options[0]
|
265
|
+
|
266
|
+
assert_equal 0, opt.given_index
|
267
|
+
assert_equal specifications[0], opt.argument_specification
|
268
|
+
assert_equal '--level', opt.name
|
269
|
+
assert_equal '', opt.given_value
|
270
|
+
assert_equal 1234, opt.value
|
271
|
+
end
|
272
|
+
|
273
|
+
# with explicit value 0
|
274
|
+
begin
|
275
|
+
|
276
|
+
argv = [ '--level=0' ]
|
277
|
+
|
278
|
+
assert_raise_with_message(CLASP::Exceptions::IntegerOutOfRangeException, /\b0\b.*--level.*does not fall within the required range/) { CLASP.parse argv, specifications }
|
279
|
+
end
|
280
|
+
|
281
|
+
spec0 = specifications[0]
|
282
|
+
values = spec0.values_range.sort[0]..spec0.values_range.sort[-1]
|
283
|
+
|
284
|
+
values.each do |val|
|
285
|
+
|
286
|
+
argv = [ "--level=#{val}" ]
|
287
|
+
|
288
|
+
if spec0.values_range.include? val
|
289
|
+
|
290
|
+
args = CLASP.parse argv, specifications
|
291
|
+
|
292
|
+
assert_equal 0, args.flags.size
|
293
|
+
assert_equal 1, args.options.size
|
294
|
+
assert_equal 0, args.values.size
|
295
|
+
|
296
|
+
opt = args.options[0]
|
297
|
+
|
298
|
+
assert_equal 0, opt.given_index
|
299
|
+
assert_equal specifications[0], opt.argument_specification
|
300
|
+
assert_equal '--level', opt.name
|
301
|
+
assert_equal val.to_s, opt.given_value
|
302
|
+
assert_equal val, opt.value
|
303
|
+
else
|
304
|
+
|
305
|
+
assert_raise_with_message(CLASP::Exceptions::IntegerOutOfRangeException, /#{val}\b.*--level.*does not fall within the required range/) { CLASP.parse argv, specifications }
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
4
|
+
|
5
|
+
require 'clasp'
|
6
|
+
|
7
|
+
require 'xqsr3/extensions/test/unit'
|
8
|
+
|
9
|
+
require 'test/unit'
|
10
|
+
|
11
|
+
class Test_WithAction < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def test_flag_with_action
|
14
|
+
|
15
|
+
debug = false
|
16
|
+
|
17
|
+
specifications = [
|
18
|
+
|
19
|
+
CLASP.Flag('--debug', alias: '-d') { debug = true }
|
20
|
+
]
|
21
|
+
argv = []
|
22
|
+
args = CLASP.parse argv, specifications
|
23
|
+
|
24
|
+
assert_equal 0, args.flags.size
|
25
|
+
assert_equal 0, args.options.size
|
26
|
+
assert_equal 0, args.values.size
|
27
|
+
|
28
|
+
assert_false debug
|
29
|
+
|
30
|
+
argv2 = [ '--debug' ]
|
31
|
+
args2 = CLASP.parse argv2, specifications
|
32
|
+
|
33
|
+
assert_equal 1, args2.flags.size
|
34
|
+
assert_equal 0, args2.options.size
|
35
|
+
assert_equal 0, args2.values.size
|
36
|
+
|
37
|
+
assert_false debug
|
38
|
+
|
39
|
+
if ix = args2.flags.index('--debug')
|
40
|
+
|
41
|
+
flag = args2.flags[ix]
|
42
|
+
|
43
|
+
flag.argument_specification.action.call(flag, flag.argument_specification)
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_true debug
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
metadata
CHANGED
@@ -1,72 +1,66 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clasp-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.22.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Matt Wilson
|
9
|
-
autorequire:
|
8
|
+
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2022-06-26 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: xqsr3
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version: '0.
|
19
|
+
version: '0.37'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '0.
|
30
|
-
description:
|
31
|
-
powerful
|
32
|
-
|
33
|
-
abstraction of command-line interpretation facilities. CLASP.Ruby is a Ruby port
|
34
|
-
of the popular CLASP (C/C++) library, and provides declarative specification of
|
35
|
-
command-line flags and options, aliasing, flag combination, UNIX de-facto standard
|
36
|
-
flag processing, and a number of utility functions for expressing usage and version
|
37
|
-
information.
|
38
|
-
|
39
|
-
'
|
26
|
+
version: '0.37'
|
27
|
+
description: |
|
28
|
+
Command-Line Argument Sorting and Parsing library that provides a powerful
|
29
|
+
abstraction of command-line interpretation facilities. CLASP.Ruby is a Ruby port of the popular CLASP (C/C++) library, and provides declarative specification of command-line flags and options, aliasing, flag combination, UNIX de-facto standard flag processing, and a number of utility functions for expressing usage and version information.
|
40
30
|
email: matthew@synesis.com.au
|
41
31
|
executables: []
|
42
32
|
extensions: []
|
43
33
|
extra_rdoc_files: []
|
44
34
|
files:
|
35
|
+
- LICENSE
|
36
|
+
- README.md
|
45
37
|
- examples/cr-example.rb
|
46
38
|
- examples/flag_and_option_specifications.md
|
47
39
|
- examples/flag_and_option_specifications.rb
|
48
40
|
- examples/show_usage_and_version.md
|
49
41
|
- examples/show_usage_and_version.rb
|
50
42
|
- examples/simple_command_line_no_specifications.rb
|
43
|
+
- lib/clasp-ruby.rb
|
44
|
+
- lib/clasp.rb
|
51
45
|
- lib/clasp/arguments.rb
|
52
46
|
- lib/clasp/clasp.rb
|
53
47
|
- lib/clasp/cli.rb
|
54
48
|
- lib/clasp/doc_.rb
|
55
49
|
- lib/clasp/old_module.rb
|
56
50
|
- lib/clasp/specifications.rb
|
51
|
+
- lib/clasp/util/exceptions.rb
|
52
|
+
- lib/clasp/util/value_parser.rb
|
57
53
|
- lib/clasp/version.rb
|
58
|
-
- lib/clasp-ruby.rb
|
59
|
-
- lib/clasp.rb
|
60
54
|
- test/scratch/test_list_command_line.rb
|
61
55
|
- test/scratch/test_specifications.rb
|
62
56
|
- test/scratch/test_usage.rb
|
63
57
|
- test/scratch/test_usage_from_DATA.rb
|
64
58
|
- test/scratch/test_usage_with_duplicate_specifications.rb
|
59
|
+
- test/unit/tc_ARGV_rewrite.rb
|
65
60
|
- test/unit/tc_arguments_1.rb
|
66
61
|
- test/unit/tc_arguments_2.rb
|
67
62
|
- test/unit/tc_arguments_3.rb
|
68
63
|
- test/unit/tc_arguments_inspect.rb
|
69
|
-
- test/unit/tc_ARGV_rewrite.rb
|
70
64
|
- test/unit/tc_cli.rb
|
71
65
|
- test/unit/tc_default_value.rb
|
72
66
|
- test/unit/tc_defaults_1.rb
|
@@ -75,33 +69,34 @@ files:
|
|
75
69
|
- test/unit/tc_option_required.rb
|
76
70
|
- test/unit/tc_option_value_aliases.rb
|
77
71
|
- test/unit/tc_specifications.rb
|
72
|
+
- test/unit/tc_typed_options.rb
|
78
73
|
- test/unit/tc_usage.rb
|
74
|
+
- test/unit/tc_with_action.rb
|
79
75
|
- test/unit/ts_all.rb
|
80
|
-
- README.md
|
81
|
-
- LICENSE
|
82
76
|
homepage: http://github.com/synesissoftware/CLASP.Ruby
|
83
77
|
licenses:
|
84
78
|
- BSD-3-Clause
|
85
|
-
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
86
81
|
rdoc_options: []
|
87
82
|
require_paths:
|
88
83
|
- lib
|
89
84
|
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
85
|
requirements:
|
92
|
-
- -
|
86
|
+
- - ">="
|
93
87
|
- !ruby/object:Gem::Version
|
94
88
|
version: 1.9.3
|
89
|
+
- - "<"
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '4'
|
95
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
-
none: false
|
97
93
|
requirements:
|
98
|
-
- -
|
94
|
+
- - ">="
|
99
95
|
- !ruby/object:Gem::Version
|
100
96
|
version: '0'
|
101
97
|
requirements: []
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
specification_version: 3
|
98
|
+
rubygems_version: 3.2.3
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
106
101
|
summary: CLASP.Ruby
|
107
102
|
test_files: []
|