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 run(self, meta): if self.interractive: os.system(self.cmd) else: child = Process(self.cmd) events = multiprocessing.Queue() parent = multiprocessing.Process(name="task", target=child.run, args=(events, True)) parent.start() exit = False returncode = None while not exit: try: msg = events.get(timeout=0.1) except Empty: if exit: break else: if msg.type == "line": print(term.lightblack("\u2502"), msg.data.decode("utf-8"), end="") elif msg.type == "start": print("$ " + term.lightwhite(self.cmd) + term.black(" # pid=%s" % msg.data["pid"])) elif msg.type == "stop": returncode = msg.data["returncode"] if returncode: print(term.lightblack("\u2514" + term.red(" failed (rc={}). ".format(returncode)))) else: print(term.lightblack("\u2514" + term.green(" success. "))) exit = True if returncode: raise RuntimeError( '"{command}" exited with status {returncode}.'.format(command=self.cmd, returncode=returncode) ) self.set_complete()
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 _handle_continue(cls, pipeline, *, filename): if not os.path.exists(filename): raise FileNotFoundError( 'Pipeline “{}” not started, hence you cannot “continue” it. Are you looking for `medikit pipeline {name} start`?'. format(name=pipeline.name) ) # XXX TODO add a lock file during the step and unlock at the end. with open(filename) as f: pipeline.unserialize(f.read()) try: step = pipeline.next() name, current, size, descr = pipeline.name, pipeline.current, len(pipeline), str(step) logger.info( term.black(' » ').join( ( term.lightblue('{} ({}/{})'.format(name.upper(), current, size)), term.yellow('⇩ BEGIN'), term.lightblack(descr), ) ) ) step.run(pipeline.meta) if step.complete: logger.info( term.black(' » ') .join(( term.lightblue('{} ({}/{})'.format(name.upper(), current, size)), term.green('SUCCESS'), )) + '\n' ) else: logger.info( term.black(' » ') .join(( term.lightblue('{} ({}/{})'.format(name.upper(), current, size)), term.red('FAILED'), )) + '\n' ) return except StopIteration: return COMPLETE with open(filename, 'w+') as f: f.write(pipeline.serialize()) return CONTINUE
def run(self, meta): if self.interractive: os.system(self.cmd) else: child = Process(self.cmd) events = multiprocessing.Queue() parent = multiprocessing.Process(name='task', target=child.run, args=(events, True)) parent.start() exit = False returncode = None while not exit: try: msg = events.get(timeout=0.1) except Empty: if exit: break else: if msg.type == 'line': print(term.lightblack('\u2502'), msg.data.decode('utf-8'), end='') elif msg.type == 'start': print('$ ' + term.lightwhite(self.cmd) + term.black(' # pid=%s' % msg.data['pid'])) elif msg.type == 'stop': returncode = msg.data['returncode'] if returncode: print( term.lightblack('\u2514' + term.red( ' failed (rc={}). '.format(returncode)))) else: print( term.lightblack('\u2514' + term.green(' success. '))) exit = True if returncode: raise RuntimeError( '"{command}" exited with status {returncode}.'.format( command=self.cmd, returncode=returncode)) self.set_complete()
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 debug(self, feature, *messages): return self.logger.debug(" ✔ " + term.bold(term.green(feature.__shortname__)) + " ".join(map(str, messages)))
def _handle_continue(cls, pipeline, *, filename): if not os.path.exists(filename): raise FileNotFoundError( "Pipeline “{}” not started, hence you cannot “continue” it. Are you looking for `medikit pipeline {name} start`?".format( name=pipeline.name ) ) # XXX TODO add a lock file during the step and unlock at the end. with open(filename) as f: pipeline.unserialize(f.read()) try: step = pipeline.next() name, current, size, descr = pipeline.name, pipeline.current, len(pipeline), str(step) logger.info( term.black(" » ").join( ( term.lightblue("{} ({}/{})".format(name.upper(), current, size)), term.yellow("⇩ BEGIN"), term.lightblack(descr), ) ) ) step.run(pipeline.meta) if step.complete: logger.info( term.black(" » ").join( (term.lightblue("{} ({}/{})".format(name.upper(), current, size)), term.green("SUCCESS")) ) + "\n" ) else: logger.info( term.black(" » ").join( (term.lightblue("{} ({}/{})".format(name.upper(), current, size)), term.red("FAILED")) ) + "\n" ) return except StopIteration: return COMPLETE with open(filename, "w+") as f: f.write(pipeline.serialize()) return CONTINUE
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)))