pipeline: identify pipelines by name

Every pipeline that gets added to the `Manifest` now need to have
a unique name by which it can be identified. The version 1 format
loader is changed so that the main pipeline that builds the tree
is always called `tree`. The build pipeline for it will be called
`build` and further recursive build pipelines `build-build`, where
the number of repetitions of `build` corresponds to their level of
nesting. An assembler, if it exists, will be added as `assembler`.
The `Manifest.__getitem__` helper is changed so it will first try
to access pipeline via its name and then fall back to an id based
search. NB: in the degenrate case of multiple pipelines that have
exactly the same `id`, i.e. same stages, with the same options and
same build pipeline, only the first one will be return; but only
the first one here will be built as well, so this is in practice
not a problem.
The formatter uses this helper to get the tree pipeline  via its
name wherever it is needed.
This also adds an `__iter__` method `Manifest` to ease iterating
over just the pipeline values, a la `for pipeline in manifet`.
This commit is contained in:
Christian Kellner 2021-01-20 20:58:05 +00:00
parent 88acd7bb00
commit 569345cc72
4 changed files with 44 additions and 25 deletions

View file

@ -35,7 +35,7 @@ def describe(manifest: Manifest, *, with_id=False) -> Dict:
return description
description = {
"pipeline": describe_pipeline(manifest.pipelines[-1])
"pipeline": describe_pipeline(manifest["tree"])
}
if manifest.sources:
@ -44,25 +44,34 @@ def describe(manifest: Manifest, *, with_id=False) -> Dict:
return description
def load_build(description: Dict, index: Index, manifest: Manifest):
def load_build(description: Dict, index: Index, manifest: Manifest, n: int):
pipeline = description.get("pipeline")
if pipeline:
build_pipeline = load_pipeline(pipeline, index, manifest)
build_pipeline = load_pipeline(pipeline, index, manifest, n + 1)
else:
build_pipeline = None
return build_pipeline, description["runner"]
def load_pipeline(description: Dict, index: Index, manifest: Manifest) -> Pipeline:
def load_pipeline(description: Dict, index: Index, manifest: Manifest, n: int = 0) -> Pipeline:
build = description.get("build")
if build:
build_pipeline, runner = load_build(build, index, manifest)
build_pipeline, runner = load_build(build, index, manifest, n)
else:
build_pipeline, runner = None, detect_host_runner()
# the "main" pipeline is called `tree`, since it is building the
# tree that will later be used by the `assembler`. Nested build
# pipelines will get call "build", and "build-build-...", where
# the number of repetitions is equal their level of nesting
if not n:
name = "tree"
else:
name = "-".join(["build"] * n)
build_id = build_pipeline and build_pipeline.tree_id
pipeline = manifest.add_pipeline(runner, build_id)
pipeline = manifest.add_pipeline(name, runner, build_id)
for s in description.get("stages", []):
info = index.get_module_info("Stage", s["name"])
@ -91,7 +100,7 @@ def load(description: Dict, index: Index) -> Manifest:
load_pipeline(pipeline, index, manifest)
for pipeline in manifest.pipelines:
for pipeline in manifest.pipelines.values():
for stage in pipeline.stages:
stage.sources = sources
@ -99,7 +108,7 @@ def load(description: Dict, index: Index) -> Manifest:
def get_ids(manifest: Manifest) -> Tuple[Optional[str], Optional[str]]:
pipeline = manifest.pipelines[-1]
pipeline = manifest["tree"]
return pipeline.tree_id, pipeline.output_id
@ -126,7 +135,7 @@ def output(manifest: Manifest, res: Dict) -> Dict:
retval["assembler"] = assembler
return retval
return result_for_pipeline(manifest.pipelines[-1])
return result_for_pipeline(manifest["tree"])
def validate(manifest: Dict, index: Index) -> ValidationResult: