Ejemplo n.º 1
0
    def _pre_parse_args(self, sysargs):
        """Pre-parse sys args.

        Several steps:

        - extract the global options and detects the possible command and its args

        - validate global options and apply them

        - validate that command is correct (NOT loading and parsing its arguments)
        """
        # get all flags (default to False) and those per options, to filter sysargs
        flags = {}
        flag_per_option = {}
        for flag, short_option, long_option, _ in GLOBAL_FLAGS:
            flag_per_option[short_option] = flag
            flag_per_option[long_option] = flag
            flags[flag] = False

        filtered_sysargs = []
        for arg in sysargs:
            if arg in flag_per_option:
                flags[flag_per_option[arg]] = True
            else:
                filtered_sysargs.append(arg)

        # control and use quiet/verbose options
        if flags['quiet'] and flags['verbose']:
            raise CommandError(
                "The 'verbose' and 'quiet' options are mutually exclusive.")
        if flags['quiet']:
            message_handler.set_mode(message_handler.QUIET)
        elif flags['verbose']:
            message_handler.set_mode(message_handler.VERBOSE)
        logger.debug("Raw pre-parsed sysargs: flags=%s filtered=%s", flags,
                     filtered_sysargs)

        # if help requested, transform the parameters to make that explicit
        if flags['help']:
            command = HelpCommand.name
            cmd_args = filtered_sysargs
        elif filtered_sysargs:
            command = filtered_sysargs[0]
            cmd_args = filtered_sysargs[1:]
            if command not in self.commands:
                msg = "no such command {!r}".format(command)
                help_text = helptexts.get_usage_message('charmcraft', msg)
                raise CommandError(help_text, argsparsing=True)
        else:
            # no command!
            help_text = get_general_help()
            raise CommandError(help_text, argsparsing=True)

        logger.debug("General parsed sysargs: command=%r args=%s", command,
                     cmd_args)
        return command, cmd_args
Ejemplo n.º 2
0
def test_get_usage_message():
    """Check the general "usage" text."""
    text = get_usage_message("charmcraft build", "bad parameter for the build")
    expected = textwrap.dedent("""\
        Usage: charmcraft [options] command [args]...
        Try 'charmcraft build -h' for help.

        Error: bad parameter for the build
    """)
    assert text == expected
Ejemplo n.º 3
0
    def run(self, parsed_args, all_commands):
        """Present different help messages to the user.

        Unlike other commands, this one receives an extra parameter with all commands,
        to validate if the help requested is on a valid one, or even parse its data.
        """
        if parsed_args.command_to_help is None or parsed_args.command_to_help == self.name:
            # help on no command in particular, get general text
            help_text = get_general_help(detailed=parsed_args.all)
        elif parsed_args.command_to_help not in all_commands:
            # asked help on a command that doesn't exist
            msg = "no such command {!r}".format(parsed_args.command_to_help)
            help_text = helptexts.get_usage_message('charmcraft', msg)
        else:
            cmd_class, group = all_commands[parsed_args.command_to_help]
            cmd = cmd_class(group)
            parser = CustomArgumentParser(prog=cmd.name)
            cmd.fill_parser(parser)
            help_text = get_command_help(parser, cmd)
        raise CommandError(help_text, argsparsing=True)
Ejemplo n.º 4
0
    def _pre_parse_args(self, sysargs):
        """Pre-parse sys args.

        Several steps:

        - extract the global options and detects the possible command and its args

        - validate global options and apply them

        - validate that command is correct (NOT loading and parsing its arguments)
        """
        # get all arguments (default to what's specified) and those per options, to filter sysargs
        global_args = {}
        arg_per_option = {}
        options_with_equal = []
        for arg in GLOBAL_ARGS:
            arg_per_option[arg.short_option] = arg
            arg_per_option[arg.long_option] = arg
            if arg.type == 'flag':
                default = False
            elif arg.type == 'option':
                default = None
                options_with_equal.append(arg.long_option + '=')
            else:
                raise ValueError("Bad GLOBAL_ARGS structure.")
            global_args[arg.name] = default

        filtered_sysargs = []
        sysargs = iter(sysargs)
        options_with_equal = tuple(options_with_equal)
        for sysarg in sysargs:
            if sysarg in arg_per_option:
                arg = arg_per_option[sysarg]
                if arg.type == 'flag':
                    value = True
                else:
                    try:
                        value = next(sysargs)
                    except StopIteration:
                        raise CommandError(
                            "The 'project-dir' option expects one argument.")
                global_args[arg.name] = value
            elif sysarg.startswith(options_with_equal):
                option, value = sysarg.split('=', 1)
                if not value:
                    raise CommandError(
                        "The 'project-dir' option expects one argument.")
                arg = arg_per_option[option]
                global_args[arg.name] = value
            else:
                filtered_sysargs.append(sysarg)

        # control and use quiet/verbose options
        if global_args['quiet'] and global_args['verbose']:
            raise CommandError(
                "The 'verbose' and 'quiet' options are mutually exclusive.")
        if global_args['quiet']:
            message_handler.set_mode(message_handler.QUIET)
        elif global_args['verbose']:
            message_handler.set_mode(message_handler.VERBOSE)
        logger.debug("Raw pre-parsed sysargs: args=%s filtered=%s",
                     global_args, filtered_sysargs)

        # if help requested, transform the parameters to make that explicit
        if global_args['help']:
            command = HelpCommand.name
            cmd_args = filtered_sysargs
        elif filtered_sysargs:
            command = filtered_sysargs[0]
            cmd_args = filtered_sysargs[1:]
            if command not in self.commands:
                msg = "no such command {!r}".format(command)
                help_text = helptexts.get_usage_message('charmcraft', msg)
                raise CommandError(help_text, argsparsing=True)
        else:
            # no command!
            help_text = get_general_help()
            raise CommandError(help_text, argsparsing=True)

        # load the system's config
        charmcraft_config = config.load(global_args['project_dir'])

        logger.debug("General parsed sysargs: command=%r args=%s", command,
                     cmd_args)
        return command, cmd_args, charmcraft_config
Ejemplo n.º 5
0
 def error(self, message):
     """Show the usage, the error message, and no more."""
     fullcommand = "charmcraft " + self.prog
     full_msg = helptexts.get_usage_message(fullcommand, message)
     raise CommandError(full_msg, argsparsing=True)