Ejemplo n.º 1
0
 def emit(self, record):
     try:
         message = self.format(record)
         level_settings = self.colors[self.terminal_background].get(record.levelno, {})
         ConsoleHelper.cprint(message, **level_settings)
         self.flush()
     except Exception:  # pylint: disable=broad-except
         self.handleError(record)
Ejemplo n.º 2
0
 def emit(self, record):
     try:
         message = self.format(record)
         level_settings = self.colors[self.terminal_background].get(record.levelno, {})
         ConsoleHelper.cprint(message, **level_settings)
         self.flush()
     except Exception:  # pylint: disable=broad-except
         self.handleError(record)
Ejemplo n.º 3
0
 def expand(s, default=None, suppress_errors=False):
     try:
         if not suppress_errors:
             return rpm.expandMacro(s)
         with ConsoleHelper.Capturer(stderr=True):
             return rpm.expandMacro(s)
     except rpm.error:
         return default
Ejemplo n.º 4
0
    def run():
        debug_log_file = None
        try:
            cli = CLI()
            if hasattr(cli, 'version'):
                logger.info(VERSION)
                sys.exit(0)

            config = Config(getattr(cli, 'config-file', None))
            config.merge(cli)
            for handler in [main_handler, output_tool_handler]:
                handler.set_terminal_background(config.background)

            ConsoleHelper.use_colors = ConsoleHelper.should_use_colors(config)
            execution_dir, results_dir, debug_log_file = Application.setup(
                config)
            traceback_log = os.path.join(results_dir, LOGS_DIR, TRACEBACK_LOG)
            if config.verbose == 0:
                main_handler.setLevel(logging.INFO)
            elif config.verbose == 1:
                main_handler.setLevel(CustomLogger.VERBOSE)
            else:
                main_handler.setLevel(logging.DEBUG)
            app = Application(config, execution_dir, results_dir,
                              debug_log_file)
            app.run()
        except KeyboardInterrupt:
            logger.info('Interrupted by user')
        except RebaseHelperError as e:
            if e.msg:
                logger.error('%s', e.msg)
            else:
                logger.error('%s', six.text_type(e))
            sys.exit(1)
        except SystemExit as e:
            sys.exit(e.code)
        except BaseException:
            if debug_log_file:
                logger.error(
                    'rebase-helper failed due to an unexpected error. Please report this problem'
                    '\nusing the following link: %s'
                    '\nand include the content of'
                    '\n\'%s\' and'
                    '\n\'%s\''
                    '\nin the report.'
                    '\nThank you!', NEW_ISSUE_LINK, debug_log_file,
                    traceback_log)
                LoggerHelper.add_file_handler(logger_traceback, traceback_log)
                logger_traceback.trace('', exc_info=1)
            else:
                logger.error(
                    'rebase-helper failed due to an unexpected error. Please report this problem'
                    '\nusing the following link: %s'
                    '\nThank you!', NEW_ISSUE_LINK)
            sys.exit(1)

        sys.exit(0)
Ejemplo n.º 5
0
    def run():
        debug_log_file = None
        try:
            cli = CLI()
            if hasattr(cli, 'version'):
                logger.info(VERSION)
                sys.exit(0)

            config = Config(getattr(cli, 'config-file', None))
            config.merge(cli)
            for handler in [main_handler, output_tool_handler]:
                handler.set_terminal_background(config.background)

            ConsoleHelper.use_colors = ConsoleHelper.should_use_colors(config)
            execution_dir, results_dir, debug_log_file = Application.setup(config)
            traceback_log = os.path.join(results_dir, LOGS_DIR, TRACEBACK_LOG)
            if config.verbose == 0:
                main_handler.setLevel(logging.INFO)
            elif config.verbose == 1:
                main_handler.setLevel(CustomLogger.VERBOSE)
            else:
                main_handler.setLevel(logging.DEBUG)
            app = Application(config, execution_dir, results_dir, debug_log_file)
            app.run()
        except KeyboardInterrupt:
            logger.info('Interrupted by user')
        except RebaseHelperError as e:
            if e.msg:
                logger.error('%s', e.msg)
            else:
                logger.error('%s', str(e))
            sys.exit(1)
        except SystemExit as e:
            sys.exit(e.code)
        except BaseException:
            if debug_log_file:
                logger.error('rebase-helper failed due to an unexpected error. Please report this problem'
                             '\nusing the following link: %s'
                             '\nand include the content of'
                             '\n\'%s\' and'
                             '\n\'%s\''
                             '\nin the report.'
                             '\nThank you!',
                             NEW_ISSUE_LINK, debug_log_file, traceback_log)
                LoggerHelper.add_file_handler(logger_traceback, traceback_log)
                logger_traceback.trace('', exc_info=1)
            else:
                logger.error('rebase-helper failed due to an unexpected error. Please report this problem'
                             '\nusing the following link: %s'
                             '\nThank you!',
                             NEW_ISSUE_LINK)
            sys.exit(1)

        sys.exit(0)
