| Class | CommandLine::Application |
| In: |
lib/commandline/application.rb
|
| Parent: | Object |
| DEFAULT_CONSOLE_WIDTH | = | 70 | TODO: Consolidate these with OptionParser - put in command line | |
| MIN_CONSOLE_WIDTH | = | 10 | ||
| DEFAULT_BODY_INDENT | = | 4 |
| initialize | -> | __child_initialize |
| args | [R] | |
| argv | [R] |
# File lib/commandline/application.rb, line 269
269: def self.__set_auto_run
270: at_exit { @@child_class.run }
271: end
# File lib/commandline/application.rb, line 261
261: def self.inherited(child_class)
262: @@appname = caller[0][/.*:/][0..-2]
263: @@child_class = child_class
264: if @@appname == $0
265: __set_auto_run
266: end
267: end
# File lib/commandline/application.rb, line 41
41: def initialize
42: @synopsis = ""
43: @arg_arity = [0,0]
44: @options = []
45: @arg_names = []
46: @args = []
47: @replay = false
48: @replay_file = ".replay"
49:
50: __initialize_text_formatting
51:
52: # Call the child usurped initialize
53: __child_initialize if
54: self.class.private_instance_methods(false).include?("__child_initialize")
55:
56: @option_parser ||= CommandLine::OptionParser.new(@options)
57: end
# File lib/commandline/application.rb, line 238
238: def self.run(argv=ARGV)
239: # Usurp an existing initialize so ours can be called first.
240: # We rename it __child_initialize and call it from initialize.
241: if self.private_instance_methods(false).include?("initialize")
242: $VERBOSE, verbose = nil, $VERBOSE
243: self.class_eval {
244: alias :__child_initialize :initialize
245: remove_method :initialize
246: }
247: $VERBOSE = verbose
248: end
249: obj = self.new
250: obj.__parse_command_line(argv)
251: obj.main
252:
253: #alias :user_init :initialize
254: #@@child_class.new.main if ($0 == @@appname)
255: obj
256: rescue => err
257: puts "ERROR: #{err}"
258: exit(-1)
259: end
# File lib/commandline/application.rb, line 405
405: def __debug
406: {
407: :names => %w(--debug -d),
408: :arity => [0,0],
409: :opt_description => "Sets debug to true.",
410: :arg_description => "",
411: :opt_found => lambda { $DEBUG = true }
412: }
413: end
# File lib/commandline/application.rb, line 364
364: def __help
365: {
366: :names => %w(--help -h),
367: :arity => [0,0],
368: :opt_description => "Displays help page.",
369: :arg_description => "",
370: :opt_found => lambda { puts man; exit },
371: :opt_not_found => false
372: }
373: end
# File lib/commandline/application.rb, line 334
334: def __initialize_text_formatting
335: #
336: # Formatting defaults
337: #
338: console_width = ENV["COLUMNS"]
339: @columns =
340: if console_width.nil?
341: DEFAULT_CONSOLE_WIDTH
342: elsif console_width < MIN_CONSOLE_WIDTH
343: console_width
344: else
345: console_width - DEFAULT_BODY_INDENT
346: end
347: @body_indent = DEFAULT_BODY_INDENT
348: @tag_paragraph = false
349: @order = :index # | :alpha
350: end
# File lib/commandline/application.rb, line 297
297: def __parse_command_line(argv)
298: @argv = argv
299: if @replay && File.exist?(@replay_file) && !@argv.grep("-r").empty?
300: __restore_argv
301: elsif @argv.empty? && @arg_arity[0] != 0
302: puts usage
303: exit(0)
304: end
305:
306: begin
307: @option_data = @option_parser.parse(@argv)
308: @args = @option_data.args
309: rescue => err
310: puts err
311: puts
312: puts usage
313: exit(-1)
314: end
315:
316: __validate_args(@option_data.args)
317: @arg_names.each_with_index { |name, idx|
318: instance_variable_set("@#{name}", @option_data.args[idx])
319: }
320:
321: __save_argv
322: end
# File lib/commandline/application.rb, line 292
292: def __restore_argv
293: @argv = File.read(@replay_file).gsub(/\n/, "").split
294: raise "Bad @argv" unless @argv.kind_of?(Array)
295: end
# File lib/commandline/application.rb, line 279
279: def __save_argv
280: return unless @replay
281:
282: line = 0
283: File.open(@replay_file, "w") { |f|
284: @argv.each { |arg|
285: f.puts "\n" if arg[0] == ?- && line != 0
286: f.print " #{arg}"
287: line += 1
288: }
289: }
290: end
# File lib/commandline/application.rb, line 324
324: def __validate_arg_arity(arity)
325: min, max = *arity
326: raise(InvalidArgumentArityError, "Minimum argument arity '#{min}' must be "+
327: "greater than or equal to 0.") unless min >= 0
328: raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
329: "greater than or equal to -1.") if max < -1
330: raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
331: "greater than minimum arg_arity '#{min}'.") if max < min && max != -1
332: end
# File lib/commandline/application.rb, line 352
352: def __validate_args(od_args)
353: size = od_args.size
354: min, max = @arg_arity
355: max = 1.0/0.0 if -1 == max
356: raise(ArgumentError,
357: "Missing expected arguments. Found #{size} but expected #{min}. "+
358: "#{od_args.inspect}\n"+
359: "#{usage}") if size < min
360: raise(ArgumentError, "Too many arguments. Found #{size} but "+
361: "expected #{max}.\n#{usage}") if size > max
362: end
# File lib/commandline/application.rb, line 375
375: def __verbose
376: {
377: :names => %w(--verbose -v),
378: :arity => [0,0],
379: :opt_description => "Sets verbosity level. Subsequent "+
380: "flags increase verbosity level",
381: :arg_description => "",
382: :opt_found => lambda { @verbose ||= -1; @verbose += 1 },
383: :opt_not_found => nil
384: }
385: end
# File lib/commandline/application.rb, line 387
387: def __version
388: {
389: :names => %w(--version -V),
390: :arity => [0,0],
391: :opt_description => "Displays application version.",
392: :arg_description => "",
393: :opt_found => lambda {
394: begin
395: puts "#{name} - Version: #{version}"
396: rescue
397: puts "No version specified"
398: end;
399: exit
400: },
401: :opt_not_found => nil
402: }
403: end
# File lib/commandline/application.rb, line 230
230: def append_arg
231: CommandLine::OptionParser::GET_ARG_ARRAY
232: end
expected_args :cmd Now, what to do if command line has more args than expected app —app-option cmd —cmd-option arg-for-cmd
# File lib/commandline/application.rb, line 134
134: def expected_args(*exp_args)
135: @arg_names = []
136: case exp_args.size
137: when 0 then @arg_arity = [0,0]
138: when 1
139: case exp_args[0]
140: when Fixnum
141: v = exp_args[0]
142: @arg_arity = [v,v]
143: when Symbol
144: @arg_names = exp_args
145: @arg_arity = [1,1]
146: when Array
147: v = exp_args[0]
148: __validate_arg_arity(v)
149: @arg_arity = v
150: else
151: raise(InvalidArgumentArityError,
152: "Args must be a Fixnum or Array: #{exp_args[0].inspect}.")
153: end
154: else
155: @arg_names = exp_args
156: size = exp_args.size
157: @arg_arity = [size, size]
158: end
159: end
# File lib/commandline/application.rb, line 225
225: def get_arg
226: CommandLine::OptionParser::GET_ARGS
227: end
# File lib/commandline/application.rb, line 273
273: def main
274: #raise(MissingMainError, "Method #main must be defined in class #{@@child_class}.")
275: @@child_class.class_eval %{ def main; end }
276: #self.class_eval %{ def main; end }
277: end
# File lib/commandline/application.rb, line 170
170: def man
171: require 'text/format'
172: f = Text::Format.new
173: f = Text::Format.new
174: f.columns = @columns
175: f.first_indent = 4
176: f.body_indent = @body_indent
177: f.tag_paragraph = false
178:
179: s = []
180: s << ["NAME\n"]
181:
182: nm = "#{short_description}".empty? ? name : "#{name} - #{short_description}"
183: s << f.format(nm)
184:
185: sn = "#{synopsis}".empty? ? "" : "#{name} #{synopsis}"
186: unless sn.empty?
187: s << "SYNOPSIS\n"
188: s << f.format(sn)
189: end
190:
191: dc = "#{long_description}"
192: unless dc.empty?
193: s << "DESCRIPTION\n"
194: s << f.format(dc)
195: end
196:
197: op = option_parser.to_s
198: unless op.empty?
199: s << option_parser.to_s
200: end
201:
202: ar = "#{author}"
203: unless ar.empty?
204: s << "AUTHOR: #{ar}"
205: end
206:
207:
208: ct = "COPYRIGHT (c) #{copyright}"
209: unless "#{copyright}".empty?
210: s << ct
211: end
212:
213: s.join("\n")
214: end
# File lib/commandline/application.rb, line 63
63: def option(*args)
64: @options ||= []
65: new_list = []
66: args.each { |arg|
67: new_list <<
68: case arg
69: when :help then __help
70: when :debug then __debug
71: when :verbose then __verbose
72: when :version then __version
73: else arg
74: end
75: }
76: #p new_list
77: @options << CommandLine::Option.new(*new_list)
78: end
# File lib/commandline/application.rb, line 59
59: def options(*opts)
60: opts.each { |opt| option(*[opt].flatten) }
61: end
# File lib/commandline/application.rb, line 234
234: def required
235: CommandLine::OptionParser::OPT_NOT_FOUND_BUT_REQUIRED
236: end
# File lib/commandline/application.rb, line 166
166: def usage
167: " Usage: #{name} #{synopsis}"
168: end