fester/backend/graph/target_dag.py

81 lines
2.7 KiB
Python
Executable File

"""Build-target DAG construction.
F-11 remediation: the 6-branch if/elif chain on ``target.system``
has been replaced with a dispatch table (``_SYSTEM_BUILDERS``).
Adding a new build system is now a one-line dict entry instead of
a new elif branch.
"""
from __future__ import annotations
from typing import Any, Callable, Dict, List, Mapping
def build_target_dag(project: Mapping[str, Any], targets: list) -> List[Dict[str, Any]]:
"""Build a DAG of {name, target, steps} for each target in ``targets``."""
return [
{
"name": f"{t.system}-{t.arch}",
"target": t,
"steps": generate_steps(project, t),
}
for t in targets
]
# ---------------------------------------------------------------------------
# Per-system command builders
# ---------------------------------------------------------------------------
def _cmd(name: str, command: str) -> Dict[str, str]:
"""Helper: build a {name, command} step dict."""
return {"name": name, "command": command}
def _build_gentoo(project: Mapping[str, Any], target: Any) -> List[Dict[str, str]]:
return [_cmd("emerge", f"emerge -e {project['name']}")]
def _build_buildroot(project: Mapping[str, Any], target: Any) -> List[Dict[str, str]]:
return [_cmd("buildroot", "make")]
def _build_openwrt(project: Mapping[str, Any], target: Any) -> List[Dict[str, str]]:
return [_cmd("openwrt", "make world")]
def _build_alfs(project: Mapping[str, Any], target: Any) -> List[Dict[str, str]]:
return [_cmd("alfs", "./build-lfs.sh")]
def _build_sourcemage(project: Mapping[str, Any], target: Any) -> List[Dict[str, str]]:
return [_cmd("sorcery", "cast " + project["name"])]
def _build_lunar(project: Mapping[str, Any], target: Any) -> List[Dict[str, str]]:
return [_cmd("lunar", "lunar build " + project["name"])]
# Dispatch table — single source of truth for build-system lookup.
# Adding a new system = one entry here. Unknown systems return [].
_SYSTEM_BUILDERS: Dict[str, Callable[[Mapping[str, Any], Any], List[Dict[str, str]]]] = {
"gentoo": _build_gentoo,
"buildroot": _build_buildroot,
"openwrt": _build_openwrt,
"alfs": _build_alfs,
"sourcemage": _build_sourcemage,
"lunar": _build_lunar,
}
def generate_steps(project: Mapping[str, Any], target: Any) -> List[Dict[str, str]]:
"""Return the build steps for ``target`` under ``project``.
Returns an empty list if ``target.system`` is unknown — this
satisfies MISRA Rule 16.4 (switch shall have default).
"""
system = getattr(target, "system", None) or (target.get("system") if isinstance(target, Mapping) else None)
builder = _SYSTEM_BUILDERS.get(system)
if builder is None:
return []
return builder(project, target)