Ejemplo n.º 6
0
    def test_capture_output(self):
        def write():
            with os.fdopen(sys.__stdout__.fileno(), 'w') as f:  # pylint: disable=no-member
                f.write('test stdout')
            with os.fdopen(sys.__stderr__.fileno(), 'w') as f:  # pylint: disable=no-member
                f.write('test stderr')

        with ConsoleHelper.Capturer(stdout=True, stderr=True) as capturer:
            write()

        assert capturer.stdout == 'test stdout'
        assert capturer.stderr == 'test stderr'
Ejemplo n.º 7
0
    def dump():
        """Gets list of all defined macros.

        Returns:
            list: All defined macros.

        """
        macro_re = re.compile(
            r'''
            ^\s*
            (?P<level>-?\d+)
            (?P<used>=|:)
            [ ]
            (?P<name>\w+)
            (?P<options>\(.+?\))?
            [\t]
            (?P<value>.*)
            $
            ''', re.VERBOSE)

        with ConsoleHelper.Capturer(stderr=True) as capturer:
            rpm.expandMacro('%dump')

        macros = []

        def add_macro(properties):
            macro = dict(properties)
            macro['used'] = macro['used'] == '='
            macro['level'] = int(macro['level'])
            if parse_version(rpm.__version__) < parse_version('4.13.90'):
                # in RPM < 4.13.90 level of some macros is decreased by 1
                if macro['level'] == -1:
                    # this could be macro with level -1 or level 0, we can not be sure
                    # so just duplicate the macro for both levels
                    macros.append(macro)
                    macro = dict(macro)
                    macro['level'] = 0
                    macros.append(macro)
                elif macro['level'] in (-14, -16):
                    macro['level'] += 1
                    macros.append(macro)
                else:
                    macros.append(macro)
            else:
                macros.append(macro)

        for line in capturer.stderr.split('\n'):
            match = macro_re.match(line)
            if match:
                add_macro(match.groupdict())

        return macros
Ejemplo n.º 8
0
 def parse_spec(cls, path, flags=None):
     with open(path, 'rb') as orig:
         with tempfile.NamedTemporaryFile() as tmp:
             # remove BuildArch to workaround rpm bug
             tmp.write(b''.join(l for l in orig.readlines() if not l.startswith(b'BuildArch')))
             tmp.flush()
             capturer = None
             try:
                 with ConsoleHelper.Capturer(stderr=True) as capturer:
                     result = rpm.spec(tmp.name, flags) if flags is not None else rpm.spec(tmp.name)
             except ValueError as e:
                 output = capturer.stderr.strip().split('\n') if capturer else []
                 if len(output) == 1:
                     output = output[0]
                 raise RebaseHelperError('Failed to parse SPEC file{0}'.format(
                     ': ' + str(output) if output else '')) from e
             return result
Ejemplo n.º 9
0
 def parse_spec(cls, path, flags=None):
     with open(path, 'rb') as orig:
         with tempfile.NamedTemporaryFile() as tmp:
             # remove BuildArch to workaround rpm bug
             tmp.write(b''.join([
                 l for l in orig.readlines()
                 if not l.startswith(b'BuildArch')
             ]))
             tmp.flush()
             with ConsoleHelper.Capturer(stderr=True) as capturer:
                 result = rpm.spec(
                     tmp.name, flags) if flags is not None else rpm.spec(
                         tmp.name)
             for line in capturer.stderr.split('\n'):
                 if line:
                     logger.verbose('rpm: %s', line)
             return result
