Class: ArgvParser

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-process-controller/argv_parser.rb

Overview

TODO: separator between options

Defined Under Namespace

Classes: IteratableArray, Option, UnnamedOption

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argv) {|_self| ... } ⇒ ArgvParser

Returns a new instance of ArgvParser.

Yields:

  • (_self)

Yield Parameters:

  • _self (ArgvParser)

    the object that the method was called on



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/ruby-process-controller/argv_parser.rb', line 139

def initialize argv
  # TODO ! Normalisation of "=" and ",". Remove "=", join comma separated arrays to arrays.

  @argv = IteratableArray.new(argv)
  @values = {}

  @header = []
  @footer = []
  
  @errors = []
  
  @heading_opts  = IteratableArray.new
  @tailing_opts  = IteratableArray.new
  @floating_opts = IteratableArray.new
  
  @opts = {}
  @opts_list = []

  @tailing_start_position = 0
  
  yield(self) if block_given?
end

Instance Attribute Details

#errorsObject (readonly)

Returns the value of attribute errors.



196
197
198
# File 'lib/ruby-process-controller/argv_parser.rb', line 196

def errors
  @errors
end

Returns the value of attribute footer.



196
197
198
# File 'lib/ruby-process-controller/argv_parser.rb', line 196

def footer
  @footer
end

#headerObject (readonly)

Returns the value of attribute header.



196
197
198
# File 'lib/ruby-process-controller/argv_parser.rb', line 196

def header
  @header
end

Instance Method Details

#[](option) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/ruby-process-controller/argv_parser.rb', line 162

def [] option
  if @values.has_key?(option)
    @values[option]
    
  elsif @values.has_key?(key = option.to_s)
    @values[key]
    
  elsif @values.has_key?(key = option.to_s.gsub(/_/, '-'))
    @values[key]

  elsif @values.has_key?(key = option.to_s.gsub(/_/, '-').upcase)
    @values[key]
  
  else
    nil
  end
end

#[]=(option, value) ⇒ Object



180
181
182
# File 'lib/ruby-process-controller/argv_parser.rb', line 180

def []= option, value
  @values[option] = value
end

#complete?Boolean

Returns:

  • (Boolean)


202
203
204
205
206
207
208
# File 'lib/ruby-process-controller/argv_parser.rb', line 202

def complete?
  (errors? || 
   !@argv.empty? ||
    unnamed_opts_incomplete?(@heading_opts) ||
    unnamed_opts_incomplete?(@tailing_opts) ||
    unnamed_opts_incomplete?(@floating_opts)) ? false : true
end

#errors?Boolean

Returns:

  • (Boolean)


198
199
200
# File 'lib/ruby-process-controller/argv_parser.rb', line 198

def errors?
  !@errors.empty?
end

#floating_option(option, comment = nil, conditions = nil, &block) ⇒ Object

“[VALUE]” “VALUE” “[VALUE]…” (zero or more space separated values) “VALUE…” (one or more space separated values)



400
401
402
# File 'lib/ruby-process-controller/argv_parser.rb', line 400

def floating_option(option, comment = nil, conditions = nil, &block)
  push_unnamed_option(@floating_opts, parse_unnamed_option(option, comment, conditions, &block))
end

#heading_option(option, comment = nil, conditions = nil, &block) ⇒ Object

“[VALUE]” “VALUE” “[VALUE]…” (zero or more space separated values) “VALUE…” (one or more space separated values)



384
385
386
# File 'lib/ruby-process-controller/argv_parser.rb', line 384

def heading_option(option, comment = nil, conditions = nil, &block)
  push_unnamed_option(@heading_opts, parse_unnamed_option(option, comment, conditions, &block))
end

#inspectObject



192
193
194
# File 'lib/ruby-process-controller/argv_parser.rb', line 192

def inspect
  @values.inspect
end

#merge(hash) ⇒ Object



188
189
190
# File 'lib/ruby-process-controller/argv_parser.rb', line 188

def merge hash
  to_hash.merge hash
end

#option(option, comment = nil, conditions = nil, &block) ⇒ Object

“–option-foo [VALUE]” “–option [VALUE]…” (zero or more comma separated values) “–option VALUE” “–option VALUE…” (one or more comma separated values) “–option” “–[no-]option”

“-ooo [VALUE]” “-o [VALUE]…” (zero or more comma separated values) “-o VALUE” “-o VALUE…” (one or more comma separated values) “-o”

“-o, –option [VALUE]” “-o, –option [VALUE]…” (zero or more comma separated values) “-o, –option VALUE” “-o, –option VALUE…” (one or more comma separated values) “-o, –option” “-o, –[no-]option”



372
373
374
375
376
377
378
# File 'lib/ruby-process-controller/argv_parser.rb', line 372

def option(option, comment = nil, conditions = nil, &block)
  option = parse_option(option, comment, conditions, &block)
  
  @opts_list.push option
  @opts[option.short_option_name] = option if option.short_option_name
  @opts[option.option_name] = option if option.option_name
end

#parse!Object

TODO: “tar -czf file.tgz dir”, “tar czf file.tgz dir”



450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
# File 'lib/ruby-process-controller/argv_parser.rb', line 450

