help_parser 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/README.md +42 -130
- data/lib/help_parser.rb +34 -6
- data/lib/help_parser/aliases.rb +19 -0
- data/lib/help_parser/completion.rb +135 -0
- data/lib/help_parser/constants.rb +17 -69
- data/lib/help_parser/exceptions.rb +51 -0
- data/lib/help_parser/k2t2r.rb +33 -0
- data/lib/help_parser/macros.rb +199 -0
- data/lib/help_parser/options.rb +40 -0
- data/lib/help_parser/parsea.rb +29 -0
- data/lib/help_parser/parseh.rb +29 -0
- data/lib/help_parser/parseu.rb +28 -0
- data/lib/help_parser/validations.rb +98 -0
- metadata +22 -10
- data/lib/help_parser/help_parser.rb +0 -99
- data/lib/help_parser/pattern.rb +0 -140
- data/lib/help_parser/usage.rb +0 -100
metadata
CHANGED
@@ -1,29 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: help_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- carlosjhr64
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
13
|
+
description: |
|
14
|
+
All help is about to get parsed...
|
15
|
+
Again!!!
|
14
16
|
|
15
|
-
|
17
|
+
And this time,
|
18
|
+
the battle between complexity and simplicity
|
19
|
+
has as familiar text.
|
16
20
|
email: carlosjhr64@gmail.com
|
17
21
|
executables: []
|
18
22
|
extensions: []
|
19
23
|
extra_rdoc_files: []
|
20
24
|
files:
|
25
|
+
- LICENSE
|
21
26
|
- README.md
|
22
27
|
- lib/help_parser.rb
|
28
|
+
- lib/help_parser/aliases.rb
|
29
|
+
- lib/help_parser/completion.rb
|
23
30
|
- lib/help_parser/constants.rb
|
24
|
-
- lib/help_parser/
|
25
|
-
- lib/help_parser/
|
26
|
-
- lib/help_parser/
|
31
|
+
- lib/help_parser/exceptions.rb
|
32
|
+
- lib/help_parser/k2t2r.rb
|
33
|
+
- lib/help_parser/macros.rb
|
34
|
+
- lib/help_parser/options.rb
|
35
|
+
- lib/help_parser/parsea.rb
|
36
|
+
- lib/help_parser/parseh.rb
|
37
|
+
- lib/help_parser/parseu.rb
|
38
|
+
- lib/help_parser/validations.rb
|
27
39
|
homepage: https://github.com/carlosjhr64/help_parser
|
28
40
|
licenses:
|
29
41
|
- MIT
|
@@ -43,10 +55,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
55
|
- !ruby/object:Gem::Version
|
44
56
|
version: '0'
|
45
57
|
requirements:
|
46
|
-
- 'ruby: ruby 2.4.
|
58
|
+
- 'ruby: ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]'
|
47
59
|
rubyforge_project:
|
48
|
-
rubygems_version: 2.6.
|
60
|
+
rubygems_version: 2.6.11
|
49
61
|
signing_key:
|
50
62
|
specification_version: 4
|
51
|
-
summary:
|
63
|
+
summary: All help is about to get parsed... Again!!!
|
52
64
|
test_files: []
|
@@ -1,99 +0,0 @@
|
|
1
|
-
module HELP_PARSER
|
2
|
-
|
3
|
-
# HelpParser should not alter argv
|
4
|
-
class HelpParser < BasicObject
|
5
|
-
USAGE_ERROR = lambda do |msg|
|
6
|
-
::Kernel::raise ::HELP_PARSER::UsageError,msg
|
7
|
-
end
|
8
|
-
|
9
|
-
Ms,Es = ::HELP_PARSER::M.to_sym, ::HELP_PARSER::E.to_sym
|
10
|
-
VALIDATE_KEY = lambda do |hsh,k|
|
11
|
-
USAGE_ERROR[DUP_KEY+k.to_s] if hsh.key?(k)
|
12
|
-
USAGE_ERROR[ILLEGAL_KEY+k.to_s] if Ms==k or Es==k
|
13
|
-
end
|
14
|
-
|
15
|
-
PARSE_ARGV = lambda do |argv|
|
16
|
-
hsh,n,i = {},0,0
|
17
|
-
argv.each do |a|
|
18
|
-
if a[0]==M # '-'
|
19
|
-
break if a==M
|
20
|
-
if a[1]==M
|
21
|
-
s,v = a.split(E,2) # split by '='
|
22
|
-
k = s[2..-1].to_sym
|
23
|
-
VALIDATE_KEY[hsh,k]
|
24
|
-
hsh[k] = (v)? v : true
|
25
|
-
else
|
26
|
-
# set each flag
|
27
|
-
a[1..-1].chars.each do |c|
|
28
|
-
k = c.to_sym
|
29
|
-
VALIDATE_KEY[hsh,k]
|
30
|
-
hsh[k]=true
|
31
|
-
end
|
32
|
-
end
|
33
|
-
else
|
34
|
-
# the nth argument
|
35
|
-
hsh[n] = a
|
36
|
-
n+=1
|
37
|
-
end
|
38
|
-
i+=1
|
39
|
-
end
|
40
|
-
return hsh
|
41
|
-
end
|
42
|
-
|
43
|
-
def initialize(version=nil, help=nil, argv=nil)
|
44
|
-
begin
|
45
|
-
hsh = PARSE_ARGV[(argv.nil?)? [::File.basename($0)]+::ARGV : argv]
|
46
|
-
if version and (hsh.key?(V) or hsh.key?(LV)) # -v or --version
|
47
|
-
$stdout.puts version
|
48
|
-
::Kernel::exit(0)
|
49
|
-
end
|
50
|
-
if help
|
51
|
-
if hsh.key?(H) or hsh.key?(LH) # -h or --help
|
52
|
-
$stdout.puts help
|
53
|
-
::Kernel::exit(0)
|
54
|
-
end
|
55
|
-
@usage = ::HELP_PARSER::Usage.new(help).validate(hsh)
|
56
|
-
end
|
57
|
-
rescue ::HELP_PARSER::UsageError => e
|
58
|
-
$stderr.puts COLOR[1]+e.message+COLOR[0]
|
59
|
-
$stderr.puts help if help
|
60
|
-
::Kernel::exit(64) # Usage
|
61
|
-
rescue ::HELP_PARSER::HelpError => e
|
62
|
-
msg = e.message
|
63
|
-
$stderr.puts COLOR[1]+msg+COLOR[0]
|
64
|
-
if ERROR_KEY =~ msg
|
65
|
-
$stderr.puts help.gsub($1,COLOR[1]+$1+COLOR[0])
|
66
|
-
else
|
67
|
-
$stderr.puts help
|
68
|
-
end
|
69
|
-
::Kernel::exit(78) # Config
|
70
|
-
end
|
71
|
-
@hash = hsh.freeze
|
72
|
-
end
|
73
|
-
|
74
|
-
def [](k)
|
75
|
-
@hash[k]
|
76
|
-
end
|
77
|
-
|
78
|
-
def _hash
|
79
|
-
@hash
|
80
|
-
end
|
81
|
-
|
82
|
-
def _usage
|
83
|
-
@usage
|
84
|
-
end
|
85
|
-
|
86
|
-
def method_missing(mthd, *args, &block)
|
87
|
-
super if block or args.length > 0
|
88
|
-
m = mthd.to_s
|
89
|
-
case m[-1]
|
90
|
-
when '?'
|
91
|
-
@hash.key? m[0..-2].to_sym
|
92
|
-
when '!'
|
93
|
-
super
|
94
|
-
else
|
95
|
-
@hash[mthd]
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
data/lib/help_parser/pattern.rb
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
module HELP_PARSER
|
2
|
-
class Pattern
|
3
|
-
|
4
|
-
TYPE_MAP = lambda do |type,values,&block|
|
5
|
-
case type
|
6
|
-
when INT
|
7
|
-
case values
|
8
|
-
when Array
|
9
|
-
block.call values.map{|v|v.to_i}
|
10
|
-
when String
|
11
|
-
block.call values.to_i
|
12
|
-
end
|
13
|
-
when FLOAT
|
14
|
-
case values
|
15
|
-
when Array
|
16
|
-
block.call values.map{|v|v.to_f}
|
17
|
-
when String
|
18
|
-
block.call values.to_f
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
TYPE_VALIDATE = lambda do |values,tx,msg|
|
24
|
-
[*values].each do |value|
|
25
|
-
unless tx.match(value)
|
26
|
-
raise UsageError, sprintf(msg,value)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def initialize(options,usage)
|
32
|
-
@options,@usage = options,usage
|
33
|
-
@keys = options.keys
|
34
|
-
@cache = {}
|
35
|
-
end
|
36
|
-
|
37
|
-
def types
|
38
|
-
@usage[TYPES].each do |type,*words|
|
39
|
-
tx = Types[type] || Regexp.new(type.to_s)
|
40
|
-
words.each do |word|
|
41
|
-
values = @options[word]
|
42
|
-
next if values.nil?
|
43
|
-
TYPE_VALIDATE[values,tx,"#{word}: %s !~ /#{type}/"]
|
44
|
-
TYPE_MAP.call(type,values){|m| @options[word]=m}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def pad
|
50
|
-
@cache.each{|k,v|@options[k]=v}
|
51
|
-
@usage.each do |name,words|
|
52
|
-
next if [USAGE,TYPES,DEFAULTS].include?(name)
|
53
|
-
words.each do |word|
|
54
|
-
next unless word.length==2
|
55
|
-
k,v = word
|
56
|
-
if v.class==Symbol
|
57
|
-
# Synonyms
|
58
|
-
if @options[k].nil?
|
59
|
-
@options[k]=@options[v] if @options.key?(v)
|
60
|
-
else
|
61
|
-
@options[v]=@options[k] unless @options.key?(v)
|
62
|
-
end
|
63
|
-
else
|
64
|
-
# Default
|
65
|
-
@options[k]=v unless @options.key?(k)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
if @usage.key?(DEFAULTS)
|
70
|
-
@usage[DEFAULTS].each do |words|
|
71
|
-
*ks,v = words
|
72
|
-
ks.each do |k|
|
73
|
-
@options[k]=v.to_s unless @options.key?(k)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def _matches(pattern, i)
|
80
|
-
pattern.each do |token|
|
81
|
-
key = @keys[i] # Might be nil, but need to proceed...
|
82
|
-
case token
|
83
|
-
when Array # it's optional, so a key.nil? might be ok
|
84
|
-
begin
|
85
|
-
i = _matches(token,i)
|
86
|
-
rescue NoMatch
|
87
|
-
# Ok, no problem!
|
88
|
-
end
|
89
|
-
next
|
90
|
-
when SELECTION_P # it's a selection
|
91
|
-
raise NoMatch if key.nil?
|
92
|
-
section,plus = $1,$2
|
93
|
-
list = @usage[section]
|
94
|
-
list = list.flatten
|
95
|
-
raise NoMatch unless list.include?(key)
|
96
|
-
unless plus.nil?
|
97
|
-
while list.include?(@keys[i+1])
|
98
|
-
i+=1
|
99
|
-
end
|
100
|
-
end
|
101
|
-
when VARIABLE_P # it's a variable
|
102
|
-
raise NoMatch if key.to_s.to_i==0 # nil.to_s.to_i==0 also works
|
103
|
-
word,plus = $1.to_sym,$2
|
104
|
-
unless plus.nil?
|
105
|
-
@cache[word] = [@options[key]]
|
106
|
-
while (key=@keys[i+1]).to_s.to_i > 0
|
107
|
-
i+=1
|
108
|
-
@cache[word].push(@options[key])
|
109
|
-
end
|
110
|
-
else
|
111
|
-
@cache[word] = @options[key]
|
112
|
-
end
|
113
|
-
else # it's a literal
|
114
|
-
raise NoMatch if key.nil?
|
115
|
-
if token[0]==M
|
116
|
-
raise NoMatch unless token == ((key.length>1)? MM : M)+key.to_s
|
117
|
-
else
|
118
|
-
raise NoMatch unless @options[key]==token
|
119
|
-
end
|
120
|
-
end
|
121
|
-
i+=1
|
122
|
-
end
|
123
|
-
return i
|
124
|
-
end
|
125
|
-
|
126
|
-
def matches(pattern)
|
127
|
-
begin
|
128
|
-
i = _matches(pattern, 0)
|
129
|
-
raise NoMatch if i != @options.length
|
130
|
-
pad
|
131
|
-
types if @usage[TYPES]
|
132
|
-
rescue NoMatch
|
133
|
-
return false
|
134
|
-
ensure
|
135
|
-
@cache.clear
|
136
|
-
end
|
137
|
-
return true
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
data/lib/help_parser/usage.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
module HELP_PARSER
|
2
|
-
class Usage
|
3
|
-
using HELP_PARSER::Refinements
|
4
|
-
|
5
|
-
DUPLICATES = lambda do |hsh|
|
6
|
-
a = hsh.select{|k| k!=TYPES and k!=DEFAULTS}.values.flatten.select{|e|e.class==Symbol}
|
7
|
-
if d = a.detect_duplicate
|
8
|
-
raise HelpError, DUP_KEY+d.to_s
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
VALIDATE_USAGE = lambda do |tokens|
|
13
|
-
seen = {}
|
14
|
-
tokens.flatten.each do |token|
|
15
|
-
t = token
|
16
|
-
if VARIABLE=~token
|
17
|
-
t = $1
|
18
|
-
elsif KEY=~token
|
19
|
-
t = $1
|
20
|
-
end
|
21
|
-
#raise HelpError, 'Duplicate Token: '+t if seen[t]
|
22
|
-
raise HelpError, DUP_KEY+t if seen[t]
|
23
|
-
seen[t]=true
|
24
|
-
end
|
25
|
-
return tokens
|
26
|
-
end
|
27
|
-
|
28
|
-
PARSE_USAGE = lambda do |chars|
|
29
|
-
tokens, token = [], I
|
30
|
-
while c = chars.shift
|
31
|
-
case c
|
32
|
-
when S,P,Q
|
33
|
-
unless token==I
|
34
|
-
tokens.push(token)
|
35
|
-
token = I
|
36
|
-
end
|
37
|
-
tokens.push PARSE_USAGE[chars] if c==P
|
38
|
-
return tokens if c==Q
|
39
|
-
else
|
40
|
-
token += c
|
41
|
-
end
|
42
|
-
end
|
43
|
-
tokens.push(token) unless token==I
|
44
|
-
return tokens
|
45
|
-
end
|
46
|
-
|
47
|
-
BALANCED = lambda do |chars|
|
48
|
-
count = 0
|
49
|
-
chars.each do |c|
|
50
|
-
if c==P then count+=1 elsif c==Q then count-=1 end
|
51
|
-
break if count<0
|
52
|
-
end
|
53
|
-
return count==0
|
54
|
-
end
|
55
|
-
|
56
|
-
def initialize(help)
|
57
|
-
hsh,name = {},Z
|
58
|
-
help.strip.split(SNS).each do |line|
|
59
|
-
next if line[0]==C # skip comment lines
|
60
|
-
line.sub!(COMMENTARY,'') # strip out commentary
|
61
|
-
case line
|
62
|
-
when SELECTION
|
63
|
-
name = $1.downcase
|
64
|
-
break if name==NOTES
|
65
|
-
raise HelpError, SECTION_REDEFINITION+name if hsh[name]
|
66
|
-
hsh[name] = []
|
67
|
-
else
|
68
|
-
case name
|
69
|
-
when Z
|
70
|
-
# Nothing to do
|
71
|
-
when USAGE
|
72
|
-
chars = line.chars
|
73
|
-
raise HelpError, UNBALANCE_BRACKETS+line unless BALANCED[chars]
|
74
|
-
hsh[USAGE].push(VALIDATE_USAGE[PARSE_USAGE[chars]])
|
75
|
-
when TYPES,DEFAULTS
|
76
|
-
raise HelpError, NOT_A_FLAG+line if line[0]==M
|
77
|
-
hsh[name].push line.split(SPS).map{|_|_.to_sym}
|
78
|
-
else
|
79
|
-
raise HelpError, MISSING_MINUS+line unless line[0]==M
|
80
|
-
hsh[name].push line.split(SPS).map{|_|(_[0]==M)? _.sub(MNS,'').to_sym : _}
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
DUPLICATES[hsh]
|
85
|
-
@hash = hsh.freeze
|
86
|
-
end
|
87
|
-
|
88
|
-
def _hash
|
89
|
-
@hash
|
90
|
-
end
|
91
|
-
|
92
|
-
def validate(options)
|
93
|
-
pattern = Pattern.new(options,@hash)
|
94
|
-
@hash[USAGE].each do |cmd|
|
95
|
-
return self if pattern.matches(cmd)
|
96
|
-
end
|
97
|
-
raise UsageError, MATCH_USAGE
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|