simple_scripting 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Gemfile.lock +1 -1
- data/lib/simple_scripting/argv.rb +59 -37
- data/lib/simple_scripting/version.rb +1 -1
- data/simple_scripting.gemspec +1 -1
- data/spec/simple_scripting/argv_spec.rb +42 -13
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d451df42fd6ecf5e2de7ec01680151cecaf8f7438fe38beecc20c8a096669c3c
|
4
|
+
data.tar.gz: e295f1ff9885ce49834785c2c134aee3a85c5d26840a0234ab613d5041f7e4b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51e691d5371ae18047cda52434f84e3e87bee48f1aa3b6db9022287e066be389f32bc3a9e3a9249289755c9b206ee634550562e4231474ce99fb8087a588fa94
|
7
|
+
data.tar.gz: 063a6e93572108e28a9228d8f06c121599dfc19dcbf031c2262fe4e18e22cfbbf1782acf60c1c8e2d2273aae05399b8264fce0bb094a2e04c98a12da0b137677
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -37,7 +37,14 @@ module SimpleScripting
|
|
37
37
|
|
38
38
|
extend self
|
39
39
|
|
40
|
-
def decode(*
|
40
|
+
def decode(*definition_and_options)
|
41
|
+
params_definition, options = decode_definition_and_options(definition_and_options)
|
42
|
+
|
43
|
+
arguments = options.fetch(:arguments, ARGV)
|
44
|
+
long_help = options[:long_help]
|
45
|
+
auto_help = options.fetch(:auto_help, true)
|
46
|
+
output = options.fetch(:output, $stdout)
|
47
|
+
|
41
48
|
# WATCH OUT! @long_help can also be set in :decode_command!. See issue #17.
|
42
49
|
#
|
43
50
|
@long_help = long_help
|
@@ -59,6 +66,31 @@ module SimpleScripting
|
|
59
66
|
|
60
67
|
private
|
61
68
|
|
69
|
+
# This is trivial to define with named arguments, however, Ruby 2.6 removed the support for
|
70
|
+
# mixing strings and symbols as argument keys, so we're forced to perform manual decoding.
|
71
|
+
# The complexity of this code supports the rationale for the removal of the functionality.
|
72
|
+
#
|
73
|
+
def decode_definition_and_options(definition_and_options)
|
74
|
+
# Only a hash (commands)
|
75
|
+
if definition_and_options.size == 1 && definition_and_options.first.is_a?(Hash)
|
76
|
+
options = definition_and_options.first.each_with_object({}) do |(key, value), current_options|
|
77
|
+
current_options[key] = definition_and_options.first.delete(key) if key.is_a?(Symbol)
|
78
|
+
end
|
79
|
+
|
80
|
+
# If there is an empty hash left, we remove it, so it's not considered commands.
|
81
|
+
#
|
82
|
+
definition_and_options = [] if definition_and_options.first.empty?
|
83
|
+
# Options passed
|
84
|
+
elsif definition_and_options.last.is_a?(Hash)
|
85
|
+
options = definition_and_options.pop
|
86
|
+
# No options passed
|
87
|
+
else
|
88
|
+
options = {}
|
89
|
+
end
|
90
|
+
|
91
|
+
[definition_and_options, options]
|
92
|
+
end
|
93
|
+
|
62
94
|
# MAIN CASES ###########################################
|
63
95
|
|
64
96
|
# Input params_definition for a non-nested case:
|
@@ -118,10 +150,10 @@ module SimpleScripting
|
|
118
150
|
end
|
119
151
|
end
|
120
152
|
|
121
|
-
def decode_arguments!(params_definition,
|
153
|
+
def decode_arguments!(params_definition, arg_values, auto_help, commands_stack=[])
|
122
154
|
result = {}
|
123
155
|
parser_opts_copy = nil # not available outside the block
|
124
|
-
|
156
|
+
arg_definitions = {} # { 'name' => mandatory? }
|
125
157
|
|
126
158
|
OptionParser.new do |parser_opts|
|
127
159
|
params_definition.each do |param_definition|
|
@@ -129,7 +161,7 @@ module SimpleScripting
|
|
129
161
|
when Array
|
130
162
|
process_option_definition!(param_definition, parser_opts, result)
|
131
163
|
when String
|
132
|
-
process_argument_definition!(param_definition,
|
164
|
+
process_argument_definition!(param_definition, arg_definitions)
|
133
165
|
else
|
134
166
|
# This is an error in the params definition, so it doesn't follow the user error/help
|
135
167
|
# workflow.
|
@@ -142,7 +174,7 @@ module SimpleScripting
|
|
142
174
|
#
|
143
175
|
parser_opts.on('-h', '--help', 'Help') do
|
144
176
|
if auto_help
|
145
|
-
throw :exit, ExitWithArgumentsHelpPrinting.new(commands_stack,
|
177
|
+
throw :exit, ExitWithArgumentsHelpPrinting.new(commands_stack, arg_definitions, parser_opts_copy)
|
146
178
|
else
|
147
179
|
# Needs to be better handled. When help is required, generally, it trumps the
|
148
180
|
# correctness of the rest of the options/arguments.
|
@@ -152,16 +184,19 @@ module SimpleScripting
|
|
152
184
|
end
|
153
185
|
|
154
186
|
parser_opts_copy = parser_opts
|
155
|
-
end.parse!(
|
156
|
-
|
157
|
-
first_arg_name = args.keys.first.to_s
|
187
|
+
end.parse!(arg_values)
|
158
188
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
189
|
+
arg_definitions.each do |arg_name, arg_is_mandatory|
|
190
|
+
if arg_name.to_s.start_with?('*')
|
191
|
+
arg_name = arg_name.to_s[1..-1].to_sym
|
192
|
+
process_varargs!(arg_values, result, commands_stack, arg_name, arg_is_mandatory)
|
193
|
+
else
|
194
|
+
process_regular_argument!(arg_values, result, commands_stack, arg_name, arg_is_mandatory)
|
195
|
+
end
|
163
196
|
end
|
164
197
|
|
198
|
+
check_no_remaining_arguments(arg_values)
|
199
|
+
|
165
200
|
result
|
166
201
|
end
|
167
202
|
|
@@ -191,38 +226,25 @@ module SimpleScripting
|
|
191
226
|
end
|
192
227
|
end
|
193
228
|
|
194
|
-
def process_varargs!(
|
195
|
-
|
229
|
+
def process_varargs!(arg_values, result, commands_stack, arg_name, arg_is_mandatory)
|
230
|
+
raise ArgumentError.new("Missing mandatory argument(s)") if arg_is_mandatory && arg_values.empty?
|
196
231
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
raise ArgumentError.new("Missing mandatory argument(s)")
|
201
|
-
else
|
202
|
-
name = args.keys.first[1..-1].to_sym
|
232
|
+
result[arg_name] = arg_values.dup
|
233
|
+
arg_values.clear
|
234
|
+
end
|
203
235
|
|
204
|
-
|
236
|
+
def process_regular_argument!(arg_values, result, commands_stack, arg_name, arg_is_mandatory)
|
237
|
+
if arg_values.empty?
|
238
|
+
if arg_is_mandatory
|
239
|
+
raise ArgumentError.new("Missing mandatory argument(s)")
|
205
240
|
end
|
206
|
-
# Optional
|
207
241
|
else
|
208
|
-
|
209
|
-
|
210
|
-
result[name] = arguments
|
242
|
+
result[arg_name] = arg_values.shift
|
211
243
|
end
|
212
244
|
end
|
213
245
|
|
214
|
-
def
|
215
|
-
|
216
|
-
|
217
|
-
if arguments.size < min_args_size
|
218
|
-
raise ArgumentError.new("Missing mandatory argument(s)")
|
219
|
-
elsif arguments.size > args.size
|
220
|
-
raise ArgumentError.new("Too many arguments")
|
221
|
-
else
|
222
|
-
arguments.zip(args) do |value, (name, _)|
|
223
|
-
result[name] = value
|
224
|
-
end
|
225
|
-
end
|
246
|
+
def check_no_remaining_arguments(arg_values)
|
247
|
+
raise ArgumentError.new("Too many arguments") if !arg_values.empty?
|
226
248
|
end
|
227
249
|
|
228
250
|
# HELPERS ##############################################
|
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 = "2019-01-15"
|
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."
|
@@ -169,28 +169,57 @@ describe SimpleScripting::Argv do
|
|
169
169
|
|
170
170
|
describe '(mandatory)' do
|
171
171
|
|
172
|
-
|
173
|
-
'*varargs',
|
174
|
-
output: output_buffer,
|
175
|
-
]}
|
172
|
+
context 'as only parameter' do
|
176
173
|
|
177
|
-
|
178
|
-
|
174
|
+
let(:decoder_params) {[
|
175
|
+
'*varargs',
|
176
|
+
output: output_buffer,
|
177
|
+
arguments: ['varval1', 'varval2'],
|
178
|
+
]}
|
179
179
|
|
180
|
-
|
180
|
+
it "should be decoded" do
|
181
|
+
actual_result = described_class.decode(*decoder_params)
|
181
182
|
|
182
|
-
|
183
|
-
|
184
|
-
|
183
|
+
expected_result = {
|
184
|
+
varargs: ['varval1', 'varval2'],
|
185
|
+
}
|
186
|
+
|
187
|
+
expect(actual_result).to eql(expected_result)
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
context 'followed by varargs' do
|
193
|
+
|
194
|
+
let(:decoder_params) {[
|
195
|
+
'mandatory',
|
196
|
+
'*varargs',
|
197
|
+
output: output_buffer,
|
198
|
+
arguments: ['mandval', 'varval1', 'varval2']
|
199
|
+
]}
|
200
|
+
|
201
|
+
it "should be decoded" do
|
202
|
+
actual_result = described_class.decode(*decoder_params)
|
203
|
+
|
204
|
+
expected_result = {
|
205
|
+
mandatory: 'mandval',
|
206
|
+
varargs: ['varval1', 'varval2'],
|
207
|
+
}
|
208
|
+
|
209
|
+
expect(actual_result).to eql(expected_result)
|
210
|
+
end
|
185
211
|
|
186
|
-
expect(actual_result).to eql(expected_result)
|
187
212
|
end
|
188
213
|
|
189
214
|
context "error handling" do
|
190
215
|
|
191
|
-
|
192
|
-
|
216
|
+
let(:decoder_params) {[
|
217
|
+
'*varargs',
|
218
|
+
output: output_buffer,
|
219
|
+
arguments: [],
|
220
|
+
]}
|
193
221
|
|
222
|
+
it "should exit when they are not specified" do
|
194
223
|
decoding = -> { described_class.decode(*decoder_params) }
|
195
224
|
|
196
225
|
expect(decoding).to raise_error(SimpleScripting::Argv::ArgumentError, "Missing mandatory argument(s)")
|
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.10.
|
4
|
+
version: 0.10.2
|
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: 2019-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parseconfig
|
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
101
|
version: '0'
|
102
102
|
requirements: []
|
103
103
|
rubyforge_project:
|
104
|
-
rubygems_version: 2.7.
|
104
|
+
rubygems_version: 2.7.6
|
105
105
|
signing_key:
|
106
106
|
specification_version: 4
|
107
107
|
summary: Library for simplifying some typical scripting functionalities.
|