def FancyGetopt(cmd, option_table, args): """ Parses command line options and parameter list. args is the argument list to be parsed, without the leading reference to the running program. Typically, this means "sys.argv[1:]". option_table is an instance of Ft.Lib.CommandLine.Options.Options. Raises an exception if args contains syntax errors. Returns a tuple of (options, args) where options is a dictionary and args is the list of args after the first arg that wasn't in option_table. Note the options return value is different than what getopt.getopt() returns. cmd is an Ft.Lib.CommandLine.Command instance, and is only used in reporting errors. """ short_opts = [] long_opts = [] short2long = {} takes_arg = {} # the resulting options options = {} for option in option_table: (short, long) = option.getForGetOpt(short2long, takes_arg) short_opts.append(short) long_opts.extend(long) short_opts = ''.join(short_opts) try: (opts, args) = getopt.getopt(args, short_opts, long_opts) except getopt.error, msg: raise CommandLineUtil.ArgumentError(cmd, str(msg))
def _parse_command_opts(self, arglist): options, arglist = FancyGetOpt.FancyGetopt(self, self.options, arglist) if not self.validate_options(options): return None # Args can either be a subcommand, or the start of the argument # list. Subcommand takes precedence. if self.subCommands: try: cmd = arglist[0] except IndexError: msg = "subcommand required" raise CommandLineUtil.ArgumentError(self, msg) try: cmd = self.subCommands[cmd] except KeyError: msg = "invalid subcommand: %s" % cmd raise CommandLineUtil.ArgumentError(self, msg) parsed = cmd._parse_command_opts(arglist[1:]) else: parsed = (self, options, self.validate_arguments(arglist)) return parsed
def __gen_command_line_help(self, command_string): """ Generates the indented usage summary only. """ # command_string looks like this: ' 4ss create user ' # i.e., it is '4ss create user', indented and ready to # have the option & argument syntax appended like so: # ' 4ss create user (syntax line 1) # (syntax line 2) # (syntax line 3)' # generate the option/arg syntax string, which looks like this: # '[--help] [[--username=<USER>] | [--anonymous]] # [--password=<PASSWORD>] [--port=<PORT>] [--host=<HOST>] # [--container=<PATH>] userName ' syntax_string = '' for opt in self.options: syntax_string += opt.gen_command_line() + ' ' if self.subCommands: if len(self.arguments): syntax_string += '[' syntax_string += '<subcommand> ' if len(self.arguments): syntax_string += '[' syntax_string += '<subcommand> ' if len(self.arguments): syntax_string += '] | [' if self.arguments: for arg in self.arguments: syntax_string += arg.gen_command_line() + ' ' if self.subCommands: syntax_string += ']' # wrap the syntax line to a width that won't exceed the console # width when appended to command_string command_size = len(command_string) syntax_string_lines = CommandLineUtil.wrap_text( syntax_string, CONSOLE_WIDTH - command_size) # append first line of wrapped syntax string to command_string # and indent the remaining lines appropriately lines = [command_string + syntax_string_lines[0]] indent = ' ' * command_size lines.extend([ indent + s for s in syntax_string_lines[1:] ]) return lines
def __gen_command_line_help(self, command_string): """ Generates the indented usage summary only. """ # command_string looks like this: ' 4ss create user ' # i.e., it is '4ss create user', indented and ready to # have the option & argument syntax appended like so: # ' 4ss create user (syntax line 1) # (syntax line 2) # (syntax line 3)' # generate the option/arg syntax string, which looks like this: # '[--help] [[--username=<USER>] | [--anonymous]] # [--password=<PASSWORD>] [--port=<PORT>] [--host=<HOST>] # [--container=<PATH>] userName ' syntax_string = '' for opt in self.options: syntax_string += opt.gen_command_line() + ' ' if self.subCommands: if len(self.arguments): syntax_string += '[' syntax_string += '<subcommand> ' if len(self.arguments): syntax_string += '[' syntax_string += '<subcommand> ' if len(self.arguments): syntax_string += '] | [' if self.arguments: for arg in self.arguments: syntax_string += arg.gen_command_line() + ' ' if self.subCommands: syntax_string += ']' # wrap the syntax line to a width that won't exceed the console # width when appended to command_string command_size = len(command_string) syntax_string_lines = CommandLineUtil.wrap_text( syntax_string, CONSOLE_WIDTH - command_size) # append first line of wrapped syntax string to command_string # and indent the remaining lines appropriately lines = [command_string + syntax_string_lines[0]] indent = ' ' * command_size lines.extend([indent + s for s in syntax_string_lines[1:]]) return lines
def run(self, options, arguments): if not self.function: raise CommandLineUtil.ArgumentError(self, "subcommand required") return self.function(options, arguments)
def _gen_usage(self, command_string): """ Generates the usage summary, example command line, and descriptions of options and subcommands or arguments """ lines = self.__gen_command_line_help(command_string) # saved for use in the example command_size = len(command_string) # generate the example, if available if self.example is not None: lines.append('\nExample:') text_width = CONSOLE_WIDTH - command_size text = CommandLineUtil.wrap_text(self.example, text_width) lines.append(command_string + text[0]) indent = ' ' * command_size lines.extend([indent + s for s in text[1:]]) # generate the option descriptions option_desc = self.options.generate_help() if option_desc: lines.append('\nOptions:') lines.extend(option_desc) # generate the subcommand descriptions if self.subCommands: max_cmd = 0 for cmd in self.subCommands.keys(): if len(cmd) > max_cmd: max_cmd = len(cmd) lines.append('\nSubcommands:') # column size = indent + longest command + gutter indent = ' ' * (2 + max_cmd + 2) + ' ' text_width = CONSOLE_WIDTH - len(indent) names = self.subCommands.keys() names.sort() for name in names: cmd = self.subCommands[name] text = CommandLineUtil.wrap_text(cmd.description, text_width) lines.append(' %-*s %s' % (max_cmd, name, text[0])) lines.extend([indent + s for s in text[1:]]) # generate the argument descriptions if self.arguments: max_arg = 0 for arg in self.arguments: if len(arg.name) > max_arg: max_arg = len(arg.name) lines.append('\nArguments:') # column size = indent + longest command + gutter indent = ' ' * (2 + max_arg + 2) text_width = CONSOLE_WIDTH - len(indent) for arg in self.arguments: text = CommandLineUtil.wrap_text(arg.description, text_width) lines.append(' %-*s %s' % (max_arg, arg.name, text[0])) lines.extend([indent + s for s in text[1:]]) lines.append('') # add a blank line return lines
def _gen_usage(self,command_string): """ Generates the usage summary, example command line, and descriptions of options and subcommands or arguments """ lines = self.__gen_command_line_help(command_string) # saved for use in the example command_size = len(command_string) # generate the example, if available if self.example is not None: lines.append('\nExample:') text_width = CONSOLE_WIDTH - command_size text = CommandLineUtil.wrap_text(self.example, text_width) lines.append(command_string + text[0]) indent = ' ' * command_size lines.extend([ indent + s for s in text[1:] ]) # generate the option descriptions option_desc = self.options.generate_help() if option_desc: lines.append('\nOptions:') lines.extend(option_desc) # generate the subcommand descriptions if self.subCommands: max_cmd = 0 for cmd in self.subCommands.keys(): if len(cmd) > max_cmd: max_cmd = len(cmd) lines.append('\nSubcommands:') # column size = indent + longest command + gutter indent = ' ' * (2 + max_cmd + 2) + ' ' text_width = CONSOLE_WIDTH - len(indent) names = self.subCommands.keys() names.sort() for name in names: cmd = self.subCommands[name] text = CommandLineUtil.wrap_text(cmd.description, text_width) lines.append(' %-*s %s' % (max_cmd, name, text[0])) lines.extend([ indent + s for s in text[1:] ]) # generate the argument descriptions if self.arguments: max_arg = 0 for arg in self.arguments: if len(arg.name) > max_arg: max_arg = len(arg.name) lines.append('\nArguments:') # column size = indent + longest command + gutter indent = ' ' * (2 + max_arg + 2) text_width = CONSOLE_WIDTH - len(indent) for arg in self.arguments: text = CommandLineUtil.wrap_text(arg.description, text_width) lines.append(' %-*s %s' % (max_arg, arg.name, text[0])) lines.extend([ indent + s for s in text[1:] ]) lines.append('') # add a blank line return lines