Class: Clip::Parser
- Inherits:
-
Object
- Object
- Clip::Parser
- Defined in:
- lib/clip.rb
Instance Attribute Summary collapse
-
#banner ⇒ Object
Set the usage ‘banner’ displayed when calling
to_s
to display the usage message. -
#remainder ⇒ Object
readonly
Returns any remaining command line arguments that were not parsed because they were neither flags or option/value pairs.
Instance Method Summary collapse
-
#errors ⇒ Object
Returns a
Hash
of errors (by the long name) of any errors encountered during parsing. -
#flag(short, long, options = {}) ⇒ Object
Declare a parameter as a simple boolean flag.
-
#help ⇒ Object
Returns a formatted
String
indicating the usage of the parser, formatted to fit within 80 display columns. -
#help_with(short, long = "--help") ⇒ Object
Override the flag to trigger help usage.
-
#initialize ⇒ Parser
constructor
:nodoc:.
-
#optional(short, long, options = {}, &block) ⇒ Object
(also: #opt)
Declare an optional parameter for your parser.
-
#options ⇒ Object
:nodoc:.
-
#order ⇒ Object
:nodoc:.
-
#parse(args) ⇒ Object
Parse the given
args
and set the corresponding instance fields to the given values. -
#required(short, long, options = {}, &block) ⇒ Object
(also: #req)
Declare a required parameter for your parser.
-
#to_s ⇒ Object
Returns a formatted
String
of thehelp
method prefixed by any parsing errors. -
#valid? ⇒ Boolean
Indicates whether or not the parsing process succeeded.
Constructor Details
#initialize ⇒ Parser
:nodoc:
147 148 149 150 151 152 153 |
# File 'lib/clip.rb', line 147 def initialize # :nodoc: @errors = {} @valid = true @longest = 10 @help_long = "--help" @help_short = "-h" end |
Instance Attribute Details
#banner ⇒ Object
Set the usage ‘banner’ displayed when calling to_s
to display the usage message. If not set, the default will be used. If the value is set this completely replaces the default
36 37 38 |
# File 'lib/clip.rb', line 36 def @banner end |
#remainder ⇒ Object (readonly)
Returns any remaining command line arguments that were not parsed because they were neither flags or option/value pairs
30 31 32 |
# File 'lib/clip.rb', line 30 def remainder @remainder end |
Instance Method Details
#errors ⇒ Object
Returns a Hash
of errors (by the long name) of any errors encountered during parsing. If you simply want to display error messages to the user, you can just print out a call to the to_s method.
226 227 228 |
# File 'lib/clip.rb', line 226 def errors @errors end |
#flag(short, long, options = {}) ⇒ Object
Declare a parameter as a simple boolean flag. This declaration will create a “question” method matching the given long
. For example, declaring with the name of ‘verbose’ will create a method on your parser called verbose?
.
options
Valid options are:
-
desc
: Descriptive text for the flag
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/clip.rb', line 126 def flag(short, long, ={}) check_args(short, long) short = short.to_sym long = long.gsub('-', '_').to_sym self.class.class_eval do define_method("flag_#{long}") do instance_variable_set("@#{long}", true) end define_method("#{long}?") do instance_variable_get("@#{long}") end end self.[long] = Flag.new(short, long, ) self.[short] = self.[long] self.order << self.[long] check_longest(long) end |
#help ⇒ Object
Returns a formatted String
indicating the usage of the parser, formatted to fit within 80 display columns.
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/clip.rb', line 233 def help out = "" if out << "#{}\n" else out << "Usage:\n" end order.each do |option| line = sprintf("-%-2s --%-#{@longest}s ", option.short, option.long.to_s.gsub('_', '-')) out << line if line.length + option.description.length <= 80 out << option.description else rem = 80 - line.length desc = option.description i = 0 while i < desc.length out << "\n" if i > 0 j = [i + rem, desc.length].min while desc[j..j] =~ /[\w\d]/ j -= 1 end chunk = desc[i..j].strip out << " " * line.length if i > 0 out << chunk i = j + 1 end end if option.has_default? out << " (default: #{option.default})" end if option.required? out << " REQUIRED" end out << "\n" end out end |
#help_with(short, long = "--help") ⇒ Object
Override the flag to trigger help usage. By default the short flag ‘-h’ and long flag ‘–help’ will trigger displaying usage. If you need to override this, particularly in the case of ‘-h’, call this method
43 44 45 46 |
# File 'lib/clip.rb', line 43 def help_with(short, long="--help") @help_short = short @help_long = long end |
#optional(short, long, options = {}, &block) ⇒ Object Also known as: opt
Declare an optional parameter for your parser. This creates an accessor method matching the long
parameter and a present method long?
. The short
parameter indicates the single-letter equivalent. Options that use the ‘-’ character as a word separator are converted to method names using ‘_’. For example the name ‘exclude-files’ would create two methods named exclude_files
and exclude_files?
.
When the :multi
option is enabled, the associated accessor method will return an Array
instead of a single scalar value.
options
Valid options include:
-
desc
: a helpful description (used for printing usage) -
default
: a default value to provide if one is not given -
multi
: indicates that mulitple values are okay for this param. -
block
: an optional block to process the parsed value
Note that specifying the :multi
option means that the parameter can be specified several times with different values, or that a single comma-separated value can be specified which will then be broken up into separate tokens.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/clip.rb', line 70 def optional(short, long, ={}, &block) check_args(short, long) short = short.to_sym long = long.gsub('-', '_').to_sym var_name = "@#{long}".to_sym self.class.class_eval do define_method("#{long}=".to_sym) do |v| begin v = yield(v) if block_given? instance_variable_set(var_name, v) rescue StandardError => e @valid = false @errors[long] = e. end end define_method(long.to_sym) do instance_variable_get(var_name) end define_method("#{long}?") do !instance_variable_get(var_name).nil? end end self.[short] = self.[long] = Option.new(short, long, ) self.order << self.[long] check_longest(long) end |
#options ⇒ Object
:nodoc:
293 294 295 |
# File 'lib/clip.rb', line 293 def # :nodoc: (@options ||= {}) end |
#order ⇒ Object
:nodoc:
297 298 299 |
# File 'lib/clip.rb', line 297 def order # :nodoc: (@order ||= []) end |
#parse(args) ⇒ Object
Parse the given args
and set the corresponding instance fields to the given values. If any errors occurred during parsing you can get them from the Hash
returned by the errors
method.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/clip.rb', line 159 def parse(args) @valid = true args = Shellwords::shellwords(args) unless args.kind_of?(Array) consumed = [] option = nil args.each do |token| case token when @help_long, @help_short puts help exit 0 when /\A--\z/ consumed << token break when /^-(-)?\w/ consumed << token param = token.sub(/^-(-)?/, '').gsub('-', '_').to_sym option = [param] if option.nil? @errors[param] = "Unrecognized parameter" @valid = false next end if option.kind_of?(Flag) option.process(self, nil) option = nil end else if option consumed << token option.process(self, token) option = nil end end end @remainder = args - consumed # Find required options that are missing arguments .each do |param, opt| if opt.kind_of?(Option) and self.send(opt.long).nil? if opt.required? @valid = false @errors[opt.long.to_sym] = "Missing required parameter: #{opt.long}" elsif opt.has_default? opt.process(self, opt.default) end end end end |
#required(short, long, options = {}, &block) ⇒ Object Also known as: req
Declare a required parameter for your parser. If this parameter is not provided in the parsed content, the parser instance will be invalid (i.e. where valid? returns false
).
This method takes the same options as the optional method.
112 113 114 |
# File 'lib/clip.rb', line 112 def required(short, long, ={}, &block) optional(short, long, .merge({ :required => true }), &block) end |
#to_s ⇒ Object
Returns a formatted String
of the help
method prefixed by any parsing errors. Either way you have one method to call to let your users know what to do.
282 283 284 285 286 287 288 289 290 291 |
# File 'lib/clip.rb', line 282 def to_s out = "" unless valid? out << "Errors:\n" errors.each do |field, msg| out << "#{field}: #{msg}\n" end end out << help end |
#valid? ⇒ Boolean
Indicates whether or not the parsing process succeeded. If this returns false
you probably just want to print out a call to the to_s method.
217 218 219 |
# File 'lib/clip.rb', line 217 def valid? @valid end |