"""CLI entry point for synthetic database variant generation.""" from __future__ import annotations import argparse from pathlib import Path from .generate import generate_variant, generate_variants_for_question def _default_output_dir(db_path: str) -> str: db_name = Path(db_path).stem return str(Path("data") / "databases" / "variants" / db_name) def _parse_mutations(value: str | None) -> list[str] | None: if value is None: return None mutations = [item.strip() for item in value.split(",") if item.strip()] return mutations or None def _build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( prog="python -m server.synthetic", description="Generate synthetic SQLite variants for metamorphic SQL testing.", ) parser.add_argument("--db-path", required=True, help="Path to source SQLite DB") parser.add_argument("--gold-sql", required=True, help="Gold SQL query to validate") parser.add_argument( "--output-dir", default=None, help="Directory for generated variants (default: data/databases/variants/{db})", ) parser.add_argument( "--n-variants", type=int, default=2, help="Number of variants to generate", ) parser.add_argument( "--mutations", default=None, help="Comma-separated mutation names (default: all)", ) return parser def main(argv: list[str] | None = None) -> int: """Run synthetic DB generation CLI and return process exit code.""" parser = _build_parser() args = parser.parse_args(argv) output_dir = args.output_dir or _default_output_dir(args.db_path) selected_mutations = _parse_mutations(args.mutations) if selected_mutations is None: results = generate_variants_for_question( db_path=args.db_path, gold_sql=args.gold_sql, output_dir=output_dir, n_variants=args.n_variants, ) else: results = [] for variant_id in range(max(args.n_variants, 0)): result = generate_variant( db_path=args.db_path, gold_sql=args.gold_sql, output_dir=output_dir, mutations=selected_mutations, variant_id=variant_id, ) if result.gold_sql_valid: results.append(result) print(f"Generated {len(results)} valid variant(s) in {output_dir}") for result in results: print(f"- {result.variant_path}") return 0 if results else 1 if __name__ == "__main__": raise SystemExit(main())