help_parser 2.0.0 → 3.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/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
|