Ejemplo n.º 1
0
def main():
    clickable = Clickable()
    args = clickable.parse_args()

    if args.verbose:
        console_handler.setLevel(logging.DEBUG)
    logger.debug('Clickable v' + __version__)

    try:
        clickable.run(args.commands, args)
    except ClickableException as e:
        logger.error(str(e))
        sys.exit(1)
    except subprocess.CalledProcessError as e:
        logger.debug('Command exited with an error:' + str(e.cmd), exc_info=e)
        logger.critical(
            'Command exited with non-zero exit status {}, see above for details. This is most likely not a problem with Clickable.'
            .format(e.returncode, ))

        sys.exit(2)
    except Exception as e:
        logger.debug('Encountered an unknown error', exc_info=e)
        if not args.verbose:
            logger.critical('Encountered an unknown error: ' + str(e))

        logger.critical(
            'If you believe this is a bug, please file a report at https://gitlab.com/clickable/clickable/issues with the log file located at '
            + log_file)
        sys.exit(3)
Ejemplo n.º 2
0
    def run(self, commands=[], args=None):
        self.config = Config(
            args=args,
            clickable_version=__version__,
            desktop=('desktop' in commands or 'test' in commands),
        )
        self.config.container = Container(self.config)

        VALID_COMMANDS = self.command_names + list(self.config.scripts.keys())

        if len(commands) == 0:
            commands = self.config.default.split(' ')
        '''
        Detect senarios when an argument is passed to a command. For example:
        `clickable install /path/to/click`. Since clickable allows commands
        to be strung together it makes detecting this harder. This check has
        been limited to just the case when we have 2 values in args.commands as
        stringing together multiple commands and a command with an argument is
        unlikely to occur.
        TODO determine if there is a better way to do this.
        '''
        command_arg = ''
        if len(commands) == 2 and commands[1] not in VALID_COMMANDS:
            command_arg = commands[1]
            commands = commands[:1]

        commands = [
            self.command_aliases[command]
            if command in self.command_aliases else command
            for command in commands
        ]

        for command in commands:
            if command in self.command_names:
                cmd = self.command_classes[command](self.config)
                cmd.preprocess(command_arg)

        # TODO consider removing the ability to string together multiple commands
        # This should help clean up the arguments & command_arg
        for command in commands:
            if command in self.config.scripts:
                logger.debug('Running the "{}" script'.format(command))
                subprocess.check_call(self.config.scripts[command],
                                      cwd=self.config.cwd,
                                      shell=True)
            elif command in self.command_names:
                logger.debug('Running the "{}" command'.format(command))
                cmd = self.command_classes[command](self.config)
                cmd.run(command_arg)
            else:
                logger.error(
                    'There is no builtin or custom command named "{}"'.format(
                        command))
                self.print_valid_commands()
                sys.exit(1)
Ejemplo n.º 3
0
def validate_clickable_json(config, schema):
    try:
        from jsonschema import validate, ValidationError
        try:
            validate(instance=config, schema=schema)
        except ValidationError as e:
            logger.error("The clickable.json configuration file is invalid!")
            error_message = e.message
            # Lets add the key to the invalid value
            if e.path:
                if len(e.path) > 1 and isinstance(e.path[-1], int):
                    error_message = "{} (in '{}')".format(
                        error_message, e.path[-2])
                else:
                    error_message = "{} (in '{}')".format(
                        error_message, e.path[-1])
            raise ClickableException(error_message)
    except ImportError:
        logger.warning(
            "Dependency 'jsonschema' not found. Could not validate clickable.json."
        )
        pass
Ejemplo n.º 4
0
def main():
    clickable = Clickable()
    args = clickable.parse_args()

    if args.verbose:
        console_handler.setLevel(logging.DEBUG)
    logger.debug('Clickable v' + __version__)
    clickable.check_version(quiet=True)

    try:
        clickable.run(args.commands, args)
    except ClickableException as e:
        logger.error(str(e))
        sys.exit(1)
    except subprocess.CalledProcessError as e:
        logger.debug('Command exited with an error:' + str(e.cmd), exc_info=e)
        logger.critical(
            'Command exited with non-zero exit status {}, see above for details. This is most likely not a problem with Clickable.'
            .format(e.returncode, ))

        sys.exit(2)
    except KeyboardInterrupt as e:
        logger.info(
            '')  # Print an empty space at then end so the cli prompt is nicer
        sys.exit(0)
    except Exception as e:
        if isinstance(e, OSError) and '28' in str(e):
            logger.critical('No space left on device')
            sys.exit(2)
            return

        logger.debug('Encountered an unknown error', exc_info=e)
        if not args.verbose:
            logger.critical('Encountered an unknown error: ' + str(e))

        logger.critical(
            'If you believe this is a bug, please file a report at https://gitlab.com/clickable/clickable/issues with the log file located at '
            + log_file)
        sys.exit(3)
Ejemplo n.º 5
0
    def run(self, arg_commands=[], args=None):
        self.config = self.setup_config(args, arg_commands)
        self.config.container = Container(
            self.config, minimum_version=__container_minimum_required__)
        commands = self.config.commands

        VALID_COMMANDS = self.command_names + list(self.config.scripts.keys())

        is_default = not arg_commands
        '''
        Detect senarios when an argument is passed to a command. For example:
        `clickable install /path/to/click`. Since clickable allows commands
        to be strung together it makes detecting this harder. This check has
        been limited to just the case when we have 2 values in args.commands as
        stringing together multiple commands and a command with an argument is
        unlikely to occur.
        TODO remove chaining and clean this up
        '''
        command_arg = ''
        if len(commands) == 2 and commands[1] not in VALID_COMMANDS:
            command_arg = commands[1]
            commands = commands[:1]

        commands = [
            self.command_aliases[command]
            if command in self.command_aliases else command
            for command in commands
        ]
        if len(commands) > 1 and not is_default:
            logger.warning(
                'Chaining multiple commands is deprecated and will be rejected in a future version of Clickable.'
            )

        for command in commands:
            if command in self.command_names:
                cmd = self.command_classes[command](self.config)
                cmd.preprocess(command_arg)

        for command in commands:
            if command == 'bash-completion':
                cli_args = [
                    '--serial-number',
                    '--config',
                    '--ssh',
                    '--arch',
                    '--verbose',
                    '--container-mode',
                    '--apikey',
                    '--docker-image',
                    '--dirty',
                    '--debug',
                ]
                print(' '.join(sorted(VALID_COMMANDS + cli_args)))
            elif command == 'bash-completion-desktop':
                cli_args = [
                    '--nvidia',
                    '--no-nvidia'
                    '--gdbserver',
                    '--gdb',
                    '--dark-mode',
                    '--lang',
                    '--skip-build',
                    '--dirty',
                    '--verbose',
                    '--config',
                ]
                print(' '.join(sorted(cli_args)))
            elif command in self.config.scripts:
                logger.debug('Running the "{}" script'.format(command))
                subprocess.check_call(self.config.scripts[command],
                                      cwd=self.config.cwd,
                                      shell=True)
            elif command in self.command_names:
                logger.debug('Running the "{}" command'.format(command))
                cmd = self.command_classes[command](self.config)
                cmd.run(command_arg)
            else:
                logger.error(
                    'There is no builtin or custom command named "{}"'.format(
                        command))
                self.print_valid_commands()
                sys.exit(1)
Ejemplo n.º 6
0
 def or_exit(self):
     if not self.query.is_met():
         self.print_instructions()
         logger.error('System requirement not met')
         exit(1)