class Nucleon::Util::CLI::Parser

Attributes

arguments[RW]
extra[RW]
options[RW]
parser[RW]
processed[RW]
strict[RW]

Public Class Methods

new(args, banner = '', help = '', split_help = false) { |self| ... } click to toggle source
   # File lib/core/util/cli.rb
39 def initialize(args, banner = '', help = '', split_help = false)
40   @parser = OptionParser.new
41 
42   self.options   = {}
43   self.arguments = {}
44   self.extra     = {}
45   self.processed = false
46   self.strict    = true
47 
48   @arg_settings  = []
49 
50   self.banner  = banner
51   self.help    = help
52 
53   yield(self) if block_given?
54 
55   parse_command(args, split_help)
56 end
split(args, banner, separator = '') click to toggle source
    # File lib/core/util/cli.rb
 60 def self.split(args, banner, separator = '')
 61   check_args  = []
 62   main_args   = nil
 63   sub_command = nil
 64   sub_args    = []
 65 
 66   # Log level gets processed in main args so we can log executable init
 67   parse_log_value = false
 68 
 69   args.each do |arg|
 70     if arg =~ /^\-\-log_level(?=\=(.*))?/
 71       if $1
 72         Nucleon.log_level = $1
 73       else
 74         parse_log_value = true
 75       end
 76     elsif parse_log_value
 77       Nucleon.log_level = arg
 78       parse_log_value = false
 79     else
 80       check_args << arg
 81     end
 82   end
 83 
 84   check_args.each_index do |index|
 85     if !check_args[index].start_with?('-')
 86       main_args   = check_args[0, index]
 87       sub_command = check_args[index]
 88       sub_args    = check_args[index + 1, check_args.length - index + 1]
 89       break
 90     end
 91   end
 92 
 93   main_args = check_args.dup if main_args.nil?
 94   results   = [ Parser.new(main_args, banner, separator, true) ]
 95 
 96   if sub_command
 97     results << [ sub_command, sub_args ]
 98   end
 99 
100   return results.flatten
101 end

Public Instance Methods

arg(name, default, allowed_values, message_id, config = {}, &block) click to toggle source
    # File lib/core/util/cli.rb