def parse!
  @argv.position = 0
  
  parse_unnamed_opts @heading_opts
  
  @argv.each_with_iterator do |item|
    next unless (matchdata = item.match(/^--?(no-)?([\w\d\-\?]+)$/))
    next unless (option = @opts[matchdata[2]])
    
    @tailing_start_position = @argv.position
    
    if option.option_is_boolean
      check_and_assign_value(option, (matchdata[1].nil? ? true : false))
      next :and_crop, 1
      
    elsif @argv.look_ahead =~ /^-/ || !@argv.look_ahead
      if option.value_is_optional
        check_and_assign_value(option, true)
      else
        errors << "#{option.display_names} must have a value"
      end
      next :and_crop, 1
    else
      check_and_assign_value(option, @argv.look_ahead)
      next :and_crop, 2
    end
  end
  
  unless @argv.detect{|item| item =~ /^-/}
    @argv.position = @tailing_start_position
    parse_unnamed_opts @tailing_opts
    
    @argv.position = 0
    parse_unnamed_opts @floating_opts
  end
end

#show_errors(output = STDERR) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/ruby-process-controller/argv_parser.rb', line 241

def show_errors output = STDERR
  
  # TODO: Check MacOS compatibility
  
  if ENV["LANG"].include?("UTF-8")
    header_line = "⬇⬇⬇ "
    footer_line = "⬆⬆⬆ "
  else
    header_line = "vvv "
    footer_line = "^^^ "
  end
  
  output << (header_line * 20 + "\n\n")
  output << (@errors * "\n" +  "\n") unless @errors.empty?
  output << ("Can't parse options: " + @argv * " " +  "\n") unless @argv.empty?
  output << ("Incomplete heading options: " + display_incomplete_required_unnamed_opts(@heading_opts) * " " + "\n") if unnamed_opts_incomplete?(@heading_opts)
  output << ("Incomplete tailing options: " + display_incomplete_required_unnamed_opts(@tailing_opts) * " " + "\n") if unnamed_opts_incomplete?(@tailing_opts)
  output << ("Incomplete floating options: " + display_incomplete_required_unnamed_opts(@floating_opts) * " " + "\n") if unnamed_opts_incomplete?(@floating_opts)
  output << ("\n" + (footer_line * 20) + "\n\n")
  
  output.flush if output.respond_to?(:flush)
end

#show_errors_and_optionsObject



236
237
238
239
# File 'lib/ruby-process-controller/argv_parser.rb', line 236

def show_errors_and_options
  show_errors
  show_options
end

#show_options(output = STDOUT) ⇒ Object



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/ruby-process-controller/argv_parser.rb', line 264

def show_options output = STDOUT
  output << (@header * "\n" + "\n\n") unless @header.empty?
  
  overview = @heading_opts.collect{|option| option.display}
  overview += [("[Options]..." unless @opts_list.empty?)]
    
  unless @floating_opts.empty?
    overview += @floating_opts.collect{|option| option.display}
    overview += [("[Options]..." unless @opts_list.empty?)]
  end
  
  overview += @tailing_opts.collect{|option| option.display}

  output << "Usage:\n  " + ("#{$0} " + (overview * " ") + "\n\n")
  
  options = @opts_list.collect {|option| option.columnized_display }
  unnamed_opts = (@heading_opts + @tailing_opts + @floating_opts).collect{|option| option.columnized_display}

  first_column = options.collect{|option| "#{option[0]},".length}.max
  second_column = (unnamed_opts.collect{|option| "#{option[0]}".length} + options.collect{|option| option[1] ? "#{option[1]} #{option[2]}".length : ("#{option[2]}".length - 1)}).max

  lines = unnamed_opts.collect do |option|
    sprintf("  %#{first_column}s %#{0 - second_column}s %s", nil, option[0], option[1])
  end
  
  lines.push ""
  lines.push "Options:"

  lines += options.collect do |option|
    if option[1]
      sprintf("  %#{first_column}s %#{0 - second_column}s %s", ("#{option[0]}," if option[0]), "#{option[1]} #{option[2]}", option[3])
    else
      sprintf("  %#{first_column - 1}s %#{-1-second_column}s %s", option[0], option[2], option[3])
    end
  end

  output << (lines * "\n" + "\n\n")
  
  output << (@footer * "\n" + "\n\n")
  
  output.flush if output.respond_to?(:flush)
end

#show_options_and_errorsObject



231
232
233
234
# File 'lib/ruby-process-controller/argv_parser.rb', line 231

def show_options_and_errors
  show_options
  show_errors
end

#show_options_and_errors_on_incompleteObject



222
223
224
225
226
227
228
229
# File 'lib/ruby-process-controller/argv_parser.rb', line 222

def show_options_and_errors_on_incomplete
  unless complete?
    show_options_and_errors
    true
  else
    false
  end
end

#tailing_option(option, comment = nil, conditions = nil, &block) ⇒ Object

“[VALUE]” “VALUE” “[VALUE]…” (zero or more space separated values) “VALUE…” (one or more space separated values)



392
393
394
# File 'lib/ruby-process-controller/argv_parser.rb', line 392

def tailing_option(option, comment = nil, conditions = nil, &block)
  push_unnamed_option(@tailing_opts, parse_unnamed_option(option, comment, conditions, &block))
end

#to_hashObject



184
185
186
# File 'lib/ruby-process-controller/argv_parser.rb', line 184

def to_hash
  @values
end