Files
KNELCloudronPackages/scripts/generate_status.py

76 lines
2.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""Produce status documentation for all apps."""
import json
import pathlib
from datetime import datetime
from typing import Dict, List
ROOT = pathlib.Path(__file__).resolve().parents[1]
def load_catalog() -> List[Dict[str, str]]:
catalog_path = ROOT / "apps" / "catalog.json"
return json.loads(catalog_path.read_text(encoding="utf-8"))
def load_manifest(app_dir: pathlib.Path) -> Dict[str, object]:
manifest_path = app_dir / "CloudronManifest.json"
if not manifest_path.exists():
return {}
try:
return json.loads(manifest_path.read_text(encoding="utf-8"))
except json.JSONDecodeError:
return {}
def detect_status(app_dir: pathlib.Path) -> str:
manifest = load_manifest(app_dir)
start_script = (app_dir / "start.sh").read_text(encoding="utf-8") if (app_dir / "start.sh").exists() else ""
placeholders = 0
if "TODO" in json.dumps(manifest):
placeholders += 1
if "Replace start.sh" in start_script:
placeholders += 1
if placeholders == 0:
return "ready"
if placeholders == 1:
return "in-progress"
return "todo"
def render_table(rows: List[Dict[str, str]]) -> str:
header = "| Slug | Title | Version | Status | Issue |\n| --- | --- | --- | --- | --- |"
lines = [header]
for row in rows:
lines.append(
f"| {row['slug']} | {row['title']} | {row['version']} | {row['status']} | {row['issue']} |"
)
return "\n".join(lines)
def main() -> None:
catalog = load_catalog()
rows: List[Dict[str, str]] = []
for entry in catalog:
slug = entry["slug"]
app_dir = ROOT / "apps" / slug
manifest = load_manifest(app_dir)
rows.append({
"slug": slug,
"title": entry["title"],
"version": manifest.get("version", "0.1.0"),
"status": detect_status(app_dir),
"issue": entry.get("issue", "")
})
output = ["# Application Status", "", f"_Updated: {datetime.utcnow().isoformat(timespec='seconds')}Z_", "", render_table(rows)]
status_path = ROOT / "docs" / "APP_STATUS.md"
status_path.write_text("\n".join(output) + "\n", encoding="utf-8")
print(f"Updated {status_path.relative_to(ROOT)}")
if __name__ == "__main__":
main()