377 def arg(name, default, allowed_values, message_id, config = {}, &block)
378   config       = Config.ensure(config)
379   name         = name.to_sym
380 
381   message_name = name.to_s + '_message'
382   message      = CLI.message(message_id, arguments[name])
383 
384   settings     = {
385     :name    => name,
386     :default => config.get(name, default),
387     :message => config.get(message_name.to_sym, message)
388   }
389   settings[:allowed] = allowed_values if allowed_values
390   settings[:block]   = block if block
391 
392   settings.delete(:default) if settings[:default].nil?
393 
394   @arg_settings << settings
395 end
arg_array(name, default, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
481 def arg_array(name, default, message_id, config = {})
482   arg(name, default, Array, message_id, config) do |value|
483     block_given? ? yield(value) : value
484   end
485 end
arg_bool(name, default, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
412 def arg_bool(name, default, message_id, config = {})
413   arg(name, default, nil, message_id, config) do |value|
414     value = Util::Data.value(value)
415     if value == true || value == false
416       block_given? ? yield(value) : value
417     else
418       nil
419     end
420   end
421 end
arg_float(name, default, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
449 def arg_float(name, default, message_id, config = {})
450   arg(name, default, Float, message_id, config) do |value|
451     block_given? ? yield(value) : value
452   end
453 end
arg_int(name, default, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
433 def arg_int(name, default, message_id, config = {})
434   arg(name, default, Integer, message_id, config) do |value|
435     block_given? ? yield(value) : value
436   end
437 end
arg_str(name, default, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
465 def arg_str(name, default, message_id, config = {})
466   arg(name, default, nil, message_id, config) do |value|
467     block_given? ? yield(value) : value
468   end
469 end
banner=(banner) click to toggle source
help() click to toggle source
    # File lib/core/util/cli.rb
111 def help
112   return parser.help
113 end
help=(help) click to toggle source
    # File lib/core/util/cli.rb
115 def help=help
116   if help.is_a?(Array)
117     help.each do |line|
118       parser.separator line
119     end
120   else
121     parser.separator help
122   end
123 end
option(name, default, option_str, allowed_values, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
352 def option(name, default, option_str, allowed_values, message_id, config = {})
353   config        = Config.ensure(config)
354   name          = name.to_sym
355   options[name] = config.get(name, default)
356 
357   message_name = name.to_s + '_message'
358   message      = CLI.message(message_id, options[name])
359 
360   option_str   = Util::Data.array(option_str)
361 
362   if allowed_values
363     parser.on(*option_str, allowed_values, config.get(message_name.to_sym, message)) do |value|
364       value         = yield(value) if block_given?
365       options[name] = value unless value.nil?
366     end
367   else
368     parser.on(*option_str, config.get(message_name.to_sym, message)) do |value|
369       value         = yield(value) if block_given?
370       options[name] = value unless value.nil?
371     end
372   end
373 end
option_array(name, default, option_str, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
473 def option_array(name, default, option_str, message_id, config = {})
474   option(name, default, option_str, Array, message_id, config) do |value|
475     block_given? ? yield(value) : value
476   end
477 end
option_bool(name, default, option_str, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
399 def option_bool(name, default, option_str, message_id, config = {})
400   option(name, default, option_str, nil, message_id, config) do |value|
401     value = Util::Data.value(value)
402     if value == true || value == false
403       block_given? ? yield(value) : value
404     else
405       nil
406     end
407   end
408 end
option_float(name, default, option_str, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
441 def option_float(name, default, option_str, message_id, config = {})
442   option(name, default, option_str, Float, message_id, config) do |value|
443     block_given? ? yield(value) : value
444   end
445 end
option_int(name, default, option_str, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
425 def option_int(name, default, option_str, message_id, config = {})
426   option(name, default, option_str, Integer, message_id, config) do |value|
427     block_given? ? yield(value) : value
428   end
429 end
option_str(name, default, option_str, message_id, config = {}) { |value| ... } click to toggle source
    # File lib/core/util/cli.rb
457 def option_str(name, default, option_str, message_id, config = {})
458   option(name, default, option_str, nil, message_id, config) do |value|
459     block_given? ? yield(value) : value
460   end
461 end
parse_command(args, split_help = false) click to toggle source
    # File lib/core/util/cli.rb
133 def parse_command(args, split_help = false)
134   args  = args.dup
135   error = false
136 
137   self.processed = false
138 
139   option_bool(:version, false,
140     '--version',
141     'nucleon.core.util.cli.options.version'
142   )
143   option_bool(:color, Util::Console.use_colors,
144     '--[no-]color',
145     'nucleon.core.util.cli.options.color'
146   )
147   option_bool(:parallel, Nucleon.parallel?,
148     '--[no-]parallel',
149     'nucleon.core.util.cli.options.parallel'
150   )
151   option_str(:log_level, nil,
152     '--log_level STR',
153     'nucleon.core.util.cli.options.log_level'
154   )
155   option_str(:exec_dir, nil,
156     '--exec_dir STR',
157     'nucleon.core.util.cli.options.exec_dir'
158   )
159   option_str(:encoded_params, false,
160     '--encoded STR',
161     'nucleon.core.util.cli.options.encoded'
162   )
163   if split_help
164     parser.on_tail('-h', CLI.message('nucleon.core.util.cli.options.short_help')) do
165       options[:help] = true
166     end
167     parser.on_tail('--help', CLI.message('nucleon.core.util.cli.options.extended_help')) do
168       options[:help]          = true
169       options[:extended_help] = true
170     end
171   else
172     parser.on_tail('-h', '--help', CLI.message('nucleon.core.util.cli.options.short_help')) do
173       options[:help] = true
174     end
175   end
176 
177   if strict
178     parser.parse!(args)
179     extra_args = {}
180   else
181     args, extra_args = parse_known_args(parser, args)
182   end
183 
184   # Now we can act on options given
185   options[:color] = Util::Console.use_colors
186 
187   if options[:version]
188     puts version
189     exit 0
190   end
191 
192   if options[:exec_dir]
193     Dir.chdir(options[:exec_dir])
194   end
195 
196   return if options[:help]
197 
198   parse_encoded
199 
200   self.extra = normalize_extra_options(extra_args) unless extra_args.empty?
201 
202   remaining_args = args.dup
203   arg_messages   = []
204 
205   if arguments.empty?
206     @arg_settings.each_with_index do |settings, index|
207       if index >= args.length
208         value = nil
209       else
210         value = Util::Data.value(args[index])
211       end
212 
213       if !value.nil? && settings.has_key?(:allowed)
214         allowed = settings[:allowed]
215         case allowed
216         when Class
217           if (allowed == Array)
218             value          = remaining_args
219             remaining_args = []
220           end
221           unless value.is_a?(allowed)
222             arg_messages << CLI.message(settings[:message])
223             error = true
224           end
225         when Array
226           unless allowed.include(value)
227             arg_messages << CLI.message(settings[:message])
228             error = true
229           end
230         end
231       end
232 
233       if value.nil?
234         if settings.has_key?(:default)
235           value = settings[:default]
236         else
237           error = true
238         end
239       end
240 
241       if !value.nil? && settings.has_key?(:block)
242         value = settings[:block].call(value)
243         error = true if value.nil?
244       end
245 
246       break if error
247 
248       remaining_args.shift unless remaining_args.empty?
249       self.arguments[settings[:name]] = value
250     end
251   end
252 
253   if error
254     if ! arg_messages.empty?
255       parser.warn(CLI.message('nucleon.core.util.cli.parse.error') + "\n\n" + arg_messages.join("\n") + "\n\n" + parser.help)
256     else
257       parser.warn(CLI.message('nucleon.core.util.cli.parse.error') + "\n\n" + parser.help)
258     end
259   else
260     self.processed = true
261   end
262 
263 rescue OptionParser::InvalidOption => e
264   parser.warn(e.message + "\n\n" + parser.help)
265 end
parse_encoded() click to toggle source
    # File lib/core/util/cli.rb
269 def parse_encoded
270   if options[:encoded_params]
271     encoded_properties = CLI.decode(options[:encoded_params])
272 
273     @arg_settings.each do |settings|
274       if encoded_properties.has_key?(settings[:name].to_sym)
275         self.arguments[settings[:name]] = encoded_properties.delete(settings[:name].to_sym)
276       end
277     end
278 
279     encoded_properties.each do |name, value|
280       self.options[name] = value
281 
282       if name == :color
283         Util::Console.use_colors = value
284       end
285     end
286   end
287   options.delete(:encoded_params)
288 end
parse_known_args(parser, args) click to toggle source
    # File lib/core/util/cli.rb
292 def parse_known_args(parser, args)
293   extra_args = []
294 
295   parse_args = lambda do |arg_list|
296     begin
297       original_list = arg_list.clone
298 
299       parser.parse! arg_list
300       args = arg_list
301 
302     rescue OptionParser::InvalidOption => e
303       extra_args += e.args
304       while arg_list[0] && arg_list[0][0] != '-'
305         extra_args << arg_list.shift
306       end
307       parse_args.call original_list - extra_args
308     end
309   end
310   parse_args.call args
311   [ args, extra_args ]
312 end
version() click to toggle source
    # File lib/core/util/cli.rb
127 def version
128   # Override in executable script
129 end

Protected Instance Methods

normalize_extra_options(arg_list) click to toggle source
    # File lib/core/util/cli.rb
316 def normalize_extra_options(arg_list)
317   options     = {}
318   last_option = nil
319 
320   Util::Data.array(arg_list).each do |arg|
321     components = arg.split('=')
322     value      = nil
323 
324     if components.size > 1
325       arg   = components[0]
326       value = components[1]
327     end
328 
329     if arg[0] == '-'
330       last_option          = arg.sub(/^\-+/, '').to_sym
331       options[last_option] = Util::Data.value(value) if value
332     else
333       if last_option
334         if options[last_option]
335           options[last_option] = [ options[last_option] ] unless options[last_option].is_a?(Array)
336           options[last_option] << Util::Data.value(arg)
337         else
338           options[last_option] = Util::Data.value(arg)
339         end
340       else
341         parser.warn(CLI.message('nucleon.core.util.cli.parse.error') + "\n\n" + parser.help)
342         break
343       end
344     end
345   end
346   options
347 end