Initial SQL-only 1C adapter baseline

This commit is contained in:
2026-07-22 03:03:47 +03:00
commit e2503b77e7
545 changed files with 184711 additions and 0 deletions
@@ -0,0 +1,172 @@
#!/usr/bin/env python3
"""Check manual evidence files for a 1C extension validation plan."""
from __future__ import annotations
import argparse
import json
import re
from pathlib import Path
from typing import Any
PENDING_MARKERS = ("status: pending", '"status": "pending"')
PASSED_STATUSES = {"passed", "success", "ok"}
STATUS_LINE_RE = re.compile(r"^\s*status\s*:\s*([A-Za-zА-Яа-я0-9_-]+)\s*$", re.IGNORECASE | re.MULTILINE)
SECRET_TEXT_RE = re.compile(r"(password|passwd|pwd|secret|token|парол|секрет|usr|user)\s*[:=]", re.IGNORECASE)
def load_json(path: Path) -> dict[str, Any]:
return json.loads(path.read_text(encoding="utf-8-sig"))
def write_json(path: Path, data: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
def issue(severity: str, code: str, message: str, *, path: Path | str | None = None, detail: dict[str, Any] | None = None) -> dict[str, Any]:
result: dict[str, Any] = {"severity": severity, "code": code, "message": message}
if path is not None:
result["path"] = str(path)
if detail:
result["detail"] = detail
return result
def evidence_root(plan: dict[str, Any], override: Path | None = None) -> Path:
if override:
return override
configured = ((plan.get("runner_config") or {}).get("evidence_root")) or ((plan.get("evidence") or {}).get("root"))
if not configured:
raise SystemExit("Validation plan has no evidence root.")
return Path(str(configured))
def text_status(text: str) -> str | None:
match = STATUS_LINE_RE.search(text)
return match.group(1).casefold() if match else None
def check_json_evidence(path: Path, text: str, findings: list[dict[str, Any]]) -> tuple[bool, str | None]:
try:
payload = json.loads(text)
except json.JSONDecodeError as exc:
findings.append(issue("error", "invalid_json_evidence", f"Evidence JSON is invalid: {exc}", path=path))
return False, None
status = str(payload.get("status") or "").casefold()
if status not in PASSED_STATUSES:
findings.append(issue("error", "evidence_status_not_passed", "Evidence JSON status must be passed/success/ok.", path=path, detail={"status": status or None}))
return False, status or None
if path.name == "changed-objects-smoke.json":
objects = payload.get("objects")
if not isinstance(objects, list) or not objects:
findings.append(issue("error", "missing_smoke_objects", "changed-objects-smoke.json must contain a non-empty objects list.", path=path))
return False, status
failed = [
{"object_name": item.get("object_name"), "status": item.get("status")}
for item in objects
if not isinstance(item, dict) or str(item.get("status") or "").casefold() not in PASSED_STATUSES
]
if failed:
findings.append(issue("error", "smoke_object_status_not_passed", "Every changed object smoke record must have status passed/success/ok.", path=path, detail={"failed": failed}))
return False, status
return True, status
def check_text_evidence(path: Path, text: str, findings: list[dict[str, Any]]) -> tuple[bool, str | None]:
status = text_status(text)
if status not in PASSED_STATUSES:
findings.append(issue("error", "evidence_status_not_passed", "Evidence text must contain a Status: passed/success/ok line.", path=path, detail={"status": status}))
return False, status
return True, status
def check_evidence(plan_path: Path, output_root: Path | None = None) -> dict[str, Any]:
findings: list[dict[str, Any]] = []
file_checks: list[dict[str, Any]] = []
plan = load_json(plan_path)
if plan.get("schema") != "onec_extension_validation_plan.v1":
findings.append(issue("error", "invalid_plan_schema", "Validation plan schema is not onec_extension_validation_plan.v1.", path=plan_path, detail={"schema": plan.get("schema")}))
return build_result(plan_path, Path("."), findings, file_checks)
root = evidence_root(plan, output_root)
if not root.exists() or not root.is_dir():
findings.append(issue("error", "missing_evidence_root", "Evidence root is missing.", path=root))
return build_result(plan_path, root, findings, file_checks)
for name in (plan.get("evidence") or {}).get("required_files") or []:
relative = Path(str(name).replace("\\", "/"))
path = root / relative
check: dict[str, Any] = {
"relative_path": str(relative).replace("\\", "/"),
"path": str(path),
"exists": path.exists(),
"filled": False,
}
if not path.exists():
findings.append(issue("error", "missing_evidence_file", "Required evidence file is missing.", path=path))
else:
text = path.read_text(encoding="utf-8-sig", errors="replace")
stripped = text.strip()
check["size"] = len(text.encode("utf-8"))
if SECRET_TEXT_RE.search(text):
findings.append(issue("error", "secret_like_text_in_evidence", "Evidence file contains secret-like key/value text.", path=path))
pending = any(marker in text.casefold() for marker in PENDING_MARKERS)
if pending:
findings.append(issue("error", "pending_evidence_file", "Evidence file still contains a pending template.", path=path))
if not stripped:
findings.append(issue("error", "empty_evidence_file", "Evidence file is empty.", path=path))
elif path.suffix.casefold() == ".json":
passed, status = check_json_evidence(path, text, findings)
check["status"] = status
check["filled"] = passed and not pending
else:
passed, status = check_text_evidence(path, text, findings)
check["status"] = status
check["filled"] = passed and not pending
file_checks.append(check)
manifest_path = root / "_codex_validation_evidence_manifest.json"
if not manifest_path.exists():
findings.append(issue("warning", "missing_evidence_manifest", "Evidence manifest is missing.", path=manifest_path))
return build_result(plan_path, root, findings, file_checks)
def build_result(plan_path: Path, root: Path, findings: list[dict[str, Any]], file_checks: list[dict[str, Any]]) -> dict[str, Any]:
errors = [row for row in findings if row.get("severity") == "error"]
warnings = [row for row in findings if row.get("severity") == "warning"]
return {
"schema": "onec_extension_validation_evidence_check.v1",
"plan_path": str(plan_path),
"evidence_root": str(root),
"passed": not errors,
"status": "validated" if not errors else "pending_or_blocked",
"findings": findings,
"file_checks": file_checks,
"counts": {
"files": len(file_checks),
"filled": sum(1 for item in file_checks if item.get("filled")),
"errors": len(errors),
"warnings": len(warnings),
},
}
def main() -> int:
parser = argparse.ArgumentParser(description="Check manual evidence files for a 1C extension validation plan.")
parser.add_argument("--plan", type=Path, required=True)
parser.add_argument("--evidence-root", type=Path)
parser.add_argument("--output", type=Path)
args = parser.parse_args()
result = check_evidence(args.plan, args.evidence_root)
if args.output:
write_json(args.output, result)
print(json.dumps({"output": str(args.output) if args.output else None, "passed": result["passed"], "status": result["status"], "counts": result["counts"]}, ensure_ascii=False))
return 0 if result["passed"] else 2
if __name__ == "__main__":
raise SystemExit(main())