feat(i18n): tools + landing page + doorstop generator in English
Phase 1 of full English translation: - generate_doorstop_items.py: all 55 items (SG/SYS/SWE/SA/SWA) rewritten in English - generate_landing_page.py: full UI labels, KPI cards, section headings in English - traceability.py: docstring, error messages, HTML headers in English - generate_test_report.py: report content + table headers in English - All 55 markdown items in safety/sg/, reqs/, arch/ regenerated in English Still to come: - demo-epb filled Word docs (PID, plans, safety, manuals, audit artefacts) - Code comments + test names + CI workflow step names - README + dev-process repo templates
This commit is contained in:
+21
-21
@@ -1,17 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Traceability-Werkzeug fuer demo-epb.
|
||||
Traceability tool for demo-epb.
|
||||
|
||||
Liest Markdown-Items aus safety/sg, reqs/sys, reqs/swe, arch/sys, arch/swe und
|
||||
verifiziert die Traceability-Kette:
|
||||
Reads Markdown items from safety/sg, reqs/sys, reqs/swe, arch/sys, arch/swe and
|
||||
verifies the traceability chain:
|
||||
|
||||
SG <-- SYS <-- SA
|
||||
<-- SWE <-- SWA <-- Code (@arch)
|
||||
<-- Tests (@reqs)
|
||||
|
||||
Subcommands:
|
||||
check Validiert Konsistenz, exit 1 bei Fehlern
|
||||
publish DIR Schreibt HTML + JSON nach DIR/
|
||||
check Validates consistency, exits 1 on errors
|
||||
publish DIR Writes HTML + JSON to DIR/
|
||||
|
||||
Run:
|
||||
python3 tools/traceability.py check
|
||||
@@ -160,27 +160,27 @@ def check_code_test_mapping(items: dict[str, Item]) -> list[str]:
|
||||
src = REPO / src_rel
|
||||
arch_tags, _ = extract_tags(src)
|
||||
if swa_id not in arch_tags:
|
||||
errors.append(f"{src_rel}: header @arch enthaelt {swa_id} nicht "
|
||||
f"(gefunden: {arch_tags or '—'})")
|
||||
errors.append(f"{src_rel}: header @arch does not contain {swa_id} "
|
||||
f"(found: {arch_tags or '—'})")
|
||||
|
||||
# For each test, verify @reqs covers the SWE that the corresponding SWA links to
|
||||
for test_file, swa_id in IMPLEMENTED_TESTS.items():
|
||||
test_path = REPO / "tests" / "unit" / test_file
|
||||
_, reqs_in_test = extract_tags(test_path)
|
||||
if not reqs_in_test:
|
||||
errors.append(f"tests/unit/{test_file}: kein @reqs Tag im Header")
|
||||
errors.append(f"tests/unit/{test_file}: no @reqs tag in header")
|
||||
continue
|
||||
swa = items.get(swa_id)
|
||||
if swa is None:
|
||||
errors.append(f"tests/unit/{test_file}: referenziertes "
|
||||
f"{swa_id} nicht gefunden")
|
||||
errors.append(f"tests/unit/{test_file}: referenced "
|
||||
f"{swa_id} not found")
|
||||
continue
|
||||
swa_swe = set(swa.links)
|
||||
test_swe = set(reqs_in_test)
|
||||
missing = swa_swe - test_swe
|
||||
if missing:
|
||||
errors.append(f"tests/unit/{test_file}: deckt nicht alle SWE "
|
||||
f"der {swa_id} ab — fehlend: {sorted(missing)}")
|
||||
errors.append(f"tests/unit/{test_file}: does not cover all SWE of "
|
||||
f"{swa_id} — missing: {sorted(missing)}")
|
||||
|
||||
return errors
|
||||
|
||||
@@ -241,7 +241,7 @@ def cmd_check(items: dict[str, Item]) -> int:
|
||||
for e in errors:
|
||||
print(f" - {e}")
|
||||
return 1
|
||||
print("OK — Traceability vollstaendig (SG → SYS → SA, SWE → SWA → Code+Test).")
|
||||
print("OK — Traceability complete (SG → SYS → SA, SWE → SWA → Code+Test).")
|
||||
return 0
|
||||
|
||||
|
||||
@@ -314,7 +314,7 @@ def cmd_publish(items: dict[str, Item], out_dir: Path) -> int:
|
||||
".missing{color:#c00}",
|
||||
"</style></head><body>",
|
||||
"<h1>demo-epb — Traceability Matrix</h1>",
|
||||
"<p>Vollstaendige Kette: <code>SG → SYS → SA, SWE → SWA → Code (@arch) + Test (@reqs)</code></p>",
|
||||
"<p>Complete chain: <code>SG → SYS → SA, SWE → SWA → Code (@arch) + Test (@reqs)</code></p>",
|
||||
"<p>",
|
||||
]
|
||||
for p, _, label in SOURCES:
|
||||
@@ -325,9 +325,9 @@ def cmd_publish(items: dict[str, Item], out_dir: Path) -> int:
|
||||
|
||||
parts.append("<table>")
|
||||
parts.append(
|
||||
"<tr><th>Safety Goal</th><th>System-Requirement</th>"
|
||||
"<th>System-Arch</th><th>Software-Req</th>"
|
||||
"<th>Software-Arch</th><th>Code</th><th>Test</th></tr>"
|
||||
"<tr><th>Safety Goal</th><th>System Requirement</th>"
|
||||
"<th>System Arch</th><th>Software Req</th>"
|
||||
"<th>Software Arch</th><th>Code</th><th>Test</th></tr>"
|
||||
)
|
||||
|
||||
def cell_items(ids: list[str]) -> str:
|
||||
@@ -377,8 +377,8 @@ def cmd_publish(items: dict[str, Item], out_dir: Path) -> int:
|
||||
parts.append("</table>")
|
||||
|
||||
# Code/Test details
|
||||
parts.append("<h2>Code → Architektur</h2>")
|
||||
parts.append("<table><tr><th>Datei</th><th>@arch</th><th>@reqs</th></tr>")
|
||||
parts.append("<h2>Code → Architecture</h2>")
|
||||
parts.append("<table><tr><th>File</th><th>@arch</th><th>@reqs</th></tr>")
|
||||
for swa_id, src_rel in IMPLEMENTED_SWA.items():
|
||||
arch, reqs = extract_tags(REPO / src_rel)
|
||||
parts.append(
|
||||
@@ -388,8 +388,8 @@ def cmd_publish(items: dict[str, Item], out_dir: Path) -> int:
|
||||
)
|
||||
parts.append("</table>")
|
||||
|
||||
parts.append("<h2>Test → Anforderungen</h2>")
|
||||
parts.append("<table><tr><th>Test-Datei</th><th>Decklt SWA</th><th>@reqs</th></tr>")
|
||||
parts.append("<h2>Test → Requirements</h2>")
|
||||
parts.append("<table><tr><th>Test file</th><th>Covers SWA</th><th>@reqs</th></tr>")
|
||||
for test_file, swa_id in IMPLEMENTED_TESTS.items():
|
||||
_, reqs = extract_tags(REPO / "tests" / "unit" / test_file)
|
||||
parts.append(
|
||||
|
||||
Reference in New Issue
Block a user