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