help_parser 8.1.221206 → 9.0.240926
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 +74 -62
- data/lib/help_parser/aliases.rb +2 -2
- data/lib/help_parser/completion.rb +46 -38
- data/lib/help_parser/constants.rb +12 -11
- data/lib/help_parser/exceptions.rb +24 -10
- data/lib/help_parser/k2t2r.rb +7 -7
- data/lib/help_parser/macros.rb +20 -174
- data/lib/help_parser/options.rb +18 -18
- data/lib/help_parser/parsea.rb +3 -3
- data/lib/help_parser/parseh.rb +15 -10
- data/lib/help_parser/parseu.rb +2 -2
- data/lib/help_parser/validate.rb +36 -33
- data/lib/help_parser.rb +4 -4
- metadata +110 -8
- data/LICENSE +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60dd76f994f506e15f1593b7561ee1b23cc59c0cf3cd53cc1140dcbc59b7b0f5
|
4
|
+
data.tar.gz: c113698c66f7790c4977d57c7906dad639774dd315158677091e59c5db188cef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f40ba2d34b2340c12d69812d8554a942dac423a2e5e764ac15d58cf644f978eb937e2104bef8ce288dd79f0875d8bda92998ad692e50ebbe6ff0f5cb6d130ec3
|
7
|
+
data.tar.gz: f12bfbd92bfe9101292598c69ceff2beb81bd92838b975f39d61e15e16fc6268ffb525896f5983186bced970e3e63d4e6a27cbd5d63cad91943a264236b184b4
|
data/README.md
CHANGED
@@ -1,114 +1,126 @@
|
|
1
|
-
# Help Parser
|
1
|
+
# Help Parser IX: Revelations
|
2
2
|
|
3
|
-
* [VERSION
|
3
|
+
* [VERSION 9.0.240926](https://github.com/carlosjhr64/help_parser/releases)
|
4
4
|
* [github](https://www.github.com/carlosjhr64/help_parser)
|
5
5
|
* [rubygems](https://rubygems.org/gems/help_parser)
|
6
6
|
|
7
7
|
## DESCRIPTION:
|
8
8
|
|
9
|
-
|
10
|
-
Do you have your help text?
|
11
|
-
Let's parse!
|
9
|
+
Options parsing based on your help text.
|
12
10
|
|
13
11
|
## INSTALL:
|
14
|
-
|
15
12
|
```console
|
16
13
|
$ gem install help_parser
|
17
14
|
```
|
18
|
-
|
19
15
|
## SYNOPSIS:
|
20
16
|
<!-- The following PREVIEW has been approved for ALL PROGRAMMERS by CarlosJHR64.
|
21
17
|
For the README validator that checks against me lying....
|
22
18
|
```ruby
|
23
|
-
unless File.basename($PROGRAM_NAME) == '
|
19
|
+
unless File.basename($PROGRAM_NAME) == 'revelations'
|
24
20
|
# For example's sake say
|
25
|
-
$PROGRAM_NAME = '
|
21
|
+
$PROGRAM_NAME = 'revelations'
|
26
22
|
# and ARGV is
|
27
|
-
ARGV.concat [
|
28
|
-
# and proceed as if run as:
|
29
|
-
# awesome -\-name=Doe -\-value a b c
|
23
|
+
ARGV.concat ['1,2,3','4,5,6']
|
24
|
+
# and proceed as if run as: `revelations 1,2,3 4,5,6`
|
30
25
|
end
|
31
26
|
```
|
32
27
|
The following gem has been rated
|
33
|
-
| M | Mature |
|
34
|
-
-->
|
35
|
-
|
28
|
+
| M | Mature | -->
|
36
29
|
```ruby
|
37
|
-
|
30
|
+
#!/usr/bin/env ruby
|
31
|
+
require 'help_parser'
|
38
32
|
|
39
|
-
|
33
|
+
VERSION = '1.2.3'
|
34
|
+
OPTIONS = HelpParser[VERSION, <<-HELP]
|
40
35
|
# <= Hash here, parser skips
|
41
|
-
# HelpParser
|
36
|
+
# HelpParser command example #
|
37
|
+
|
38
|
+
One can write any notes on the help text as long as
|
39
|
+
it does not start with a space or a "Keyword:".
|
40
|
+
|
42
41
|
Usage:
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
revelations :options+ [<arg>]
|
43
|
+
revelations :alternate <args=FLOAT>+
|
44
|
+
revelations literal <arg1=WORD> <arg2=WORD>
|
45
|
+
revelations <numbers=CSVI>+
|
46
|
+
|
47
|
+
The ":keyword" refers to a flag in defined in the "Keyword:" section.
|
48
|
+
A "[...]" is an optional part of the usage.
|
49
|
+
A "+" means one or more of it is allowed.
|
50
|
+
|
46
51
|
Options:
|
47
|
-
-v --version
|
48
|
-
-h --help
|
49
|
-
|
50
|
-
--
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
-v --version \t Give version and quit
|
53
|
+
-h --help \t Give help and quit
|
54
|
+
--verbose \t Set $VERBOSE true
|
55
|
+
--debug \t Set $DEBUG true
|
56
|
+
|
57
|
+
The above(version, help, verbose, debug) are built-in options.
|
58
|
+
The tab, "\t", splits the comment from the flags.
|
59
|
+
On its own a flag is set to true, else it's nil.
|
60
|
+
But you can also set a long flag value to a string as allowed by its type.
|
61
|
+
|
62
|
+
-a --all=YN y \t Short, long, typed, and defaulted
|
63
|
+
|
64
|
+
OPTIONS.all at first is nil. If set without a value, it's set to "y"
|
65
|
+
One can set it to to either "n" of "y" as allowed by YN(see below under Types:).
|
66
|
+
|
67
|
+
--stop=NUMBER \t Typed
|
68
|
+
--start=NUMBER 0 \t Typed and defaulted
|
69
|
+
|
56
70
|
--rain
|
57
71
|
--water
|
58
72
|
--wet
|
73
|
+
|
74
|
+
--to_be
|
75
|
+
--not_to_be
|
76
|
+
|
59
77
|
Exclusive:
|
60
|
-
to_be not_to_be
|
78
|
+
to_be not_to_be \t Tells parser these are mutually exclusive keys
|
61
79
|
Inclusive:
|
62
|
-
|
80
|
+
start stop \t Tells parser any of these must include all of these
|
63
81
|
Conditional:
|
64
|
-
rain water wet
|
82
|
+
rain water wet \t Tells parser if first then all
|
83
|
+
\t Note how one can continue the comment as needed
|
84
|
+
|
65
85
|
Alternate:
|
66
|
-
--
|
67
|
-
--
|
86
|
+
--sum
|
87
|
+
--multiply
|
88
|
+
|
68
89
|
Types:
|
69
90
|
WORD /^[A-Za-z]+$/
|
70
|
-
|
71
|
-
INTEGER /^\\d+$/
|
91
|
+
NUMBER /^\\d+$/
|
72
92
|
FLOAT /^\\d+\\.\\d+$/
|
73
93
|
YN /^[YNyn]$/
|
94
|
+
CSVI /^\\d+(,\\d+)*$/
|
74
95
|
# <= Hash here, parser breaks out
|
75
|
-
|
76
|
-
I wouldn't touch that!
|
96
|
+
And now one can freely write whatever....
|
77
97
|
HELP
|
78
98
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
# Macros:
|
84
|
-
HelpParser.strings?(:args) # for OPTIONS.args : Array(String) | Nil
|
85
|
-
HelpParser.int?(:age) # for OPTIONS.age? : Integer | Nil
|
86
|
-
HelpParser.float(:arg) # for options.arg : Float
|
87
|
-
HelpParser.string(:arg1, :arg2, :arg3) # for OPTIONS.arg1, etc : String
|
88
|
-
#=> [:arg1, :arg2, :arg3]
|
89
|
-
|
90
|
-
## If run as:
|
91
|
-
## party --age --date=2020-09-07 touch that
|
92
|
-
OPTIONS.age? #=> 80
|
93
|
-
OPTIONS.age?.class #=> Integer
|
94
|
-
OPTIONS.args? #=> ["touch", "that"]
|
95
|
-
OPTIONS.args?.class #=> Array
|
96
|
-
OPTIONS.arg? and OPTIONS.arg #=> false
|
97
|
-
OPTIONS.arg?.class #=> FalseClass
|
98
|
-
```
|
99
|
+
# Tell HelpParser how to remap the string values:
|
100
|
+
HelpParser.integer(:stop, :start) # HelpParser.map(:stop, :start, map: :to_i)
|
101
|
+
HelpParser.float(:args) # HelpParser.map(:args, map: :to_f)
|
102
|
+
# Also available: HelpParser.rational(*name) = HelpParser.map(*names, map: to_r)
|
99
103
|
|
104
|
+
# Tell HelpParser how to split the string values:
|
105
|
+
HelpParser.split(:numbers, sep: ',', map: :to_i)
|
106
|
+
# Also available: HelpParser.csv(*name) = HelpParser.split(*names)
|
107
|
+
|
108
|
+
# If one runs `revelations 1,2,3 4,5,6`, then:
|
109
|
+
OPTIONS.numbers #=> [[1, 2, 3], [4, 5, 6]]
|
110
|
+
# And everything else is unset:
|
111
|
+
OPTIONS.stop #=> nil
|
112
|
+
```
|
100
113
|
## Features
|
101
114
|
|
102
|
-
* `$DEBUG=true` on --debug
|
103
|
-
* `$VERBOSE=true` on --verbose
|
104
115
|
* -h and --help simultaneously will check help string for errors
|
116
|
+
* `ARGV` setup for `ARGF` when one of the "Types:" given is "ARGF"
|
105
117
|
* `HelpParser::REDTTY[msg]` will red color output `msg` to `$stderr`.
|
106
118
|
|
107
119
|
## LICENSE:
|
108
120
|
|
109
121
|
(The MIT License)
|
110
122
|
|
111
|
-
Copyright (c)
|
123
|
+
Copyright (c) 2024 CarlosJHR64
|
112
124
|
|
113
125
|
Permission is hereby granted, free of charge, to any person obtaining
|
114
126
|
a copy of this software and associated documentation files (the
|
data/lib/help_parser/aliases.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module HelpParser
|
2
2
|
class NoDupHash < Hash
|
3
3
|
def []=(k,v)
|
4
|
-
raise HelpError, MSG[DUP_KEY,k]
|
4
|
+
raise HelpError, MSG[DUP_KEY,k] if key?(k)
|
5
5
|
super
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
class ArgvHash < Hash
|
10
10
|
def []=(k,v)
|
11
|
-
raise UsageError, MSG[DUP_KEY,k] if
|
11
|
+
raise UsageError, MSG[DUP_KEY,k] if key?(k)
|
12
12
|
super
|
13
13
|
end
|
14
14
|
end
|
@@ -3,26 +3,35 @@ module HelpParser
|
|
3
3
|
def initialize(hash, specs)
|
4
4
|
@hash,@specs = hash,specs
|
5
5
|
@cache = NoDupHash.new
|
6
|
-
usage or diagnose
|
6
|
+
usage or diagnose if @specs.key?(USAGE)
|
7
7
|
pad
|
8
|
-
|
8
|
+
if @specs.key?(TYPES)
|
9
|
+
k2t = types
|
10
|
+
handle_argf(k2t) if k2t.detect{|_,v|v=='ARGF'}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Prepare ARGV for ARGF.
|
15
|
+
def handle_argf(k2t)
|
16
|
+
files = @hash.select{|k,_|k2t[k]=='ARGF'}.map{|_,v|v}.flatten
|
17
|
+
e = files.reject{File.exist?_1}.join(', ')
|
18
|
+
raise UsageError, MSG[NOT_EXIST, e] unless e.empty?
|
19
|
+
ARGV.replace files
|
9
20
|
end
|
10
21
|
|
11
22
|
# Which usage does the user's command options match?
|
12
23
|
def usage
|
13
24
|
@specs[USAGE].each do |cmd|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@cache.clear
|
23
|
-
end
|
25
|
+
i = matches(cmd)
|
26
|
+
raise NoMatch unless @hash.size==i
|
27
|
+
@cache.each{|k,v|@hash[k]=v} # Variables
|
28
|
+
return true # Good! Found matching usage.
|
29
|
+
rescue NoMatch
|
30
|
+
next
|
31
|
+
ensure
|
32
|
+
@cache.clear
|
24
33
|
end
|
25
|
-
|
34
|
+
false # Bad! Did not match any of the expected usage.
|
26
35
|
end
|
27
36
|
|
28
37
|
# Diagnose user's usage.
|
@@ -37,7 +46,7 @@ module HelpParser
|
|
37
46
|
end
|
38
47
|
end
|
39
48
|
end
|
40
|
-
typos = @hash.keys.select{
|
49
|
+
typos = @hash.keys.select{_1.is_a?(String) && !dict[_1]}
|
41
50
|
raise UsageError, MSG[UNRECOGNIZED, typos] unless typos.empty?
|
42
51
|
|
43
52
|
raise UsageError, MATCH_USAGE
|
@@ -46,26 +55,25 @@ module HelpParser
|
|
46
55
|
def types
|
47
56
|
t2r,k2t = HelpParser.t2r(@specs),HelpParser.k2t(@specs)
|
48
57
|
@hash.each do |key,value|
|
49
|
-
next unless key.is_a?(String)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
"--#{key}=#{string} !~ #{type}=#{regex.inspect}"
|
62
|
-
end
|
58
|
+
next unless key.is_a?(String) && (type=k2t[key])
|
59
|
+
regex = t2r[type]
|
60
|
+
case value
|
61
|
+
when String
|
62
|
+
unless value=~regex
|
63
|
+
raise UsageError, "--#{key}=#{value} !~ #{type}=#{regex.inspect}"
|
64
|
+
end
|
65
|
+
when Array
|
66
|
+
value.each do |string|
|
67
|
+
unless string=~regex
|
68
|
+
raise UsageError,
|
69
|
+
"--#{key}=#{string} !~ #{type}=#{regex.inspect}"
|
63
70
|
end
|
64
|
-
else
|
65
|
-
raise UsageError, "--#{key} !~ #{type}=#{regex.inspect}"
|
66
71
|
end
|
72
|
+
else
|
73
|
+
raise UsageError, "--#{key} !~ #{type}=#{regex.inspect}"
|
67
74
|
end
|
68
75
|
end
|
76
|
+
k2t
|
69
77
|
end
|
70
78
|
|
71
79
|
def pad
|
@@ -79,12 +87,12 @@ module HelpParser
|
|
79
87
|
if second[0]=='-'
|
80
88
|
i = second.index('=') || 0
|
81
89
|
short,long = first[1],second[2..(i-1)]
|
82
|
-
if @hash.
|
83
|
-
if @hash.
|
90
|
+
if @hash.key?(short)
|
91
|
+
if @hash.key?(long)
|
84
92
|
raise UsageError, MSG[REDUNDANT, short, long]
|
85
93
|
end
|
86
|
-
@hash[long] =
|
87
|
-
elsif value
|
94
|
+
@hash[long] = default.nil? ? true : default
|
95
|
+
elsif (value=@hash[long])
|
88
96
|
@hash[short] = true
|
89
97
|
if value==true && !default.nil?
|
90
98
|
@hash.delete(long) # ArgvHash reset
|
@@ -117,7 +125,7 @@ module HelpParser
|
|
117
125
|
# OK, NEVERMIND!
|
118
126
|
end
|
119
127
|
next
|
120
|
-
elsif m=FLAG_GROUP.match
|
128
|
+
elsif (m=FLAG_GROUP.match token)
|
121
129
|
group,plus = m[:k],m[:p]
|
122
130
|
key = keys[i]
|
123
131
|
raise NoMatch unless key.is_a? String
|
@@ -126,11 +134,11 @@ module HelpParser
|
|
126
134
|
unless plus.nil?
|
127
135
|
loop do
|
128
136
|
key = keys[i+1]
|
129
|
-
break unless key.is_a?(String)
|
137
|
+
break unless key.is_a?(String) && list.include?(key)
|
130
138
|
i+=1
|
131
139
|
end
|
132
140
|
end
|
133
|
-
elsif m=VARIABLE.match(token)
|
141
|
+
elsif (m=VARIABLE.match(token))
|
134
142
|
key = keys[i]
|
135
143
|
raise NoMatch unless key.is_a?(Integer)
|
136
144
|
variable,plus = m[:k],m[:p]
|
@@ -153,7 +161,7 @@ module HelpParser
|
|
153
161
|
end
|
154
162
|
i += 1
|
155
163
|
end
|
156
|
-
|
164
|
+
i
|
157
165
|
end
|
158
166
|
end
|
159
167
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module HelpParser
|
2
|
-
VSN = [
|
3
|
-
HLP = [
|
2
|
+
VSN = %w[v version]
|
3
|
+
HLP = %w[h help]
|
4
4
|
VRBS,DBG = 'verbose','debug'
|
5
5
|
|
6
6
|
# reserved name
|
@@ -16,19 +16,19 @@ module HelpParser
|
|
16
16
|
SECTION_NAME = /^(?<name>[A-Z]\w+):$/
|
17
17
|
|
18
18
|
# usage
|
19
|
-
FLAG =
|
19
|
+
FLAG = /^--?(?<k>\w+)$/
|
20
20
|
LITERAL = /^(?<k>\w[\w.-]*:?)$/
|
21
21
|
VARIABLE = /^<(?<k>\w+)(=(?<t>[A-Z]+))?>(?<p>[+])?$/
|
22
22
|
FLAG_GROUP = /^:(?<k>\w+)(?<p>[+])?$/
|
23
23
|
|
24
24
|
# spec --?w+
|
25
|
-
SHORT =
|
26
|
-
LONG =
|
25
|
+
SHORT = /^-(?<s>\w)$/
|
26
|
+
LONG = /^--(?<k>\w+)(=(?<t>[A-Z]+))?(,?\s+(?<d>[^-\s]\S*))?$/
|
27
27
|
|
28
28
|
# spec -w,? --w+
|
29
|
-
SHORT_LONG =
|
29
|
+
SHORT_LONG = /^-(?<s>\w),?\s+--(?<k>\w+)$/
|
30
30
|
SHORT_LONG_DEFAULT =
|
31
|
-
|
31
|
+
/^-(?<s>\w),?\s+--(?<k>\w+)(=(?<t>[A-Z]+))?,?\s+(?<d>\S*)$/
|
32
32
|
|
33
33
|
# spec W+ /~/
|
34
34
|
TYPE_DEF = /^(?<t>[A-Z]+),?\s+\/(?<r>\S+)\/$/
|
@@ -73,15 +73,16 @@ module HelpParser
|
|
73
73
|
NOT_FLOATS = 'Not all Floats'
|
74
74
|
NOT_INTEGER = 'Not an Integer'
|
75
75
|
NOT_INTEGERS = 'Not all Integers'
|
76
|
+
NOT_EXIST = 'Does not exist'
|
76
77
|
# error messages, full:
|
77
78
|
NO_MATCH = 'Software Error: NoMatch was not caught by HelpParser.'
|
78
79
|
MATCH_USAGE = 'Please match usage.'
|
79
80
|
EXTRANEOUS_SPACES = 'Extraneous spaces in help.'
|
80
81
|
|
81
82
|
# lambda utilities
|
82
|
-
MSG =
|
83
|
-
F2K =
|
84
|
-
REDTTY = lambda
|
83
|
+
MSG = ->(msg,*keys){"#{msg}: #{keys.join(' ')}"}
|
84
|
+
F2K = ->(f){f[1]=='-' ? f[2..((f.index('=')||0)-1)] : f[1]}
|
85
|
+
REDTTY = lambda do |msg,out=$stderr|
|
85
86
|
out.tty? ? out.puts("\033[0;31m#{msg}\033[0m"): out.puts(msg)
|
86
|
-
|
87
|
+
end
|
87
88
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module HelpParser
|
2
2
|
class HelpParserException < Exception
|
3
|
-
def _init
|
3
|
+
def _init
|
4
|
+
@code = 1
|
5
|
+
end
|
4
6
|
|
5
7
|
# Must give message
|
6
8
|
def initialize(message)
|
@@ -9,35 +11,45 @@ module HelpParser
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def exit
|
12
|
-
if @code
|
13
|
-
REDTTY[
|
14
|
+
if @code.positive?
|
15
|
+
REDTTY[message]
|
14
16
|
else
|
15
|
-
$stdout.puts
|
17
|
+
$stdout.puts message
|
16
18
|
end
|
17
19
|
Kernel.exit @code
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
23
|
class VersionException < HelpParserException
|
22
|
-
def _init
|
24
|
+
def _init
|
25
|
+
@code = 0
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
class HelpException < HelpParserException
|
26
|
-
def _init
|
30
|
+
def _init
|
31
|
+
@code = 0
|
32
|
+
end
|
27
33
|
end
|
28
34
|
|
29
35
|
class UsageError < HelpParserException
|
30
|
-
def _init
|
36
|
+
def _init
|
37
|
+
@code = EX_USAGE
|
38
|
+
end
|
31
39
|
end
|
32
40
|
|
33
41
|
class SoftwareError < HelpParserException
|
34
42
|
# Stuff that should not happen
|
35
|
-
def _init
|
43
|
+
def _init
|
44
|
+
@code = EX_SOFTWARE
|
45
|
+
end
|
36
46
|
end
|
37
47
|
|
38
48
|
class NoMatch < HelpParserException
|
39
49
|
# used to short-circuit out
|
40
|
-
def _init
|
50
|
+
def _init
|
51
|
+
@code = EX_SOFTWARE
|
52
|
+
end
|
41
53
|
|
42
54
|
# Forces it's own message
|
43
55
|
def initialize
|
@@ -46,6 +58,8 @@ module HelpParser
|
|
46
58
|
end
|
47
59
|
|
48
60
|
class HelpError < HelpParserException
|
49
|
-
def _init
|
61
|
+
def _init
|
62
|
+
@code = EX_CONFIG
|
63
|
+
end
|
50
64
|
end
|
51
65
|
end
|
data/lib/help_parser/k2t2r.rb
CHANGED
@@ -3,14 +3,14 @@ module HelpParser
|
|
3
3
|
def self.k2t(specs)
|
4
4
|
k2t = NoDupHash.new
|
5
5
|
# If specs section is not a RESERVED section, it's an options list.
|
6
|
-
tokens = specs.select{|k,
|
6
|
+
tokens = specs.select{|k,_| k==USAGE or !RESERVED.include?(k)}
|
7
7
|
# Tokens associating a key to a type.
|
8
8
|
.values.flatten.select{|v|v.include?('=')}
|
9
9
|
tokens.each do |token|
|
10
|
-
if match = VARIABLE.match(token) || LONG.match(token)
|
10
|
+
if (match = VARIABLE.match(token) || LONG.match(token))
|
11
11
|
name, type = match[:k], match[:t]
|
12
|
-
if _=k2t[name]
|
13
|
-
raise HelpError, MSG[INCONSISTENT,name,type,_]
|
12
|
+
if (_=k2t[name])
|
13
|
+
raise HelpError, MSG[INCONSISTENT,name,type,_] unless type==_
|
14
14
|
else
|
15
15
|
k2t[name] = type
|
16
16
|
end
|
@@ -19,12 +19,12 @@ module HelpParser
|
|
19
19
|
raise SoftwareError, MSG[UNEXPECTED,token]
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
k2t
|
23
23
|
end
|
24
24
|
|
25
25
|
# t2r is an acronym for "type to regexp"
|
26
26
|
def self.t2r(specs)
|
27
|
-
if types
|
27
|
+
if (types=specs[TYPES])
|
28
28
|
t2r = NoDupHash.new
|
29
29
|
types.each do |pair|
|
30
30
|
type, pattern = *pair
|
@@ -36,6 +36,6 @@ module HelpParser
|
|
36
36
|
end
|
37
37
|
return t2r
|
38
38
|
end
|
39
|
-
|
39
|
+
nil
|
40
40
|
end
|
41
41
|
end
|
data/lib/help_parser/macros.rb
CHANGED
@@ -1,183 +1,29 @@
|
|
1
1
|
module HelpParser
|
2
|
-
def self.
|
2
|
+
def self.map(*names, map:)
|
3
3
|
names.each do |name|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
CODE
|
13
|
-
eval code
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.string?(*names)
|
18
|
-
names.each do |name|
|
19
|
-
code = <<-CODE
|
20
|
-
class Options
|
21
|
-
def #{name}?
|
22
|
-
s = @hash['#{name}']
|
23
|
-
raise UsageError, MSG[NOT_STRING,'#{name}'] unless s.nil? ||
|
24
|
-
s.is_a?(String)
|
25
|
-
return s
|
26
|
-
end
|
27
|
-
end
|
28
|
-
CODE
|
29
|
-
eval code
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.strings(*names)
|
34
|
-
names.each do |name|
|
35
|
-
code = <<-CODE
|
36
|
-
class Options
|
37
|
-
def #{name}
|
38
|
-
a = @hash['#{name}']
|
39
|
-
raise UsageError, MSG[NOT_STRINGS,'#{name}'] unless a.is_a?(Array)
|
40
|
-
return a
|
41
|
-
end
|
42
|
-
end
|
43
|
-
CODE
|
44
|
-
eval code
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.strings?(*names)
|
49
|
-
names.each do |name|
|
50
|
-
code = <<-CODE
|
51
|
-
class Options
|
52
|
-
def #{name}?
|
53
|
-
a = @hash['#{name}']
|
54
|
-
raise UsageError, MSG[NOT_STRINGS,'#{name}'] unless a.nil? ||
|
55
|
-
a.is_a?(Array)
|
56
|
-
return a
|
57
|
-
end
|
58
|
-
end
|
59
|
-
CODE
|
60
|
-
eval code
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.float(*names)
|
65
|
-
names.each do |name|
|
66
|
-
code = <<-CODE
|
67
|
-
class Options
|
68
|
-
def #{name}
|
69
|
-
@hash['#{name}']&.to_f or raise
|
70
|
-
rescue
|
71
|
-
raise UsageError, MSG[NOT_FLOAT,'#{name}']
|
72
|
-
end
|
73
|
-
end
|
74
|
-
CODE
|
75
|
-
eval code
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.float?(*names)
|
80
|
-
names.each do |name|
|
81
|
-
code = <<-CODE
|
82
|
-
class Options
|
83
|
-
def #{name}?
|
84
|
-
@hash['#{name}']&.to_f
|
85
|
-
rescue
|
86
|
-
raise UsageError, MSG[NOT_FLOAT,'#{name}']
|
87
|
-
end
|
88
|
-
end
|
89
|
-
CODE
|
90
|
-
eval code
|
4
|
+
Options.instance_eval do
|
5
|
+
define_method(name) do
|
6
|
+
v = @hash[name.to_s] and (v.is_a?(Array) ?
|
7
|
+
v.map(&map) :
|
8
|
+
v.method(map).call)
|
9
|
+
end
|
10
|
+
end
|
91
11
|
end
|
92
12
|
end
|
13
|
+
def self.integer(*names) = HelpParser.map(*names, map: :to_i)
|
14
|
+
def self.float(*names) = HelpParser.map(*names, map: :to_f)
|
15
|
+
def self.rational(*names) = HelpParser.map(*names, map: :to_r)
|
93
16
|
|
94
|
-
def self.
|
17
|
+
def self.split(*names, sep:, map:)
|
95
18
|
names.each do |name|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
104
|
-
CODE
|
105
|
-
eval code
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def self.floats?(*names)
|
110
|
-
names.each do |name|
|
111
|
-
code = <<-CODE
|
112
|
-
class Options
|
113
|
-
def #{name}?
|
114
|
-
@hash['#{name}']&.map{_1.to_f}
|
115
|
-
rescue
|
116
|
-
raise UsageError, MSG[NOT_FLOATS,'#{name}']
|
117
|
-
end
|
118
|
-
end
|
119
|
-
CODE
|
120
|
-
eval code
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def self.int(*names)
|
125
|
-
names.each do |name|
|
126
|
-
code = <<-CODE
|
127
|
-
class Options
|
128
|
-
def #{name}
|
129
|
-
@hash['#{name}']&.to_i or raise
|
130
|
-
rescue
|
131
|
-
raise UsageError, MSG[NOT_INTEGER,'#{name}']
|
132
|
-
end
|
133
|
-
end
|
134
|
-
CODE
|
135
|
-
eval code
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def self.int?(*names)
|
140
|
-
names.each do |name|
|
141
|
-
code = <<-CODE
|
142
|
-
class Options
|
143
|
-
def #{name}?
|
144
|
-
@hash['#{name}']&.to_i
|
145
|
-
rescue
|
146
|
-
raise UsageError, MSG[NOT_INTEGER,'#{name}']
|
147
|
-
end
|
148
|
-
end
|
149
|
-
CODE
|
150
|
-
eval code
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def self.ints(*names)
|
155
|
-
names.each do |name|
|
156
|
-
code = <<-CODE
|
157
|
-
class Options
|
158
|
-
def #{name}
|
159
|
-
@hash['#{name}'].map{_1.to_i}
|
160
|
-
rescue
|
161
|
-
raise UsageError, MSG[NOT_INTEGERS,'#{name}']
|
162
|
-
end
|
163
|
-
end
|
164
|
-
CODE
|
165
|
-
eval code
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
def self.ints?(*names)
|
170
|
-
names.each do |name|
|
171
|
-
code = <<-CODE
|
172
|
-
class Options
|
173
|
-
def #{name}?
|
174
|
-
@hash['#{name}']&.map{_1.to_i}
|
175
|
-
rescue
|
176
|
-
raise UsageError, MSG[NOT_INTEGERS,'#{name}']
|
177
|
-
end
|
178
|
-
end
|
179
|
-
CODE
|
180
|
-
eval code
|
19
|
+
Options.instance_eval do
|
20
|
+
define_method(name) do
|
21
|
+
v = @hash[name.to_s] and (v.is_a?(Array) ?
|
22
|
+
v.map{_1.split(sep).map(&map)} :
|
23
|
+
v.split(sep).map(&map))
|
24
|
+
end
|
25
|
+
end
|
181
26
|
end
|
182
27
|
end
|
28
|
+
def self.csv(*names) = HelpParser.split(*names, sep: ',', map: :strip)
|
183
29
|
end
|
data/lib/help_parser/options.rb
CHANGED
@@ -2,34 +2,35 @@ module HelpParser
|
|
2
2
|
class Options
|
3
3
|
def initialize(version, help, argv)
|
4
4
|
@hash = HelpParser.parsea(argv)
|
5
|
-
if version && VSN.any?{@hash.
|
5
|
+
if version && VSN.any?{@hash.key? _1}
|
6
6
|
# -v or --version
|
7
|
-
raise VersionException, version
|
7
|
+
raise VersionException, String(version)
|
8
8
|
end
|
9
9
|
if help
|
10
|
+
help = String(help)
|
10
11
|
if HLP.any?{@hash.key? _1}
|
11
|
-
HelpParser.parseh(help, validate: true)
|
12
|
+
HelpParser.parseh(help, validate: true) if HLP.all?{@hash.key? _1}
|
12
13
|
raise HelpException, help
|
13
14
|
end
|
14
15
|
specs = HelpParser.parseh(help)
|
15
16
|
Completion.new(@hash, specs)
|
16
|
-
if exclusive=specs[EXCLUSIVE]
|
17
|
+
if (exclusive=specs[EXCLUSIVE])
|
17
18
|
exclusive.each do |x|
|
18
19
|
count = x.count{@hash.key? _1}
|
19
20
|
raise HelpParser::UsageError, MSG[EXCLUSIVE_KEYS,*x] if count > 1
|
20
21
|
end
|
21
22
|
end
|
22
|
-
if inclusive=specs[INCLUSIVE]
|
23
|
+
if (inclusive=specs[INCLUSIVE])
|
23
24
|
inclusive.each do |i|
|
24
25
|
count = i.count{@hash.key? _1}
|
25
|
-
unless count
|
26
|
+
unless count.zero? || count==i.length
|
26
27
|
raise HelpParser::UsageError, MSG[INCLUSIVE_KEYS,*i]
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
30
|
-
if conditional=specs[CONDITIONAL]
|
31
|
+
if (conditional=specs[CONDITIONAL])
|
31
32
|
conditional.each do |c|
|
32
|
-
if @hash.key?
|
33
|
+
if @hash.key?(c[0]) && !c.all?{@hash.key? _1}
|
33
34
|
raise HelpParser::UsageError, MSG[CONDITIONAL_KEYS,*c]
|
34
35
|
end
|
35
36
|
end
|
@@ -47,17 +48,16 @@ module HelpParser
|
|
47
48
|
@hash[k]
|
48
49
|
end
|
49
50
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
else
|
59
|
-
@hash[m]
|
51
|
+
def respond_to_missing?(m, include_all=false)
|
52
|
+
m[-1]=='!' ? super : true
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_missing(m, *args, &block)
|
56
|
+
super unless respond_to_missing?(m)
|
57
|
+
unless args.empty? && block.nil?
|
58
|
+
raise ArgumentError, 'expected neither args nor block'
|
60
59
|
end
|
60
|
+
m[-1]=='?' ? @hash.key?(m[0..-2].to_s) : @hash[m.to_s]
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
data/lib/help_parser/parsea.rb
CHANGED
@@ -7,7 +7,7 @@ module HelpParser
|
|
7
7
|
break if a.size==1 # '-' quits argv processing
|
8
8
|
if a[1]=='-'
|
9
9
|
break if a.size==2 # '--' also quits argv processing
|
10
|
-
s = a[2
|
10
|
+
s = a[2..]
|
11
11
|
if s.include?('=')
|
12
12
|
k,v = s.split('=',2)
|
13
13
|
hsh[k] = v
|
@@ -15,7 +15,7 @@ module HelpParser
|
|
15
15
|
hsh[s] = true
|
16
16
|
end
|
17
17
|
else
|
18
|
-
a.chars[1
|
18
|
+
a.chars[1..].each do |c|
|
19
19
|
hsh[c] = true
|
20
20
|
end
|
21
21
|
end
|
@@ -24,6 +24,6 @@ module HelpParser
|
|
24
24
|
n += 1
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
27
|
+
hsh
|
28
28
|
end
|
29
29
|
end
|
data/lib/help_parser/parseh.rb
CHANGED
@@ -4,15 +4,18 @@ module HelpParser
|
|
4
4
|
help.each_line do |line|
|
5
5
|
line.chomp!
|
6
6
|
next if line==''
|
7
|
-
if md
|
7
|
+
if (md=SECTION_NAME.match(line))
|
8
8
|
name = md[:name].downcase
|
9
9
|
specs[name] = []
|
10
10
|
else
|
11
11
|
next if name==''
|
12
12
|
break if line[0]=='#'
|
13
|
-
next
|
14
|
-
spec =
|
15
|
-
|
13
|
+
next unless line[0]==' '
|
14
|
+
spec,comment = line.split("\t", 2).map(&:strip)
|
15
|
+
if spec.empty?
|
16
|
+
raise HelpError, EXTRANEOUS_SPACES if validate && comment.to_s.empty?
|
17
|
+
next
|
18
|
+
end
|
16
19
|
case name
|
17
20
|
when USAGE
|
18
21
|
Validate.balanced_brackets(spec.chars) if validate
|
@@ -20,29 +23,31 @@ module HelpParser
|
|
20
23
|
Validate.usage_tokens(tokens) if validate
|
21
24
|
specs[USAGE].push tokens
|
22
25
|
when TYPES
|
23
|
-
if validate
|
26
|
+
if validate && !TYPE_DEF.match?(spec)
|
24
27
|
raise HelpError, MSG[UNRECOGNIZED_TYPE,spec]
|
25
28
|
end
|
26
29
|
specs[TYPES].push spec.split(CSV)
|
27
30
|
when *FLAG_CLUMPS # EXCLUSIVE,INCLUSIVE,CONDITIONAL,...
|
28
|
-
if validate
|
31
|
+
if validate && !X_DEF.match?(spec)
|
29
32
|
raise HelpError, MSG[UNRECOGNIZED_X,spec]
|
30
33
|
end
|
31
34
|
specs[name].push spec.split(CSV)
|
32
35
|
else
|
33
|
-
|
34
|
-
|
36
|
+
if validate &&
|
37
|
+
[SHORT, LONG, SHORT_LONG, SHORT_LONG_DEFAULT].none?{_1=~spec}
|
38
|
+
raise HelpError, MSG[UNRECOGNIZED_OPTION,spec]
|
39
|
+
end
|
35
40
|
specs[name].push spec.split(CSV)
|
36
41
|
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
if validate
|
40
45
|
Validate.usage_specs(specs)
|
41
|
-
if t2r
|
46
|
+
if (t2r=HelpParser.t2r(specs))
|
42
47
|
k2t = HelpParser.k2t(specs)
|
43
48
|
Validate.k2t2r(specs, k2t, t2r)
|
44
49
|
end
|
45
50
|
end
|
46
|
-
|
51
|
+
specs
|
47
52
|
end
|
48
53
|
end
|
data/lib/help_parser/parseu.rb
CHANGED
@@ -5,7 +5,7 @@ module HelpParser
|
|
5
5
|
# Tokens := Array(Token|Tokens)
|
6
6
|
def self.parseu(chars)
|
7
7
|
tokens,token = [],''
|
8
|
-
while c
|
8
|
+
while (c=chars.shift)
|
9
9
|
case c
|
10
10
|
when ' ','[',']'
|
11
11
|
unless token==''
|
@@ -19,6 +19,6 @@ module HelpParser
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
tokens.push(token) unless token==''
|
22
|
-
|
22
|
+
tokens
|
23
23
|
end
|
24
24
|
end
|
data/lib/help_parser/validate.rb
CHANGED
@@ -3,14 +3,10 @@ module Validate
|
|
3
3
|
def self.balanced_brackets(chars)
|
4
4
|
count = 0
|
5
5
|
chars.each do |c|
|
6
|
-
|
7
|
-
|
8
|
-
elsif c==']'
|
9
|
-
count -= 1
|
10
|
-
end
|
11
|
-
break if count<0
|
6
|
+
c=='[' && (count+=1) or c==']' && (count-=1)
|
7
|
+
break if count.negative?
|
12
8
|
end
|
13
|
-
raise HelpError, MSG[UNBALANCED,chars.join] unless count
|
9
|
+
raise HelpError, MSG[UNBALANCED,chars.join] unless count.zero?
|
14
10
|
end
|
15
11
|
|
16
12
|
def self.usage_tokens(tokens)
|
@@ -18,7 +14,7 @@ module Validate
|
|
18
14
|
tokens.flatten.each do |token|
|
19
15
|
raise HelpError, MSG[UNRECOGNIZED_TOKEN,token] unless
|
20
16
|
[FLAG,LITERAL,VARIABLE,FLAG_GROUP]
|
21
|
-
.detect{_=token.match
|
17
|
+
.detect{(_=token.match _1) && words.push(_[:k])}
|
22
18
|
end
|
23
19
|
words.each_with_index do |word,i|
|
24
20
|
raise HelpError, MSG[DUP_WORD,word] unless i==words.rindex(word)
|
@@ -26,40 +22,47 @@ module Validate
|
|
26
22
|
end
|
27
23
|
|
28
24
|
def self.usage_specs(specs)
|
29
|
-
flags = specs.
|
30
|
-
|
25
|
+
flags = specs.except(*RESERVED).values.flatten
|
26
|
+
.select{_1[0]=='-'}.map{F2K[_1]}
|
31
27
|
FLAG_CLUMPS.each do |k|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
28
|
+
next unless (a=specs[k])
|
29
|
+
seen = {}
|
30
|
+
a.each do |xs|
|
31
|
+
k = xs.sort.join(' ').to_sym
|
32
|
+
if seen[k] || xs.length!=xs.uniq.length
|
33
|
+
raise HelpError, MSG[DUP_X,k]
|
34
|
+
end
|
35
|
+
seen[k] = true
|
36
|
+
xs.each do |x|
|
37
|
+
raise HelpError, MSG[UNSEEN_FLAG, x] unless flags.include?(x)
|
43
38
|
end
|
44
39
|
end
|
45
40
|
end
|
46
41
|
flags.each_with_index do |flag,i|
|
47
42
|
raise HelpError, MSG[DUP_FLAG,flag] unless i==flags.rindex(flag)
|
48
|
-
end
|
49
|
-
group = []
|
43
|
+
end
|
44
|
+
group,var = [],{}
|
50
45
|
specs_usage = specs[USAGE]
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
46
|
+
specs_usage&.flatten&.each do |token|
|
47
|
+
case token
|
48
|
+
when VARIABLE
|
49
|
+
key,bool = $~[:k],$~[:p].nil?
|
50
|
+
if var.key? key
|
51
|
+
unless var[key]==bool
|
52
|
+
raise HelpError, MSG[INCONSISTENT,"<#{key}>","<#{key}>+"]
|
53
|
+
end
|
54
|
+
else
|
55
|
+
var[key]=bool
|
57
56
|
end
|
57
|
+
when FLAG_GROUP
|
58
|
+
key = $~[:k]
|
59
|
+
raise HelpError, MSG[UNDEFINED_SECTION,key] unless specs[key]
|
60
|
+
group.push(key)
|
58
61
|
end
|
59
62
|
end
|
60
63
|
specs.each do |key,tokens|
|
61
|
-
raise HelpError, MSG[MISSING_CASES,key]
|
62
|
-
next if specs_usage.nil?
|
64
|
+
raise HelpError, MSG[MISSING_CASES,key] if tokens.empty?
|
65
|
+
next if specs_usage.nil? || RESERVED.include?(key)
|
63
66
|
raise HelpError, MSG[MISSING_USAGE,key] unless group.include?(key)
|
64
67
|
end
|
65
68
|
end
|
@@ -67,7 +70,7 @@ module Validate
|
|
67
70
|
def self.k2t2r(specs, k2t, t2r)
|
68
71
|
a,b = k2t.values.uniq.sort,t2r.keys.sort
|
69
72
|
unless a==b
|
70
|
-
c = (a+b).uniq.
|
73
|
+
c = (a+b).uniq.reject{|x|a.include?(x) && b.include?(x)}
|
71
74
|
raise HelpError, MSG[UNCOMPLETED_TYPES,c.join(',')]
|
72
75
|
end
|
73
76
|
specs.each do |section,tokens|
|
@@ -80,7 +83,7 @@ module Validate
|
|
80
83
|
i = long_type.index('=')
|
81
84
|
next if i.nil?
|
82
85
|
long = long_type[2..(i-1)]
|
83
|
-
type = long_type[(i+1)
|
86
|
+
type = long_type[(i+1)..]
|
84
87
|
regex = t2r[type]
|
85
88
|
unless regex=~default
|
86
89
|
raise HelpError, MSG[BAD_DEFAULT,long,default,type,regex.inspect]
|
data/lib/help_parser.rb
CHANGED
@@ -10,7 +10,7 @@ require_relative 'help_parser/options'
|
|
10
10
|
require_relative 'help_parser/macros'
|
11
11
|
|
12
12
|
module HelpParser
|
13
|
-
VERSION = '
|
13
|
+
VERSION = '9.0.240926'
|
14
14
|
autoload :Validate, 'help_parser/validate'
|
15
15
|
|
16
16
|
def self.[](
|
@@ -18,10 +18,10 @@ module HelpParser
|
|
18
18
|
help = nil,
|
19
19
|
argv = [File.basename($0)]+ARGV)
|
20
20
|
Options.new(version, help, argv)
|
21
|
-
rescue HelpParserException =>
|
22
|
-
|
21
|
+
rescue HelpParserException => e
|
22
|
+
e.exit
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
# Requires:
|
27
|
-
|
27
|
+
# `ruby`
|
metadata
CHANGED
@@ -1,22 +1,123 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: help_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 9.0.240926
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- CarlosJHR64
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2024-09-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.1.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: cucumber
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '9.2'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 9.2.0
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '9.2'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 9.2.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: parser
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.3'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 3.3.5
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.3'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 3.3.5
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rubocop
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '1.66'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.66.1
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.66'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 1.66.1
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: test-unit
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '3.6'
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 3.6.2
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '3.6'
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 3.6.2
|
113
|
+
description: 'Options parsing based on your help text.
|
114
|
+
|
115
|
+
'
|
14
116
|
email: carlosjhr64@gmail.com
|
15
117
|
executables: []
|
16
118
|
extensions: []
|
17
119
|
extra_rdoc_files: []
|
18
120
|
files:
|
19
|
-
- LICENSE
|
20
121
|
- README.md
|
21
122
|
- lib/help_parser.rb
|
22
123
|
- lib/help_parser/aliases.rb
|
@@ -49,9 +150,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
150
|
- !ruby/object:Gem::Version
|
50
151
|
version: '0'
|
51
152
|
requirements:
|
52
|
-
- '
|
53
|
-
|
153
|
+
- 'git: 2.30'
|
154
|
+
- 'ruby: 3.3'
|
155
|
+
rubygems_version: 3.5.19
|
54
156
|
signing_key:
|
55
157
|
specification_version: 4
|
56
|
-
summary:
|
158
|
+
summary: Options parsing based on your help text.
|
57
159
|
test_files: []
|
data/LICENSE
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright (c) 2017 carlosjhr64
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
13
|
-
all copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|