simple_scripting 0.11.1 → 0.13.0
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/lib/simple_scripting/argv.rb +38 -11
- data/lib/simple_scripting/version.rb +1 -1
- data/simple_scripting.gemspec +1 -1
- data/spec/simple_scripting/argv_spec.rb +371 -356
- data/spec/simple_scripting/configuration_spec.rb +4 -8
- data/spec/simple_scripting/tab_completion_spec.rb +0 -12
- metadata +3 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0a31e06185c711924565be44455735e02e55b31a98fc6782a101214cf9d37266
|
|
4
|
+
data.tar.gz: 2fa2139a689a85e1703604a3da2be186ac8596b9b17c0bc2af4c8c8244c8ad4d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bbf4a7477108d85b62922592eedbc550f0896ca75265385c219c052636d0c45628cd93ca59603649f9ee9227cf00fdf2526732918efb0ab7d55fe62d4b158196
|
|
7
|
+
data.tar.gz: b754caa9b812a0d7a5882d5bc2c67b0e72a276da9385a2be70d423838f00da711a182fb1f9b67c4072176c73a9d4020acb3b2070fba54f83615edd830cc5aa5c
|
|
@@ -7,9 +7,19 @@ module SimpleScripting
|
|
|
7
7
|
# The fact that the following errors don't descend from OptionParser::InvalidOption is somewhat
|
|
8
8
|
# annoying, however, there should be no practical problem.
|
|
9
9
|
#
|
|
10
|
-
class InvalidCommand < StandardError; end
|
|
11
10
|
class ArgumentError < StandardError; end
|
|
12
11
|
|
|
12
|
+
class InvalidCommand < StandardError
|
|
13
|
+
|
|
14
|
+
attr_reader :valid_commands
|
|
15
|
+
|
|
16
|
+
def initialize(message, valid_commands)
|
|
17
|
+
super(message)
|
|
18
|
+
@valid_commands = valid_commands
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
13
23
|
class ExitWithCommandsHelpPrinting < Struct.new(:commands_definition)
|
|
14
24
|
# Note that :long_help is not used.
|
|
15
25
|
def print_help(output, long_help)
|
|
@@ -61,12 +71,18 @@ module SimpleScripting
|
|
|
61
71
|
exit_data.print_help(output, @long_help)
|
|
62
72
|
|
|
63
73
|
nil # to be used with the 'decode(...) || exit' pattern
|
|
64
|
-
rescue SimpleScripting::Argv::ArgumentError,
|
|
65
|
-
if raise_errors
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
rescue SimpleScripting::Argv::ArgumentError, OptionParser::InvalidOption => error
|
|
75
|
+
raise if raise_errors
|
|
76
|
+
|
|
77
|
+
output.puts "Command error!: #{error.message}"
|
|
78
|
+
rescue SimpleScripting::Argv::InvalidCommand => error
|
|
79
|
+
raise if raise_errors
|
|
80
|
+
|
|
81
|
+
output.puts <<~MESSAGE
|
|
82
|
+
Command error!: #{error.message}"
|
|
83
|
+
|
|
84
|
+
Valid commands: #{error.valid_commands.join(", ")}
|
|
85
|
+
MESSAGE
|
|
70
86
|
ensure
|
|
71
87
|
@long_help = nil
|
|
72
88
|
end
|
|
@@ -129,13 +145,13 @@ module SimpleScripting
|
|
|
129
145
|
|
|
130
146
|
command = command_for_check
|
|
131
147
|
|
|
132
|
-
raise InvalidCommand.new("Missing command") if command.nil?
|
|
148
|
+
raise InvalidCommand.new("Missing command!", commands_definition.keys) if command.nil?
|
|
133
149
|
|
|
134
150
|
command_params_definition = commands_definition[command]
|
|
135
151
|
|
|
136
152
|
case command_params_definition
|
|
137
153
|
when nil
|
|
138
|
-
raise InvalidCommand.new("Invalid command: #{command}")
|
|
154
|
+
raise InvalidCommand.new("Invalid command: #{command}", commands_definition.keys)
|
|
139
155
|
when Hash
|
|
140
156
|
commands_stack << command
|
|
141
157
|
|
|
@@ -210,14 +226,25 @@ module SimpleScripting
|
|
|
210
226
|
# DEFINITIONS PROCESSING ###############################
|
|
211
227
|
|
|
212
228
|
def process_option_definition!(param_definition, parser_opts, result)
|
|
229
|
+
# Work on a copy; in at least one case (data type definition), we perform destructive
|
|
230
|
+
# operations.
|
|
231
|
+
#
|
|
232
|
+
param_definition = param_definition.dup
|
|
233
|
+
|
|
213
234
|
if param_definition[1] && param_definition[1].start_with?('--')
|
|
214
|
-
|
|
235
|
+
raw_key, key_argument = param_definition[1].split(' ')
|
|
236
|
+
key = raw_key[2 .. -1].tr('-', '_').to_sym
|
|
237
|
+
|
|
238
|
+
if key_argument&.include?(',')
|
|
239
|
+
param_definition.insert(2, Array)
|
|
240
|
+
end
|
|
215
241
|
else
|
|
216
242
|
key = param_definition[0][1 .. -1].to_sym
|
|
217
243
|
end
|
|
218
244
|
|
|
219
245
|
parser_opts.on(*param_definition) do |value|
|
|
220
|
-
|
|
246
|
+
raise "Unexpected (nil; likely programmatic error) value for param definition #{param_definition}" if value.nil?
|
|
247
|
+
result[key] = value
|
|
221
248
|
end
|
|
222
249
|
end
|
|
223
250
|
|
data/simple_scripting.gemspec
CHANGED
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
s.platform = Gem::Platform::RUBY
|
|
11
11
|
s.required_ruby_version = '>= 2.3.0'
|
|
12
12
|
s.authors = ["Saverio Miroddi"]
|
|
13
|
-
s.date = "
|
|
13
|
+
s.date = "2022-07-21"
|
|
14
14
|
s.email = ["saverio.pub2@gmail.com"]
|
|
15
15
|
s.homepage = "https://github.com/saveriomiroddi/simple_scripting"
|
|
16
16
|
s.summary = "Library for simplifying some typical scripting functionalities."
|
|
@@ -2,497 +2,512 @@ require_relative '../../lib/simple_scripting/argv.rb'
|
|
|
2
2
|
|
|
3
3
|
require 'stringio'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
describe 'Basic functionality' do
|
|
12
|
-
|
|
13
|
-
let(:decoder_params) {[
|
|
14
|
-
['-a' ],
|
|
15
|
-
['-b', '"-b" description'],
|
|
16
|
-
['-c', '--c-switch' ],
|
|
17
|
-
['-d', '--d-switch', '"-d" description'],
|
|
18
|
-
['-e', '--e-switch VALUE' ],
|
|
19
|
-
['-f', '--f-switch VALUE', '"-f" description'],
|
|
20
|
-
'mandatory',
|
|
21
|
-
'[optional]',
|
|
22
|
-
long_help: 'This is the long help!',
|
|
23
|
-
output: output_buffer,
|
|
24
|
-
]}
|
|
25
|
-
|
|
26
|
-
context 'help' do
|
|
27
|
-
|
|
28
|
-
it 'should print help automatically by default' do
|
|
29
|
-
decoder_params.last[:arguments] = ['-h']
|
|
30
|
-
|
|
31
|
-
return_value = described_class.decode(*decoder_params)
|
|
32
|
-
|
|
33
|
-
expected_output = <<~OUTPUT
|
|
34
|
-
Usage: rspec [options] <mandatory> [<optional>]
|
|
35
|
-
-a
|
|
36
|
-
-b "-b" description
|
|
37
|
-
-c, --c-switch
|
|
38
|
-
-d, --d-switch "-d" description
|
|
39
|
-
-e, --e-switch VALUE
|
|
40
|
-
-f, --f-switch VALUE "-f" description
|
|
41
|
-
-h, --help Help
|
|
42
|
-
|
|
43
|
-
This is the long help!
|
|
44
|
-
OUTPUT
|
|
45
|
-
|
|
46
|
-
expect(output_buffer.string).to eql(expected_output)
|
|
47
|
-
expect(return_value).to be(nil)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it 'should not interpret the --help argument, and not print the help, on auto_help: false' do
|
|
51
|
-
decoder_params.last.merge!(
|
|
52
|
-
arguments: ['--help', 'm_arg'],
|
|
53
|
-
auto_help: false
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
actual_result = described_class.decode(*decoder_params)
|
|
57
|
-
|
|
58
|
-
expected_result = {
|
|
59
|
-
help: true,
|
|
60
|
-
mandatory: 'm_arg',
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
expect(output_buffer.string).to eql('')
|
|
64
|
-
expect(actual_result).to eql(expected_result)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it "should check all the options/arguments when --help is passed, raising an error when they're not correct" do
|
|
68
|
-
decoder_params.last.merge!(
|
|
69
|
-
arguments: ['--help'],
|
|
70
|
-
auto_help: false,
|
|
71
|
-
raise_errors: true,
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
decoding = -> { described_class.decode(*decoder_params) }
|
|
5
|
+
module SimpleScripting
|
|
6
|
+
describe Argv do
|
|
7
|
+
let(:output_buffer) do
|
|
8
|
+
StringIO.new
|
|
9
|
+
end
|
|
75
10
|
|
|
76
|
-
|
|
77
|
-
|
|
11
|
+
describe 'Basic functionality' do
|
|
12
|
+
let(:decoder_params) {[
|
|
13
|
+
['-a' ],
|
|
14
|
+
['-b', '"-b" description'],
|
|
15
|
+
['-c', '--c-switch VAL1,VAL2' ],
|
|
16
|
+
['-d', '--d-switch', '"-d" description'],
|
|
17
|
+
['-e', '--e-switch VALUE' ],
|
|
18
|
+
['-f', '--f-switch VALUE', '"-f" description'],
|
|
19
|
+
'mandatory',
|
|
20
|
+
'[optional]',
|
|
21
|
+
long_help: 'This is the long help!',
|
|
22
|
+
output: output_buffer,
|
|
23
|
+
]}
|
|
78
24
|
|
|
79
|
-
|
|
25
|
+
context 'help' do
|
|
26
|
+
it 'should print help automatically by default' do
|
|
27
|
+
decoder_params.last[:arguments] = ['-h']
|
|
80
28
|
|
|
81
|
-
|
|
82
|
-
decoder_params.last[:arguments] = ['-a', '-b', '-c', '-d', '-ev_swt', '-fv_swt', 'm_arg', 'o_arg']
|
|
29
|
+
return_value = described_class.decode(*decoder_params)
|
|
83
30
|
|
|
84
|
-
|
|
31
|
+
expected_output = <<~OUTPUT
|
|
32
|
+
Usage: rspec [options] <mandatory> [<optional>]
|
|
33
|
+
-a
|
|
34
|
+
-b "-b" description
|
|
35
|
+
-c, --c-switch VAL1,VAL2
|
|
36
|
+
-d, --d-switch "-d" description
|
|
37
|
+
-e, --e-switch VALUE
|
|
38
|
+
-f, --f-switch VALUE "-f" description
|
|
39
|
+
-h, --help Help
|
|
85
40
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
b: true,
|
|
89
|
-
c_switch: true,
|
|
90
|
-
d_switch: true,
|
|
91
|
-
e_switch: 'v_swt',
|
|
92
|
-
f_switch: 'v_swt',
|
|
93
|
-
mandatory: 'm_arg',
|
|
94
|
-
optional: 'o_arg',
|
|
95
|
-
}
|
|
41
|
+
This is the long help!
|
|
42
|
+
OUTPUT
|
|
96
43
|
|
|
97
|
-
|
|
98
|
-
|
|
44
|
+
expect(output_buffer.string).to eql(expected_output)
|
|
45
|
+
expect(return_value).to be(nil)
|
|
46
|
+
end
|
|
99
47
|
|
|
100
|
-
|
|
101
|
-
|
|
48
|
+
it 'should not interpret the --help argument, and not print the help, on auto_help: false' do
|
|
49
|
+
decoder_params.last.merge!(
|
|
50
|
+
arguments: ['--help', 'm_arg'],
|
|
51
|
+
auto_help: false
|
|
52
|
+
)
|
|
102
53
|
|
|
103
|
-
|
|
54
|
+
actual_result = described_class.decode(*decoder_params)
|
|
104
55
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
56
|
+
expected_result = {
|
|
57
|
+
help: true,
|
|
58
|
+
mandatory: 'm_arg',
|
|
59
|
+
}
|
|
108
60
|
|
|
109
|
-
|
|
110
|
-
|
|
61
|
+
expect(output_buffer.string).to eql('')
|
|
62
|
+
expect(actual_result).to eql(expected_result)
|
|
63
|
+
end
|
|
111
64
|
|
|
112
|
-
|
|
65
|
+
it "should check all the options/arguments when --help is passed, raising an error when they're not correct" do
|
|
66
|
+
decoder_params.last.merge!(
|
|
67
|
+
arguments: ['--help'],
|
|
68
|
+
auto_help: false,
|
|
69
|
+
raise_errors: true,
|
|
70
|
+
)
|
|
113
71
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
72
|
+
expect {
|
|
73
|
+
described_class.decode(*decoder_params)
|
|
74
|
+
}.to raise_error(Argv::ArgumentError, "Missing mandatory argument(s)")
|
|
75
|
+
end
|
|
76
|
+
end # context 'help'
|
|
119
77
|
|
|
120
|
-
it "should
|
|
121
|
-
decoder_params.last[:arguments] = ['
|
|
78
|
+
it "should implement basic switches, with conversion, and arguments (all set)" do
|
|
79
|
+
decoder_params.last[:arguments] = ['-a', '-b', '-c', 'a,b,c', '-d', '-ev_swt', '-fv_swt', 'm_arg', 'o_arg']
|
|
122
80
|
|
|
123
81
|
actual_result = described_class.decode(*decoder_params)
|
|
124
82
|
|
|
125
83
|
expected_result = {
|
|
126
|
-
|
|
84
|
+
a: true,
|
|
85
|
+
b: true,
|
|
86
|
+
c_switch: %w(a b c),
|
|
87
|
+
d_switch: true,
|
|
88
|
+
e_switch: 'v_swt',
|
|
89
|
+
f_switch: 'v_swt',
|
|
90
|
+
mandatory: 'm_arg',
|
|
91
|
+
optional: 'o_arg',
|
|
127
92
|
}
|
|
128
93
|
|
|
129
94
|
expect(actual_result).to eql(expected_result)
|
|
130
95
|
end
|
|
131
96
|
|
|
132
|
-
it "should
|
|
133
|
-
decoder_params.last[:arguments] = ['
|
|
97
|
+
it "should implement basic switches and arguments (no optional argument)" do
|
|
98
|
+
decoder_params.last[:arguments] = ['m_arg']
|
|
134
99
|
|
|
135
100
|
actual_result = described_class.decode(*decoder_params)
|
|
136
101
|
|
|
137
102
|
expected_result = {
|
|
138
|
-
|
|
139
|
-
optional2: 'o_arg2',
|
|
103
|
+
mandatory: 'm_arg',
|
|
140
104
|
}
|
|
141
105
|
|
|
142
106
|
expect(actual_result).to eql(expected_result)
|
|
143
107
|
end
|
|
144
108
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
it "should print the error, with a previx, by default, instead of raising an error" do
|
|
151
|
-
decoder_params.last[:arguments] = []
|
|
152
|
-
|
|
153
|
-
actual_result = described_class.decode(*decoder_params)
|
|
154
|
-
|
|
155
|
-
# Returning nil is an important specification, as it's part of the Argv protocol of doing
|
|
156
|
-
# so in case of problem/exit.
|
|
157
|
-
expect(actual_result).to be(nil)
|
|
158
|
-
|
|
159
|
-
expect(output_buffer.string).to eql("Command error!: Missing mandatory argument(s)\n")
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
it "should raise an error when mandatory arguments are missing" do
|
|
163
|
-
decoder_params.last.merge!(
|
|
164
|
-
arguments: [],
|
|
165
|
-
raise_errors: true,
|
|
166
|
-
)
|
|
109
|
+
context "booleans" do
|
|
110
|
+
VALID_BOOLS = {
|
|
111
|
+
'false' => false,
|
|
112
|
+
'true' => true,
|
|
113
|
+
}
|
|
167
114
|
|
|
168
|
-
|
|
115
|
+
INVALID_BOOLS = %w[falx FALSE TRUE]
|
|
169
116
|
|
|
170
|
-
|
|
171
|
-
|
|
117
|
+
VALID_BOOLS.each do |user_value, decoded_value|
|
|
118
|
+
it "should decode a #{decoded_value} value" do
|
|
119
|
+
decoder_params = [
|
|
120
|
+
["-b", "--mybool VAL", TrueClass],
|
|
121
|
+
output: output_buffer,
|
|
122
|
+
arguments: ['--mybool', 'false']
|
|
123
|
+
]
|
|
172
124
|
|
|
173
|
-
|
|
174
|
-
decoder_params.last.merge!(
|
|
175
|
-
arguments: ['arg1', 'arg2', 'excessive_arg'],
|
|
176
|
-
raise_errors: true,
|
|
177
|
-
)
|
|
125
|
+
actual_result = described_class.decode(*decoder_params)
|
|
178
126
|
|
|
179
|
-
|
|
127
|
+
expected_result = {
|
|
128
|
+
mybool: false
|
|
129
|
+
}
|
|
180
130
|
|
|
181
|
-
|
|
131
|
+
expect(actual_result).to eql(expected_result)
|
|
132
|
+
end
|
|
133
|
+
end # context "booleans"
|
|
134
|
+
|
|
135
|
+
INVALID_BOOLS.each do |value|
|
|
136
|
+
it "should raise an error on invalid bool #{value.inspect}" do
|
|
137
|
+
decoder_params = [
|
|
138
|
+
["-b", "--mybool VAL", TrueClass],
|
|
139
|
+
output: output_buffer,
|
|
140
|
+
arguments: ['--mybool', value],
|
|
141
|
+
raise_errors: true,
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
expect {
|
|
145
|
+
described_class.decode(*decoder_params)
|
|
146
|
+
}.to raise_error(OptionParser::InvalidArgument)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
182
149
|
end
|
|
183
150
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
end # describe 'Basic functionality'
|
|
187
|
-
|
|
188
|
-
describe 'Varargs' do
|
|
189
|
-
|
|
190
|
-
describe '(mandatory)' do
|
|
191
|
-
|
|
192
|
-
context 'as only parameter' do
|
|
193
|
-
|
|
151
|
+
context "multiple optional arguments" do
|
|
194
152
|
let(:decoder_params) {[
|
|
195
|
-
'
|
|
153
|
+
'[optional1]',
|
|
154
|
+
'[optional2]',
|
|
196
155
|
output: output_buffer,
|
|
197
|
-
arguments: ['varval1', 'varval2'],
|
|
198
156
|
]}
|
|
199
157
|
|
|
200
|
-
it "should
|
|
158
|
+
it "should correctly decode a single argument passed" do
|
|
159
|
+
decoder_params.last[:arguments] = ['o_arg1']
|
|
160
|
+
|
|
201
161
|
actual_result = described_class.decode(*decoder_params)
|
|
202
162
|
|
|
203
163
|
expected_result = {
|
|
204
|
-
|
|
164
|
+
optional1: 'o_arg1',
|
|
205
165
|
}
|
|
206
166
|
|
|
207
167
|
expect(actual_result).to eql(expected_result)
|
|
208
168
|
end
|
|
209
169
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
context 'followed by varargs' do
|
|
170
|
+
it "should correctly decode all arguments passed" do
|
|
171
|
+
decoder_params.last[:arguments] = ['o_arg1', 'o_arg2']
|
|
213
172
|
|
|
214
|
-
let(:decoder_params) {[
|
|
215
|
-
'mandatory',
|
|
216
|
-
'*varargs',
|
|
217
|
-
output: output_buffer,
|
|
218
|
-
arguments: ['mandval', 'varval1', 'varval2']
|
|
219
|
-
]}
|
|
220
|
-
|
|
221
|
-
it "should be decoded" do
|
|
222
173
|
actual_result = described_class.decode(*decoder_params)
|
|
223
174
|
|
|
224
175
|
expected_result = {
|
|
225
|
-
|
|
226
|
-
|
|
176
|
+
optional1: 'o_arg1',
|
|
177
|
+
optional2: 'o_arg2',
|
|
227
178
|
}
|
|
228
179
|
|
|
229
180
|
expect(actual_result).to eql(expected_result)
|
|
230
181
|
end
|
|
231
|
-
|
|
232
182
|
end
|
|
233
183
|
|
|
234
184
|
context "error handling" do
|
|
185
|
+
# All the other UTs use error raising, for convenience.
|
|
186
|
+
it "should print the error, with a previx, by default, instead of raising an error" do
|
|
187
|
+
decoder_params.last[:arguments] = []
|
|
235
188
|
|
|
236
|
-
|
|
237
|
-
'*varargs',
|
|
238
|
-
output: output_buffer,
|
|
239
|
-
arguments: [],
|
|
240
|
-
]}
|
|
241
|
-
|
|
242
|
-
it "should raise an error when they are not specified" do
|
|
243
|
-
decoder_params.last[:raise_errors] = true
|
|
189
|
+
actual_result = described_class.decode(*decoder_params)
|
|
244
190
|
|
|
245
|
-
|
|
191
|
+
# Returning nil is an important specification, as it's part of the Argv protocol of doing
|
|
192
|
+
# so in case of problem/exit.
|
|
193
|
+
expect(actual_result).to be(nil)
|
|
246
194
|
|
|
247
|
-
expect(
|
|
195
|
+
expect(output_buffer.string).to eql("Command error!: Missing mandatory argument(s)\n")
|
|
248
196
|
end
|
|
249
197
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
let(:decoder_params) {[
|
|
257
|
-
'[*varargs]',
|
|
258
|
-
output: output_buffer,
|
|
259
|
-
]}
|
|
260
|
-
|
|
261
|
-
it "should be decoded" do
|
|
262
|
-
decoder_params.last[:arguments] = ['varval1', 'varval2']
|
|
263
|
-
|
|
264
|
-
actual_result = described_class.decode(*decoder_params)
|
|
265
|
-
|
|
266
|
-
expected_result = {
|
|
267
|
-
varargs: ['varval1', 'varval2'],
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
expect(actual_result).to eql(expected_result)
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
it "should be allowed not to be specified" do
|
|
274
|
-
decoder_params.last[:arguments] = []
|
|
198
|
+
it "should raise an error when mandatory arguments are missing" do
|
|
199
|
+
decoder_params.last.merge!(
|
|
200
|
+
arguments: [],
|
|
201
|
+
raise_errors: true,
|
|
202
|
+
)
|
|
275
203
|
|
|
276
|
-
|
|
204
|
+
expect {
|
|
205
|
+
described_class.decode(*decoder_params)
|
|
206
|
+
}.to raise_error(Argv::ArgumentError, "Missing mandatory argument(s)")
|
|
207
|
+
end
|
|
277
208
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
209
|
+
it "should raise an error when there are too many arguments" do
|
|
210
|
+
decoder_params.last.merge!(
|
|
211
|
+
arguments: ['arg1', 'arg2', 'excessive_arg'],
|
|
212
|
+
raise_errors: true,
|
|
213
|
+
)
|
|
281
214
|
|
|
282
|
-
|
|
283
|
-
|
|
215
|
+
expect {
|
|
216
|
+
described_class.decode(*decoder_params)
|
|
217
|
+
}.to raise_error(Argv::ArgumentError, "Too many arguments")
|
|
218
|
+
end
|
|
219
|
+
end # context "error handling"
|
|
220
|
+
end # describe 'Basic functionality'
|
|
284
221
|
|
|
285
|
-
|
|
222
|
+
describe 'Varargs' do
|
|
223
|
+
describe '(mandatory)' do
|
|
224
|
+
context 'as only parameter' do
|
|
225
|
+
let(:decoder_params) {[
|
|
226
|
+
'*varargs',
|
|
227
|
+
output: output_buffer,
|
|
228
|
+
arguments: ['varval1', 'varval2'],
|
|
229
|
+
]}
|
|
286
230
|
|
|
287
|
-
|
|
231
|
+
it "should be decoded" do
|
|
232
|
+
actual_result = described_class.decode(*decoder_params)
|
|
288
233
|
|
|
289
|
-
|
|
234
|
+
expected_result = {
|
|
235
|
+
varargs: ['varval1', 'varval2'],
|
|
236
|
+
}
|
|
290
237
|
|
|
291
|
-
|
|
238
|
+
expect(actual_result).to eql(expected_result)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
292
241
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
],
|
|
301
|
-
output: output_buffer,
|
|
302
|
-
}}
|
|
242
|
+
context 'followed by varargs' do
|
|
243
|
+
let(:decoder_params) {[
|
|
244
|
+
'mandatory',
|
|
245
|
+
'*varargs',
|
|
246
|
+
output: output_buffer,
|
|
247
|
+
arguments: ['mandval', 'varval1', 'varval2']
|
|
248
|
+
]}
|
|
303
249
|
|
|
304
|
-
|
|
305
|
-
|
|
250
|
+
it "should be decoded" do
|
|
251
|
+
actual_result = described_class.decode(*decoder_params)
|
|
306
252
|
|
|
307
|
-
|
|
253
|
+
expected_result = {
|
|
254
|
+
mandatory: 'mandval',
|
|
255
|
+
varargs: ['varval1', 'varval2'],
|
|
256
|
+
}
|
|
308
257
|
|
|
309
|
-
|
|
258
|
+
expect(actual_result).to eql(expected_result)
|
|
259
|
+
end
|
|
260
|
+
end
|
|
310
261
|
|
|
311
|
-
|
|
312
|
-
|
|
262
|
+
context "error handling" do
|
|
263
|
+
let(:decoder_params) {[
|
|
264
|
+
'*varargs',
|
|
265
|
+
output: output_buffer,
|
|
266
|
+
arguments: [],
|
|
267
|
+
]}
|
|
313
268
|
|
|
314
|
-
|
|
269
|
+
it "should raise an error when they are not specified" do
|
|
270
|
+
decoder_params.last[:raise_errors] = true
|
|
315
271
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
272
|
+
expect {
|
|
273
|
+
described_class.decode(*decoder_params)
|
|
274
|
+
}.to raise_error(Argv::ArgumentError, "Missing mandatory argument(s)")
|
|
275
|
+
end
|
|
276
|
+
end # context "error handling"
|
|
277
|
+
end # describe '(mandatory)'
|
|
321
278
|
|
|
322
|
-
|
|
279
|
+
describe '(optional)' do
|
|
280
|
+
let(:decoder_params) {[
|
|
281
|
+
'[*varargs]',
|
|
282
|
+
output: output_buffer,
|
|
283
|
+
]}
|
|
323
284
|
|
|
324
|
-
|
|
325
|
-
|
|
285
|
+
it "should be decoded" do
|
|
286
|
+
decoder_params.last[:arguments] = ['varval1', 'varval2']
|
|
326
287
|
|
|
327
|
-
|
|
328
|
-
decoder_params.merge!(
|
|
329
|
-
arguments: [],
|
|
330
|
-
raise_errors: true,
|
|
331
|
-
)
|
|
288
|
+
actual_result = described_class.decode(*decoder_params)
|
|
332
289
|
|
|
333
|
-
|
|
290
|
+
expected_result = {
|
|
291
|
+
varargs: ['varval1', 'varval2'],
|
|
292
|
+
}
|
|
334
293
|
|
|
335
|
-
expect(
|
|
294
|
+
expect(actual_result).to eql(expected_result)
|
|
336
295
|
end
|
|
337
296
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
context "help" do
|
|
341
|
-
|
|
342
|
-
it 'should implement the commands help' do
|
|
343
|
-
decoder_params[:arguments] = ['-h']
|
|
297
|
+
it "should be allowed not to be specified" do
|
|
298
|
+
decoder_params.last[:arguments] = []
|
|
344
299
|
|
|
345
|
-
described_class.decode(decoder_params)
|
|
346
|
-
|
|
347
|
-
expected_output = <<~OUTPUT
|
|
348
|
-
Valid commands:
|
|
300
|
+
actual_result = described_class.decode(*decoder_params)
|
|
349
301
|
|
|
350
|
-
|
|
351
|
-
|
|
302
|
+
expected_result = {
|
|
303
|
+
varargs: [],
|
|
304
|
+
}
|
|
352
305
|
|
|
353
|
-
expect(
|
|
306
|
+
expect(actual_result).to eql(expected_result)
|
|
354
307
|
end
|
|
308
|
+
end # describe '(optional)'
|
|
309
|
+
end # describe 'Varargs'
|
|
355
310
|
|
|
356
|
-
|
|
357
|
-
|
|
311
|
+
describe 'Commands' do
|
|
312
|
+
describe 'regular case' do
|
|
313
|
+
let(:decoder_params) {{
|
|
314
|
+
'command1' => [
|
|
315
|
+
'arg1',
|
|
316
|
+
long_help: 'This is the long help.'
|
|
317
|
+
],
|
|
318
|
+
'command2' => [
|
|
319
|
+
'arg2'
|
|
320
|
+
],
|
|
321
|
+
output: output_buffer,
|
|
322
|
+
}}
|
|
358
323
|
|
|
359
|
-
|
|
324
|
+
it 'should be decoded' do
|
|
325
|
+
decoder_params[:arguments] = ['command1', 'value1']
|
|
360
326
|
|
|
361
|
-
|
|
362
|
-
Usage: rspec command1 [options] <arg1>
|
|
363
|
-
-h, --help Help
|
|
327
|
+
actual_result = described_class.decode(decoder_params)
|
|
364
328
|
|
|
365
|
-
|
|
366
|
-
OUTPUT
|
|
329
|
+
expected_result = ['command1', arg1: 'value1']
|
|
367
330
|
|
|
368
|
-
expect(
|
|
331
|
+
expect(actual_result).to eql(expected_result)
|
|
369
332
|
end
|
|
370
333
|
|
|
371
|
-
context
|
|
372
|
-
|
|
373
|
-
it 'should not interpret the --help argument, and not print the help' do
|
|
334
|
+
context "error handling" do
|
|
335
|
+
it "should raise an error on invalid command" do
|
|
374
336
|
decoder_params.merge!(
|
|
375
|
-
arguments: ['
|
|
376
|
-
|
|
337
|
+
arguments: ['pizza'],
|
|
338
|
+
raise_errors: true,
|
|
377
339
|
)
|
|
378
340
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
expect(actual_result).to eql(expected_result)
|
|
341
|
+
expect {
|
|
342
|
+
described_class.decode(decoder_params)
|
|
343
|
+
}.to raise_error(an_instance_of(Argv::InvalidCommand).and having_attributes(
|
|
344
|
+
message: "Invalid command: pizza",
|
|
345
|
+
valid_commands: ["command1", "command2"],
|
|
346
|
+
))
|
|
386
347
|
end
|
|
387
348
|
|
|
388
|
-
it
|
|
349
|
+
it "should raise a specific error message on missing command" do
|
|
389
350
|
decoder_params.merge!(
|
|
390
|
-
arguments: [
|
|
391
|
-
|
|
351
|
+
arguments: [],
|
|
352
|
+
raise_errors: true,
|
|
392
353
|
)
|
|
393
354
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
expect(actual_result).to eql(expected_result)
|
|
355
|
+
expect {
|
|
356
|
+
described_class.decode(decoder_params)
|
|
357
|
+
}.to raise_error(an_instance_of(Argv::InvalidCommand).and having_attributes(
|
|
358
|
+
message: "Missing command!",
|
|
359
|
+
valid_commands: ["command1", "command2"],
|
|
360
|
+
))
|
|
401
361
|
end
|
|
362
|
+
end # context "error handling"
|
|
402
363
|
|
|
403
|
-
|
|
364
|
+
context "help" do
|
|
365
|
+
it 'should implement the commands help' do
|
|
366
|
+
decoder_params[:arguments] = ['-h']
|
|
404
367
|
|
|
405
|
-
|
|
368
|
+
described_class.decode(decoder_params)
|
|
406
369
|
|
|
407
|
-
|
|
370
|
+
expected_output = <<~OUTPUT
|
|
371
|
+
Valid commands:
|
|
408
372
|
|
|
409
|
-
|
|
373
|
+
command1, command2
|
|
374
|
+
OUTPUT
|
|
410
375
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
'nested1a' => [
|
|
414
|
-
'arg1',
|
|
415
|
-
long_help: 'nested1a long help.'
|
|
416
|
-
],
|
|
417
|
-
'nested1b' => [
|
|
418
|
-
'arg1b'
|
|
419
|
-
],
|
|
420
|
-
},
|
|
421
|
-
'command2' => [
|
|
422
|
-
'arg2'
|
|
423
|
-
],
|
|
424
|
-
output: output_buffer
|
|
425
|
-
}}
|
|
376
|
+
expect(output_buffer.string).to eql(expected_output)
|
|
377
|
+
end
|
|
426
378
|
|
|
427
|
-
|
|
428
|
-
|
|
379
|
+
it "should display the command given command's help" do
|
|
380
|
+
decoder_params[:arguments] = ['command1', '-h']
|
|
429
381
|
|
|
430
|
-
|
|
382
|
+
described_class.decode(decoder_params)
|
|
431
383
|
|
|
432
|
-
|
|
384
|
+
expected_output = <<~OUTPUT
|
|
385
|
+
Usage: rspec command1 [options] <arg1>
|
|
386
|
+
-h, --help Help
|
|
433
387
|
|
|
434
|
-
|
|
435
|
-
|
|
388
|
+
This is the long help.
|
|
389
|
+
OUTPUT
|
|
436
390
|
|
|
437
|
-
|
|
438
|
-
|
|
391
|
+
expect(output_buffer.string).to eql(expected_output)
|
|
392
|
+
end
|
|
439
393
|
|
|
440
|
-
|
|
394
|
+
context 'auto_help: false' do
|
|
395
|
+
it 'should not interpret the --help argument, and not print the help' do
|
|
396
|
+
decoder_params.merge!(
|
|
397
|
+
arguments: ['-h'],
|
|
398
|
+
auto_help: false,
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
actual_result = described_class.decode(decoder_params)
|
|
402
|
+
|
|
403
|
+
expected_result = {
|
|
404
|
+
help: true,
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
expect(actual_result).to eql(expected_result)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
it 'should ignore and not return all the other arguments' do
|
|
411
|
+
decoder_params.merge!(
|
|
412
|
+
arguments: ['-h', 'pizza'],
|
|
413
|
+
auto_help: false,
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
actual_result = described_class.decode(decoder_params)
|
|
417
|
+
|
|
418
|
+
expected_result = {
|
|
419
|
+
help: true,
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
expect(actual_result).to eql(expected_result)
|
|
423
|
+
end
|
|
424
|
+
end # context 'auto_help: false'
|
|
425
|
+
end # context 'help'
|
|
426
|
+
end # describe 'regular case'
|
|
427
|
+
|
|
428
|
+
describe 'Nested commands' do
|
|
429
|
+
let(:decoder_params) {{
|
|
430
|
+
'command1' => {
|
|
431
|
+
'nested1a' => [
|
|
432
|
+
'arg1',
|
|
433
|
+
long_help: 'nested1a long help.'
|
|
434
|
+
],
|
|
435
|
+
'nested1b' => [
|
|
436
|
+
'arg1b'
|
|
437
|
+
],
|
|
438
|
+
},
|
|
439
|
+
'command2' => [
|
|
440
|
+
'arg2'
|
|
441
|
+
],
|
|
442
|
+
output: output_buffer
|
|
443
|
+
}}
|
|
441
444
|
|
|
442
|
-
|
|
445
|
+
it 'should be decoded (two levels)' do
|
|
446
|
+
decoder_params[:arguments] = ['command1', 'nested1a', 'value1']
|
|
443
447
|
|
|
444
|
-
|
|
445
|
-
end
|
|
448
|
+
actual_result = described_class.decode(decoder_params)
|
|
446
449
|
|
|
447
|
-
|
|
448
|
-
decoder_params[:arguments] = ['command1', '-h']
|
|
450
|
+
expected_result = ['command1.nested1a', arg1: 'value1']
|
|
449
451
|
|
|
450
|
-
|
|
452
|
+
expect(actual_result).to eql(expected_result)
|
|
453
|
+
end
|
|
451
454
|
|
|
452
|
-
|
|
453
|
-
|
|
455
|
+
it 'should be decoded (one level)' do
|
|
456
|
+
decoder_params[:arguments] = ['command2', 'value2']
|
|
454
457
|
|
|
455
|
-
|
|
456
|
-
OUTPUT
|
|
458
|
+
actual_result = described_class.decode(decoder_params)
|
|
457
459
|
|
|
458
|
-
|
|
459
|
-
end
|
|
460
|
+
expected_result = ['command2', arg2: 'value2']
|
|
460
461
|
|
|
461
|
-
|
|
462
|
-
|
|
462
|
+
expect(actual_result).to eql(expected_result)
|
|
463
|
+
end
|
|
463
464
|
|
|
464
|
-
|
|
465
|
+
it 'should print the command1 help' do
|
|
466
|
+
decoder_params[:arguments] = ['command1', '-h']
|
|
467
|
+
|
|
468
|
+
actual_result = described_class.decode(decoder_params)
|
|
465
469
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
-h, --help Help
|
|
470
|
+
expected_output = <<~OUTPUT
|
|
471
|
+
Valid commands:
|
|
469
472
|
|
|
470
|
-
|
|
471
|
-
|
|
473
|
+
nested1a, nested1b
|
|
474
|
+
OUTPUT
|
|
472
475
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
end # describe 'Nested commands'
|
|
476
|
+
expect(output_buffer.string).to eql(expected_output)
|
|
477
|
+
end
|
|
476
478
|
|
|
477
|
-
|
|
479
|
+
it 'should print the nested1a help, and long help' do
|
|
480
|
+
decoder_params[:arguments] = ['command1', 'nested1a', '-h']
|
|
478
481
|
|
|
479
|
-
|
|
480
|
-
#
|
|
481
|
-
describe 'No definitions given' do
|
|
482
|
+
actual_result = described_class.decode(decoder_params)
|
|
482
483
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
484
|
+
expected_output = <<~OUTPUT
|
|
485
|
+
Usage: rspec command1 nested1a [options] <arg1>
|
|
486
|
+
-h, --help Help
|
|
486
487
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
decoder_params[:raise_errors] = true
|
|
488
|
+
nested1a long help.
|
|
489
|
+
OUTPUT
|
|
490
490
|
|
|
491
|
-
|
|
491
|
+
expect(output_buffer.string).to eql(expected_output)
|
|
492
|
+
end
|
|
493
|
+
end # describe 'Nested commands'
|
|
494
|
+
end # describe 'Commands'
|
|
492
495
|
|
|
493
|
-
|
|
494
|
-
|
|
496
|
+
# Special case.
|
|
497
|
+
#
|
|
498
|
+
describe 'No definitions given' do
|
|
499
|
+
let(:decoder_params) {{
|
|
500
|
+
output: output_buffer,
|
|
501
|
+
}}
|
|
495
502
|
|
|
496
|
-
|
|
503
|
+
it 'should avoid options being interpreted as definitions' do
|
|
504
|
+
decoder_params[:arguments] = ['pizza']
|
|
505
|
+
decoder_params[:raise_errors] = true
|
|
497
506
|
|
|
498
|
-
|
|
507
|
+
expect {
|
|
508
|
+
described_class.decode(decoder_params)
|
|
509
|
+
}.to raise_error(Argv::ArgumentError, "Too many arguments")
|
|
510
|
+
end
|
|
511
|
+
end # describe 'No definitions given'
|
|
512
|
+
end # describe Argv
|
|
513
|
+
end # module SimpleScripting
|
|
@@ -4,7 +4,6 @@ require 'tempfile'
|
|
|
4
4
|
require 'tmpdir'
|
|
5
5
|
|
|
6
6
|
module SimpleScripting::ConfigurationSpecHelper
|
|
7
|
-
|
|
8
7
|
def with_tempfile(config_content)
|
|
9
8
|
tempfile = Tempfile.new('ss_config_test')
|
|
10
9
|
tempfile.write(config_content)
|
|
@@ -14,11 +13,9 @@ module SimpleScripting::ConfigurationSpecHelper
|
|
|
14
13
|
ensure
|
|
15
14
|
tempfile.unlink
|
|
16
15
|
end
|
|
17
|
-
|
|
18
16
|
end
|
|
19
17
|
|
|
20
18
|
describe SimpleScripting::Configuration do
|
|
21
|
-
|
|
22
19
|
include SimpleScripting::ConfigurationSpecHelper
|
|
23
20
|
|
|
24
21
|
let(:configuration_text) {"
|
|
@@ -56,9 +53,9 @@ g2_key=bang
|
|
|
56
53
|
|
|
57
54
|
it "should raise an error when required keys are missing" do
|
|
58
55
|
with_tempfile(configuration_text) do |config_file|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
expect {
|
|
57
|
+
described_class.load(config_file: config_file, required: %w(abspath_key missing_key group1))
|
|
58
|
+
}.to raise_error(RuntimeError, "Missing required configuration key(s): missing_key, group1")
|
|
62
59
|
end
|
|
63
60
|
end
|
|
64
61
|
|
|
@@ -73,5 +70,4 @@ g2_key=bang
|
|
|
73
70
|
File.delete(temp_config_file)
|
|
74
71
|
end
|
|
75
72
|
end
|
|
76
|
-
|
|
77
|
-
end
|
|
73
|
+
end # describe SimpleScripting::Configuration
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
require_relative '../../lib/simple_scripting/tab_completion.rb'
|
|
4
4
|
|
|
5
5
|
describe SimpleScripting::TabCompletion do
|
|
6
|
-
|
|
7
6
|
include TabCompletionCustomRSpecMatchers
|
|
8
7
|
|
|
9
8
|
let(:output_buffer) {
|
|
@@ -45,9 +44,7 @@ describe SimpleScripting::TabCompletion do
|
|
|
45
44
|
subject { described_class.new(switches_definition, output: output_buffer) }
|
|
46
45
|
|
|
47
46
|
context "with a correct configuration" do
|
|
48
|
-
|
|
49
47
|
context "standard cases" do
|
|
50
|
-
|
|
51
48
|
# Note that the conversion of mandatory to optional argument is defined by most of the cases.
|
|
52
49
|
#
|
|
53
50
|
STANDARD_CASES = {
|
|
@@ -79,11 +76,9 @@ describe SimpleScripting::TabCompletion do
|
|
|
79
76
|
expect(symbolic_commandline_options).to complete_with(expected_entries)
|
|
80
77
|
end
|
|
81
78
|
end
|
|
82
|
-
|
|
83
79
|
end # context "standard cases"
|
|
84
80
|
|
|
85
81
|
context "suffix management" do
|
|
86
|
-
|
|
87
82
|
SUFFIX_CASES = {
|
|
88
83
|
"arg1<tab>v" => %w(arg1v1 arg1v2), # the execution target of the test suite doesn't
|
|
89
84
|
"arg1<tab>x" => %w(), # ignore the suffix; programmer-defined
|
|
@@ -97,11 +92,9 @@ describe SimpleScripting::TabCompletion do
|
|
|
97
92
|
expect(symbolic_commandline_options).to complete_with(expected_entries)
|
|
98
93
|
end
|
|
99
94
|
end
|
|
100
|
-
|
|
101
95
|
end # context "suffix management"
|
|
102
96
|
|
|
103
97
|
context "escaped cases" do
|
|
104
|
-
|
|
105
98
|
ESCAPED_CASES = {
|
|
106
99
|
"\ <tab>" => [" _argv1spc"],
|
|
107
100
|
'\-<tab>' => %w(), # this is the result of typing `command "\-<tab>`
|
|
@@ -111,7 +104,6 @@ describe SimpleScripting::TabCompletion do
|
|
|
111
104
|
ESCAPED_CASES.each do |symbolic_commandline_options, _|
|
|
112
105
|
it "should output the entries for #{symbolic_commandline_options.inspect}"
|
|
113
106
|
end
|
|
114
|
-
|
|
115
107
|
end # context "escaped cases"
|
|
116
108
|
|
|
117
109
|
it "should support multiple values for an option"
|
|
@@ -119,11 +111,9 @@ describe SimpleScripting::TabCompletion do
|
|
|
119
111
|
it "should keep parsing also when --help is passed" do
|
|
120
112
|
expect("--help a<tab>").to complete_with(%w(arg1v1 arg1v2))
|
|
121
113
|
end
|
|
122
|
-
|
|
123
114
|
end # context "with a correct configuration"
|
|
124
115
|
|
|
125
116
|
context "with an incorrect configuration" do
|
|
126
|
-
|
|
127
117
|
INCORRECT_CASES = [
|
|
128
118
|
"a b <tab>", # too many args
|
|
129
119
|
"-O<tab>", # no values for this option
|
|
@@ -134,7 +124,5 @@ describe SimpleScripting::TabCompletion do
|
|
|
134
124
|
expect(symbolic_commandline_options).to not_complete
|
|
135
125
|
end
|
|
136
126
|
end
|
|
137
|
-
|
|
138
127
|
end # context "with an incorrect configuration"
|
|
139
|
-
|
|
140
128
|
end # describe SimpleScripting::TabCompletion
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: simple_scripting
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Saverio Miroddi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-07-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: parseconfig
|
|
@@ -99,8 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
99
99
|
- !ruby/object:Gem::Version
|
|
100
100
|
version: '0'
|
|
101
101
|
requirements: []
|
|
102
|
-
|
|
103
|
-
rubygems_version: 2.7.8
|
|
102
|
+
rubygems_version: 3.1.6
|
|
104
103
|
signing_key:
|
|
105
104
|
specification_version: 4
|
|
106
105
|
summary: Library for simplifying some typical scripting functionalities.
|