Ejemplo n.º 10
0
 def set_terminal_background(self, background):
     if background == 'auto':
         self.terminal_background = ConsoleHelper.detect_background()
     else:
         self.terminal_background = background
Ejemplo n.º 11
0
 def set_terminal_background(self, background):
     if background == 'auto':
         self.terminal_background = ConsoleHelper.detect_background()
     else:
         self.terminal_background = background
Ejemplo n.º 12
0
    def watch_koji_tasks(cls, session, tasklist):
        """Waits for Koji tasks to finish and prints their states.

        Args:
            session (koji.ClientSession): Active Koji session instance.
            tasklist (list): List of task IDs.

        Returns:
            dict: Dictionary mapping task IDs to their states or None if interrupted.

        """
        if not tasklist:
            return None
        sys.stdout.flush()
        rh_tasks = {}
        try:
            tasks = {}
            for task_id in tasklist:
                task_id = int(task_id)
                tasks[task_id] = TaskWatcher(task_id, session, quiet=False)
            while True:
                all_done = True
                for task_id, task in list(tasks.items()):
                    with ConsoleHelper.Capturer(stdout=True) as capturer:
                        changed = task.update()
                    for line in capturer.stdout.split('\n'):
                        if line:
                            logger.info(line)
                    info = session.getTaskInfo(task_id)
                    state = task.info['state']
                    if state == koji.TASK_STATES['FAILED']:
                        return {info['id']: state}
                    else:
                        # FIXME: multiple arches
                        if info['arch'] == 'x86_64' or info['arch'] == 'noarch':
                            rh_tasks[info['id']] = state
                    if not task.is_done():
                        all_done = False
                    else:
                        if changed:
                            # task is done and state just changed
                            cls.display_task_results(list(tasks.values()))
                        if not task.is_success():
                            rh_tasks = None
                    for child in session.getTaskChildren(task_id):
                        child_id = child['id']
                        if child_id not in list(tasks.keys()):
                            tasks[child_id] = TaskWatcher(child_id,
                                                          session,
                                                          task.level + 1,
                                                          quiet=False)
                            with ConsoleHelper.Capturer(
                                    stdout=True) as capturer:
                                tasks[child_id].update()
                            for line in capturer.stdout.split('\n'):
                                if line:
                                    logger.info(line)
                            info = session.getTaskInfo(child_id)
                            state = task.info['state']
                            if state == koji.TASK_STATES['FAILED']:
                                return {info['id']: state}
                            else:
                                # FIXME: multiple arches
                                if info['arch'] == 'x86_64' or info[
                                        'arch'] == 'noarch':
                                    rh_tasks[info['id']] = state
                            # If we found new children, go through the list again,
                            # in case they have children also
                            all_done = False
                if all_done:
                    cls.display_task_results(list(tasks.values()))
                    break
                sys.stdout.flush()
                time.sleep(1)
        except KeyboardInterrupt:
            rh_tasks = None
        return rh_tasks
Ejemplo n.º 13
0
 def test_color_is_light(self, rgb_tuple, bit_width, expected_result):
     assert ConsoleHelper.color_is_light(rgb_tuple, bit_width) == expected_result
Ejemplo n.º 14
0
 def test_parse_rgb_device_specification(self, specification, expected_rgb, expected_bit_width):
     rgb, bit_width = ConsoleHelper.parse_rgb_device_specification(specification)
     assert rgb == expected_rgb
     assert bit_width == expected_bit_width
Ejemplo n.º 15
0
 def test_color_is_light(self, rgb_tuple, bit_width, expected_result):
     assert ConsoleHelper.color_is_light(rgb_tuple,
                                         bit_width) == expected_result
Ejemplo n.º 16
0
 def test_parse_rgb_device_specification(self, specification, expected_rgb,
                                         expected_bit_width):
     rgb, bit_width = ConsoleHelper.parse_rgb_device_specification(
         specification)
     assert rgb == expected_rgb
     assert bit_width == expected_bit_width
