bin/create-work-package.py

#!/usr/bin/env python3
"""Lokaler Runtime-Adapter für das kanonische GAP-Arbeitspaketwerkzeug."""
from __future__ import annotations

import argparse
import json
import os
import subprocess
import sys
from pathlib import Path
from typing import Any


def _resolve(root: Path, value: str) -> Path:
    path = Path(value).expanduser()
    return path if path.is_absolute() else (root / path).resolve()


def _entries(config: dict[str, Any], key: str) -> list[dict[str, str]]:
    values = config.get(key, [])
    if not isinstance(values, list):
        raise ValueError(f"{key} muss eine Liste sein")
    result: list[dict[str, str]] = []
    for item in values:
        if not isinstance(item, dict) or not isinstance(item.get("name"), str) or not isinstance(item.get("archive"), str):
            raise ValueError(f"{key} enthält einen ungültigen Eintrag")
        result.append(item)
    return result


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--config", required=True, type=Path)
    parser.add_argument("--runtime-root", type=Path, default=Path(__file__).resolve().parents[1])
    args = parser.parse_args()
    try:
        config = json.loads(args.config.read_text(encoding="utf-8"))
        root = args.runtime_root.resolve()
        configured_tool = config.get("tool")
        if not isinstance(configured_tool, str):
            raise ValueError("tool fehlt in der Konfiguration")
        tool = Path(os.environ["NS_GAP_WORK_PACKAGE_TOOL"]) if "NS_GAP_WORK_PACKAGE_TOOL" in os.environ else _resolve(root, configured_tool)
        if not tool.is_file():
            raise ValueError(f"GAP-Arbeitspaketwerkzeug nicht gefunden: {tool}")
        gap = _resolve(root, config["gap"])
        output = _resolve(root, config["outputDirectory"])
        command = [sys.executable, str(tool), "create", "--gap", str(gap), "--output-dir", str(output)]
        configured_filter = config.get("filterConfig")
        if not isinstance(configured_filter, str):
            raise ValueError("filterConfig fehlt in der Konfiguration")
        command.extend(["--filter-config", str(_resolve(root, configured_filter))])
        for item in _entries(config, "sources"):
            command.extend(["--source", f"{item['name']}={_resolve(root, item['archive'])}"])
        for item in _entries(config, "targets"):
            command.extend(["--target", f"{item['name']}={_resolve(root, item['archive'])}"])
        return subprocess.run(command, check=False).returncode
    except (OSError, KeyError, json.JSONDecodeError, ValueError) as exc:
        print(f"FEHLER: {exc}", file=sys.stderr)
        return 2


if __name__ == "__main__":
    raise SystemExit(main())