nub 0.0.50 → 0.0.51
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 +1 -1
- data/lib/nub/commander.rb +113 -50
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c58496cf243b60e9ca662e07c1e8c30a0dba10bb6cd290d748df9b9f93d7897b
|
4
|
+
data.tar.gz: 5a918972eb7de66173b9c2ec31eccb396804a900d2cf3b25cb9b3c046e863256
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4eefd3a45e934ebc542d862ab1e867c3e88d8eb3f07fa5de50d525e305cb22e594027ba9523c280480ceaa37c62fe4021d2a4d820edcf8001ff8f49cb1dfa7e6
|
7
|
+
data.tar.gz: 53ae4e3e35ef1c7d496539bb2fb4649b79c021a663bddc6411d671ee10ea10ed9ed7af62f1152597ecdd97792f1bc9ea78e495871426bc1592acb607014635b4
|
data/README.md
CHANGED
@@ -51,7 +51,7 @@ type and name in the named case.
|
|
51
51
|
|
52
52
|
***Global*** options are options that are added with the ***add_global*** function and will show up
|
53
53
|
set in the commands results using the ***:global*** symbol. Global options are given on the command
|
54
|
-
line before anything else.
|
54
|
+
line before anything else in the case of positional, but anywhere in the case of named.
|
55
55
|
|
56
56
|
***Shared*** options are options that are added with the command ***add_shared*** function before
|
57
57
|
any commands and are added to all commands.
|
data/lib/nub/commander.rb
CHANGED
@@ -174,7 +174,7 @@ class Commander
|
|
174
174
|
end
|
175
175
|
|
176
176
|
# Returns banner string
|
177
|
-
# @
|
177
|
+
# @return [String] the app's banner
|
178
178
|
def banner
|
179
179
|
version = @version.nil? ? "" : "_v#{@version}"
|
180
180
|
banner = "#{@app}#{version}\n#{'-' * 80}".colorize(:light_yellow)
|
@@ -182,7 +182,7 @@ class Commander
|
|
182
182
|
end
|
183
183
|
|
184
184
|
# Return the app's help string
|
185
|
-
# @
|
185
|
+
# @return [String] the app's help string
|
186
186
|
def help
|
187
187
|
help = @app.nil? ? "" : "#{banner}\n"
|
188
188
|
if !@examples.nil? && !@examples.empty?
|
@@ -201,17 +201,14 @@ class Commander
|
|
201
201
|
|
202
202
|
# Construct the command line parser and parse
|
203
203
|
def parse!
|
204
|
+
cmd_names = @config.map{|x| x.name }
|
204
205
|
|
205
206
|
# Set help if nothing was given
|
206
207
|
ARGV.clear and ARGV << '-h' if ARGV.empty?
|
207
|
-
|
208
|
-
# Process global options
|
209
|
-
#---------------------------------------------------------------------------
|
210
|
-
cmd_names = @config.map{|x| x.name }
|
211
|
-
ARGV.unshift('global') if @config.find{|x| x.name == 'global'}
|
212
208
|
|
213
209
|
# Process command options
|
214
210
|
#---------------------------------------------------------------------------
|
211
|
+
order_globals!
|
215
212
|
loop {
|
216
213
|
break if ARGV.first.nil?
|
217
214
|
|
@@ -275,26 +272,15 @@ class Commander
|
|
275
272
|
# Validate/set named options
|
276
273
|
# --------------------------------------------------------------------
|
277
274
|
# e.g. -s, --skip, --skip=VALUE
|
278
|
-
if opt.
|
279
|
-
|
280
|
-
|
281
|
-
value =
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
# Handle help for the command
|
288
|
-
!puts(help) and exit if cmd.name == 'global' && sym == :help
|
289
|
-
!puts(cmd.help) and exit if sym == :help
|
290
|
-
|
291
|
-
# Collect value
|
292
|
-
if cmd_opt.type == FalseClass
|
293
|
-
value = true if !value
|
294
|
-
elsif !value
|
295
|
-
value = opts.shift
|
296
|
-
end
|
297
|
-
end
|
275
|
+
if (match = match_named(opt, cmd)).hit?
|
276
|
+
sym = match.sym
|
277
|
+
cmd_opt = match.opt
|
278
|
+
value = match.value
|
279
|
+
value = match.flag? || opts.shift if !value
|
280
|
+
|
281
|
+
# Handle help for the command
|
282
|
+
!puts(help) and exit if cmd.name == 'global' && match.sym == :help
|
283
|
+
!puts(cmd.help) and exit if match.sym == :help
|
298
284
|
|
299
285
|
# Validate/set positional options
|
300
286
|
# --------------------------------------------------------------------
|
@@ -309,28 +295,7 @@ class Commander
|
|
309
295
|
|
310
296
|
# Convert value to appropriate type and validate against allowed
|
311
297
|
# --------------------------------------------------------------------
|
312
|
-
|
313
|
-
if cmd_opt.type == String
|
314
|
-
if cmd_opt.allowed.any?
|
315
|
-
!puts("Error: invalid string value '#{value}'!".colorize(:red)) && !puts(cmd.help) and
|
316
|
-
exit if !cmd_opt.allowed.include?(value)
|
317
|
-
end
|
318
|
-
elsif cmd_opt.type == Integer
|
319
|
-
value = value.to_i
|
320
|
-
if cmd_opt.allowed.any?
|
321
|
-
!puts("Error: invalid integer value '#{value}'!".colorize(:red)) && !puts(cmd.help) and
|
322
|
-
exit if !cmd_opt.allowed.include?(value)
|
323
|
-
end
|
324
|
-
elsif cmd_opt.type == Array
|
325
|
-
value = value.split(',')
|
326
|
-
if cmd_opt.allowed.any?
|
327
|
-
value.each{|x|
|
328
|
-
!puts("Error: invalid array value '#{x}'!".colorize(:red)) && !puts(cmd.help) and
|
329
|
-
exit if !cmd_opt.allowed.include?(x)
|
330
|
-
}
|
331
|
-
end
|
332
|
-
end
|
333
|
-
end
|
298
|
+
value = convert_value(value, cmd, cmd_opt)
|
334
299
|
|
335
300
|
# Set option with value
|
336
301
|
# --------------------------------------------------------------------
|
@@ -360,12 +325,110 @@ class Commander
|
|
360
325
|
# Private methods
|
361
326
|
#-----------------------------------------------------------------------------
|
362
327
|
private
|
328
|
+
OptionMatch = Struct.new(:arg, :sym, :value, :opt) do
|
329
|
+
def hit?
|
330
|
+
return !!sym
|
331
|
+
end
|
332
|
+
def flag?
|
333
|
+
return opt.type == FalseClass
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
# Parses the command line, moving all global options to the begining
|
338
|
+
# and inserting the global command
|
339
|
+
def order_globals!
|
340
|
+
if !(global_cmd = @config.find{|x| x.name == 'global'}).nil?
|
341
|
+
ARGV.delete('global')
|
342
|
+
|
343
|
+
# Collect positional and named options from begining
|
344
|
+
globals = ARGV.take_while{|x| !@config.any?{|y| y.name == x}}
|
345
|
+
ARGV.shift(globals.size)
|
346
|
+
|
347
|
+
# Collect named options throughout
|
348
|
+
i = -1
|
349
|
+
cmd = nil
|
350
|
+
while (i += 1) < ARGV.size do
|
351
|
+
|
352
|
+
# Set command and skip command and matching options
|
353
|
+
if !(_cmd = @config.find{|x| x.name == ARGV[i]}).nil?
|
354
|
+
cmd = _cmd; next
|
355
|
+
end
|
356
|
+
next if cmd && match_named(ARGV[i], cmd).hit?
|
357
|
+
|
358
|
+
# Collect global matches
|
359
|
+
if (match = match_named(ARGV[i], global_cmd)).hit?
|
360
|
+
globals << ARGV.delete_at(i)
|
361
|
+
globals << ARGV.delete_at(i) if !match.flag?
|
362
|
+
i -= 1
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
# Re-insert options in correct order at end with command
|
367
|
+
globals.reverse.each{|x| ARGV.unshift(x)}
|
368
|
+
ARGV.unshift('global')
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
# Match the given command line arg with a configured named option
|
373
|
+
# @param opt [String] the command line argument given
|
374
|
+
# @param cmd [Command] configured command to match against
|
375
|
+
# @return [OptionMatch]] struct with some helper functions
|
376
|
+
def match_named(opt, cmd)
|
377
|
+
match = OptionMatch.new(opt)
|
378
|
+
cmd_named_opts = cmd.opts.select{|x| !x.key.nil? }
|
379
|
+
|
380
|
+
if opt.start_with?('-')
|
381
|
+
short = opt[@short_regex, 1]
|
382
|
+
long = opt[@long_regex, 1]
|
383
|
+
match.value = opt[@value_regex, 1]
|
384
|
+
|
385
|
+
# Set symbol converting dashes to underscores for named options
|
386
|
+
if (cmd_opt = cmd_named_opts.find{|x| x.short == short || x.long == long})
|
387
|
+
match.opt = cmd_opt
|
388
|
+
match.sym = cmd_opt.long[2..-1].gsub("-", "_").to_sym
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
return match
|
393
|
+
end
|
394
|
+
|
395
|
+
# Convert the given option value to appropriate type and validate against allowed
|
396
|
+
# @param value [String] type to convert and and check
|
397
|
+
# @param cmd [Command] configured command to reference
|
398
|
+
# @param opt [Option] matching option to validate against
|
399
|
+
# @return [String|Integer|Array] depending on option type
|
400
|
+
def convert_value(value, cmd, opt)
|
401
|
+
if value
|
402
|
+
if opt.type == String
|
403
|
+
if opt.allowed.any?
|
404
|
+
!puts("Error: invalid string value '#{value}'!".colorize(:red)) && !puts(cmd.help) and
|
405
|
+
exit if !opt.allowed.include?(value)
|
406
|
+
end
|
407
|
+
elsif opt.type == Integer
|
408
|
+
value = value.to_i
|
409
|
+
if opt.allowed.any?
|
410
|
+
!puts("Error: invalid integer value '#{value}'!".colorize(:red)) && !puts(cmd.help) and
|
411
|
+
exit if !opt.allowed.include?(value)
|
412
|
+
end
|
413
|
+
elsif opt.type == Array
|
414
|
+
value = value.split(',')
|
415
|
+
if opt.allowed.any?
|
416
|
+
value.each{|x|
|
417
|
+
!puts("Error: invalid array value '#{x}'!".colorize(:red)) && !puts(cmd.help) and
|
418
|
+
exit if !opt.allowed.include?(x)
|
419
|
+
}
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
return value
|
425
|
+
end
|
363
426
|
|
364
427
|
# Add a command to the command list
|
365
428
|
# @param cmd [String] name of the command
|
366
429
|
# @param desc [String] description of the command
|
367
430
|
# @param opts [List] list of command options
|
368
|
-
# @
|
431
|
+
# @return [Command] new command
|
369
432
|
def add_cmd(cmd, desc, options)
|
370
433
|
Log.die("command names must be pure lowercase letters") if cmd =~ /[^a-z]/
|
371
434
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.51
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Crummett
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|