feat: 多轮运行 + GCOV 合并 + JSON 出力 + DesignDataGenerator
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
"""データ統合 — 白盒 + 机能 + 策略データの統合と合併。
|
||||
|
||||
generate_all_data() エントリポイント:
|
||||
① generate_data() → 白盒(MC/DC パスカバレッジ)
|
||||
② DesignDataGenerator → 机能(式样书から LLM 生成)
|
||||
③ strategy_supplement() → 策略(HINA 分類に基づく境界条件)
|
||||
④ 重複除去 + フィールド名正規化
|
||||
⑤ 統合リスト返却
|
||||
"""
|
||||
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from cobol_testgen import extract_structure, generate_data
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _dedup(
|
||||
main_records: list[dict],
|
||||
additional_records: list[dict] | None = None,
|
||||
key_fields: list[str] | None = None,
|
||||
) -> list[dict]:
|
||||
"""合并+去重,additional 优先保留。"""
|
||||
if not additional_records:
|
||||
return list(main_records)
|
||||
|
||||
seen = set()
|
||||
result = []
|
||||
|
||||
def _hash(rec, keys):
|
||||
if keys:
|
||||
return tuple(rec.get(k, "") for k in keys)
|
||||
return tuple(sorted(rec.items()))
|
||||
|
||||
for rec in additional_records:
|
||||
h = _hash(rec, key_fields)
|
||||
if h not in seen:
|
||||
seen.add(h)
|
||||
result.append(rec)
|
||||
|
||||
for rec in main_records:
|
||||
h = _hash(rec, key_fields)
|
||||
if h not in seen:
|
||||
seen.add(h)
|
||||
result.append(rec)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def generate_all_data(
|
||||
program_id: str,
|
||||
src_text: str,
|
||||
st: dict | None = None,
|
||||
copybook_dirs: list[str | Path] | None = None,
|
||||
design_doc_dir: str | Path | None = None,
|
||||
llm_client=None,
|
||||
config=None,
|
||||
merge_strategy: str = "merge_to_normal",
|
||||
) -> list[dict]:
|
||||
"""白盒 + 机能 + 策略 全量生成と統合。
|
||||
|
||||
Args:
|
||||
program_id: プログラム ID
|
||||
src_text: COBOL ソーステキスト
|
||||
st: extract_structure() 結果(省略時は内部で再解析)
|
||||
copybook_dirs: COPYBOOK 探索パス
|
||||
design_doc_dir: 式样书配置ディレクトリ
|
||||
llm_client: LLMClient インスタンス(None で LLM 系スキップ)
|
||||
config: Config インスタンス
|
||||
merge_strategy: merge_to_normal / as_separate_scenes / auto
|
||||
|
||||
Returns:
|
||||
list[dict]: 統合済みレコードリスト
|
||||
"""
|
||||
cbd = [str(d) for d in (copybook_dirs or [])]
|
||||
|
||||
# ① 白盒データ
|
||||
if st is None:
|
||||
st = extract_structure(src_text, copybook_dirs=cbd)
|
||||
whitebox = generate_data(src_text, st, copybook_dirs=cbd)
|
||||
logger.info(f" White-box records: {len(whitebox)}")
|
||||
|
||||
# ② 机能データ(式样书 + LLM)
|
||||
func_data: list[dict] = []
|
||||
if design_doc_dir and llm_client:
|
||||
design_path = Path(design_doc_dir) / f"詳細設計書_{program_id}.md"
|
||||
if design_path.exists():
|
||||
from agents.design_data import DesignDataGenerator, _extract_replacing_rules
|
||||
|
||||
gen = DesignDataGenerator(llm_client, cbd)
|
||||
v3_names = list(st.get("field_names", [])) if st else None
|
||||
replacing = _extract_replacing_rules(src_text)
|
||||
|
||||
try:
|
||||
func_data = gen.generate(
|
||||
design_md_text=design_path.read_text(encoding="utf-8"),
|
||||
source_text=src_text,
|
||||
replacing_rules=replacing,
|
||||
v3_field_names=v3_names,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(f" DesignDataGenerator failed: {e}")
|
||||
else:
|
||||
logger.info(f" Design doc not found: {design_path}")
|
||||
|
||||
logger.info(f" Functional records: {len(func_data)}")
|
||||
|
||||
# ③ 策略データ
|
||||
strategy_data: list[dict] = []
|
||||
try:
|
||||
from hina.strategy import supplement
|
||||
|
||||
strat_raw = supplement([], {})
|
||||
for s in strat_raw:
|
||||
if isinstance(s, dict) and "fields" in s:
|
||||
strategy_data.append(s["fields"])
|
||||
except Exception as e:
|
||||
logger.debug(f" Strategy supplement skipped: {e}")
|
||||
|
||||
logger.info(f" Strategy records: {len(strategy_data)}")
|
||||
|
||||
# ④ 統合
|
||||
all_records = _dedup(whitebox, func_data)
|
||||
if strategy_data:
|
||||
all_records = _dedup(all_records, strategy_data)
|
||||
|
||||
logger.info(f" Total merged records: {len(all_records)}")
|
||||
return all_records
|
||||
Reference in New Issue
Block a user