Source code for temci.build.build_processor

from temci.utils.config_utils import ATTRIBUTES_TYPE
from temci.utils.util import get_doc_for_type_scheme, sphinx_doc, document

import yaml
from ..utils.typecheck import *
from ..utils.settings import Settings
from .builder import Builder, BuilderKeyboardInterrupt, BuildError
import typing as t


[docs]@document(block_scheme="A block in the configuration has the following format:") class BuildProcessor: """ Build programs """ block_scheme = Dict({ "attributes": ATTRIBUTES_TYPE, "run_config": Dict(unknown_keys=True) // Description("Run configuration for this program block"), "build_config": Dict({ "cmd": Str() // Default("") // Description("Command to build this program block, might randomize it"), "number": (PositiveInt() | NonExistent()) // Default(1) // Description("Number of times to build this program"), "working_dir": (DirName() | NonExistent()) // Default(".") // Description("Working directory in which the build command is run"), "revision": (Str() | Int() | NonExistent()) // Default(-1) // Description("Used version control system revision of the program (-1 is the current revision)"), "branch": (Str() | NonExistent()) // Default("") // Description("Used version control system branch (default is the current branch)"), "base_dir": (DirName() | NonExistent()) // Default(".") // Description("Base directory that contains everything to build an run the program") }, unknown_keys=True) // Description("Build configuration for this program block") }) # type: Dict """ Type scheme of the program block configurations """ def __init__(self, build_blocks: t.Optional[t.List[t.Dict[str, t.Any]]] = None): """ Creates a build processor for the passed build block configurations. :param build_blocks: passed build block configurations """ if build_blocks is None: typecheck(Settings()["build/in"], ValidYamlFileName()) with open(Settings()["build/in"], "r") as f: build_blocks = yaml.safe_load(f) self.build_blocks = self.preprocess_build_blocks(build_blocks) typecheck(Settings()["build/out"], FileName()) typecheck_locals(build_blocks=List()) self.out = Settings()["build/out"] # type. str """ Temporary directory in which the building takes place """
[docs] @classmethod def preprocess_build_blocks(cls, blocks: t.List[t.Dict[str, t.Any]]) -> t.List[t.Dict[str, t.Any]]: """ Pre process and check build blocks :return: pre processed copy """ typecheck(blocks, List(cls.block_scheme)) build_blocks = [cls.block_scheme.get_default() for _ in range(len(blocks))] """ Build block configurations. type: t.Optional[t.List[t.Dict[str, t.Any]]] """ for i, block in enumerate(blocks): for key in block.keys(): build_blocks[i][key].update(block[key]) typecheck(build_blocks[i], cls.block_scheme, "build block {}".format(i)) return build_blocks
[docs] def build(self): """ Build the configured programs. """ run_blocks = [] try: for id, block in enumerate(self.build_blocks): error = None try: block_builder = Builder(id, block["build_config"]["working_dir"], block["build_config"]["cmd"], block["build_config"]["revision"], block["build_config"]["number"], block["build_config"]["base_dir"], block["build_config"]["branch"]) working_dirs = block_builder.build() except BuilderKeyboardInterrupt as err: working_dirs = err.result error = err.error except BuildError as err: err.log() raise err block["run_config"]["cwd"] = working_dirs run_blocks.append({ "attributes": block["attributes"], "run_config": block["run_config"] }) if error: raise error except KeyboardInterrupt as err: with open(self.out, "w") as f: yaml.dump(run_blocks, f) raise err with open(self.out, "w") as f: yaml.dump(run_blocks, f)
[docs] @classmethod def store_example_config(cls, file: str, comment_out_defaults: bool = False): import click with click.open_file(file, "w") as f: print(List(cls.block_scheme).get_default_yaml(comment_out_defaults=comment_out_defaults), file=f)