class Cmdline::CmdLine
Public Class Methods
new(*)
click to toggle source
Calls superclass method
# File lib/cmdline.rb, line 91 def initialize(*) super self.options ||= {} self.commands ||= {} self.command ||= "" self.arguments ||= [] self.command_arguments ||= [] self.program_name ||= "" end
Public Instance Methods
add_argument(name, description)
click to toggle source
# File lib/cmdline.rb, line 131 def add_argument(name, description) argument = Argument.new( name: name.to_s, description: description.to_s ) addarg(argument) end
add_command(name, description)
click to toggle source
# File lib/cmdline.rb, line 150 def add_command(name, description) if self.arguments.size.zero? add_argument("command", "the command to execute") elsif self.arguments.first.name != "command" raise(ArgumentError, "cannot have both arguments and commands") end cmd = Command.new( name: name.to_s, description: description.to_s ) self.commands[cmd.name] = cmd end
add_flag(short, long, description)
click to toggle source
# File lib/cmdline.rb, line 101 def add_flag(short, long, description) option = Option.new( short_name: short.to_s, long_name: long.to_s, value_string: "", description: description.to_s ) addopt(option) end
add_option(short, long, value, description)
click to toggle source
# File lib/cmdline.rb, line 112 def add_option(short, long, value, description) option = Option.new( short_name: short.to_s, long_name: long.to_s, value_string: value.to_s, description: description.to_s ) addopt(option) end
add_trailing_arguments(name, description)
click to toggle source
# File lib/cmdline.rb, line 140 def add_trailing_arguments(name, description) argument = Argument.new( name: name.to_s, description: description.to_s, trailing: true ) addarg(argument) end
argument_value(name)
click to toggle source
# File lib/cmdline.rb, line 360 def argument_value(name) self.arguments.each do |arg| if arg.name == name return arg.value end end raise(ArgumentError, "unknown argument") end
command_arguments_values()
click to toggle source
# File lib/cmdline.rb, line 381 def command_arguments_values raise(RuntimeError, "no command defined") if self.commands.empty? self.command_arguments end
command_name()
click to toggle source
# File lib/cmdline.rb, line 376 def command_name raise(RuntimeError, "no command defined") if self.commands.empty? self.command end
command_name_and_arguments()
click to toggle source
# File lib/cmdline.rb, line 386 def command_name_and_arguments raise(RuntimeError, "no command defined") if self.commands.empty? [self.command, *self.command_arguments] end
die(format, *args)
click to toggle source
# File lib/cmdline.rb, line 165 def die(format, *args) msg = sprintf(format, *args) STDERR.puts("error: #{msg}") exit(1) end
is_option_set(name)
click to toggle source
# File lib/cmdline.rb, line 346 def is_option_set(name) opt = self.options[name] raise(ArgumentError, "unknown option") if opt.nil? opt.set end
option_value(name)
click to toggle source
# File lib/cmdline.rb, line 352 def option_value(name) opt = self.options[name] raise(ArgumentError, "unknown option") if opt.nil? return opt.value if opt.set opt.default end
parse(args)
click to toggle source
# File lib/cmdline.rb, line 171 def parse(args) die("empty argument array") if args.size == 0 self.program_name = args.shift while args.size > 0 arg = args.first if arg == "--" args.shift break end is_short = arg.size == 2 && arg[0] == "-" && arg[1] != "-" is_long = arg.size > 2 && arg[0,2] == "--" if is_short || is_long key = if is_short arg[1,2] else arg[2..] end opt = self.options[key] die("unknown option \"%s\"", key) if opt.nil? opt.set = true if opt.value_string.empty? args = args[1..] else die("missing value for option \"%s\"", key) if args.size < 2 opt.value = args[1] args = args[2..] end else break end end if self.arguments.size > 0 && !is_option_set("help") last = self.arguments.last min = self.arguments.size min -= 1 if last.trailing die("missing argument(s)") if args.size < min min.times do |i| self.arguments[i].value = args[i] end args = args[min..] if last.trailing last.trailing_values = args args = args[args.size..] end end if self.commands.size > 0 self.command = self.arguments.first.value self.command_arguments = args end if !is_option_set("help") if self.commands.size > 0 cmd = self.commands[self.command] if cmd.nil? die("unknown command \"%s\"", self.command) end elsif args.size > 0 die("invalid extra argument(s)") end end if is_option_set("help") print_usage exit(0) end end
print_usage()
click to toggle source
# File lib/cmdline.rb, line 252 def print_usage usage = sprintf("Usage: %s OPTIONS", self.program_name) if self.arguments.size > 0 self.arguments.each do |arg| if arg.trailing usage << sprintf(" [<%s> ...]", arg.name) else usage << sprintf(" <%s>", arg.name) end end end usage << "\n\n" opt_strs = {} max_width = 0 self.options.each do |_, opt| next if opt_strs[opt] buf = "" if opt.short_name != "" buf << sprintf("-%s", opt.short_name) end if opt.long_name != "" if opt.short_name != "" buf << ", " end buf << sprintf("--%s", opt.long_name) end if opt.value_string != "" buf << sprintf(" <%s>", opt.value_string) end opt_strs[opt] = buf if buf.size > max_width max_width = buf.size end end if self.commands.size > 0 self.commands.each do |name, _| max_width = name.size if name.size > max_width end elsif self.arguments.size > 0 self.arguments.each do |arg| max_width = arg.name.size if arg.name.size > max_width end end # Print options usage << "OPTIONS\n\n" opts = [] opt_strs.each do |opt, _| opts << opt end # TODO: sort options opts.each do |opt| usage << sprintf("%-*s %s", max_width, opt_strs[opt], opt.description) usage << sprintf(" (default: %s)", opt.default) unless opt.default.empty? usage << "\n" end if self.commands.size > 0 usage << "\nCOMMANDS\n\n" names = [] self.commands.each do |name, _| names << name end names.sort! names.each do |name| cmd = self.commands[name] usage << sprintf("%-*s %s\n", max_width, cmd.name, cmd.description) end elsif self.arguments.size > 0 usage << "\nARGUMENTS\n\n" self.arguments.each do |arg| usage << sprintf("%-*s %s\n", max_width, arg.name, arg.description) end end printf(usage) end
set_option_default(name, value)
click to toggle source
# File lib/cmdline.rb, line 123 def set_option_default(name, value) option = self.options[name] raise(ArgumentError, "unknown option") if option.nil? raise(ArgumentError, "flags cannot have a default value") if option.value_string.empty? option.default = value end
trailing_arguments_values(name)
click to toggle source
# File lib/cmdline.rb, line 369 def trailing_arguments_values(name) raise(ArgumentError, "empty argument array") if self.arguments.empty? last = self.arguments.last raise(ArgumentError, "no trailing arguments") unless last.trailing last.trailing_values end
Private Instance Methods
addarg(arg)
click to toggle source
# File lib/cmdline.rb, line 411 def addarg(arg) raise(ArgumentError, "cannot have both arguments and commands") if self.commands.size > 0 if self.arguments.size > 0 last = self.arguments.last if last.trailing raise(ArgumentError, "cannot add argument after trailing argument") end end self.arguments << arg end
addopt(opt)
click to toggle source
# File lib/cmdline.rb, line 393 def addopt(opt) if !opt.short_name.empty? if opt.short_name.size != 1 raise(ArgumentError, "option short names must be one character long") end self.options[opt.short_name] = opt end if !opt.long_name.empty? if opt.long_name.size < 2 raise(ArgumentError, "option long names must be at least two characters long") end self.options[opt.long_name] = opt end end