help_parser 8.1.221206 → 9.0.240926
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|