Skip to content

Commit ec985dd

Browse files
committed
fix(codegen): infer backend from sources without metadata
Allow codegen backend resolution to use on-disk source scanning as a fallback when feature_spec and RPG metadata do not declare a target language. Pass the repo path through prompt-building call sites so API summaries and TDD prompts resolve the same backend, while preserving explicit feature_spec/RPG language metadata precedence. Add regression coverage for metadata-free Go repos and explicit metadata overriding source-scan fallback.
1 parent 046453f commit ec985dd

2 files changed

Lines changed: 48 additions & 4 deletions

File tree

CoderMind/scripts/code_gen/batch_prompts.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
ToolchainUnavailable,
5353
get_backend,
5454
resolve_decoder_language,
55+
scan_repo_source_files,
5556
)
5657

5758
logger = logging.getLogger(__name__)
@@ -387,11 +388,18 @@ def _load_json_if_exists(path: Path) -> Any:
387388
return None
388389

389390

390-
def _resolve_codegen_backend() -> LanguageBackend:
391+
def _resolve_codegen_backend(repo_path: Path | None = None) -> LanguageBackend:
391392
"""Resolve the target language backend for code generation."""
392393
feature_spec = _load_json_if_exists(FEATURE_SPEC_FILE)
393394
rpg_obj = _load_json_if_exists(REPO_RPG_FILE)
394-
language = resolve_decoder_language(feature_spec=feature_spec, rpg_obj=rpg_obj)
395+
valid_files = None
396+
if repo_path is not None:
397+
valid_files = scan_repo_source_files(repo_path) or None
398+
language = resolve_decoder_language(
399+
feature_spec=feature_spec,
400+
rpg_obj=rpg_obj,
401+
valid_files=valid_files,
402+
)
395403
return get_backend(language)
396404

397405

@@ -599,7 +607,7 @@ def _build_api_summary(repo_path: Path, source_files: List[str], max_chars: int
599607
# receive real API context instead of nothing.
600608
import ast as _ast # local import; only used for unparse(returns)
601609

602-
backend = _resolve_codegen_backend()
610+
backend = _resolve_codegen_backend(repo_path)
603611
is_python = backend.name == "python"
604612
summaries = []
605613
for filepath in sorted(source_files):
@@ -757,7 +765,7 @@ def build_tdd_prompt(
757765
Returns:
758766
Complete prompt string ready for LLMClient.generate().
759767
"""
760-
backend = _resolve_codegen_backend()
768+
backend = _resolve_codegen_backend(repo_path)
761769
venv_python = get_dev_python(repo_path) or "python3"
762770
import_convention = (
763771
build_import_convention_snippet(repo_path=repo_path)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import json
2+
import os
3+
import sys
4+
5+
# Ensure scripts/ is importable when tests run from the project root.
6+
_project_root = os.path.join(os.path.dirname(__file__), "..")
7+
sys.path.insert(0, os.path.join(_project_root, "scripts"))
8+
9+
from code_gen import batch_prompts
10+
11+
12+
def _isolate_metadata(monkeypatch, tmp_path):
13+
monkeypatch.setattr(batch_prompts, "FEATURE_SPEC_FILE", tmp_path / "missing_feature_spec.json")
14+
monkeypatch.setattr(batch_prompts, "REPO_RPG_FILE", tmp_path / "missing_rpg.json")
15+
16+
17+
def test_resolve_codegen_backend_uses_repo_source_scan_without_metadata(monkeypatch, tmp_path):
18+
_isolate_metadata(monkeypatch, tmp_path)
19+
(tmp_path / "cmd" / "app").mkdir(parents=True)
20+
(tmp_path / "cmd" / "app" / "main.go").write_text("package main\n", encoding="utf-8")
21+
22+
assert batch_prompts._resolve_codegen_backend(tmp_path).name == "go"
23+
24+
25+
def test_resolve_codegen_backend_prefers_feature_spec_metadata(monkeypatch, tmp_path):
26+
feature_spec = tmp_path / "feature_spec.json"
27+
feature_spec.write_text(
28+
json.dumps({"meta": {"primary_language": "python", "target_languages": ["python"]}}),
29+
encoding="utf-8",
30+
)
31+
monkeypatch.setattr(batch_prompts, "FEATURE_SPEC_FILE", feature_spec)
32+
monkeypatch.setattr(batch_prompts, "REPO_RPG_FILE", tmp_path / "missing_rpg.json")
33+
(tmp_path / "cmd" / "app").mkdir(parents=True)
34+
(tmp_path / "cmd" / "app" / "main.go").write_text("package main\n", encoding="utf-8")
35+
36+
assert batch_prompts._resolve_codegen_backend(tmp_path).name == "python"

0 commit comments

Comments
 (0)