def handle(config_filename, **kwargs): import logging logger = logging.getLogger() dispatcher = LoggingDispatcher() variables, features, files, config = _read_configuration( dispatcher, config_filename) feature_instances = {} logger.info('Updating {} with {} features'.format( term.bold(config['python'].get('name')), ', '.join( term.bold(term.green(feature_name)) for feature_name in sorted(features)))) all_features = load_feature_extensions() sorted_features = sorted( features) # sort to have a predictable display order for feature_name in sorted_features: logger.debug('Initializing feature {}...'.format( term.bold(term.green(feature_name)))) try: feature = all_features[feature_name] except KeyError as exc: logger.exception( 'Feature "{}" not found.'.format(feature_name)) if feature: feature_instances[feature_name] = feature(dispatcher) for req in feature_instances[feature_name].requires: if not req in sorted_features: raise RuntimeError( 'Unmet dependency: {} requires {}.'.format( feature_name, req)) for con in feature_instances[feature_name].conflicts: if con in sorted_features: raise RuntimeError( 'Conflicting dependency: {} conflicts with {}.'. format(con, feature_name)) else: raise RuntimeError( 'Required feature {} not found.'.format(feature_name)) event = ProjectEvent(config=config) event.variables, event.files = variables, files # todo: add listener dump list in debug/verbose mode ? event = dispatcher.dispatch('medikit.on_start', event) dispatcher.dispatch('medikit.on_end', event) logger.info('Done.')
def handle(config_filename, **kwargs): import logging logger = logging.getLogger() dispatcher = LoggingDispatcher() variables, features, files, config = _read_configuration(dispatcher, config_filename) # This is a hack, but we'd need a flexible option parser which requires too much work as of today. if kwargs.pop("override_requirements", False): if "python" in config: config["python"].override_requirements = True feature_instances = {} logger.info( "Updating {} with {} features".format( term.bold(config.package_name), ", ".join(term.bold(term.green(feature_name)) for feature_name in sorted(features)), ) ) all_features = load_feature_extensions() sorted_features = sorted(features) # sort to have a predictable display order for feature_name in sorted_features: logger.debug("Initializing feature {}...".format(term.bold(term.green(feature_name)))) try: feature = all_features[feature_name] except KeyError as exc: logger.exception('Feature "{}" not found.'.format(feature_name)) if feature: feature_instances[feature_name] = feature(dispatcher) for req in feature_instances[feature_name].requires: if not req in sorted_features: raise RuntimeError("Unmet dependency: {} requires {}.".format(feature_name, req)) for con in feature_instances[feature_name].conflicts: if con in sorted_features: raise RuntimeError("Conflicting dependency: {} conflicts with {}.".format(con, feature_name)) else: raise RuntimeError("Required feature {} not found.".format(feature_name)) event = ProjectEvent(config=config) event.variables, event.files = variables, files # todo: add listener dump list in debug/verbose mode ? event = dispatcher.dispatch("medikit.on_start", event) dispatcher.dispatch("medikit.on_end", event) logger.info("Done.")
def execute(self, command, *, cwd, shell=True): self.logger.info( term.bold(">>> %s") + " " + term.lightblack("(in %s)"), command, cwd) retval = subprocess.call(command, cwd=cwd, shell=shell) if retval: self.logger.error(term.red(term.bold("... ✖ failed"))) raise RuntimeError('"{}" returned {}.'.format(command, retval)) else: self.logger.info(term.green(term.bold("... ✓ ok")))
def dispatch(self, event_id, event=None): should_log = not event_id.startswith("medikit.on_file_") or self.logger.getEffectiveLevel() <= logging.DEBUG if should_log: self.logger.info( self.indent + term.bold(">") + " dispatch ⚡ {} ({})".format(term.bold(term.blue(event_id)), type(event or Event).__name__) ) type(self).indent_level += 1 event = super(LoggingDispatcher, self).dispatch(event_id, event) type(self).indent_level -= 1 if should_log: self.logger.info(self.indent + term.bold("<") + " {}".format(term.lightblack("dispatched " + event_id))) return event
def dispatch(self, event_id, event=None): should_log = not event_id.startswith('medikit.on_file_') or \ self.logger.getEffectiveLevel() <= logging.DEBUG if should_log: self.logger.info( self.indent + term.bold('>') + ' dispatch ⚡ {} ({})'.format(term.bold(term.blue(event_id)), type(event or Event).__name__) ) type(self).indent_level += 1 event = super(LoggingDispatcher, self).dispatch(event_id, event) type(self).indent_level -= 1 if should_log: self.logger.info(self.indent + term.bold('<') + ' {}'.format(term.lightblack('dispatched ' + event_id))) return event
def format_arg(arg): length = len(pre_re.sub("\\1\\2\\3", arg)) arg = pre_re.sub(w("\\1") + term.bold("\\2") + w("\\3"), arg) arg = re.sub(r"^ \$ (.*)", term.lightblack(" $ ") + term.reset("\\1"), arg) return (arg, length)
def dispatch(self, event_id, event=None): should_log = not event_id.startswith( "medikit.on_file_" ) or self.logger.getEffectiveLevel() <= logging.DEBUG if should_log: self.logger.info( self.indent + term.bold(">") + " dispatch ⚡ {} ({})".format(term.bold(term.blue(event_id)), type(event or Event).__name__)) type(self).indent_level += 1 event = super(LoggingDispatcher, self).dispatch(event_id, event) type(self).indent_level -= 1 if should_log: self.logger.info( self.indent + term.bold("<") + " {}".format(term.lightblack("dispatched " + event_id))) return event
def sweeten_errors(): try: yield except Exception as exc: SPACES = 2 w = term.white prefix = w("║" + " " * (SPACES - 1)) suffix = w(" " * (SPACES - 1) + "║") pre_re = re.compile("([^`]*)`([^`]*)`([^`]*)") def format_arg(arg): length = len(pre_re.sub("\\1\\2\\3", arg)) arg = pre_re.sub(w("\\1") + term.bold("\\2") + w("\\3"), arg) arg = re.sub(r"^ \$ (.*)", term.lightblack(" $ ") + term.reset("\\1"), arg) return (arg, length) def f(*args): return "".join(args) term_width, term_height = term.get_size() line_length = min(80, term_width) for arg in exc.args: line_length = max(min(line_length, len(arg) + 2 * SPACES), 120) print(f(w("╔" + "═" * (line_length - 2) + "╗"))) for i, arg in enumerate(exc.args): if i == 1: print(f(prefix, " " * (line_length - 2 * SPACES), suffix)) arg_formatted, arg_length = format_arg(arg) if not i: # first line print( f( prefix, term.red_bg(term.bold(" " + type(exc).__name__ + " ")), " ", w(arg_formatted), " " * (line_length - (arg_length + 3 + len(type(exc).__name__) + 2 * SPACES)), suffix, ) ) else: # other lines print(f(prefix, arg_formatted + " " * (line_length - arg_length - 2 * SPACES), suffix)) print(f(w("╚" + "═" * (line_length - 2) + "╝"))) logging.getLogger().debug("This error was caused by the following exception chain.", exc_info=exc_info())
def _log_file(self, target, override, content=()): self.dispatcher.info( term.bold(term.red('W!') if override else term.green('W?')), target, '({} bytes)'.format(len(content)) )
def _log_file(self, target, override, content=()): self.dispatcher.info( term.bold(term.red("W!") if override else term.green("W?")), target, "({} bytes)".format(len(content)) )
def humanized(exc, *, fg=term.red, bg=lambda *args: term.red_bg(term.bold(*args)), help_url=None): SPACES = 2 prefix, suffix = fg(VERT + " " * (SPACES - 1)), fg(" " * (SPACES - 1) + VERT) result = [] def format_arg(arg): length = len(preformatted_pattern.sub("\\1\\2\\3", arg)) arg = preformatted_pattern.sub("\\1" + term.bold("\\2") + "\\3", arg) arg = re.sub("^ \$ (.*)", term.lightblack(" $ ") + term.reset("\\1"), arg) return (arg, length) def joined(*args): return "".join(args) term_width, term_height = term.get_size() line_length = min(80, term_width) for arg in exc.args: line_length = max(min(line_length, len(arg) + 2 * SPACES), 120) result.append(joined(fg(TOP_LEFT + HORIZ * (line_length - 2) + TOP_RIGHT))) args = list(exc.args) for i, arg in enumerate(args): if i == 1: result.append( joined(prefix, " " * (line_length - 2 * SPACES), suffix)) arg_formatted, arg_length = format_arg(arg) if not i: # first line result.append( joined( prefix, bg(" " + type(exc).__name__ + " "), " ", term.white(arg_formatted), " " * (line_length - (arg_length + 3 + len(type(exc).__name__) + 2 * SPACES)), suffix, )) else: # other lines result.append( joined( prefix, arg_formatted + " " * (line_length - arg_length - 2 * SPACES), suffix)) if help_url: help_prefix = "Read more: " arg_length = len(help_url) + len(help_prefix) arg_formatted = help_prefix + term.underline(term.lightblue(help_url)) result.append(joined(prefix, " " * (line_length - 2 * SPACES), suffix)) result.append( joined( prefix, arg_formatted + " " * (line_length - arg_length - 2 * SPACES), suffix)) more = settings.DEBUG exc_lines = format_exception(exc_info(), fg=fg, bg=bg, summary=False).splitlines() if not len(exc_lines): more = False result.append( joined( fg((VERT_LEFT if more else BOTTOM_LEFT) + HORIZ * (line_length - 2) + BOTTOM_RIGHT))) if more: for _line in exc_lines: result.append(_line) result.append(joined(fg("╵"))) elif len(exc_lines): result.append( term.lightblack( "(add DEBUG=1 to system environment for stack trace)".rjust( line_length))) return "\n".join(result)
def debug(self, feature, *messages): return self.logger.debug(" ✔ " + term.bold(term.green(feature.__shortname__)) + " ".join(map(str, messages)))
def handle(config_filename, **kwargs): import logging logger = logging.getLogger() dispatcher = LoggingDispatcher() variables, features, files, config = _read_configuration( dispatcher, config_filename) # This is a hack, but we'd need a flexible option parser which requires too much work as of today. if kwargs.pop("override_requirements", False): if "python" in config: config["python"].override_requirements = True feature_instances = {} logger.info("Updating {} with {} features".format( term.bold(config.package_name), ", ".join( term.bold(term.green(feature_name)) for feature_name in sorted(features)), )) all_features = load_feature_extensions() sorted_features = sorted( features) # sort to have a predictable display order for feature_name in sorted_features: logger.debug('Initializing feature "{}"...'.format( term.bold(term.green(feature_name)))) try: feature = all_features[feature_name] except KeyError as exc: logger.exception( 'Feature "{}" not found.'.format(feature_name)) if feature: feature_instances[feature_name] = feature(dispatcher) for req in feature_instances[feature_name].requires: if not req in sorted_features: raise RuntimeError( 'Unmet dependency: "{}" requires "{}".'.format( feature_name, req)) for con in feature_instances[feature_name].conflicts: if con in sorted_features: raise RuntimeError( 'Conflicting dependency: "{}" conflicts with "{}".' .format(con, feature_name)) else: raise RuntimeError( "Required feature {} not found.".format(feature_name)) event = ProjectEvent(config=config) event.variables, event.files = variables, files # todo: add listener dump list in debug/verbose mode ? event = dispatcher.dispatch(medikit.on_start, event) dispatcher.dispatch(medikit.on_end, event) logger.info("Done.")
def _log_file(self, target, override, content=()): self.dispatcher.info( term.bold(term.red("W!") if override else term.green("W?")), target, "({} bytes)".format(len(content)))
def write_resources(self, event): for target, resource in self.resources.items(): exists = os.path.exists(target) resource.write(event, target) self.dispatcher.info( term.bold((term.red if exists else term.green)("W!")), target)