47 lines
1.2 KiB
Python
47 lines
1.2 KiB
Python
"""Project artifact helpers shared by the Python runtime."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
PROJECTS_DIR = REPO_ROOT / "projects"
|
|
|
|
|
|
def resolve_project(project: str | Path) -> Path:
|
|
p = Path(project)
|
|
if p.is_dir():
|
|
return p.resolve()
|
|
candidate = PROJECTS_DIR / str(project)
|
|
if candidate.is_dir():
|
|
return candidate.resolve()
|
|
raise FileNotFoundError(f"project not found: {project}")
|
|
|
|
|
|
def load_manifest(project_root: Path) -> dict[str, Any]:
|
|
path = project_root / "manifest.json"
|
|
if not path.exists():
|
|
raise FileNotFoundError(f"manifest not found: {path}")
|
|
return json.loads(path.read_text(encoding="utf-8"))
|
|
|
|
|
|
def write_manifest(project_root: Path, manifest: dict[str, Any]) -> None:
|
|
path = project_root / "manifest.json"
|
|
path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
|
|
|
|
def ensure_phase_dirs(project_root: Path) -> None:
|
|
for rel in (
|
|
"phase1",
|
|
"phase2/drafts",
|
|
"phase2/evidence",
|
|
"phase2/packets",
|
|
"phase3",
|
|
"phase4",
|
|
):
|
|
(project_root / rel).mkdir(parents=True, exist_ok=True)
|
|
|