()
| 316 | |
| 317 | |
| 318 | def load_projects() -> list[dict]: |
| 319 | projects: list[dict] = [] |
| 320 | for metadata_path in sorted(REPO_ROOT.glob("project-*/project.yaml")): |
| 321 | project_dir = metadata_path.parent |
| 322 | metadata = parse_project_yaml(metadata_path.read_text(encoding="utf-8")) |
| 323 | readme_path = project_dir / "README.md" |
| 324 | readme_text = readme_path.read_text(encoding="utf-8") |
| 325 | project = metadata["project"] |
| 326 | number = int(project["number"]) |
| 327 | slug = project["slug"] |
| 328 | route = f"{number:02d}-{slug}" |
| 329 | item = { |
| 330 | "number": number, |
| 331 | "slug": slug, |
| 332 | "route": route, |
| 333 | "dir": project_dir.name, |
| 334 | "name": project["name"], |
| 335 | "classification": metadata["classification"], |
| 336 | "status": metadata["status"], |
| 337 | "deployability": metadata["deployability"], |
| 338 | "stack": metadata.get("stack", []), |
| 339 | "cloud": metadata.get("cloud", []), |
| 340 | "iac": metadata.get("iac", []), |
| 341 | "ci_cd": metadata.get("ci_cd", []), |
| 342 | "cost_risk": metadata["cost_risk"], |
| 343 | "security_posture": metadata["security_posture"], |
| 344 | "validation": metadata["validation"]["command"], |
| 345 | "notes": metadata["notes"], |
| 346 | "readme": readme_path, |
| 347 | } |
| 348 | item.update(lab_metadata(item, readme_text)) |
| 349 | projects.append(item) |
| 350 | return sorted(projects, key=lambda item: item["number"]) |
| 351 | |
| 352 | |
| 353 | def project_maps(projects: list[dict]) -> tuple[dict[str, str], dict[str, dict]]: |
no test coverage detected