clasp-ruby 0.23.0.2 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/examples/cr-example.rb +16 -16
- data/examples/flag_and_option_specifications.rb +15 -15
- data/examples/show_usage_and_version.rb +10 -11
- data/lib/clasp/arguments.rb +86 -87
- data/lib/clasp/clasp.rb +15 -11
- data/lib/clasp/cli.rb +135 -134
- data/lib/clasp/old_module.rb +8 -8
- data/lib/clasp/specifications.rb +325 -322
- data/lib/clasp/util/exceptions.rb +21 -22
- data/lib/clasp/util/value_parser.rb +99 -101
- data/lib/clasp/version.rb +12 -12
- data/lib/clasp-ruby.rb +8 -7
- data/lib/clasp.rb +8 -7
- data/test/scratch/test_list_command_line.rb +6 -6
- data/test/scratch/test_specifications.rb +14 -14
- data/test/scratch/test_usage.rb +5 -5
- data/test/scratch/test_usage_with_duplicate_specifications.rb +5 -5
- data/test/unit/tc_ARGV_rewrite.rb +36 -36
- data/test/unit/tc_arguments_1.rb +708 -708
- data/test/unit/tc_arguments_2.rb +43 -43
- data/test/unit/tc_arguments_3.rb +77 -77
- data/test/unit/tc_arguments_inspect.rb +55 -55
- data/test/unit/tc_cli.rb +4 -4
- data/test/unit/tc_default_value.rb +91 -91
- data/test/unit/tc_defaults_1.rb +38 -38
- data/test/unit/tc_examples_Arguments.rb +130 -130
- data/test/unit/tc_extras.rb +24 -24
- data/test/unit/tc_option_required.rb +38 -38
- data/test/unit/tc_option_value_aliases.rb +44 -44
- data/test/unit/tc_specifications.rb +7 -7
- data/test/unit/tc_typed_options.rb +200 -200
- data/test/unit/tc_usage.rb +69 -69
- data/test/unit/tc_with_action.rb +23 -23
- metadata +9 -8
data/lib/clasp/cli.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
|
2
2
|
# ######################################################################## #
|
3
|
-
# File:
|
3
|
+
# File: clasp/cli.rb
|
4
4
|
#
|
5
|
-
# Purpose:
|
5
|
+
# Purpose: Command-line interface
|
6
6
|
#
|
7
|
-
# Created:
|
8
|
-
# Updated:
|
7
|
+
# Created: 27th July 2015
|
8
|
+
# Updated: 6th March 2025
|
9
9
|
#
|
10
|
-
# Home:
|
10
|
+
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
11
|
#
|
12
|
-
# Author:
|
12
|
+
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c)
|
14
|
+
# Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems
|
15
|
+
# Copyright (c) 2015-2019, Matthew Wilson and Synesis Software
|
15
16
|
# All rights reserved.
|
16
17
|
#
|
17
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -65,45 +66,45 @@ module CLASP
|
|
65
66
|
# @!visibility private
|
66
67
|
module CLI_helpers_ # :nodoc: all
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
69
|
+
# @!visibility private
|
70
|
+
module Constants # :nodoc: all
|
76
71
|
|
77
72
|
# @!visibility private
|
78
|
-
|
73
|
+
VALID_ALIAS_TYPES = [ FlagSpecification, OptionSpecification, AliasSpecification ]
|
74
|
+
# @!visibility private
|
75
|
+
VALID_ALIAS_TYPES_STRING = VALID_ALIAS_TYPES[0...-1].join(', ') + ', or ' + VALID_ALIAS_TYPES[-1].to_s
|
76
|
+
end # module Constants
|
79
77
|
|
80
|
-
|
78
|
+
# @!visibility private
|
79
|
+
def self.generate_version_string_ options # :nodoc:
|
81
80
|
|
82
|
-
|
81
|
+
program_name = options[:program_name] || File.basename($0)
|
83
82
|
|
84
|
-
|
83
|
+
version_prefix = options[:version_prefix]
|
85
84
|
|
86
|
-
|
87
|
-
when ::Array
|
88
|
-
version = options[:version].join('.')
|
89
|
-
else
|
90
|
-
version = options[:version]
|
91
|
-
end
|
92
|
-
else
|
85
|
+
if options[:version]
|
93
86
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
87
|
+
case options[:version]
|
88
|
+
when ::Array
|
89
|
+
version = options[:version].join('.')
|
90
|
+
else
|
91
|
+
version = options[:version]
|
92
|
+
end
|
93
|
+
else
|
98
94
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
95
|
+
version_major = options[:version_major] or raise ArgumentError, "options must specify :version or :version_major [ + :version_minor [ + :version_revision [ + :version_build ]]]"
|
96
|
+
version_minor = options[:version_minor]
|
97
|
+
version_rev = options[:version_revision]
|
98
|
+
version_build = options[:version_build]
|
104
99
|
|
105
|
-
|
100
|
+
version = version_major.to_s
|
101
|
+
version += ".#{version_minor}" if version_minor
|
102
|
+
version += ".#{version_rev}" if version_rev
|
103
|
+
version += ".#{version_build}" if version_build
|
106
104
|
end
|
105
|
+
|
106
|
+
"#{program_name} #{version_prefix}#{version}"
|
107
|
+
end
|
107
108
|
end # module CLI_helpers_
|
108
109
|
|
109
110
|
|
@@ -134,142 +135,142 @@ end # module CLI_helpers_
|
|
134
135
|
# - +: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
|
135
136
|
def self.show_usage specifications, options={}
|
136
137
|
|
137
|
-
|
138
|
+
options ||= {}
|
138
139
|
|
139
|
-
|
140
|
-
|
140
|
+
raise ArgumentError, "specifications may not be nil" if specifications.nil?
|
141
|
+
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))
|
141
142
|
|
142
|
-
|
143
|
+
constants = CLI_helpers_::Constants
|
143
144
|
|
144
|
-
|
145
|
+
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
146
|
|
146
|
-
|
147
|
-
|
147
|
+
alias_dups = {}
|
148
|
+
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; } }
|
148
149
|
|
149
|
-
|
150
|
+
suppress_blanks = options[:suppress_blank_lines_between_options] || ENV['SUPPRESS_BLANK_LINES_BETWEEN_OPTIONS']
|
150
151
|
|
151
|
-
|
152
|
-
|
152
|
+
stream = options[:stream] || $stdout
|
153
|
+
program_name = options[:program_name] || File.basename($0)
|
153
154
|
|
154
|
-
|
155
|
-
|
156
|
-
|
155
|
+
info_lines = options[:info_lines]
|
156
|
+
case info_lines
|
157
|
+
when ::Array
|
157
158
|
|
158
|
-
|
159
|
-
|
159
|
+
;
|
160
|
+
when ::NilClass
|
160
161
|
|
161
|
-
|
162
|
-
|
162
|
+
info_lines = []
|
163
|
+
else
|
163
164
|
|
164
|
-
|
165
|
-
|
166
|
-
|
165
|
+
info_lines = [ info_lines ] unless [ :each, :empty? ].all? { |m| info_lines.respond_to? m }
|
166
|
+
end
|
167
|
+
info_lines = info_lines.map do |line|
|
167
168
|
|
168
|
-
|
169
|
-
|
169
|
+
case line
|
170
|
+
when :version
|
170
171
|
|
171
|
-
|
172
|
-
|
172
|
+
CLI_helpers_.generate_version_string_ options
|
173
|
+
else
|
173
174
|
|
174
|
-
|
175
|
-
end
|
175
|
+
line
|
176
176
|
end
|
177
|
+
end
|
177
178
|
|
178
|
-
|
179
|
-
|
179
|
+
values = options[:values] || ''
|
180
|
+
values = " #{values}" if !values.empty? && ' ' != values[0]
|
180
181
|
|
181
|
-
|
182
|
-
|
182
|
+
flags_and_options = options[:flags_and_options] || ' [ ... flags and options ... ]'
|
183
|
+
flags_and_options = " #{flags_and_options}" if !flags_and_options.empty? && ' ' != flags_and_options[0]
|
183
184
|
|
184
|
-
|
185
|
-
|
185
|
+
default_indicator = options[:default_indicator] || '(default)'
|
186
|
+
default_indicator = nil if default_indicator.empty?
|
186
187
|
|
187
|
-
|
188
|
-
|
188
|
+
# sift the specifications to sort out which are value-option
|
189
|
+
# specifications (VOAs)
|
189
190
|
|
190
|
-
|
191
|
+
voas = {}
|
191
192
|
|
192
|
-
|
193
|
+
specifications.select { |s| s.name =~ /^-+[a-zA-Z0-3_-]+[=:].+/ }.each do |s|
|
193
194
|
|
194
|
-
|
195
|
+
s.name =~ /^(-+[a-zA-Z0-3_-]+)[=:](.+)$/
|
195
196
|
|
196
|
-
|
197
|
-
|
198
|
-
|
197
|
+
voas[$1] = [] unless voas.has_key? $1
|
198
|
+
voas[$1] << [ s, $2 ]
|
199
|
+
end
|
199
200
|
|
200
|
-
|
201
|
+
fas = {}
|
201
202
|
|
202
|
-
|
203
|
+
specifications.select { |s| AliasSpecification === s }.each do |s|
|
203
204
|
|
204
|
-
|
205
|
-
|
206
|
-
|
205
|
+
fas[s.name] = [] unless fas.has_key? $1
|
206
|
+
fas[s.name] << s
|
207
|
+
end
|
207
208
|
|
208
|
-
|
209
|
+
specifications = specifications.reject { |s| s.name =~ /^-+[a-zA-Z0-3_-]+[=:].+/ }
|
209
210
|
|
210
|
-
|
211
|
+
info_lines.each { |info_line| stream.puts info_line } unless info_lines.empty?
|
211
212
|
|
212
|
-
|
213
|
-
|
213
|
+
stream.puts "USAGE: #{program_name}#{flags_and_options}#{values}"
|
214
|
+
stream.puts
|
214
215
|
|
215
|
-
|
216
|
+
unless specifications.empty?
|
216
217
|
|
217
|
-
|
218
|
-
|
219
|
-
|
218
|
+
stream.puts "flags/options:"
|
219
|
+
stream.puts
|
220
|
+
specifications.each do |s|
|
220
221
|
|
221
|
-
|
222
|
-
|
222
|
+
case s
|
223
|
+
when AliasSpecification
|
223
224
|
|
224
|
-
|
225
|
-
|
225
|
+
next
|
226
|
+
when FlagSpecification
|
226
227
|
|
227
|
-
|
228
|
+
if fas.has_key? s.name
|
228
229
|
|
229
|
-
|
230
|
+
fas[s.name].each do |fa|
|
230
231
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
232
|
+
fa.aliases.each { |al| stream.puts "\t#{al}" }
|
233
|
+
end
|
234
|
+
end
|
235
|
+
s.aliases.each { |al| stream.puts "\t#{al}" }
|
236
|
+
stream.puts "\t#{s.name}"
|
237
|
+
stream.puts "\t\t#{s.help}"
|
238
|
+
when OptionSpecification
|
238
239
|
|
239
|
-
|
240
|
+
if voas.has_key? s.name
|
240
241
|
|
241
|
-
|
242
|
+
voas[s.name].each do |ar|
|
242
243
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
244
|
+
ar[0].aliases.each { |al| stream.puts "\t#{al} #{ar[0].name}" }
|
245
|
+
end
|
246
|
+
end
|
247
|
+
s.aliases.each { |al| stream.puts "\t#{al} <value>" }
|
248
|
+
stream.puts "\t#{s.name}=<value>"
|
249
|
+
stream.puts "\t\t#{s.help}"
|
250
|
+
unless s.values_range.empty?
|
250
251
|
|
251
|
-
|
252
|
+
d = s.default_value
|
252
253
|
|
253
|
-
|
254
|
-
|
254
|
+
stream.puts "\t\twhere <value> one of:"
|
255
|
+
s.values_range.each do |v|
|
255
256
|
|
256
|
-
|
257
|
+
if default_indicator && v == d
|
257
258
|
|
258
|
-
|
259
|
-
|
259
|
+
stream.puts "\t\t\t#{v}\t#{default_indicator}"
|
260
|
+
else
|
260
261
|
|
261
|
-
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
262
|
+
stream.puts "\t\t\t#{v}"
|
265
263
|
end
|
266
|
-
|
264
|
+
end
|
267
265
|
end
|
266
|
+
end
|
267
|
+
stream.puts unless suppress_blanks
|
268
268
|
end
|
269
|
+
end
|
269
270
|
|
270
|
-
|
271
|
+
exit_code = options[:exit_code] || options[:exit]
|
271
272
|
|
272
|
-
|
273
|
+
exit exit_code if exit_code
|
273
274
|
end
|
274
275
|
|
275
276
|
# Displays version for the program according to the given specifications and options
|
@@ -292,24 +293,24 @@ end
|
|
292
293
|
# - +:version_prefix+ optional string to prefix the version number(s).
|
293
294
|
def self.show_version specifications, options = {}
|
294
295
|
|
295
|
-
|
296
|
+
options ||= {}
|
296
297
|
|
297
|
-
|
298
|
-
|
298
|
+
raise ArgumentError, "specifications may not be nil" if specifications.nil?
|
299
|
+
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))
|
299
300
|
|
300
|
-
|
301
|
+
constants = CLI_helpers_::Constants
|
301
302
|
|
302
|
-
|
303
|
+
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 } }
|
303
304
|
|
304
|
-
|
305
|
+
stream = options[:stream] || $stdout
|
305
306
|
|
306
|
-
|
307
|
+
version_string = CLI_helpers_.generate_version_string_ options
|
307
308
|
|
308
|
-
|
309
|
+
stream.puts version_string
|
309
310
|
|
310
|
-
|
311
|
+
exit_code = options[:exit_code] || options[:exit]
|
311
312
|
|
312
|
-
|
313
|
+
exit exit_code if exit_code
|
313
314
|
end
|
314
315
|
|
315
316
|
|
data/lib/clasp/old_module.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
|
2
2
|
# ######################################################################## #
|
3
|
-
# File:
|
3
|
+
# File: clasp/old_module.rb
|
4
4
|
#
|
5
|
-
# Purpose:
|
6
|
-
# gem)
|
5
|
+
# Purpose: Introduces old module Clasp (which clashes with an existing gem)
|
7
6
|
#
|
8
|
-
# Created:
|
9
|
-
# Updated:
|
7
|
+
# Created: 10th June 2016
|
8
|
+
# Updated: 6th March 2025
|
10
9
|
#
|
11
|
-
# Home:
|
10
|
+
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
12
11
|
#
|
13
|
-
# Author:
|
12
|
+
# Author: Matthew Wilson
|
14
13
|
#
|
15
|
-
# Copyright (c)
|
14
|
+
# Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems
|
15
|
+
# Copyright (c) 2016-2019, 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
|