s0nspark-choice 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README.rdoc +441 -0
- data/lib/choice.rb +155 -0
- data/lib/choice/lazyhash.rb +67 -0
- data/lib/choice/option.rb +90 -0
- data/lib/choice/parser.rb +227 -0
- data/lib/choice/version.rb +8 -0
- data/lib/choice/writer.rb +187 -0
- data/test/choice_test.rb +231 -0
- data/test/lazyhash_test.rb +77 -0
- data/test/option_test.rb +146 -0
- data/test/parser_test.rb +374 -0
- data/test/test_helper.rb +5 -0
- data/test/writer_test.rb +104 -0
- metadata +69 -0
data/lib/choice.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
require 'choice/option'
|
3
|
+
require 'choice/parser'
|
4
|
+
require 'choice/writer'
|
5
|
+
require 'choice/lazyhash'
|
6
|
+
|
7
|
+
#
|
8
|
+
# Usage of this module is lovingly detailed in the README file.
|
9
|
+
#
|
10
|
+
module Choice
|
11
|
+
extend self
|
12
|
+
|
13
|
+
# The main method, which defines the options
|
14
|
+
def options(hash = {}, &block)
|
15
|
+
# if we are passing in a hash to define our options, use that straight
|
16
|
+
options_from_hash(hash) unless hash.empty?
|
17
|
+
|
18
|
+
# Setup all instance variables
|
19
|
+
reset! if hash.empty?
|
20
|
+
@@args ||= ARGV
|
21
|
+
|
22
|
+
# Eval the passed block to define the options.
|
23
|
+
instance_eval(&block) if block_given?
|
24
|
+
|
25
|
+
# Parse what we've got.
|
26
|
+
parse unless parsed?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Set options from a hash, shorthand style
|
30
|
+
def options_from_hash(options_hash)
|
31
|
+
options_hash.each do |name, definition|
|
32
|
+
option = Option.new
|
33
|
+
definition.each do |key, value|
|
34
|
+
Array(value).each { |hit| option.send(key, hit) }
|
35
|
+
end
|
36
|
+
@@options << [name.to_s, option]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns a hash representing options passed in via the command line.
|
41
|
+
def choices
|
42
|
+
@@choices
|
43
|
+
end
|
44
|
+
|
45
|
+
# Defines an option.
|
46
|
+
def option(opt, options = {}, &block)
|
47
|
+
# Notice: options is maintained as an array of arrays, the first element
|
48
|
+
# the option name and the second the option object.
|
49
|
+
@@options << [opt.to_s, Option.new(options, &block)]
|
50
|
+
end
|
51
|
+
|
52
|
+
# Separators are text displayed by --help within the options block.
|
53
|
+
def separator(str)
|
54
|
+
# We store separators as simple strings in the options array to maintain
|
55
|
+
# order. They are ignored by the parser.
|
56
|
+
@@options << str
|
57
|
+
end
|
58
|
+
|
59
|
+
# Define the banner, header, footer methods. All are just getters/setters
|
60
|
+
# of class variables.
|
61
|
+
%w[banner header footer].each do |method|
|
62
|
+
define_method(method) do |string|
|
63
|
+
variable = "@@#{method}"
|
64
|
+
return class_variable_get(variable) if string.nil?
|
65
|
+
val = class_variable_get(variable) || ''
|
66
|
+
class_variable_set(variable, val << string)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
# Parse the provided args against the defined options.
|
72
|
+
def parse #:nodoc:
|
73
|
+
# Do nothing if options are not defined.
|
74
|
+
return unless @@options.size > 0
|
75
|
+
|
76
|
+
# Show help if it's anywhere in the argument list.
|
77
|
+
if @@args.include?('--help') or @@args.include?('-h')
|
78
|
+
help
|
79
|
+
else
|
80
|
+
begin
|
81
|
+
# Delegate parsing to our parser class, passing it our defined
|
82
|
+
# options and the passed arguments.
|
83
|
+
@@choices = LazyHash.new(Parser.parse(@@options, @@args))
|
84
|
+
rescue Choice::Parser::ParseError
|
85
|
+
# If we get an expected exception, show the help file.
|
86
|
+
help
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Did we already parse the arguments?
|
92
|
+
def parsed? #:nodoc:
|
93
|
+
@@choices ||= false
|
94
|
+
end
|
95
|
+
|
96
|
+
# Print the help screen by calling our Writer object
|
97
|
+
def help #:nodoc:
|
98
|
+
Writer.help( { :banner => @@banner, :header => @@header,
|
99
|
+
:options => @@options, :footer => @@footer },
|
100
|
+
output_to, exit_on_help? )
|
101
|
+
end
|
102
|
+
|
103
|
+
# Set the args, potentially to something other than ARGV.
|
104
|
+
def args=(args) #:nodoc:
|
105
|
+
@@args = args.dup.map { |a| a + '' }
|
106
|
+
parse if parsed?
|
107
|
+
end
|
108
|
+
|
109
|
+
# Return the args.
|
110
|
+
def args #:nodoc:
|
111
|
+
@@args
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns the arguments that follow an argument
|
115
|
+
def args_of(opt)
|
116
|
+
args_of_opt = []
|
117
|
+
|
118
|
+
# Return an array of the arguments between opt and the next option,
|
119
|
+
# which all start with "-"
|
120
|
+
@@args.slice(@@args.index(opt)+1, @@args.length).select do |arg|
|
121
|
+
if arg[0].chr != "-"
|
122
|
+
args_of_opt << arg
|
123
|
+
else
|
124
|
+
break
|
125
|
+
end
|
126
|
+
end
|
127
|
+
args_of_opt
|
128
|
+
end
|
129
|
+
|
130
|
+
# You can choose to not kill the script after the help screen is printed.
|
131
|
+
def dont_exit_on_help=(val) #:nodoc:
|
132
|
+
@@exit = true
|
133
|
+
end
|
134
|
+
|
135
|
+
# Do we want to exit on help?
|
136
|
+
def exit_on_help? #:nodoc:
|
137
|
+
@@exit rescue false
|
138
|
+
end
|
139
|
+
|
140
|
+
# If we want to write to somewhere other than STDOUT.
|
141
|
+
def output_to(target = nil) #:nodoc:
|
142
|
+
@@output_to ||= STDOUT
|
143
|
+
return @@output_to if target.nil?
|
144
|
+
@@output_to = target
|
145
|
+
end
|
146
|
+
|
147
|
+
# Reset all the class variables.
|
148
|
+
def reset! #:nodoc:
|
149
|
+
@@args = false
|
150
|
+
@@banner = false
|
151
|
+
@@header = Array.new
|
152
|
+
@@options = Array.new
|
153
|
+
@@footer = Array.new
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Choice
|
2
|
+
|
3
|
+
# This class lets us get away with really bad, horrible, lazy hash accessing.
|
4
|
+
# Like so:
|
5
|
+
# hash = LazyHash.new
|
6
|
+
# hash[:someplace] = "somewhere"
|
7
|
+
# puts hash[:someplace]
|
8
|
+
# puts hash['someplace']
|
9
|
+
# puts hash.someplace
|
10
|
+
#
|
11
|
+
# If you'd like, you can pass in a current hash when initializing to convert
|
12
|
+
# it into a lazyhash. Or you can use the .to_lazyhash method attached to the
|
13
|
+
# Hash object (evil!).
|
14
|
+
class LazyHash < Hash
|
15
|
+
|
16
|
+
# Keep the old methods around.
|
17
|
+
alias_method :old_store, :store
|
18
|
+
alias_method :old_fetch, :fetch
|
19
|
+
|
20
|
+
# You can pass in a normal hash to convert it to a LazyHash.
|
21
|
+
def initialize(hash = nil)
|
22
|
+
hash.each { |key, value| self[key] = value } if !hash.nil? && hash.is_a?(Hash)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Wrapper for []
|
26
|
+
def store(key, value)
|
27
|
+
self[key] = value
|
28
|
+
end
|
29
|
+
|
30
|
+
# Wrapper for []=
|
31
|
+
def fetch(key)
|
32
|
+
self[key]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Store every key as a string.
|
36
|
+
def []=(key, value)
|
37
|
+
key = key.to_s if key.is_a? Symbol
|
38
|
+
self.old_store(key, value)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Every key is stored as a string. Like a normal hash, nil is returned if
|
42
|
+
# the key does not exist.
|
43
|
+
def [](key)
|
44
|
+
key = key.to_s if key.is_a? Symbol
|
45
|
+
self.old_fetch(key) rescue return nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# You can use hash.something or hash.something = 'thing' since this is
|
49
|
+
# truly a lazy hash.
|
50
|
+
def method_missing(meth, *args)
|
51
|
+
meth = meth.to_s
|
52
|
+
if meth =~ /=/
|
53
|
+
self[meth.sub('=','')] = args.first
|
54
|
+
else
|
55
|
+
self[meth]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Really ugly, horrible, extremely fun hack.
|
63
|
+
class Hash #:nodoc:
|
64
|
+
def to_lazyhash
|
65
|
+
return Choice::LazyHash.new(self)
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Choice
|
2
|
+
|
3
|
+
# The Option class parses and stores all the information about a specific
|
4
|
+
# option.
|
5
|
+
class Option #:nodoc: all
|
6
|
+
|
7
|
+
# Since we define getters/setters on the fly, we need a white list of
|
8
|
+
# which to accept. Here's the list.
|
9
|
+
CHOICES = %w[short long desc default filter action cast validate valid]
|
10
|
+
|
11
|
+
# You can instantiate an option on its own or by passing it a name and
|
12
|
+
# a block. If you give it a block, it will eval() the block and set itself
|
13
|
+
# up nicely.
|
14
|
+
def initialize(options = {}, &block)
|
15
|
+
# Here we store the definitions this option contains, to make to_a and
|
16
|
+
# to_h easier.
|
17
|
+
@choices = []
|
18
|
+
|
19
|
+
# If we got a block, eval it and set everything up.
|
20
|
+
instance_eval(&block) if block_given?
|
21
|
+
|
22
|
+
# Is this option required?
|
23
|
+
@required = options[:required] || false
|
24
|
+
@choices << 'required'
|
25
|
+
end
|
26
|
+
|
27
|
+
# This is the catch all for the getter/setter choices defined in CHOICES.
|
28
|
+
# It also gives us choice? methods.
|
29
|
+
def method_missing(method, *args, &block)
|
30
|
+
# Get the name of the choice we want, as a class variable string.
|
31
|
+
var = "@#{method.to_s.sub('?','')}"
|
32
|
+
|
33
|
+
# To string, for regex purposes.
|
34
|
+
method = method.to_s
|
35
|
+
|
36
|
+
# Don't let in any choices not defined in our white list array.
|
37
|
+
raise ParseError, "I don't know `#{method}'" unless CHOICES.include? method.sub('?','')
|
38
|
+
|
39
|
+
# If we're asking a question, give an answer. Like 'short?'.
|
40
|
+
return !!instance_variable_get(var) if method =~ /\?/
|
41
|
+
|
42
|
+
# If we were called with no arguments, we want a get.
|
43
|
+
return instance_variable_get(var) unless args[0] || block_given?
|
44
|
+
|
45
|
+
# If we were given a block or an argument, save it.
|
46
|
+
instance_variable_set(var, args[0]) if args[0]
|
47
|
+
instance_variable_set(var, block) if block_given?
|
48
|
+
|
49
|
+
# Add the choice to the @choices array if we're setting it for the first
|
50
|
+
# time.
|
51
|
+
@choices << method if args[0] || block_given? unless @choices.index(method)
|
52
|
+
end
|
53
|
+
|
54
|
+
# The desc method is slightly special: it stores itself as an array and
|
55
|
+
# each subsequent call adds to that array, rather than overwriting it.
|
56
|
+
# This is so we can do multi-line descriptions easily.
|
57
|
+
def desc(string = nil)
|
58
|
+
return @desc if string.nil?
|
59
|
+
|
60
|
+
@desc ||= []
|
61
|
+
@desc.push(string)
|
62
|
+
|
63
|
+
# Only add to @choices array if it's not already present.
|
64
|
+
@choices << 'desc' unless @choices.index('desc')
|
65
|
+
end
|
66
|
+
|
67
|
+
# Simple, desc question method.
|
68
|
+
def desc?() !!@desc end
|
69
|
+
|
70
|
+
# Returns Option converted to an array.
|
71
|
+
def to_a
|
72
|
+
@choices.inject([]) do |array, choice|
|
73
|
+
return array unless @choices.include? choice
|
74
|
+
array + [instance_variable_get("@#{choice}")]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns Option converted to a hash.
|
79
|
+
def to_h
|
80
|
+
@choices.inject({}) do |hash, choice|
|
81
|
+
return hash unless @choices.include? choice
|
82
|
+
hash.merge choice => instance_variable_get("@#{choice}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# In case someone tries to use a method we don't know about in their
|
87
|
+
# option block.
|
88
|
+
class ParseError < Exception; end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
module Choice
|
2
|
+
|
3
|
+
# The parser takes our option definitions and our arguments and produces
|
4
|
+
# a hash of values.
|
5
|
+
module Parser #:nodoc: all
|
6
|
+
extend self
|
7
|
+
|
8
|
+
# What method to call on an object for each given 'cast' value.
|
9
|
+
CAST_METHODS = { Integer => :to_i, String => :to_s, Float => :to_f,
|
10
|
+
Symbol => :to_sym }
|
11
|
+
|
12
|
+
# Perhaps this method does too much. It is, however, a parser.
|
13
|
+
# You pass it an array of arrays, the first element of each element being
|
14
|
+
# the option's name and the second element being a hash of the option's
|
15
|
+
# info. You also pass in your current arguments, so it knows what to
|
16
|
+
# check against.
|
17
|
+
def parse(options, args)
|
18
|
+
# Return empty hash if the parsing adventure would be fruitless.
|
19
|
+
return {} if options.nil? || !options || args.nil? || !args.is_a?(Array)
|
20
|
+
|
21
|
+
# If we are passed an array, make the best of it by converting it
|
22
|
+
# to a hash.
|
23
|
+
options = options.inject({}) do |hash, value|
|
24
|
+
value.is_a?(Array) ? hash.merge(value.first => value[1]) : hash
|
25
|
+
end if options.is_a? Array
|
26
|
+
|
27
|
+
# Define local hashes we're going to use. choices is where we store
|
28
|
+
# the actual values we've pulled from the argument list.
|
29
|
+
hashes, longs, required, validators, choices, arrayed = {}, {}, {}, {}, {}, {}
|
30
|
+
hard_required = {}
|
31
|
+
|
32
|
+
# We can define these on the fly because they are all so similar.
|
33
|
+
params = %w[short cast filter action default valid]
|
34
|
+
params.each { |param| hashes["#{param}s"] = {} }
|
35
|
+
|
36
|
+
# Inspect each option and move its info into our local hashes.
|
37
|
+
options.each do |name, obj|
|
38
|
+
name = name.to_s
|
39
|
+
|
40
|
+
# Only take hashes or hash-like duck objects.
|
41
|
+
raise HashExpectedForOption unless obj.respond_to? :to_h
|
42
|
+
obj = obj.to_h
|
43
|
+
|
44
|
+
# Is this option required?
|
45
|
+
hard_required[name] = true if obj['required']
|
46
|
+
|
47
|
+
# Set the local hashes if the value exists on this option object.
|
48
|
+
params.each { |param| hashes["#{param}s"][name] = obj[param] if obj[param] }
|
49
|
+
|
50
|
+
# If there is a validate statement, make it a regex or proc.
|
51
|
+
validators[name] = make_validation(obj['validate']) if obj['validate']
|
52
|
+
|
53
|
+
# Parse the long option. If it contains a =, figure out if the
|
54
|
+
# argument is required or optional. Optional arguments are formed
|
55
|
+
# like [=ARG], whereas required are just ARG (in --long=ARG style).
|
56
|
+
if obj['long'] && obj['long'] =~ /(=|\[| )/
|
57
|
+
# Save the separator we used, as we're gonna need it, then split
|
58
|
+
sep = $1
|
59
|
+
option, *argument = obj['long'].split(sep)
|
60
|
+
|
61
|
+
# The actual name of the long switch
|
62
|
+
longs[name] = option
|
63
|
+
|
64
|
+
# Preserve the original argument, as it may contain [ or =,
|
65
|
+
# by joining with the character we split on. Add a [ in front if
|
66
|
+
# we split on that.
|
67
|
+
argument = (sep == '[' ? '[' : '') << Array(argument).join(sep)
|
68
|
+
|
69
|
+
# Do we expect multiple arguments which get turned into an array?
|
70
|
+
arrayed[name] = true if argument =~ /^\[?=?\*(.+)\]?$/
|
71
|
+
|
72
|
+
# Is this long required or optional?
|
73
|
+
required[name] = true unless argument =~ /^\[=?\*?(.+)\]$/
|
74
|
+
elsif obj['long']
|
75
|
+
# We can't have a long as a switch when valid is set -- die.
|
76
|
+
raise ArgumentRequiredWithValid if obj['valid']
|
77
|
+
|
78
|
+
# Set without any checking if it's just --long
|
79
|
+
longs[name] = obj['long']
|
80
|
+
end
|
81
|
+
|
82
|
+
# If we were given a list of valid arguments with 'valid,' this option
|
83
|
+
# is definitely required.
|
84
|
+
required[name] = true if obj['valid']
|
85
|
+
end
|
86
|
+
|
87
|
+
# Go through the arguments and try to figure out whom they belong to
|
88
|
+
# at this point.
|
89
|
+
args.each_with_index do |arg, i|
|
90
|
+
if hashes['shorts'].value?(arg)
|
91
|
+
# Set the value to the next element in the args array since
|
92
|
+
# this is a short.
|
93
|
+
value = args[i+1]
|
94
|
+
|
95
|
+
# If the next element doesn't exist or starts with a -, make this
|
96
|
+
# value true.
|
97
|
+
value = true if !value || value =~ /^-/
|
98
|
+
|
99
|
+
# Add this value to the choices hash with the key of the option's
|
100
|
+
# name. If we expect an array, tack this argument on.
|
101
|
+
name = hashes['shorts'].index(arg)
|
102
|
+
if arrayed[name]
|
103
|
+
choices[name] ||= []
|
104
|
+
choices[name] += arrayize_arguments(name, args[i+1..-1])
|
105
|
+
else
|
106
|
+
choices[name] = value
|
107
|
+
end
|
108
|
+
|
109
|
+
elsif /^(--[^=]+)=?/ =~ arg && longs.value?($1)
|
110
|
+
# The joke here is we always accept both --long=VALUE and --long VALUE.
|
111
|
+
|
112
|
+
# Grab values from --long=VALUE format
|
113
|
+
if arg =~ /=/ && longs.value?((longed = arg.split('=')).first)
|
114
|
+
name = longs.index(longed.shift)
|
115
|
+
value = longed * '='
|
116
|
+
# For the arrayed options.
|
117
|
+
potential_args = args[i+1..-1]
|
118
|
+
else
|
119
|
+
# Grab value otherwise if not in --long=VALUE format. Assume --long VALUE.
|
120
|
+
name = longs.index(arg)
|
121
|
+
# Value is nil if we don't have a = and the next argument is no good
|
122
|
+
value = args[i+1] =~ /^-/ ? nil : args[i+1]
|
123
|
+
# For the arrayed options.
|
124
|
+
potential_args = args[i+2..-1]
|
125
|
+
end
|
126
|
+
|
127
|
+
# If we expect an array, tack this argument on.
|
128
|
+
if arrayed[name] && !value.nil?
|
129
|
+
# If this is arrayed and the value isn't nil, set it.
|
130
|
+
choices[name] ||= []
|
131
|
+
choices[name] << value
|
132
|
+
choices[name] += arrayize_arguments(name, potential_args)
|
133
|
+
else
|
134
|
+
# If we set the value to nil, that means nothing was set and we
|
135
|
+
# need to set the value to true. We'll find out later if that's
|
136
|
+
# acceptable or not.
|
137
|
+
choices[name] = value.nil? ? true : value
|
138
|
+
end
|
139
|
+
|
140
|
+
else
|
141
|
+
# If we're here, we have no idea what the passed argument is. Die.
|
142
|
+
raise UnknownOption if arg =~ /^-/
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Okay, we got all the choices. Now go through and run any filters or
|
147
|
+
# whatever on them.
|
148
|
+
choices.each do |name, value|
|
149
|
+
# Check to make sure we have all the required arguments.
|
150
|
+
raise ArgumentRequired if required[name] && value === true
|
151
|
+
|
152
|
+
# Validate the argument if we need to, against a regexp or a block.
|
153
|
+
if validators[name]
|
154
|
+
if validators[name].is_a?(Regexp) && validators[name] =~ value
|
155
|
+
elsif validators[name].is_a?(Proc) && validators[name].call(value)
|
156
|
+
else raise ArgumentValidationFails
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Make sure the argument is valid
|
161
|
+
raise InvalidArgument unless value.to_a.all? { |v| hashes['valids'][name].include?(v) } if hashes['valids'][name]
|
162
|
+
|
163
|
+
# Cast the argument using the method defined in the constant hash.
|
164
|
+
value = value.send(CAST_METHODS[hashes['casts'][name]]) if hashes['casts'].include?(name)
|
165
|
+
|
166
|
+
# Run the value through a filter and re-set it with the return.
|
167
|
+
value = hashes['filters'][name].call(value) if hashes['filters'].include?(name)
|
168
|
+
|
169
|
+
# Run an action block if there is one associated.
|
170
|
+
hashes['actions'][name].call(value) if hashes['actions'].include?(name)
|
171
|
+
|
172
|
+
# Now that we've done all that, re-set the element of the choice hash
|
173
|
+
# with the (potentially) new value.
|
174
|
+
choices[name] = value
|
175
|
+
end
|
176
|
+
|
177
|
+
# Die if we're missing any required arguments
|
178
|
+
hard_required.each do |name, value|
|
179
|
+
raise ArgumentRequired unless choices[name]
|
180
|
+
end
|
181
|
+
|
182
|
+
# Home stretch. Go through all the defaults defined and if a choice
|
183
|
+
# does not exist in our choices hash, set its value to the requested
|
184
|
+
# default.
|
185
|
+
hashes['defaults'].each do |name, value|
|
186
|
+
choices[name] = value unless choices[name]
|
187
|
+
end
|
188
|
+
|
189
|
+
# Return the choices hash.
|
190
|
+
choices
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
# Turns trailing command line arguments into an array for an arrayed value
|
195
|
+
def arrayize_arguments(name, args)
|
196
|
+
# Go through trailing arguments and suck them in if they don't seem
|
197
|
+
# to have an owner.
|
198
|
+
array = []
|
199
|
+
potential_args = args.dup
|
200
|
+
until (arg = potential_args.shift) =~ /^-/ || arg.nil?
|
201
|
+
array << arg
|
202
|
+
end
|
203
|
+
array
|
204
|
+
end
|
205
|
+
|
206
|
+
def make_validation(validation)
|
207
|
+
case validation
|
208
|
+
when Proc then
|
209
|
+
validation
|
210
|
+
when Regexp, String then
|
211
|
+
Regexp.new(validation.to_s)
|
212
|
+
else
|
213
|
+
raise ValidateExpectsRegexpOrBlock
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# All the possible exceptions this module can raise.
|
218
|
+
class ParseError < Exception; end
|
219
|
+
class HashExpectedForOption < Exception; end
|
220
|
+
class UnknownOption < ParseError; end
|
221
|
+
class ArgumentRequired < ParseError; end
|
222
|
+
class ValidateExpectsRegexpOrBlock < ParseError; end
|
223
|
+
class ArgumentValidationFails < ParseError; end
|
224
|
+
class InvalidArgument < ParseError; end
|
225
|
+
class ArgumentRequiredWithValid < ParseError; end
|
226
|
+
end
|
227
|
+
end
|