clasp-ruby 0.23.0.1 → 0.23.0.2
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/README.md +63 -52
- data/examples/cr-example.rb +16 -16
- data/examples/flag_and_option_specifications.md +25 -25
- data/examples/flag_and_option_specifications.rb +6 -6
- data/examples/show_usage_and_version.md +5 -5
- data/examples/show_usage_and_version.rb +1 -1
- data/examples/simple_command_line_no_specifications.rb +1 -1
- data/lib/clasp/arguments.rb +538 -537
- data/lib/clasp/clasp.rb +7 -7
- data/lib/clasp/cli.rb +140 -135
- data/lib/clasp/doc_.rb +3 -3
- data/lib/clasp/old_module.rb +3 -3
- data/lib/clasp/specifications.rb +337 -333
- data/lib/clasp/util/exceptions.rb +17 -17
- data/lib/clasp/util/value_parser.rb +97 -97
- data/lib/clasp/version.rb +15 -15
- data/lib/clasp-ruby.rb +3 -2
- data/lib/clasp.rb +3 -2
- data/test/scratch/test_list_command_line.rb +6 -6
- data/test/scratch/test_specifications.rb +14 -14
- data/test/scratch/test_usage.rb +6 -6
- data/test/scratch/test_usage_from_DATA.rb +1 -1
- data/test/scratch/test_usage_with_duplicate_specifications.rb +6 -6
- data/test/unit/tc_ARGV_rewrite.rb +36 -38
- data/test/unit/tc_arguments_1.rb +694 -694
- data/test/unit/tc_arguments_2.rb +52 -53
- data/test/unit/tc_arguments_3.rb +77 -77
- data/test/unit/tc_arguments_inspect.rb +55 -56
- 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 -132
- data/test/unit/tc_extras.rb +24 -26
- data/test/unit/tc_option_required.rb +38 -39
- data/test/unit/tc_option_value_aliases.rb +44 -44
- data/test/unit/tc_specifications.rb +7 -8
- data/test/unit/tc_typed_options.rb +204 -204
- data/test/unit/tc_usage.rb +112 -55
- data/test/unit/tc_with_action.rb +23 -24
- data/test/unit/ts_all.rb +1 -1
- metadata +5 -4
data/lib/clasp/clasp.rb
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
# Purpose: Common 'require file' for CLASP.Ruby library
|
6
6
|
#
|
7
7
|
# Created: 14th February 2014
|
8
|
-
# Updated:
|
8
|
+
# Updated: 20th January 2024
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c) 2014-
|
14
|
+
# Copyright (c) 2014-2024, Matthew Wilson and Synesis Software
|
15
15
|
# All rights reserved.
|
16
16
|
#
|
17
17
|
# Redistribution and use in source and binary forms, with or without
|
@@ -52,13 +52,13 @@ require 'clasp/version'
|
|
52
52
|
|
53
53
|
module CLASP
|
54
54
|
|
55
|
-
|
56
|
-
|
55
|
+
# TBC (but is a shorthand for calling +Arguments.new()+
|
56
|
+
def self.parse(argv = ARGV, specifications = nil, options = {})
|
57
57
|
|
58
|
-
|
59
|
-
|
58
|
+
return Arguments.new(argv, specifications, options)
|
59
|
+
end
|
60
60
|
end # module CLASP
|
61
61
|
|
62
|
-
# ############################## end of file ############################# #
|
63
62
|
|
63
|
+
# ############################## end of file ############################# #
|
64
64
|
|
data/lib/clasp/cli.rb
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
# Purpose: Command-line interface
|
6
6
|
#
|
7
7
|
# Created: 27th July 2015
|
8
|
-
# Updated:
|
8
|
+
# Updated: 20th January 2024
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c) 2015-
|
14
|
+
# Copyright (c) 2015-2024, Matthew Wilson and Synesis Software
|
15
15
|
# All rights reserved.
|
16
16
|
#
|
17
17
|
# Redistribution and use in source and binary forms, with or without
|
@@ -53,6 +53,7 @@
|
|
53
53
|
|
54
54
|
module CLASP
|
55
55
|
|
56
|
+
|
56
57
|
# ######################################################################## #
|
57
58
|
# helpers
|
58
59
|
|
@@ -64,47 +65,48 @@ module CLASP
|
|
64
65
|
# @!visibility private
|
65
66
|
module CLI_helpers_ # :nodoc: all
|
66
67
|
|
67
|
-
|
68
|
-
|
68
|
+
# @!visibility private
|
69
|
+
module Constants # :nodoc: all
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
# @!visibility private
|
72
|
+
VALID_ALIAS_TYPES = [ FlagSpecification, OptionSpecification, AliasSpecification ]
|
73
|
+
# @!visibility private
|
74
|
+
VALID_ALIAS_TYPES_STRING = VALID_ALIAS_TYPES[0...-1].join(', ') + ', or ' + VALID_ALIAS_TYPES[-1].to_s
|
75
|
+
end # module Constants
|
75
76
|
|
76
|
-
|
77
|
-
|
77
|
+
# @!visibility private
|
78
|
+
def self.generate_version_string_ options # :nodoc:
|
78
79
|
|
79
|
-
|
80
|
+
program_name = options[:program_name] || File.basename($0)
|
80
81
|
|
81
|
-
|
82
|
+
version_prefix = options[:version_prefix]
|
82
83
|
|
83
|
-
|
84
|
+
if options[:version]
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
86
|
+
case options[:version]
|
87
|
+
when ::Array
|
88
|
+
version = options[:version].join('.')
|
89
|
+
else
|
90
|
+
version = options[:version]
|
91
|
+
end
|
92
|
+
else
|
92
93
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
version_major = options[:version_major] or raise ArgumentError, "options must specify :version or :version_major [ + :version_minor [ + :version_revision [ + :version_build ]]]"
|
95
|
+
version_minor = options[:version_minor]
|
96
|
+
version_rev = options[:version_revision]
|
97
|
+
version_build = options[:version_build]
|
97
98
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
99
|
+
version = version_major.to_s
|
100
|
+
version += ".#{version_minor}" if version_minor
|
101
|
+
version += ".#{version_rev}" if version_rev
|
102
|
+
version += ".#{version_build}" if version_build
|
103
|
+
end
|
103
104
|
|
104
|
-
|
105
|
-
|
105
|
+
"#{program_name} #{version_prefix}#{version}"
|
106
|
+
end
|
106
107
|
end # module CLI_helpers_
|
107
108
|
|
109
|
+
|
108
110
|
# ######################################################################## #
|
109
111
|
# methods
|
110
112
|
|
@@ -132,141 +134,142 @@ end # module CLI_helpers_
|
|
132
134
|
# - +:default_indicator+ (String) a string placed after the matching value in the listing of an option's range of values. Defaults to "(default)". If +nil+ default is used. If empty string no indication given
|
133
135
|
def self.show_usage specifications, options={}
|
134
136
|
|
135
|
-
|
137
|
+
options ||= {}
|
136
138
|
|
137
|
-
|
138
|
-
|
139
|
+
raise ArgumentError, "specifications may not be nil" if specifications.nil?
|
140
|
+
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))
|
139
141
|
|
140
|
-
|
141
|
-
specifications.each { |s| 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 === s } }
|
142
|
+
constants = CLI_helpers_::Constants
|
142
143
|
|
143
|
-
|
144
|
-
specifications.each { |s| s.aliases.each { |aa| warn "WARNING: alias '#{aa}' is already used for specification '#{s}'" if alias_dups.has_key? aa; alias_dups[aa] = s; } }
|
144
|
+
specifications.each { |s| 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 === s } }
|
145
145
|
|
146
|
-
|
146
|
+
alias_dups = {}
|
147
|
+
specifications.each { |s| s.aliases.each { |aa| warn "WARNING: alias '#{aa}' is already used for specification '#{s}'" if alias_dups.has_key? aa; alias_dups[aa] = s; } }
|
147
148
|
|
148
|
-
|
149
|
-
program_name = options[:program_name] || File.basename($0)
|
149
|
+
suppress_blanks = options[:suppress_blank_lines_between_options] || ENV['SUPPRESS_BLANK_LINES_BETWEEN_OPTIONS']
|
150
150
|
|
151
|
-
|
152
|
-
|
153
|
-
when ::Array
|
151
|
+
stream = options[:stream] || $stdout
|
152
|
+
program_name = options[:program_name] || File.basename($0)
|
154
153
|
|
155
|
-
|
156
|
-
|
154
|
+
info_lines = options[:info_lines]
|
155
|
+
case info_lines
|
156
|
+
when ::Array
|
157
157
|
|
158
|
-
|
159
|
-
|
158
|
+
;
|
159
|
+
when ::NilClass
|
160
160
|
|
161
|
-
|
162
|
-
|
163
|
-
info_lines = info_lines.map do |line|
|
161
|
+
info_lines = []
|
162
|
+
else
|
164
163
|
|
165
|
-
|
166
|
-
|
164
|
+
info_lines = [ info_lines ] unless [ :each, :empty? ].all? { |m| info_lines.respond_to? m }
|
165
|
+
end
|
166
|
+
info_lines = info_lines.map do |line|
|
167
167
|
|
168
|
-
|
169
|
-
|
168
|
+
case line
|
169
|
+
when :version
|
170
170
|
|
171
|
-
|
172
|
-
|
173
|
-
end
|
171
|
+
CLI_helpers_.generate_version_string_ options
|
172
|
+
else
|
174
173
|
|
175
|
-
|
176
|
-
|
174
|
+
line
|
175
|
+
end
|
176
|
+
end
|
177
177
|
|
178
|
-
|
179
|
-
|
178
|
+
values = options[:values] || ''
|
179
|
+
values = " #{values}" if !values.empty? && ' ' != values[0]
|
180
180
|
|
181
|
-
|
182
|
-
|
181
|
+
flags_and_options = options[:flags_and_options] || ' [ ... flags and options ... ]'
|
182
|
+
flags_and_options = " #{flags_and_options}" if !flags_and_options.empty? && ' ' != flags_and_options[0]
|
183
183
|
|
184
|
-
|
185
|
-
|
184
|
+
default_indicator = options[:default_indicator] || '(default)'
|
185
|
+
default_indicator = nil if default_indicator.empty?
|
186
186
|
|
187
|
-
|
187
|
+
# sift the specifications to sort out which are value-option
|
188
|
+
# specifications (VOAs)
|
188
189
|
|
189
|
-
|
190
|
+
voas = {}
|
190
191
|
|
191
|
-
|
192
|
+
specifications.select { |s| s.name =~ /^-+[a-zA-Z0-3_-]+[=:].+/ }.each do |s|
|
192
193
|
|
193
|
-
|
194
|
-
voas[$1] << [ s, $2 ]
|
195
|
-
end
|
194
|
+
s.name =~ /^(-+[a-zA-Z0-3_-]+)[=:](.+)$/
|
196
195
|
|
197
|
-
|
196
|
+
voas[$1] = [] unless voas.has_key? $1
|
197
|
+
voas[$1] << [ s, $2 ]
|
198
|
+
end
|
198
199
|
|
199
|
-
|
200
|
+
fas = {}
|
200
201
|
|
201
|
-
|
202
|
-
fas[s.name] << s
|
203
|
-
end
|
202
|
+
specifications.select { |s| AliasSpecification === s }.each do |s|
|
204
203
|
|
205
|
-
|
204
|
+
fas[s.name] = [] unless fas.has_key? $1
|
205
|
+
fas[s.name] << s
|
206
|
+
end
|
206
207
|
|
207
|
-
|
208
|
+
specifications = specifications.reject { |s| s.name =~ /^-+[a-zA-Z0-3_-]+[=:].+/ }
|
208
209
|
|
209
|
-
|
210
|
-
stream.puts
|
210
|
+
info_lines.each { |info_line| stream.puts info_line } unless info_lines.empty?
|
211
211
|
|
212
|
-
|
212
|
+
stream.puts "USAGE: #{program_name}#{flags_and_options}#{values}"
|
213
|
+
stream.puts
|
213
214
|
|
214
|
-
|
215
|
-
stream.puts
|
216
|
-
specifications.each do |s|
|
215
|
+
unless specifications.empty?
|
217
216
|
|
218
|
-
|
219
|
-
|
217
|
+
stream.puts "flags/options:"
|
218
|
+
stream.puts
|
219
|
+
specifications.each do |s|
|
220
220
|
|
221
|
-
|
222
|
-
|
221
|
+
case s
|
222
|
+
when AliasSpecification
|
223
223
|
|
224
|
-
|
224
|
+
next
|
225
|
+
when FlagSpecification
|
225
226
|
|
226
|
-
|
227
|
+
if fas.has_key? s.name
|
227
228
|
|
228
|
-
|
229
|
-
end
|
230
|
-
end
|
231
|
-
s.aliases.each { |al| stream.puts "\t#{al}" }
|
232
|
-
stream.puts "\t#{s.name}"
|
233
|
-
stream.puts "\t\t#{s.help}"
|
234
|
-
when OptionSpecification
|
229
|
+
fas[s.name].each do |fa|
|
235
230
|
|
236
|
-
|
231
|
+
fa.aliases.each { |al| stream.puts "\t#{al}" }
|
232
|
+
end
|
233
|
+
end
|
234
|
+
s.aliases.each { |al| stream.puts "\t#{al}" }
|
235
|
+
stream.puts "\t#{s.name}"
|
236
|
+
stream.puts "\t\t#{s.help}"
|
237
|
+
when OptionSpecification
|
237
238
|
|
238
|
-
|
239
|
+
if voas.has_key? s.name
|
239
240
|
|
240
|
-
|
241
|
-
end
|
242
|
-
end
|
243
|
-
s.aliases.each { |al| stream.puts "\t#{al} <value>" }
|
244
|
-
stream.puts "\t#{s.name}=<value>"
|
245
|
-
stream.puts "\t\t#{s.help}"
|
246
|
-
unless s.values_range.empty?
|
241
|
+
voas[s.name].each do |ar|
|
247
242
|
|
248
|
-
|
243
|
+
ar[0].aliases.each { |al| stream.puts "\t#{al} #{ar[0].name}" }
|
244
|
+
end
|
245
|
+
end
|
246
|
+
s.aliases.each { |al| stream.puts "\t#{al} <value>" }
|
247
|
+
stream.puts "\t#{s.name}=<value>"
|
248
|
+
stream.puts "\t\t#{s.help}"
|
249
|
+
unless s.values_range.empty?
|
249
250
|
|
250
|
-
|
251
|
-
s.values_range.each do |v|
|
251
|
+
d = s.default_value
|
252
252
|
|
253
|
-
|
253
|
+
stream.puts "\t\twhere <value> one of:"
|
254
|
+
s.values_range.each do |v|
|
254
255
|
|
255
|
-
|
256
|
-
else
|
256
|
+
if default_indicator && v == d
|
257
257
|
|
258
|
-
|
259
|
-
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
stream.puts unless suppress_blanks
|
264
|
-
end
|
265
|
-
end
|
258
|
+
stream.puts "\t\t\t#{v}\t#{default_indicator}"
|
259
|
+
else
|
266
260
|
|
267
|
-
|
261
|
+
stream.puts "\t\t\t#{v}"
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
stream.puts unless suppress_blanks
|
267
|
+
end
|
268
|
+
end
|
268
269
|
|
269
|
-
|
270
|
+
exit_code = options[:exit_code] || options[:exit]
|
271
|
+
|
272
|
+
exit exit_code if exit_code
|
270
273
|
end
|
271
274
|
|
272
275
|
# Displays version for the program according to the given specifications and options
|
@@ -289,30 +292,32 @@ end
|
|
289
292
|
# - +:version_prefix+ optional string to prefix the version number(s).
|
290
293
|
def self.show_version specifications, options = {}
|
291
294
|
|
292
|
-
|
295
|
+
options ||= {}
|
296
|
+
|
297
|
+
raise ArgumentError, "specifications may not be nil" if specifications.nil?
|
298
|
+
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))
|
293
299
|
|
294
|
-
|
295
|
-
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))
|
300
|
+
constants = CLI_helpers_::Constants
|
296
301
|
|
297
|
-
|
298
|
-
specifications.each { |s| 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 === s } }
|
302
|
+
specifications.each { |s| 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 === s } }
|
299
303
|
|
300
|
-
|
304
|
+
stream = options[:stream] || $stdout
|
301
305
|
|
302
|
-
|
306
|
+
version_string = CLI_helpers_.generate_version_string_ options
|
303
307
|
|
304
|
-
|
308
|
+
stream.puts version_string
|
305
309
|
|
306
|
-
|
310
|
+
exit_code = options[:exit_code] || options[:exit]
|
307
311
|
|
308
|
-
|
312
|
+
exit exit_code if exit_code
|
309
313
|
end
|
310
314
|
|
315
|
+
|
311
316
|
# ######################################################################## #
|
312
317
|
# module
|
313
318
|
|
314
319
|
end # module CLASP
|
315
320
|
|
316
|
-
# ############################## end of file ############################# #
|
317
321
|
|
322
|
+
# ############################## end of file ############################# #
|
318
323
|
|
data/lib/clasp/doc_.rb
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
# Purpose: Documentation of the CLASP.Ruby modules
|
6
6
|
#
|
7
7
|
# Created: 11th June 2016
|
8
|
-
# Updated:
|
8
|
+
# Updated: 20th January 2024
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c) 2016-
|
14
|
+
# Copyright (c) 2016-2024, Matthew Wilson and Synesis Software
|
15
15
|
# All rights reserved.
|
16
16
|
#
|
17
17
|
# Redistribution and use in source and binary forms, with or without
|
@@ -163,6 +163,6 @@ module CLASP
|
|
163
163
|
|
164
164
|
end # module CLASP
|
165
165
|
|
166
|
-
# ############################## end of file ############################# #
|
167
166
|
|
167
|
+
# ############################## end of file ############################# #
|
168
168
|
|
data/lib/clasp/old_module.rb
CHANGED
@@ -6,13 +6,13 @@
|
|
6
6
|
# gem)
|
7
7
|
#
|
8
8
|
# Created: 10th June 2016
|
9
|
-
# Updated:
|
9
|
+
# Updated: 20th January 2024
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
12
12
|
#
|
13
13
|
# Author: Matthew Wilson
|
14
14
|
#
|
15
|
-
# Copyright (c) 2016, Matthew Wilson and Synesis Software
|
15
|
+
# Copyright (c) 2016-2024, Matthew Wilson and Synesis Software
|
16
16
|
# All rights reserved.
|
17
17
|
#
|
18
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -50,6 +50,6 @@ require 'clasp'
|
|
50
50
|
# Backwards-compatible alias for the CLASP library's CLASP module
|
51
51
|
Clasp = CLASP
|
52
52
|
|
53
|
-
# ############################## end of file ############################# #
|
54
53
|
|
54
|
+
# ############################## end of file ############################# #
|
55
55
|
|