clasp-ruby 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/examples/cr-example.rb +4 -4
- data/examples/flag_and_option_aliases.md +7 -7
- data/examples/flag_and_option_aliases.rb +7 -7
- data/examples/show_usage_and_version.md +6 -6
- data/examples/show_usage_and_version.rb +6 -6
- data/lib/clasp/aliases.rb +18 -15
- data/lib/clasp/arguments.rb +34 -31
- data/lib/clasp/cli.rb +25 -24
- data/lib/clasp/version.rb +1 -1
- data/test/scratch/test_aliases.rb +5 -5
- data/test/scratch/test_list_command_line.rb +2 -2
- data/test/scratch/test_usage.rb +4 -4
- data/test/scratch/test_usage_with_duplicate_aliases.rb +4 -4
- data/test/unit/tc_aliases.rb +1 -1
- data/test/unit/tc_cli.rb +2 -2
- data/test/unit/tc_examples_Arguments.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 119fcad10a9c01d575d47bc9f495fda5bb1869d1
|
4
|
+
data.tar.gz: 3a4c4edbf579ce92c968833ba2f13a857a7f69dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7aa695f6ef62302ac3fb64a815017e8f256130c29abcbf9b81aeb82f378cd4233f8435b0355acc91d2c24c35107809c6fa9fbcfb171f28c50b5ed5aa3018277
|
7
|
+
data.tar.gz: f0347ac65f0a4ba087c486ba2d5492890fd3f69240e547c1c3b7371d59c5c178417179fa86592a786b9816bc5b296af17bc23a23adba5d3ff85830c473751d66
|
data/README.md
CHANGED
@@ -96,7 +96,7 @@ like the following:
|
|
96
96
|
|
97
97
|
PROGRAM_VERSION = '0.1.2'
|
98
98
|
|
99
|
-
|
99
|
+
Specifications = [
|
100
100
|
|
101
101
|
CLASP.Flag('--all', alias: '-a', help: 'processes all item types'),
|
102
102
|
CLASP.Flag('-c', help: 'count the processed items'),
|
@@ -109,7 +109,7 @@ Aliases = [
|
|
109
109
|
]
|
110
110
|
|
111
111
|
# assuming the command-line `myprog -acv infile outfile`
|
112
|
-
Args = CLASP::Arguments.new(ARGV,
|
112
|
+
Args = CLASP::Arguments.new(ARGV, Specifications)
|
113
113
|
|
114
114
|
puts Args.flags.size # => 2
|
115
115
|
puts Args.flags[0].name # => "--all"
|
@@ -136,10 +136,10 @@ Args.flags.each do |f|
|
|
136
136
|
case f.name
|
137
137
|
when CLASP::Flag.Help.name
|
138
138
|
|
139
|
-
CLASP.show_usage(
|
139
|
+
CLASP.show_usage(Specifications, exit: 0, values: '<input-file> <output-file>')
|
140
140
|
when CLASP::Flag.Version.name
|
141
141
|
|
142
|
-
CLASP.show_version(
|
142
|
+
CLASP.show_version(Specifications, exit: 0, version: PROGRAM_VERSION)
|
143
143
|
when '--all'
|
144
144
|
|
145
145
|
# do something appropriate to `--all`
|
data/examples/cr-example.rb
CHANGED
@@ -18,7 +18,7 @@ require 'clasp'
|
|
18
18
|
|
19
19
|
PROGRAM_VERSION = '0.1.2'
|
20
20
|
|
21
|
-
|
21
|
+
Specifications = [
|
22
22
|
|
23
23
|
CLASP.Flag('--all', alias: '-a', help: 'processes all item types'),
|
24
24
|
CLASP.Flag('-c', help: 'count the processed items'),
|
@@ -30,17 +30,17 @@ Aliases = [
|
|
30
30
|
CLASP::Flag.Version,
|
31
31
|
]
|
32
32
|
|
33
|
-
Args = CLASP::Arguments.new(ARGV,
|
33
|
+
Args = CLASP::Arguments.new(ARGV, Specifications)
|
34
34
|
|
35
35
|
Args.flags.each do |f|
|
36
36
|
|
37
37
|
case f.name
|
38
38
|
when CLASP::Flag.Help.name
|
39
39
|
|
40
|
-
CLASP.show_usage(
|
40
|
+
CLASP.show_usage(Specifications, exit: 0, values: '<input-file> <output-file>')
|
41
41
|
when CLASP::Flag.Version.name
|
42
42
|
|
43
|
-
CLASP.show_version(
|
43
|
+
CLASP.show_version(Specifications, exit: 0, version: PROGRAM_VERSION)
|
44
44
|
when '--all'
|
45
45
|
|
46
46
|
;
|
@@ -33,26 +33,26 @@ Flag_Debug = CLASP.Flag('--debug', alias: '-d', help: 'runs in Debug mode')
|
|
33
33
|
Option_Verbosity = CLASP.Option('--verbosity', alias: '-v', help: 'specifies the verbosity', values: [ 'terse', 'quiet', 'silent', 'chatty' ])
|
34
34
|
Flag_Chatty = CLASP.Flag('--verbosity=chatty', alias: '-c')
|
35
35
|
|
36
|
-
|
36
|
+
Specifications = [
|
37
37
|
|
38
38
|
Flag_Debug,
|
39
39
|
Option_Verbosity,
|
40
40
|
Flag_Chatty,
|
41
41
|
|
42
|
-
CLASP::
|
43
|
-
CLASP::
|
42
|
+
CLASP::FlagSpecification.Help,
|
43
|
+
CLASP::FlagSpecification.Version,
|
44
44
|
]
|
45
45
|
|
46
|
-
args = CLASP::Arguments.new ARGV,
|
46
|
+
args = CLASP::Arguments.new ARGV, Specifications
|
47
47
|
|
48
|
-
if args.flags.include?(CLASP::
|
48
|
+
if args.flags.include?(CLASP::FlagSpecification.Help)
|
49
49
|
|
50
|
-
CLASP.show_usage(
|
50
|
+
CLASP.show_usage(Specifications, exit_code: 0, version: ProgramVersion, stream: $stdout, info_lines: InfoLines)
|
51
51
|
end
|
52
52
|
|
53
53
|
if args.flags.include?('--version')
|
54
54
|
|
55
|
-
CLASP.show_version(
|
55
|
+
CLASP.show_version(Specifications, exit_code: 0, version: ProgramVersion, stream: $stdout)
|
56
56
|
end
|
57
57
|
|
58
58
|
|
@@ -24,26 +24,26 @@ Flag_Debug = CLASP.Flag('--debug', alias: '-d', help: 'runs in Debug mode')
|
|
24
24
|
Option_Verbosity = CLASP.Option('--verbosity', alias: '-v', help: 'specifies the verbosity', values: [ 'terse', 'quiet', 'silent', 'chatty' ])
|
25
25
|
Flag_Chatty = CLASP.Flag('--verbosity=chatty', alias: '-c')
|
26
26
|
|
27
|
-
|
27
|
+
Specifications = [
|
28
28
|
|
29
29
|
Flag_Debug,
|
30
30
|
Option_Verbosity,
|
31
31
|
Flag_Chatty,
|
32
32
|
|
33
|
-
CLASP::
|
34
|
-
CLASP::
|
33
|
+
CLASP::FlagSpecification.Help,
|
34
|
+
CLASP::FlagSpecification.Version,
|
35
35
|
]
|
36
36
|
|
37
|
-
args = CLASP::Arguments.new ARGV,
|
37
|
+
args = CLASP::Arguments.new ARGV, Specifications
|
38
38
|
|
39
|
-
if args.flags.include?(CLASP::
|
39
|
+
if args.flags.include?(CLASP::FlagSpecification.Help)
|
40
40
|
|
41
|
-
CLASP.show_usage(
|
41
|
+
CLASP.show_usage(Specifications, exit_code: 0, version: ProgramVersion, stream: $stdout, info_lines: InfoLines)
|
42
42
|
end
|
43
43
|
|
44
44
|
if args.flags.include?('--version')
|
45
45
|
|
46
|
-
CLASP.show_version(
|
46
|
+
CLASP.show_version(Specifications, exit_code: 0, version: ProgramVersion, stream: $stdout)
|
47
47
|
end
|
48
48
|
|
49
49
|
|
@@ -29,22 +29,22 @@ InfoLines = [
|
|
29
29
|
|
30
30
|
# Specify aliases, parse, and checking standard flags
|
31
31
|
|
32
|
-
|
32
|
+
Specifications = [
|
33
33
|
|
34
|
-
CLASP::
|
35
|
-
CLASP::
|
34
|
+
CLASP::FlagSpecification.Help,
|
35
|
+
CLASP::FlagSpecification.Version,
|
36
36
|
]
|
37
37
|
|
38
|
-
args = CLASP::Arguments.new ARGV,
|
38
|
+
args = CLASP::Arguments.new ARGV, Specifications
|
39
39
|
|
40
40
|
if args.flags.include?('--help')
|
41
41
|
|
42
|
-
CLASP.show_usage(
|
42
|
+
CLASP.show_usage(Specifications, exit_code: 0, version: ProgramVersion, stream: $stdout, info_lines: InfoLines)
|
43
43
|
end
|
44
44
|
|
45
45
|
if args.flags.include?('--version')
|
46
46
|
|
47
|
-
CLASP.show_version(
|
47
|
+
CLASP.show_version(Specifications, exit_code: 0, version: ProgramVersion, stream: $stdout)
|
48
48
|
end
|
49
49
|
|
50
50
|
|
@@ -20,22 +20,22 @@ InfoLines = [
|
|
20
20
|
|
21
21
|
# Specify aliases, parse, and checking standard flags
|
22
22
|
|
23
|
-
|
23
|
+
Specifications = [
|
24
24
|
|
25
|
-
CLASP::
|
26
|
-
CLASP::
|
25
|
+
CLASP::FlagSpecification.Help,
|
26
|
+
CLASP::FlagSpecification.Version,
|
27
27
|
]
|
28
28
|
|
29
|
-
args = CLASP::Arguments.new ARGV,
|
29
|
+
args = CLASP::Arguments.new ARGV, Specifications
|
30
30
|
|
31
31
|
if args.flags.include?('--help')
|
32
32
|
|
33
|
-
CLASP.show_usage(
|
33
|
+
CLASP.show_usage(Specifications, exit_code: 0, version: ProgramVersion, stream: $stdout, info_lines: InfoLines)
|
34
34
|
end
|
35
35
|
|
36
36
|
if args.flags.include?('--version')
|
37
37
|
|
38
|
-
CLASP.show_version(
|
38
|
+
CLASP.show_version(Specifications, exit_code: 0, version: ProgramVersion, stream: $stdout)
|
39
39
|
end
|
40
40
|
|
41
41
|
|
data/lib/clasp/aliases.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# ######################################################################## #
|
3
3
|
# File: clasp/aliases.rb
|
4
4
|
#
|
5
|
-
# Purpose:
|
5
|
+
# Purpose: Argument specification classes
|
6
6
|
#
|
7
7
|
# Created: 25th October 2014
|
8
8
|
# Updated: 10th April 2019
|
@@ -58,9 +58,9 @@ module CLASP
|
|
58
58
|
# classes
|
59
59
|
|
60
60
|
# A class that represents the specification for a command-line flag
|
61
|
-
class
|
61
|
+
class FlagSpecification
|
62
62
|
|
63
|
-
# Creates a
|
63
|
+
# Creates a FlagSpecification instance from the given name, aliases, and help
|
64
64
|
#
|
65
65
|
# === Signature
|
66
66
|
#
|
@@ -96,7 +96,7 @@ class FlagAlias
|
|
96
96
|
@@Help_ = self.new('--help', [], 'shows this help and terminates')
|
97
97
|
@@Version_ = self.new('--version', [], 'shows version and terminates')
|
98
98
|
public
|
99
|
-
# An instance of
|
99
|
+
# An instance of FlagSpecification that provides default '--help' information
|
100
100
|
def self.Help(extras = nil)
|
101
101
|
|
102
102
|
h = @@Help_
|
@@ -106,7 +106,7 @@ class FlagAlias
|
|
106
106
|
h
|
107
107
|
end
|
108
108
|
|
109
|
-
# An instance of
|
109
|
+
# An instance of FlagSpecification that provides default '--version' information
|
110
110
|
def self.Version(extras = nil)
|
111
111
|
|
112
112
|
h = @@Version_
|
@@ -118,9 +118,9 @@ class FlagAlias
|
|
118
118
|
end
|
119
119
|
|
120
120
|
# A class that represents the specification for a command-line option
|
121
|
-
class
|
121
|
+
class OptionSpecification
|
122
122
|
|
123
|
-
# Creates an
|
123
|
+
# Creates an OptionSpecification instance from the given name, aliases, help,
|
124
124
|
# values_range, and default_value
|
125
125
|
#
|
126
126
|
# === Signature
|
@@ -198,7 +198,7 @@ class OptionAlias
|
|
198
198
|
end
|
199
199
|
|
200
200
|
# A class that represents an explicit alias for a flag or an option
|
201
|
-
class
|
201
|
+
class Specification
|
202
202
|
|
203
203
|
def initialize(name, aliases)
|
204
204
|
|
@@ -227,7 +227,7 @@ end
|
|
227
227
|
# ######################################################################## #
|
228
228
|
# functions
|
229
229
|
|
230
|
-
# Generator method that obtains a CLASP::
|
230
|
+
# Generator method that obtains a CLASP::FlagSpecification according to the given
|
231
231
|
# parameters
|
232
232
|
#
|
233
233
|
# === Signature
|
@@ -277,10 +277,10 @@ def CLASP.Flag(name, options = {})
|
|
277
277
|
end
|
278
278
|
end
|
279
279
|
|
280
|
-
CLASP::
|
280
|
+
CLASP::FlagSpecification.new(name, aliases, help, extras)
|
281
281
|
end
|
282
282
|
|
283
|
-
# Generator method that obtains a CLASP::
|
283
|
+
# Generator method that obtains a CLASP::OptionSpecification according to the given
|
284
284
|
# parameters
|
285
285
|
#
|
286
286
|
# === Signature
|
@@ -360,7 +360,7 @@ def CLASP.Option(name, options = {})
|
|
360
360
|
end
|
361
361
|
end
|
362
362
|
|
363
|
-
CLASP::
|
363
|
+
CLASP::OptionSpecification.new(name, aliases, help, values_range, default_value, required, require_message, extras)
|
364
364
|
end
|
365
365
|
|
366
366
|
def CLASP.Alias(name, *args)
|
@@ -379,14 +379,17 @@ def CLASP.Alias(name, *args)
|
|
379
379
|
aliases = args
|
380
380
|
end
|
381
381
|
|
382
|
-
CLASP::
|
382
|
+
CLASP::Specification.new name, aliases
|
383
383
|
end
|
384
384
|
|
385
385
|
# ######################################################################## #
|
386
386
|
# backwards-compatible
|
387
387
|
|
388
|
-
|
389
|
-
|
388
|
+
Alias = Specification
|
389
|
+
Flag = FlagSpecification
|
390
|
+
FlagAlias = FlagSpecification
|
391
|
+
Option = OptionSpecification
|
392
|
+
OptionAlias = OptionSpecification
|
390
393
|
|
391
394
|
# ######################################################################## #
|
392
395
|
# module
|
data/lib/clasp/arguments.rb
CHANGED
@@ -226,13 +226,13 @@ class Arguments
|
|
226
226
|
end
|
227
227
|
end
|
228
228
|
|
229
|
-
|
229
|
+
specifications = []
|
230
230
|
|
231
231
|
_clasp = h['clasp'] or raise ArgumentError, "missing top-level 'clasp' element in load configuration"
|
232
232
|
::Hash === _clasp or raise ArgumentError, "top-level 'clasp' element must be a #{::Hash}"
|
233
233
|
|
234
|
-
_specs = (_clasp['arg-specs'] || _clasp['aliases']) or raise ArgumentError, "missing element 'clasp/
|
235
|
-
::Array === _specs or raise ArgumentError, "top-level '
|
234
|
+
_specs = (_clasp['arg-specs'] || _clasp['specifications'] || _clasp['aliases']) or raise ArgumentError, "missing element 'clasp/specifications'"
|
235
|
+
::Array === _specs or raise ArgumentError, "top-level 'specifications' element must be a #{::Hash}"
|
236
236
|
|
237
237
|
_specs.each do |_spec|
|
238
238
|
|
@@ -250,14 +250,14 @@ class Arguments
|
|
250
250
|
|
251
251
|
unless _name
|
252
252
|
|
253
|
-
warn "flag
|
253
|
+
warn "flag specification missing required 'name' field"
|
254
254
|
else
|
255
255
|
|
256
256
|
_alias = _details['alias']
|
257
257
|
_aliases = _details['aliases']
|
258
258
|
_help = _details['help'] || _details['description']
|
259
259
|
|
260
|
-
|
260
|
+
specifications << CLASP.Flag(_name, alias: _alias, aliases: _aliases, help: _help)
|
261
261
|
end
|
262
262
|
when 'option', :option
|
263
263
|
|
@@ -265,7 +265,7 @@ class Arguments
|
|
265
265
|
|
266
266
|
unless _name
|
267
267
|
|
268
|
-
warn "option
|
268
|
+
warn "option specification missing required 'name' field"
|
269
269
|
else
|
270
270
|
|
271
271
|
_alias = _details['alias']
|
@@ -276,7 +276,7 @@ class Arguments
|
|
276
276
|
_required_message = _details['required_message']
|
277
277
|
_values_range = _details['values_range'] || _details['values']
|
278
278
|
|
279
|
-
|
279
|
+
specifications << CLASP.Option(_name, alias: _alias, aliases: _aliases, default_value: _default_value, help: _help, required: _required, required_message: _required_message, values_range: _values_range)
|
280
280
|
end
|
281
281
|
when 'alias', :alias
|
282
282
|
|
@@ -284,7 +284,7 @@ class Arguments
|
|
284
284
|
|
285
285
|
unless _resolved
|
286
286
|
|
287
|
-
warn "alias
|
287
|
+
warn "alias specification missing required 'resolved' field"
|
288
288
|
else
|
289
289
|
|
290
290
|
_alias = _details['alias']
|
@@ -292,10 +292,10 @@ class Arguments
|
|
292
292
|
|
293
293
|
unless _alias || _aliases
|
294
294
|
|
295
|
-
warn "alias
|
295
|
+
warn "alias specification missing required 'alias' or 'aliases' field"
|
296
296
|
else
|
297
297
|
|
298
|
-
|
298
|
+
specifications << CLASP.Flag(_resolved, alias: _alias, aliases: _aliases)
|
299
299
|
end
|
300
300
|
end
|
301
301
|
else
|
@@ -305,11 +305,11 @@ class Arguments
|
|
305
305
|
end
|
306
306
|
else
|
307
307
|
|
308
|
-
warn "non-#{::Hash} element in 'clasp/
|
308
|
+
warn "non-#{::Hash} element in 'clasp/specifications': #{_spec} (of type #{_spec.class})"
|
309
309
|
end
|
310
310
|
end
|
311
311
|
|
312
|
-
self.new argv,
|
312
|
+
self.new argv, specifications, options
|
313
313
|
end
|
314
314
|
|
315
315
|
# Constructs an instance of the class, according to the given parameters
|
@@ -320,13 +320,13 @@ class Arguments
|
|
320
320
|
#
|
321
321
|
# * *Parameters*:
|
322
322
|
# - +argv+:: (+Array+) The arguments array. May not be +nil+. Defaults to +ARGV+.
|
323
|
-
# - +
|
323
|
+
# - +specifications+:: (+Array+) The specifications array. Defaults to +nil+. If none supplied, no aliasing will be performed.
|
324
324
|
# - +options+:: An options hash, containing any of the following options.
|
325
325
|
#
|
326
326
|
# * *Options*:
|
327
327
|
# - +mutate_argv:+:: (+Boolean+) Determines if the library should mutate +argv+. Defaults to +true+. This is essential when using CLASP in conjunction with <tt>$\<</tt>.
|
328
328
|
#
|
329
|
-
def initialize(argv = ARGV,
|
329
|
+
def initialize(argv = ARGV, specifications = nil, options = {})
|
330
330
|
|
331
331
|
# have to do this name-swap, as 'options' has CLASP-specific
|
332
332
|
# meaning
|
@@ -340,11 +340,11 @@ class Arguments
|
|
340
340
|
argv = argv.dup
|
341
341
|
@argv_original_copy = argv.dup.freeze
|
342
342
|
|
343
|
-
@
|
343
|
+
@specifications = specifications
|
344
344
|
|
345
|
-
|
345
|
+
specifications = nil if specifications and specifications.empty?
|
346
346
|
|
347
|
-
flags, options, values = Arguments.parse(argv,
|
347
|
+
flags, options, values = Arguments.parse(argv, specifications)
|
348
348
|
|
349
349
|
[ flags, options, values ].each do |ar|
|
350
350
|
|
@@ -403,7 +403,7 @@ class Arguments
|
|
403
403
|
$0
|
404
404
|
end
|
405
405
|
|
406
|
-
def self.parse(argv,
|
406
|
+
def self.parse(argv, specifications)
|
407
407
|
|
408
408
|
flags = []
|
409
409
|
options = []
|
@@ -433,7 +433,7 @@ class Arguments
|
|
433
433
|
argument_alias = nil
|
434
434
|
resolved_name = nil
|
435
435
|
|
436
|
-
(
|
436
|
+
(specifications || []).each do |a|
|
437
437
|
|
438
438
|
if a.name == given_name or a.aliases.include? given_name
|
439
439
|
|
@@ -454,7 +454,7 @@ class Arguments
|
|
454
454
|
end
|
455
455
|
|
456
456
|
# Here we intercept and (potentially) cater to grouped flags
|
457
|
-
if not argument_alias and not value and
|
457
|
+
if not argument_alias and not value and specifications and 1 == hyphens.size
|
458
458
|
|
459
459
|
# Must match all
|
460
460
|
flag_aliases = []
|
@@ -465,10 +465,10 @@ class Arguments
|
|
465
465
|
flag_alias = nil
|
466
466
|
|
467
467
|
# special case where the flag's actual name is short form and found here
|
468
|
-
flag_alias ||=
|
468
|
+
flag_alias ||= specifications.detect { |a| a.is_a?(CLASP::FlagSpecification) && a.name == new_flag }
|
469
469
|
|
470
|
-
# if not found as a flag, look in each
|
471
|
-
flag_alias ||=
|
470
|
+
# if not found as a flag, look in each specifications' aliases
|
471
|
+
flag_alias ||= specifications.detect { |a| a.aliases.include? new_flag }
|
472
472
|
|
473
473
|
if not flag_alias
|
474
474
|
|
@@ -489,7 +489,7 @@ class Arguments
|
|
489
489
|
# convert to argv and invoke
|
490
490
|
flags_argv = flag_aliases.map { |a| a.name }
|
491
491
|
|
492
|
-
grp_flags, grp_options, grp_value = Arguments.parse flags_argv,
|
492
|
+
grp_flags, grp_options, grp_value = Arguments.parse flags_argv, specifications
|
493
493
|
|
494
494
|
grp_flags.map! { |f| FlagArgument.new(arg, index, given_name, f.name, f.argument_alias, hyphens.size, given_label, argument_alias ? argument_alias.extras : nil) }
|
495
495
|
grp_options.map! { |o| OptionArgument.new(arg, index, given_name, o.name, o.argument_alias, hyphens.size, given_label, o.value, argument_alias ? argument_alias.extras : nil) }
|
@@ -502,7 +502,7 @@ class Arguments
|
|
502
502
|
end
|
503
503
|
end
|
504
504
|
|
505
|
-
if argument_alias and argument_alias.is_a? CLASP::
|
505
|
+
if argument_alias and argument_alias.is_a? CLASP::OptionSpecification and not value
|
506
506
|
|
507
507
|
want_option_value = true
|
508
508
|
options << OptionArgument.new(arg, index, given_name, resolved_name, argument_alias, hyphens.size, given_label, nil, argument_alias ? argument_alias.extras : nil)
|
@@ -544,8 +544,11 @@ class Arguments
|
|
544
544
|
# Attributes
|
545
545
|
|
546
546
|
public
|
547
|
-
# an immutable array of
|
548
|
-
attr_reader :
|
547
|
+
# an immutable array of specifications
|
548
|
+
attr_reader :specifications
|
549
|
+
|
550
|
+
# [DEPRECATED] Instead refer to +specifications+
|
551
|
+
def aliases; @specifications; end
|
549
552
|
|
550
553
|
# an immutable array of flags
|
551
554
|
attr_reader :flags
|
@@ -572,18 +575,18 @@ class Arguments
|
|
572
575
|
|
573
576
|
raise ArgumentError, "options must be nil or Hash - #{option.class} given" unless options.is_a? ::Hash
|
574
577
|
|
575
|
-
|
578
|
+
specifications = options[:aliases] || @specifications
|
576
579
|
|
577
|
-
raise ArgumentError, "
|
580
|
+
raise ArgumentError, "specifications may not be nil" if specifications.nil?
|
578
581
|
|
579
582
|
flags.each do |f|
|
580
583
|
|
581
|
-
return f unless
|
584
|
+
return f unless specifications.any? { |al| al.is_a?(::CLASP::FlagSpecification) && al.name == f.name }
|
582
585
|
end
|
583
586
|
|
584
587
|
self.options.each do |o|
|
585
588
|
|
586
|
-
return o unless
|
589
|
+
return o unless specifications.any? { |al| al.is_a?(::CLASP::OptionSpecification) && al.name == o.name }
|
587
590
|
end
|
588
591
|
|
589
592
|
nil
|
data/lib/clasp/cli.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Purpose: Command-line interface
|
6
6
|
#
|
7
7
|
# Created: 27th July 2015
|
8
|
-
# Updated:
|
8
|
+
# Updated: 10th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
11
|
#
|
@@ -64,7 +64,7 @@ module CLI_helpers_
|
|
64
64
|
|
65
65
|
module Constants
|
66
66
|
|
67
|
-
VALID_ALIAS_TYPES = [
|
67
|
+
VALID_ALIAS_TYPES = [ FlagSpecification, OptionSpecification, Specification ]
|
68
68
|
VALID_ALIAS_TYPES_STRING = VALID_ALIAS_TYPES[0...-1].join(', ') + ', or ' + VALID_ALIAS_TYPES[-1].to_s
|
69
69
|
end # module Constants
|
70
70
|
|
@@ -109,12 +109,12 @@ end # module CLI_helpers_
|
|
109
109
|
|
110
110
|
# :startdoc:
|
111
111
|
|
112
|
-
# Displays usage for the program according to the given
|
112
|
+
# Displays usage for the program according to the given specifications and options
|
113
113
|
#
|
114
114
|
# === Signature
|
115
115
|
#
|
116
116
|
# * *Parameters*:
|
117
|
-
# - +
|
117
|
+
# - +specifications+:: (+Array+) The arguments array. May not be +nil+. Defaults to +ARGV+.
|
118
118
|
# - +options+:: An options hash, containing any of the following options.
|
119
119
|
#
|
120
120
|
# * *Options*:
|
@@ -125,18 +125,18 @@ end # module CLI_helpers_
|
|
125
125
|
# - +:values+:: appends this string to USAGE line if specified.
|
126
126
|
# - +:flags_and_options+:: inserts a custom string instead of the default string <tt>'[ ... flags and options ... ]'</tt>.
|
127
127
|
# - +:info_lines+:: inserts 0+ information lines prior to the usage.
|
128
|
-
def self.show_usage
|
128
|
+
def self.show_usage specifications, options={}
|
129
129
|
|
130
130
|
options ||= {}
|
131
131
|
|
132
|
-
raise ArgumentError, "
|
133
|
-
raise TypeError, "
|
132
|
+
raise ArgumentError, "specifications may not be nil" if specifications.nil?
|
133
|
+
raise TypeError, "specifications must be an array or must respond to each, reject and select" unless ::Array === specifications || (specifications.respond_to?(:each) && specifications.respond_to?(:reject) && specifications.respond_to?(:select))
|
134
134
|
|
135
135
|
constants = CLI_helpers_::Constants
|
136
|
-
|
136
|
+
specifications.each { |a| raise ::TypeError, "each element in specifications array must be one of the types #{constants::VALID_ALIAS_TYPES_STRING}" unless constants::VALID_ALIAS_TYPES.any? { |c| c === a } }
|
137
137
|
|
138
138
|
alias_dups = {}
|
139
|
-
|
139
|
+
specifications.each { |a| a.aliases.each { |aa| warn "WARNING: alias '#{aa}' is already used for alias '#{a}'" if alias_dups.has_key? aa; alias_dups[aa] = a; } }
|
140
140
|
|
141
141
|
suppress_blanks = options[:suppress_blank_lines_between_options] || ENV['SUPPRESS_BLANK_LINES_BETWEEN_OPTIONS']
|
142
142
|
|
@@ -173,11 +173,12 @@ def self.show_usage aliases, options={}
|
|
173
173
|
flags_and_options = options[:flags_and_options] || ' [ ... flags and options ... ]'
|
174
174
|
flags_and_options = " #{flags_and_options}" if !flags_and_options.empty? && ' ' != flags_and_options[0]
|
175
175
|
|
176
|
-
# sift the
|
176
|
+
# sift the specifications to sort out which are value-option
|
177
|
+
# specifications (VOAs)
|
177
178
|
|
178
179
|
voas = {}
|
179
180
|
|
180
|
-
|
181
|
+
specifications.select { |a| a.name =~ /^-+[a-zA-Z0-3_-]+[=:].+/ }.each do |a|
|
181
182
|
|
182
183
|
a.name =~ /^(-+[a-zA-Z0-3_-]+)[=:](.+)$/
|
183
184
|
|
@@ -187,30 +188,30 @@ def self.show_usage aliases, options={}
|
|
187
188
|
|
188
189
|
fas = {}
|
189
190
|
|
190
|
-
|
191
|
+
specifications.select { |a| Specification === a }.each do |a|
|
191
192
|
|
192
193
|
fas[a.name] = [] unless fas.has_key? $1
|
193
194
|
fas[a.name] << a
|
194
195
|
end
|
195
196
|
|
196
|
-
|
197
|
+
specifications = specifications.reject { |a| a.name =~ /^-+[a-zA-Z0-3_-]+[=:].+/ }
|
197
198
|
|
198
199
|
info_lines.each { |info_line| stream.puts info_line } unless info_lines.empty?
|
199
200
|
|
200
201
|
stream.puts "USAGE: #{program_name}#{flags_and_options}#{values}"
|
201
202
|
stream.puts
|
202
203
|
|
203
|
-
unless
|
204
|
+
unless specifications.empty?
|
204
205
|
|
205
206
|
stream.puts "flags/options:"
|
206
207
|
stream.puts
|
207
|
-
|
208
|
+
specifications.each do |a|
|
208
209
|
|
209
210
|
case a
|
210
|
-
when
|
211
|
+
when Specification
|
211
212
|
|
212
213
|
next
|
213
|
-
when
|
214
|
+
when FlagSpecification
|
214
215
|
|
215
216
|
if fas.has_key? a.name
|
216
217
|
|
@@ -222,7 +223,7 @@ def self.show_usage aliases, options={}
|
|
222
223
|
a.aliases.each { |al| stream.puts "\t#{al}" }
|
223
224
|
stream.puts "\t#{a.name}"
|
224
225
|
stream.puts "\t\t#{a.help}"
|
225
|
-
when
|
226
|
+
when OptionSpecification
|
226
227
|
|
227
228
|
if voas.has_key? a.name
|
228
229
|
|
@@ -249,12 +250,12 @@ def self.show_usage aliases, options={}
|
|
249
250
|
exit exit_code if exit_code
|
250
251
|
end
|
251
252
|
|
252
|
-
# Displays version for the program according to the given
|
253
|
+
# Displays version for the program according to the given specifications and options
|
253
254
|
#
|
254
255
|
# === Signature
|
255
256
|
#
|
256
257
|
# * *Parameters*:
|
257
|
-
# - +
|
258
|
+
# - +specifications+:: (+Array+) The arguments array. May not be +nil+. Defaults to +ARGV+.
|
258
259
|
# - +options+:: An options hash, containing any of the following options.
|
259
260
|
#
|
260
261
|
# * *Options*:
|
@@ -267,15 +268,15 @@ end
|
|
267
268
|
# - +:version_revision+:: a number or string. Only considered if +:version+ is not.
|
268
269
|
# - +:version_build+:: a number or string. Only considered if +:version+ is not.
|
269
270
|
# - +:version_prefix+:: optional string to prefix the version number(s).
|
270
|
-
def self.show_version
|
271
|
+
def self.show_version specifications, options = {}
|
271
272
|
|
272
273
|
options ||= {}
|
273
274
|
|
274
|
-
raise ArgumentError, "
|
275
|
-
raise TypeError, "
|
275
|
+
raise ArgumentError, "specifications may not be nil" if specifications.nil?
|
276
|
+
raise TypeError, "specifications must be an array or must respond to each, reject and select" unless ::Array === specifications || (specifications.respond_to?(:each) && specifications.respond_to?(:reject) && specifications.respond_to?(:select))
|
276
277
|
|
277
278
|
constants = CLI_helpers_::Constants
|
278
|
-
|
279
|
+
specifications.each { |a| raise ::TypeError, "each element in specifications array must be one of the types #{constants::VALID_ALIAS_TYPES_STRING}" unless constants::VALID_ALIAS_TYPES.any? { |c| c === a } }
|
279
280
|
|
280
281
|
stream = options[:stream] || $stdout
|
281
282
|
|
data/lib/clasp/version.rb
CHANGED
@@ -4,27 +4,27 @@ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
|
4
4
|
|
5
5
|
require 'clasp'
|
6
6
|
|
7
|
-
|
7
|
+
Specifications = [
|
8
8
|
|
9
9
|
CLASP.Flag('--help', help: 'shows this help and quits'),
|
10
10
|
CLASP.Flag('--version', alias: '-v', help: 'shows this version and quits'),
|
11
|
-
CLASP.
|
11
|
+
CLASP.Specification('--version', aliases: [ '-ver', '-V' ]),
|
12
12
|
|
13
13
|
CLASP.Option('--directory', alias: '-d', help: 'a directory within which to process'),
|
14
14
|
CLASP.Option('--patterns', alias: '-p', help: "one or more patterns against which the entries will be matched, separated by '|' or the platform-specific separator - ':' UNIX, ';' Windows"),
|
15
15
|
|
16
16
|
CLASP.Option('--case-sensitive', alias: '-c', help: 'determines whether case sensitive', values_range: %W{ yes no true false }, default_value: false),
|
17
|
-
CLASP.
|
17
|
+
CLASP.Specification('--case-sensitive=false', alias: '-I'),
|
18
18
|
]
|
19
19
|
|
20
|
-
Arguments = CLASP::Arguments.new(ARGV,
|
20
|
+
Arguments = CLASP::Arguments.new(ARGV, Specifications)
|
21
21
|
Flags = Arguments.flags
|
22
22
|
Options = Arguments.options
|
23
23
|
Values = Arguments.values
|
24
24
|
|
25
25
|
if Flags.include? '--help'
|
26
26
|
|
27
|
-
CLASP.show_usage
|
27
|
+
CLASP.show_usage Specifications, exit: 0
|
28
28
|
end
|
29
29
|
|
30
30
|
Flags.each do |f|
|
@@ -4,7 +4,7 @@ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
|
4
4
|
|
5
5
|
require 'clasp'
|
6
6
|
|
7
|
-
|
7
|
+
Specifications = [
|
8
8
|
|
9
9
|
CLASP.Flag('--help', help: 'shows this help and quits'),
|
10
10
|
CLASP.Flag('--version', alias: '-v', help: 'shows this version and quits'),
|
@@ -12,7 +12,7 @@ Aliases = [
|
|
12
12
|
CLASP.Option('--verbosity', aliases: %w{ -V --verbose }),
|
13
13
|
]
|
14
14
|
|
15
|
-
Args = CLASP::Arguments.new(ARGV,
|
15
|
+
Args = CLASP::Arguments.new(ARGV, Specifications)
|
16
16
|
|
17
17
|
puts
|
18
18
|
puts "flags #{Args.flags.size}:"
|
data/test/scratch/test_usage.rb
CHANGED
@@ -4,7 +4,7 @@ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
|
4
4
|
|
5
5
|
require 'clasp'
|
6
6
|
|
7
|
-
|
7
|
+
Specifications = [
|
8
8
|
|
9
9
|
CLASP.Flag('--version', alias: '-v', help: 'shows the program version and quits'),
|
10
10
|
|
@@ -14,17 +14,17 @@ Aliases = [
|
|
14
14
|
CLASP.Flag('--verbosity=verbose', alias: '--verbose'),
|
15
15
|
]
|
16
16
|
|
17
|
-
Arguments = CLASP::Arguments.new(ARGV,
|
17
|
+
Arguments = CLASP::Arguments.new(ARGV, Specifications)
|
18
18
|
|
19
19
|
puts
|
20
20
|
puts '*' * 40
|
21
21
|
puts 'usage:'
|
22
22
|
puts
|
23
|
-
CLASP.show_usage(
|
23
|
+
CLASP.show_usage(Specifications)
|
24
24
|
puts '*' * 40
|
25
25
|
|
26
26
|
puts 'version:'
|
27
27
|
puts
|
28
|
-
CLASP.show_version
|
28
|
+
CLASP.show_version Specifications, version: [ 1, 2, 3 ]
|
29
29
|
puts '*' * 40
|
30
30
|
|
@@ -4,7 +4,7 @@ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
|
4
4
|
|
5
5
|
require 'clasp'
|
6
6
|
|
7
|
-
|
7
|
+
Specifications = [
|
8
8
|
|
9
9
|
CLASP.Flag('--version', alias: '-v', help: 'shows the program version and quits'),
|
10
10
|
|
@@ -14,17 +14,17 @@ Aliases = [
|
|
14
14
|
CLASP.Flag('--verbosity=verbose', aliases: [ '--verbose', '-v' ]),
|
15
15
|
]
|
16
16
|
|
17
|
-
Arguments = CLASP::Arguments.new(ARGV,
|
17
|
+
Arguments = CLASP::Arguments.new(ARGV, Specifications)
|
18
18
|
|
19
19
|
puts
|
20
20
|
puts '*' * 40
|
21
21
|
puts 'usage:'
|
22
22
|
puts
|
23
|
-
CLASP.show_usage(
|
23
|
+
CLASP.show_usage(Specifications)
|
24
24
|
puts '*' * 40
|
25
25
|
|
26
26
|
puts 'version:'
|
27
27
|
puts
|
28
|
-
CLASP.show_version
|
28
|
+
CLASP.show_version Specifications, version: [ 1, 2, 3 ]
|
29
29
|
puts '*' * 40
|
30
30
|
|
data/test/unit/tc_aliases.rb
CHANGED
data/test/unit/tc_cli.rb
CHANGED
@@ -14,9 +14,9 @@ class Test_CLI < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
def test_invalid_aliases_types
|
16
16
|
|
17
|
-
assert_raise_with_message(::TypeError,
|
17
|
+
assert_raise_with_message(::TypeError, /each element in (?:aliases|specifications) array must be one of the types CLASP::FlagSpecification, CLASP::OptionSpecification, or CLASP::Specification/) { CLASP.show_usage([ 'abc', :def ]) }
|
18
18
|
|
19
|
-
assert_raise_with_message(::TypeError,
|
19
|
+
assert_raise_with_message(::TypeError, /each element in (?:aliases|specifications) array must be one of the types CLASP::FlagSpecification, CLASP::OptionSpecification, or CLASP::Specification/) { CLASP.show_version([ 'abc', :def ]) }
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -8,7 +8,7 @@ require 'test/unit'
|
|
8
8
|
|
9
9
|
class Test_Examples < Test::Unit::TestCase
|
10
10
|
|
11
|
-
def
|
11
|
+
def test_SimpleCommandLineNoSpecifications
|
12
12
|
|
13
13
|
argv = %w{ --show-all=true infile -c outfile }
|
14
14
|
|
@@ -116,7 +116,7 @@ class Test_Examples < Test::Unit::TestCase
|
|
116
116
|
assert_equal "outfile", args.values[1]
|
117
117
|
end
|
118
118
|
|
119
|
-
def
|
119
|
+
def test_UseOfFlagsAsSpecificationsForOption
|
120
120
|
|
121
121
|
aliases = [
|
122
122
|
|