help_parser 2.0.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +38 -58
- data/lib/help_parser/constants.rb +30 -0
- data/lib/help_parser/help_parser.rb +52 -144
- data/lib/help_parser/pattern.rb +121 -0
- data/lib/help_parser/usage.rb +53 -0
- data/lib/help_parser/version.rb +1 -1
- data/lib/help_parser.rb +4 -3
- metadata +10 -9
- data/lib/help_parser/errors.rb +0 -16
- data/lib/help_parser/exceptions.rb +0 -25
- data/lib/help_parser/refinements.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f2cddf5444a61128c4e9dee462687c0b806cc14
|
4
|
+
data.tar.gz: b3771ac46dd21a3c35a9b364044d9f7c8ac72eba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 452bd92f2c59ab12e26dbf7df0770f32fd12182bfd6dc3899b5d79fdccd9382daf1d908dce056833f4737f45cd3b521053d6425aca16ada30315f66f268c4dfd
|
7
|
+
data.tar.gz: 6578b276cfb4be11bf3597a650f3dd6661ddf4811e4a35b41b1d0c6394c700b3f1039df9724836e3c57b1a3938e6d4032e3e120ed3df55dd5dfb490c59b87a53
|
data/README.rdoc
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
= HelpParser
|
2
2
|
|
3
|
+
This is version 3!
|
4
|
+
|
3
5
|
github :: https://www.github.com/carlosjhr64/help_parser
|
4
6
|
rubygems :: https://rubygems.org/gems/help_parser
|
5
7
|
|
@@ -10,48 +12,45 @@ HelpParser - Parses your help text to define your command line options.
|
|
10
12
|
== FEATURES/PROBLEMS:
|
11
13
|
|
12
14
|
* long to short option mapping
|
13
|
-
* --no-lopt sets lopt to false
|
14
15
|
|
15
16
|
== SYNOPSIS:
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
18
|
+
#!/usr/bin/env ruby
|
19
|
+
require 'help_parser'
|
20
|
+
VERSION = '1.2.3'
|
21
|
+
HELP = <<HELP
|
22
|
+
### cmd ###
|
23
|
+
Usage:
|
24
|
+
cmd --wut <price> <count> <name>
|
25
|
+
cmd [:options] <args>+
|
26
|
+
Options:
|
27
|
+
-h --help \tTab marks comment
|
28
|
+
-v --version\tShort and long synonyms
|
29
|
+
-q --quiet
|
30
|
+
-V --verbose
|
31
|
+
--val 5.0 \tProvided default to long
|
32
|
+
--number \tLike --number=3
|
33
|
+
Types:
|
34
|
+
Float --val price \tPredefined Float and Int
|
35
|
+
Int --number count
|
36
|
+
^[A-Z][a-z]+$ name \tUser defined type
|
37
|
+
Notes:
|
38
|
+
Stuff the help parser will ignore.
|
39
|
+
HELP
|
40
|
+
OPTIONS = HelpParser.new(VERSION, HELP)
|
41
|
+
# Shorts and longs as booleans via missing ? methods
|
42
|
+
"Got Options!" unless OPTIONS.q?
|
43
|
+
puts OPTIONS if OPTIONS.V?
|
44
|
+
# Long values via missing ! methods
|
45
|
+
puts "val = #{OPTIONS.val!}"
|
46
|
+
# Arguments via plain missing methods
|
47
|
+
if OPTIONS.wut?
|
48
|
+
puts "price = '#{OPTIONS.price}'"
|
49
|
+
puts "count = '#{OPTIONS.count}'"
|
50
|
+
puts "name = '#{OPTIONS.name}'"
|
40
51
|
else
|
41
|
-
puts "
|
52
|
+
puts "args = '#{OPTIONS.args.join(',')}'"
|
42
53
|
end
|
43
|
-
# mycmdapp code continues...
|
44
|
-
# ...
|
45
|
-
rescue UsageException
|
46
|
-
puts $!.message # User just wants help or version
|
47
|
-
exit 0 # Not an error
|
48
|
-
rescue UsageError
|
49
|
-
STDERR.puts '*** '+$!.message+' ***'
|
50
|
-
STDERR.puts $!.obj.help
|
51
|
-
exit 64 # Usage error exit code
|
52
|
-
end
|
53
|
-
|
54
|
-
See `examples/command_suite` for an example of how to build a command suite with HelpParser.
|
55
54
|
|
56
55
|
== INSTALL:
|
57
56
|
|
@@ -59,25 +58,6 @@ See `examples/command_suite` for an example of how to build a command suite with
|
|
59
58
|
|
60
59
|
== LICENSE:
|
61
60
|
|
62
|
-
(The
|
63
|
-
|
64
|
-
Copyright (c) 2013 CarlosJHR64
|
65
|
-
|
66
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
67
|
-
a copy of this software and associated documentation files (the
|
68
|
-
'Software'), to deal in the Software without restriction, including
|
69
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
70
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
71
|
-
permit persons to whom the Software is furnished to do so, subject to
|
72
|
-
the following conditions:
|
73
|
-
|
74
|
-
The above copyright notice and this permission notice shall be
|
75
|
-
included in all copies or substantial portions of the Software.
|
61
|
+
(The "Can't touch this, b/c it's all mine!" License)
|
76
62
|
|
77
|
-
|
78
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
79
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
80
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
81
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
82
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
83
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
63
|
+
Copyright (c) 2016 CarlosJHR64
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module HELP_PARSER # Constants
|
2
|
+
|
3
|
+
NOTES,USAGE,TYPES = 'notes','usage','types'
|
4
|
+
Z,M,E,P,Q,I = '','-','=','[',']',''
|
5
|
+
H,LH,V,LV = '-h','--help','-v','--version'
|
6
|
+
|
7
|
+
S,SNS = /\s/,/\s*\n\s*/
|
8
|
+
|
9
|
+
COLOR = [
|
10
|
+
"\e[0m", # no color
|
11
|
+
"\e[1;31m", # red
|
12
|
+
]
|
13
|
+
|
14
|
+
FLOAT,INT = 'Float', 'Int'
|
15
|
+
Types = {
|
16
|
+
INT => /^[+-]?\d+$/,
|
17
|
+
FLOAT => /^[+-]?\d+\.\d+$/,
|
18
|
+
}
|
19
|
+
|
20
|
+
# Errors
|
21
|
+
class UsageError < StandardError
|
22
|
+
end
|
23
|
+
class HelpFormatError < StandardError
|
24
|
+
end
|
25
|
+
class NoMatch < StandardError
|
26
|
+
end
|
27
|
+
class SoftwareError < StandardError
|
28
|
+
end
|
29
|
+
SOFTWARE_ERROR_MSG = 'please submit a bug report'
|
30
|
+
end
|
@@ -1,163 +1,71 @@
|
|
1
1
|
module HELP_PARSER
|
2
|
+
# HelpParser Hash will act as if a GoLang map[string]string.
|
2
3
|
class HelpParser < Hash
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
4
|
+
def consume(argv)
|
5
|
+
n = 0
|
6
|
+
while a = argv.shift
|
7
|
+
if a[0]==M # '-'
|
8
|
+
if a==M
|
9
|
+
self[M] = argv
|
10
|
+
break # end of parse
|
11
|
+
else
|
12
|
+
if a[1]==M
|
13
|
+
k,v = a.split(E,2) # split by '='
|
14
|
+
self[k] = (v)? v : Z # ''
|
15
|
+
else
|
16
|
+
# set each flag
|
17
|
+
a[1..-1].chars.each{|c|self[M+c]=Z}
|
17
18
|
end
|
18
|
-
value = :F
|
19
19
|
end
|
20
|
-
block.call loption, value
|
21
20
|
else
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
end
|
21
|
+
# the nth argument
|
22
|
+
self[n.to_s] = a
|
23
|
+
n+=1
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# Figure out what parameters you were given...
|
36
|
-
argv = parameters.detect{|parameter| parameter.class == Array} || ARGV
|
37
|
-
dict = parameters.detect{|parameter| parameter.class == Hash } || {}
|
38
|
-
parameters = parameters.select{|parameter| parameter.class == String}
|
39
|
-
version = parameters.shift
|
40
|
-
help = parameters.pop
|
41
|
-
preferred = {}
|
42
|
-
|
43
|
-
raise "Need help" unless help
|
44
|
-
raise "Need version" unless version
|
45
|
-
|
46
|
-
# We ensure the following mappings...
|
47
|
-
dict[:help], preferred[:help] = :h, :T
|
48
|
-
dict[:version], preferred[:version] = :v, :T
|
49
|
-
|
50
|
-
# Using the help for the options definition
|
51
|
-
help.split("\n").select{|l|
|
52
|
-
(l=~/^\s*-/)
|
53
|
-
}.map{|l|
|
54
|
-
l.strip.split(/\s+/)[0..1].select{|o|
|
55
|
-
o[0]=='-'
|
56
|
-
}.map{|o|
|
57
|
-
v = :T
|
58
|
-
if i = o.index('=')
|
59
|
-
v = o[i+1..-1]
|
60
|
-
o = o[0...i]
|
61
|
-
end
|
62
|
-
o = o.to_key
|
63
|
-
preferred[o] = v
|
64
|
-
o
|
65
|
-
}.reverse
|
66
|
-
}.each do |k,v|
|
67
|
-
unless dict[k].nil?
|
68
|
-
# This is an implementation error. The help text is inconsistent.
|
69
|
-
# Note that we may have been given dict, and we're verifying the help.
|
70
|
-
unless dict[k]==v
|
71
|
-
raise ImplementationError, "#{k} redefinition from #{dict[k]} to #{v}."
|
72
|
-
end
|
73
|
-
end
|
74
|
-
dict[k]=v
|
28
|
+
def initialize(version=nil, help=nil, argv=nil)
|
29
|
+
consume (argv.nil?)? [File.basename($0)]+ARGV : argv
|
30
|
+
if version and (self[V] or self[LV]) # -v or --version
|
31
|
+
puts version
|
32
|
+
exit(0)
|
75
33
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
dict.each do |k,v|
|
81
|
-
next if v.nil?
|
82
|
-
if dict.has_key?(v)
|
83
|
-
unless dict[v].nil?
|
84
|
-
raise ImplementationError, "Expected terminal #{v}: #{k} => #{v} => #{dict[v]}"
|
85
|
-
end
|
86
|
-
else
|
87
|
-
terminals.push(v)
|
34
|
+
if help
|
35
|
+
if self[H] or self[LH] # -h or --help
|
36
|
+
puts help
|
37
|
+
exit(0)
|
88
38
|
end
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
value = preferred[key] if value.nil?
|
96
|
-
# Translate key to the terminal key.
|
97
|
-
key = dict[key] unless dict[key].nil?
|
98
|
-
# Ensure user only uses the defined keys.
|
99
|
-
unless dict.has_key?(key)
|
100
|
-
raise UsageError, "Not a valid option: #{opt}"
|
101
|
-
end
|
102
|
-
# As we parse ARGV, we should only be setting keys once.
|
103
|
-
if self.has_key?(key)
|
104
|
-
raise UsageError, "Duplicate command line option: #{opt}"
|
105
|
-
end
|
106
|
-
self[key] = value.to_value
|
107
|
-
end
|
108
|
-
|
109
|
-
# The parse takes all options to its terminal value.
|
110
|
-
# Now set the synonyms...
|
111
|
-
dict.each do |synonym, terminal|
|
112
|
-
next if terminal.nil?
|
113
|
-
if self.has_key?(terminal)
|
114
|
-
# I did not mean for the synonyms to have been set yet, so if I do,
|
115
|
-
# I have a bug somewhere.
|
116
|
-
raise "unexpected key overwrite" if self.has_key?(synonym)
|
117
|
-
self[synonym] = self[terminal]
|
39
|
+
begin
|
40
|
+
Usage.new(help).validate(self)
|
41
|
+
rescue UsageError
|
42
|
+
$stderr.puts COLOR[1]+$!.message+COLOR[0]
|
43
|
+
$stderr.puts help
|
44
|
+
exit(64) # Usage
|
118
45
|
end
|
119
46
|
end
|
120
|
-
|
121
|
-
# Did the user ask for help or version?
|
122
|
-
raise HelpException, help if self[:h]==true
|
123
|
-
raise VersionException, version if self[:v]==true
|
124
47
|
end
|
125
48
|
|
126
|
-
#
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
49
|
+
# obj.m? :: !obj['--m'].nil?
|
50
|
+
# obj.method! :: obj['--method']
|
51
|
+
# obj.method :: obj['method']
|
52
|
+
def method_missing(mthd, *args, &block)
|
53
|
+
if args.length==0
|
54
|
+
m=mthd.to_s
|
55
|
+
case m[-1]
|
56
|
+
when '?'
|
57
|
+
if m.length > 2
|
58
|
+
return !self[M+M+m[0..-2]].nil?
|
59
|
+
else
|
60
|
+
return !self[M+m[0]].nil?
|
61
|
+
end
|
62
|
+
when '!'
|
63
|
+
return self[M+M+m[0..-2]]
|
64
|
+
else
|
65
|
+
return self[m]
|
66
|
+
end
|
135
67
|
end
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
# HelpParser#defaults! is used to replace value with a
|
140
|
-
# default in the hash, self.
|
141
|
-
def defaults!(symbol, default1, default2=default1)
|
142
|
-
self[symbol] = defaults(symbol, default1, default2)
|
143
|
-
end
|
144
|
-
|
145
|
-
# HelpParser#[k, default1=nil, default2=nil]
|
146
|
-
# Basically, for #[k, default1, default2]:
|
147
|
-
# value = help_parser[k]
|
148
|
-
# case value
|
149
|
-
# when nil then default1
|
150
|
-
# when true then default2
|
151
|
-
# else value
|
152
|
-
# end
|
153
|
-
# For #[k, default1]:
|
154
|
-
# value = help_parser[k] || default1
|
155
|
-
# For #[k]:
|
156
|
-
# help_parser[k]
|
157
|
-
# Raises a UsageError if the value is not of the expected
|
158
|
-
# type as given by the last default.
|
159
|
-
def [](k, *defaults12)
|
160
|
-
(defaults12.length==0)? super(k) : defaults(k, *defaults12)
|
68
|
+
super
|
161
69
|
end
|
162
70
|
end
|
163
71
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module HELP_PARSER
|
2
|
+
class Pattern
|
3
|
+
def initialize(options,usage)
|
4
|
+
@options,@usage = options,usage
|
5
|
+
@keys = options.keys
|
6
|
+
@cache = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def _matches(pattern, i)
|
10
|
+
pattern.each do |token|
|
11
|
+
case token
|
12
|
+
when Array # it's optional
|
13
|
+
begin
|
14
|
+
i = _matches(token,i)
|
15
|
+
rescue NoMatch
|
16
|
+
# Ok, no problem!
|
17
|
+
end
|
18
|
+
next
|
19
|
+
when /^:(.*?)([+]?)$/ # it's a selection
|
20
|
+
list,plus = @usage[$1].flatten,$2
|
21
|
+
raise NoMatch unless list.include?(@keys[i])
|
22
|
+
if plus=='+'
|
23
|
+
while list.include?(@keys[i+1])
|
24
|
+
i+=1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
when /^<(.*)>([+]?)$/ # it's a variable
|
28
|
+
word,plus = $1,$2
|
29
|
+
raise NoMatch if @keys[i].to_i==0
|
30
|
+
if plus=='+'
|
31
|
+
@cache[word] = [@options[@keys[i]]]
|
32
|
+
while @keys[i+1].to_i > 0
|
33
|
+
i+=1
|
34
|
+
@cache[word].push(@options[@keys[i]])
|
35
|
+
end
|
36
|
+
else
|
37
|
+
@cache[word] = @options[@keys[i]]
|
38
|
+
end
|
39
|
+
else # it's a literal
|
40
|
+
if token[0]==M
|
41
|
+
raise NoMatch unless @keys[i]==token
|
42
|
+
else
|
43
|
+
raise NoMatch unless @options[@keys[i]]==token
|
44
|
+
end
|
45
|
+
end
|
46
|
+
i+=1
|
47
|
+
end
|
48
|
+
return i
|
49
|
+
end
|
50
|
+
|
51
|
+
def pad
|
52
|
+
@cache.each{|k,v|@options[k]=v}
|
53
|
+
@usage.each do |name,words|
|
54
|
+
next if [M,USAGE,TYPES].include?(name)
|
55
|
+
words.each do |word|
|
56
|
+
next unless word.length==2
|
57
|
+
k,v = word
|
58
|
+
next unless @options[k].nil?
|
59
|
+
if k[0]==M
|
60
|
+
if k[1]==M
|
61
|
+
# long option default
|
62
|
+
@options[k] = v
|
63
|
+
elsif v[0]==M and !@options[v].nil?
|
64
|
+
# long option synonym
|
65
|
+
@options[k] = @options[v]
|
66
|
+
end
|
67
|
+
else
|
68
|
+
# argument default
|
69
|
+
@options[k] = v
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def types
|
76
|
+
@usage[TYPES].each do |type,*words|
|
77
|
+
tx = Types[type] || Regexp.new(type)
|
78
|
+
words.each do |word|
|
79
|
+
values = @options[word]
|
80
|
+
next if values.nil?
|
81
|
+
[*values].each do |value|
|
82
|
+
unless tx.match(value)
|
83
|
+
raise UsageError, "ERROR: #{word}=#{value} is not /#{type}/"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
case type
|
87
|
+
when INT
|
88
|
+
case values
|
89
|
+
when Array
|
90
|
+
@options[word]=values.map{|v|v.to_i}
|
91
|
+
when String
|
92
|
+
@options[word]=values.to_i
|
93
|
+
end
|
94
|
+
when FLOAT
|
95
|
+
case values
|
96
|
+
when Array
|
97
|
+
@options[word]=values.map{|v|v.to_f}
|
98
|
+
when String
|
99
|
+
@options[word]=values.to_f
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def matches(pattern)
|
107
|
+
begin
|
108
|
+
i = _matches(pattern, 0)
|
109
|
+
raise NoMatch if i != @options.length
|
110
|
+
pad
|
111
|
+
types if @usage[TYPES]
|
112
|
+
return true
|
113
|
+
rescue NoMatch
|
114
|
+
return false
|
115
|
+
ensure
|
116
|
+
@cache.clear
|
117
|
+
end
|
118
|
+
raise SoftwareError, SOFTWARE_ERROR_MSG
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module HELP_PARSER
|
2
|
+
class Usage < Hash
|
3
|
+
def parse(chars)
|
4
|
+
tokens, token = [], I
|
5
|
+
while c = chars.shift
|
6
|
+
case c
|
7
|
+
when S,P,Q
|
8
|
+
unless token==I
|
9
|
+
tokens.push(token)
|
10
|
+
token = I
|
11
|
+
end
|
12
|
+
tokens.push parse(chars) if c==P
|
13
|
+
return tokens if c==Q
|
14
|
+
else
|
15
|
+
token += c
|
16
|
+
end
|
17
|
+
end
|
18
|
+
tokens.push(token) unless token==I
|
19
|
+
return tokens
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(help)
|
23
|
+
name = M # '-'
|
24
|
+
self[name] = []
|
25
|
+
help.strip.split(SNS).each do |line|
|
26
|
+
line.sub!(/\s*\t.*$/,'') # tabs marks comment
|
27
|
+
case line
|
28
|
+
when /^(\w+):$/
|
29
|
+
name = $1.downcase
|
30
|
+
break if name==NOTES
|
31
|
+
raise HelpFormatError, "#{name} section redefinition" if self[name]
|
32
|
+
self[name] = []
|
33
|
+
when /^\s*#/
|
34
|
+
next
|
35
|
+
else
|
36
|
+
if name==USAGE
|
37
|
+
self[USAGE].push(parse(line.chars))
|
38
|
+
else
|
39
|
+
self[name].push line.split(/\s+/)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate(options)
|
46
|
+
pattern = Pattern.new(options,self)
|
47
|
+
self[USAGE].each do |cmd|
|
48
|
+
return if pattern.matches(cmd)
|
49
|
+
end
|
50
|
+
raise UsageError, 'Please match usage!'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/help_parser/version.rb
CHANGED
data/lib/help_parser.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'help_parser/version'
|
2
|
-
require 'help_parser/
|
3
|
-
require 'help_parser/
|
4
|
-
require 'help_parser/
|
2
|
+
require 'help_parser/constants'
|
3
|
+
require 'help_parser/pattern'
|
4
|
+
require 'help_parser/usage'
|
5
5
|
require 'help_parser/help_parser'
|
6
|
+
HelpParser = HELP_PARSER::HelpParser
|
6
7
|
|
7
8
|
# Requires:
|
8
9
|
#`ruby`
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: help_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.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:
|
11
|
+
date: 2016-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
14
|
-
|
13
|
+
description: 'HelpParser - Parses your help text to define your command line options.
|
14
|
+
|
15
|
+
'
|
15
16
|
email: carlosjhr64@gmail.com
|
16
17
|
executables: []
|
17
18
|
extensions: []
|
@@ -20,10 +21,10 @@ extra_rdoc_files:
|
|
20
21
|
files:
|
21
22
|
- README.rdoc
|
22
23
|
- lib/help_parser.rb
|
23
|
-
- lib/help_parser/
|
24
|
-
- lib/help_parser/exceptions.rb
|
24
|
+
- lib/help_parser/constants.rb
|
25
25
|
- lib/help_parser/help_parser.rb
|
26
|
-
- lib/help_parser/
|
26
|
+
- lib/help_parser/pattern.rb
|
27
|
+
- lib/help_parser/usage.rb
|
27
28
|
- lib/help_parser/version.rb
|
28
29
|
homepage: https://github.com/carlosjhr64/help_parser
|
29
30
|
licenses:
|
@@ -46,9 +47,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
47
|
- !ruby/object:Gem::Version
|
47
48
|
version: '0'
|
48
49
|
requirements:
|
49
|
-
- 'ruby: ruby 2.
|
50
|
+
- 'ruby: ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]'
|
50
51
|
rubyforge_project:
|
51
|
-
rubygems_version: 2.
|
52
|
+
rubygems_version: 2.5.1
|
52
53
|
signing_key:
|
53
54
|
specification_version: 4
|
54
55
|
summary: HelpParser - Parses your help text to define your command line options.
|
data/lib/help_parser/errors.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module HELP_PARSER
|
2
|
-
|
3
|
-
# ImplementationError is an error due to a
|
4
|
-
# inconsistent help text. The raise is as follows:
|
5
|
-
# raise ImplementationError, message
|
6
|
-
class ImplementationError < StandardError
|
7
|
-
end
|
8
|
-
|
9
|
-
# UsageError is an error when the user passed command
|
10
|
-
# line options that are inconsistent with expectations.
|
11
|
-
# The raise is as follows:
|
12
|
-
# raise UsageError, message
|
13
|
-
class UsageError < StandardError
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module HELP_PARSER
|
2
|
-
|
3
|
-
# UsageException is an actual exception to normal flow.
|
4
|
-
# For example, when a user asks for help or version
|
5
|
-
# number in the command line options.
|
6
|
-
# The raise is as follows:
|
7
|
-
# raise UsageException, message
|
8
|
-
class UsageException < Exception
|
9
|
-
end
|
10
|
-
|
11
|
-
# HelpException is a type of UsageException, where the
|
12
|
-
# user asks for help in the command line options.
|
13
|
-
# The raise is as follows:
|
14
|
-
# raise HelpException, help_message
|
15
|
-
class HelpException < UsageException
|
16
|
-
end
|
17
|
-
|
18
|
-
# VersionException is a type of UsageException, where the
|
19
|
-
# user asks for version in the command line options.
|
20
|
-
# The raise is as follows:
|
21
|
-
# raise VersionException, version_message
|
22
|
-
class VersionException < UsageException
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module HELP_PARSER
|
2
|
-
# Refinements
|
3
|
-
|
4
|
-
refine Symbol do
|
5
|
-
def to_value
|
6
|
-
case self
|
7
|
-
when :T
|
8
|
-
return true
|
9
|
-
when :F
|
10
|
-
return false
|
11
|
-
end
|
12
|
-
raise "Unrecognized key: #{self}"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
refine String do
|
17
|
-
def to_value
|
18
|
-
case self
|
19
|
-
when /^[-+]?\d+$/
|
20
|
-
return self.to_i
|
21
|
-
when /^[-+]?\d+\.\d+([eE][+-]?\d+)?$/
|
22
|
-
return self.to_f
|
23
|
-
when /,/
|
24
|
-
return self.split(',').map{|s| s.to_value}
|
25
|
-
else
|
26
|
-
return self
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Converts String keys to Symbol.
|
31
|
-
# Symbol keys can have '-', but it's cumbersome notation:
|
32
|
-
# :"a-b"
|
33
|
-
# So I translate it to underscore:
|
34
|
-
# :a_b
|
35
|
-
def to_key
|
36
|
-
self.sub(/^--?/,'').gsub('-','_').to_sym
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|