feat: consolidate legacy workflows into gyxx-flow

This commit is contained in:
2026-07-28 14:51:15 +08:00
commit c23b62a8c8
374 changed files with 132990 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
"""Read-only and transient preflight diagnostics for operators."""
from __future__ import annotations
import importlib.util
import sys
import tempfile
from dataclasses import asdict, dataclass
from pathlib import Path
from gyxx_flow.catalog import WorkflowCatalog
from gyxx_flow.core.config import Settings
@dataclass(frozen=True, slots=True)
class DiagnosticCheck:
name: str
passed: bool
message: str
@dataclass(frozen=True, slots=True)
class DoctorReport:
checks: tuple[DiagnosticCheck, ...]
@property
def is_healthy(self) -> bool:
return all(check.passed for check in self.checks)
def as_dict(self) -> dict[str, object]:
return {
"is_healthy": self.is_healthy,
"checks": [asdict(check) for check in self.checks],
}
def run_doctor(settings: Settings) -> DoctorReport:
checks = [
DiagnosticCheck(
"python",
sys.version_info >= (3, 12),
f"Python {sys.version_info.major}.{sys.version_info.minor}",
),
DiagnosticCheck(
"cli",
importlib.util.find_spec("gyxx_flow.__main__") is not None,
"gyxx_flow module entry point is importable",
),
DiagnosticCheck(
"project_root",
settings.project_root.is_dir(),
"project root exists" if settings.project_root.is_dir() else "project root is missing",
),
]
try:
catalog = WorkflowCatalog.load(settings.project_root / "config")
catalog_ok = len(catalog.scheduled_workflows()) == 21
catalog_message = f"catalog has {len(catalog.scheduled_workflows())} scheduled workflows"
except Exception:
catalog_ok = False
catalog_message = "catalog cannot be validated"
checks.append(DiagnosticCheck("catalog", catalog_ok, catalog_message))
data_root_ok = settings.data_root.is_absolute() and settings.data_root != Path(
settings.data_root.anchor
)
checks.append(
DiagnosticCheck(
"data_root",
data_root_ok,
"data root is an explicit non-root path" if data_root_ok else "unsafe data root",
)
)
writable, message = _probe_write_permission(settings.data_root)
checks.append(DiagnosticCheck("data_root_write", writable, message))
return DoctorReport(tuple(checks))
def _probe_write_permission(path: Path) -> tuple[bool, str]:
candidate = Path(path)
while not candidate.exists() and candidate.parent != candidate:
candidate = candidate.parent
if not candidate.is_dir():
return False, "no existing data-root parent directory"
try:
with tempfile.NamedTemporaryFile(
mode="wb", prefix=".gyxx-doctor-probe-", dir=candidate, delete=True
) as stream:
stream.write(b"probe")
stream.flush()
except OSError:
return False, "data-root parent is not writable"
return True, "data-root parent write probe passed"