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