Ejemplo n.º 17
0
 def purge_macro(cls, macro: str) -> None:
     m = '%{{{}}}'.format(macro)
     while cls.expand(m, m) != m:
         with ConsoleHelper.Capturer(stderr=True):
             rpm.delMacro(macro)
Ejemplo n.º 18
0
    def run(cls):
        results_dir = None
        start_dir = os.getcwd()
        try:
            LoggerHelper.setup_memory_handler()
            main_handler, output_tool_handler = LoggerHelper.create_stream_handlers(
            )
            cli = CLI()
            if hasattr(cli, 'version'):
                print(VERSION)
                sys.exit(0)

            logger.info('rebase-helper version %s', VERSION)

            config = Config(getattr(cli, 'config-file', None))
            config.merge(cli)
            for handler in [main_handler, output_tool_handler]:
                handler.set_terminal_background(config.background)
            if config.verbose == 0:
                main_handler.setLevel(logging.INFO)
            elif config.verbose == 1:
                main_handler.setLevel(CustomLogger.VERBOSE)
            else:
                main_handler.setLevel(logging.DEBUG)
            ConsoleHelper.use_colors = ConsoleHelper.should_use_colors(config)
            if config.bugzilla_id:
                repo_path, config.config[
                    'sources'] = BugzillaHelper.prepare_rebase_repository(
                        config.bugzilla_id)
                try:
                    os.chdir(repo_path)
                except OSError as e:
                    raise RebaseHelperError(
                        'Could not change directory to the cloned repository'
                    ) from e
                # update relative paths in config
                for option in ('results_dir', 'workspace_dir'):
                    path = getattr(config, option)
                    if path and not os.path.isabs(path):
                        config.config[option] = os.path.join(
                            os.path.relpath(start_dir, os.getcwd()), path)

            if config.config['rpmmacros']:
                macros = ' -D ' + ' -D '.join(
                    '"{}"'.format(s) for s in config.config['rpmmacros'])
                for option in ('builder_options', 'srpm_builder_options'):
                    if config.config[option]:
                        config.config[option] += macros
                    else:
                        config.config[option] = macros

            config.config['rpmmacros'] = cls.convert_macros_to_dict(
                config.rpmmacros)
            execution_dir, results_dir = Application.setup(config)
            app = Application(config, start_dir, execution_dir, results_dir)
            app.run()
        except KeyboardInterrupt:
            logger.info('Interrupted by user')
        except RebaseHelperError as e:
            if e.msg:
                logger.error('%s', e.msg)
            else:
                logger.error('%s', str(e))
            sys.exit(1)
        except SystemExit as e:
            sys.exit(e.code)
        except BaseException:
            logger_traceback: CustomLogger = cast(
                CustomLogger, logging.getLogger('rebasehelper.traceback'))
            logger_traceback.propagate = False
            logger_traceback.setLevel(CustomLogger.TRACE)
            if results_dir:
                debug_log = os.path.join(results_dir, LOGS_DIR, DEBUG_LOG)
                traceback_log = os.path.join(results_dir, LOGS_DIR,
                                             TRACEBACK_LOG)
                logger.error(
                    'rebase-helper failed due to an unexpected error. Please report this problem'
                    '\nusing the following link: %s'
                    '\nand include the content of'
                    '\n\'%s\' and'
                    '\n\'%s\''
                    '\nin the report.'
                    '\nThank you!', NEW_ISSUE_LINK, debug_log, traceback_log)
                LoggerHelper.add_file_handler(logger_traceback, traceback_log)
            else:
                logger.error(
                    'rebase-helper failed due to an unexpected error. Please report this problem'
                    '\nusing the following link: %s'
                    '\nand include the following traceback in the report.'
                    '\nThank you!', NEW_ISSUE_LINK)

                LoggerHelper.add_stream_handler(logger_traceback,
                                                CustomLogger.TRACE)
            logger_traceback.trace('', exc_info=1)
            sys.exit(1)

        sys.exit(0)