Class: Clip::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/clip.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

:nodoc:



125
126
127
128
# File 'lib/clip.rb', line 125

def initialize # :nodoc:
  @errors = {}
  @valid = true
end

Instance Attribute Details

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



34
35
36
# File 'lib/clip.rb', line 34

def banner
  @banner
end

#remainderObject (readonly)

Returns any remaining command line arguments that were not parsed because they were neither flags or option/value pairs



28
29
30
# File 'lib/clip.rb', line 28

def remainder
  @remainder
end

Instance Method Details

#errorsObject

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.



197
198
199
# File 'lib/clip.rb', line 197

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



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/clip.rb', line 104

def flag(short, long, options={})
  short = short.to_sym
  long = long.to_sym

  check_args(short, long)

  eval <<-EOF
    def flag_#{long}
      @#{long} = true
    end

    def #{long}?
      return @#{long} || false
    end
  EOF

  self.options[long] = Flag.new(short, long, options)
  self.options[short] = self.options[long]
  self.order << self.options[long]
end

#helpObject

Returns a formatted String indicating the usage of the parser



203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/clip.rb', line 203

def help
  out = ""
  if banner
    out << "#{banner}\n"
  else
    out << "Usage:\n"
  end

  order.each do |option|
    out << "#{option.usage}\n"
  end
  out
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. 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 a method named 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.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/clip.rb', line 57

def optional(short, long, options={}, &block)
  short = short.to_sym
  long = long.to_sym
  check_args(short, long)

  var_name = "@#{long}".to_sym
  if block
    self.class.send(:define_method, "#{long}=".to_sym) do |v|
      instance_variable_set(var_name, block.call(v))
    end
  else
    self.class.send(:define_method, "#{long}=".to_sym) do |v|
      instance_variable_set(var_name, v)
    end
  end

  self.class.send(:define_method, long.to_sym) do
    instance_variable_get(var_name)        
  end

  self.options[long] = Option.new(short, long, options)
  self.options[short] = self.options[long]
  self.order << self.options[long]
end

#optionsObject

:nodoc:



232
233
234
# File 'lib/clip.rb', line 232

def options # :nodoc:
  (@options ||= {})
end

#orderObject

:nodoc:



236
237
238
# File 'lib/clip.rb', line 236

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.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/clip.rb', line 134

def parse(args)
  @valid = true
  args = args.split(/\s+/) unless args.kind_of?(Array)
  consumed = []
  if args.member?("--help")
    puts help
    exit 0
  end
  option = nil

  args.each do |token|
    case token
    when /^-(-)?\w/
      consumed << token
      param = token.sub(/^-(-)?/, '').sub('-', '_').to_sym
      option = options[param]
      unless option
        @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
  options.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.



90
91
92
# File 'lib/clip.rb', line 90

def required(short, long, options={}, &block)
  optional(short, long, options.merge({ :required => true }), &block)
end

#to_sObject

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.



221
222
223
224
225
226
227
228
229
230
# File 'lib/clip.rb', line 221

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.

Returns:

  • (Boolean)


188
189
190
# File 'lib/clip.rb', line 188

def valid?
  @valid
end