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)
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)
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
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)
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)
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'
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
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
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
def set_terminal_background(self, background): if background == 'auto': self.terminal_background = ConsoleHelper.detect_background() else: self.terminal_background = background
def set_terminal_background(self, background): if background == 'auto': self.terminal_background = ConsoleHelper.detect_background() else: self.terminal_background = background
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
def test_color_is_light(self, rgb_tuple, bit_width, expected_result): assert ConsoleHelper.color_is_light(rgb_tuple, bit_width) == expected_result
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
def test_color_is_light(self, rgb_tuple, bit_width, expected_result): assert ConsoleHelper.color_is_light(rgb_tuple, bit_width) == expected_result
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
def purge_macro(cls, macro: str) -> None: m = '%{{{}}}'.format(macro) while cls.expand(m, m) != m: with ConsoleHelper.Capturer(stderr=True): rpm.delMacro(macro)
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)