Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """Verify repository packaging, documentation references, and safe templates.""" | |
| from __future__ import annotations | |
| import re | |
| import sys | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[1] | |
| REQUIRED = ( | |
| ".env.example", ".gitignore", ".gitattributes", ".python-version", | |
| "VERSION", "BUILD_MANIFEST.md", "requirements.lock", "requirements-ci.lock", "package.json", "package-lock.json", "README.md", | |
| "scripts/check_migrations.py", "scripts/validate_startup_configuration.py", | |
| "scripts/generate_dependency_inventory.py", "docs/dependency_inventory.json", "docs/dependency_licenses.json", | |
| ) | |
| SECRET_TEMPLATE_KEYS = { | |
| "HF_TOKEN", "HERMES_ADMIN_PASSWORD", "HERMES_SESSION_SECRET", | |
| "FUTURES_API_KEY", "FUTURES_API_SECRET", "FUTURES_API_PASSPHRASE", | |
| "OPENROUTER_API_KEY", "GOOGLE_API_KEY", "TELEGRAM_BOT_TOKEN", | |
| "TELEGRAM_WEBHOOK_SECRET", "TELEGRAM_BOOTSTRAP_SECRET", | |
| } | |
| def verify(root: Path = ROOT) -> list[str]: | |
| errors: list[str] = [] | |
| for rel in REQUIRED: | |
| if not (root / rel).is_file(): | |
| errors.append(f"required repository file missing: {rel}") | |
| readme_path = root / "README.md" | |
| if readme_path.is_file(): | |
| readme = readme_path.read_text(encoding="utf-8") | |
| for target in re.findall(r"\[[^]]+\]\(([^)]+)\)", readme): | |
| if "://" in target or target.startswith("#"): | |
| continue | |
| if not (root / target).exists(): | |
| errors.append(f"README link target missing: {target}") | |
| for required_command in ( | |
| "python scripts/validate_startup_configuration.py", | |
| "python scripts/check_migrations.py", | |
| "python -m pytest hermes_overlay/tests -q", | |
| "docker build", | |
| ): | |
| if required_command not in readme: | |
| errors.append(f"README command missing: {required_command}") | |
| package_path = root / "package.json" | |
| lock_path = root / "package-lock.json" | |
| if package_path.is_file() and lock_path.is_file(): | |
| import json | |
| try: | |
| package = json.loads(package_path.read_text(encoding="utf-8")) | |
| lock = json.loads(lock_path.read_text(encoding="utf-8")) | |
| except (OSError, ValueError) as exc: | |
| errors.append(f"invalid Node metadata: {exc.__class__.__name__}") | |
| else: | |
| if package.get("engines", {}).get("node") != "22.16.0": | |
| errors.append("package.json must pin Node 22.16.0") | |
| if not lock.get("lockfileVersion"): | |
| errors.append("package-lock.json must declare lockfileVersion") | |
| root_package = lock.get("packages", {}).get("", {}) | |
| if root_package.get("engines", {}).get("node") != "22.16.0": | |
| errors.append("package-lock.json must preserve the Node engine pin") | |
| env_path = root / ".env.example" | |
| if env_path.is_file(): | |
| entries: dict[str, str] = {} | |
| for raw in env_path.read_text(encoding="utf-8").splitlines(): | |
| line = raw.strip() | |
| if not line or line.startswith("#") or "=" not in line: | |
| continue | |
| key, value = line.split("=", 1) | |
| entries[key.strip()] = value.strip() | |
| for key in SECRET_TEMPLATE_KEYS: | |
| if entries.get(key): | |
| errors.append(f"secret template key must be blank: {key}") | |
| if entries.get("TRADING_MODE") != "paper": | |
| errors.append("TRADING_MODE template must default to paper") | |
| if entries.get("HERMES_EXECUTION_ENABLED", "").lower() != "false": | |
| errors.append("HERMES_EXECUTION_ENABLED template must default false") | |
| return errors | |
| def main() -> int: | |
| errors = verify() | |
| for error in errors: | |
| print(f"ERROR: {error}") | |
| print(f"repository_metadata={'PASS' if not errors else 'FAIL'}") | |
| return 1 if errors else 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |