fix: explain missing CC2 source bundle
This commit is contained in:
parent
d229a9b022
commit
3588bbcf94
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
|
@ -93,22 +94,27 @@ def slugify(text: str, limit: int = 54) -> str:
|
|||
return slug[:limit].strip("-") or "item"
|
||||
|
||||
|
||||
def find_source_omx(repo_root: Path) -> Path:
|
||||
candidates = []
|
||||
env = None
|
||||
try:
|
||||
import os
|
||||
env = os.environ.get("CC2_SOURCE_OMX")
|
||||
except Exception:
|
||||
env = None
|
||||
def find_source_omx(repo_root: Path, env_value: str | None = None) -> Path:
|
||||
candidates: list[Path] = []
|
||||
env = env_value if env_value is not None else os.environ.get("CC2_SOURCE_OMX")
|
||||
if env:
|
||||
candidates.append(Path(env).expanduser())
|
||||
candidates.append(repo_root / ".omx")
|
||||
candidates.extend(parent / ".omx" for parent in repo_root.parents)
|
||||
for candidate in candidates:
|
||||
|
||||
checked: list[Path] = []
|
||||
for candidate in dict.fromkeys(candidate.resolve() for candidate in candidates):
|
||||
checked.append(candidate)
|
||||
if (candidate / "plans" / "claw-code-2-0-adaptive-plan.md").exists() and (candidate / "research").exists():
|
||||
return candidate
|
||||
raise FileNotFoundError("could not locate source .omx with plans/claw-code-2-0-adaptive-plan.md and research/")
|
||||
|
||||
searched = "\n".join(f" - {path}" for path in checked)
|
||||
raise FileNotFoundError(
|
||||
"could not locate source .omx with plans/claw-code-2-0-adaptive-plan.md and research/\n"
|
||||
f"searched:\n{searched}\n"
|
||||
"Recovery: restore the frozen CC2 source bundle or Set CC2_SOURCE_OMX=/path/to/.omx. "
|
||||
"The source root must contain plans/claw-code-2-0-adaptive-plan.md and research/."
|
||||
)
|
||||
|
||||
|
||||
def parse_roadmap(path: Path) -> tuple[list[RoadmapRecord], list[RoadmapRecord]]:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
GENERATOR = REPO_ROOT / "scripts" / "generate_cc2_board.py"
|
||||
|
||||
|
||||
def load_generator():
|
||||
spec = importlib.util.spec_from_file_location("generate_cc2_board", GENERATOR)
|
||||
assert spec and spec.loader
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[spec.name] = module
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
class CC2BoardGeneratorTests(unittest.TestCase):
|
||||
def test_missing_source_omx_error_lists_searched_paths_and_recovery_steps(self) -> None:
|
||||
generator = load_generator()
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
repo_root = Path(temp_dir) / "repo"
|
||||
repo_root.mkdir()
|
||||
(repo_root / "ROADMAP.md").write_text("# Roadmap\n", encoding="utf-8")
|
||||
|
||||
with self.assertRaises(FileNotFoundError) as caught:
|
||||
generator.find_source_omx(repo_root)
|
||||
|
||||
message = str(caught.exception)
|
||||
self.assertIn("could not locate source .omx", message)
|
||||
self.assertIn("searched:", message)
|
||||
self.assertIn(str(repo_root / ".omx"), message)
|
||||
self.assertIn("Set CC2_SOURCE_OMX", message)
|
||||
self.assertIn("plans/claw-code-2-0-adaptive-plan.md", message)
|
||||
self.assertIn("research/", message)
|
||||
|
||||
def test_source_omx_can_be_supplied_by_env(self) -> None:
|
||||
generator = load_generator()
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_root = Path(temp_dir)
|
||||
repo_root = temp_root / "repo"
|
||||
repo_root.mkdir()
|
||||
source = temp_root / "cc2-source"
|
||||
(source / "plans").mkdir(parents=True)
|
||||
(source / "research").mkdir()
|
||||
(source / "plans" / "claw-code-2-0-adaptive-plan.md").write_text(
|
||||
"# approved plan\n", encoding="utf-8"
|
||||
)
|
||||
|
||||
self.assertEqual(source, generator.find_source_omx(repo_root, env_value=str(source)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Reference in New Issue