Initial upload: testdata-cli with CI/CD workflow
Some checks failed
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-03-22 19:45:25 +00:00
parent e5a88380d4
commit 9f3771c582

258
src/testdatagen/cli.py Normal file
View File

@@ -0,0 +1,258 @@
"""Main CLI module for TestDataGen."""
import sys
from pathlib import Path
import click
from testdatagen.formatters.csv_formatter import CSVFormatter
from testdatagen.formatters.json_formatter import JSONFormatter
from testdatagen.formatters.sql_formatter import SQLFormatter
from testdatagen.generators.json_schema_generator import JSONSchemaGenerator
@click.group()
@click.version_option(version="0.1.0")
def main():
"""TestDataGen - Generate realistic test data from schemas and types."""
pass
@main.command()
@click.option(
"--schema", "-s",
type=click.Path(exists=True, file_okay=True, dir_okay=False),
required=True,
help="Path to JSON Schema file"
)
@click.option(
"--count", "-n",
type=int,
default=10,
help="Number of records to generate (default: 10)"
)
@click.option(
"--format", "-f",
type=click.Choice(["json", "csv", "sql"], case_sensitive=False),
default="json",
help="Output format (default: json)"
)
@click.option(
"--seed",
type=int,
default=None,
help="Random seed for reproducibility"
)
@click.option(
"--table",
type=str,
default="generated_table",
help="Table name for SQL output (default: generated_table)"
)
@click.option(
"--indent",
type=int,
default=None,
help="Indentation level for JSON output (default: None)"
)
def generate(schema, count, format, seed, table, indent):
"""Generate test data from a JSON Schema file."""
try:
schema_path = Path(schema)
with open(schema_path, "r") as f:
import json
schema_data = json.load(f)
generator = JSONSchemaGenerator(seed=seed)
records = generator.generate(schema_data, count=count)
if format.lower() == "json":
formatter = JSONFormatter(indent=indent)
elif format.lower() == "csv":
formatter = CSVFormatter()
elif format.lower() == "sql":
formatter = SQLFormatter(table_name=table)
else:
click.echo(f"Error: Unsupported format '{format}'", err=True)
sys.exit(1)
output = formatter.format(records)
click.echo(output)
except json.JSONDecodeError as e:
click.echo(f"Error: Invalid JSON in schema file: {e}", err=True)
sys.exit(1)
except FileNotFoundError:
click.echo(f"Error: Schema file not found: {schema}", err=True)
sys.exit(1)
except Exception as e:
click.echo(f"Error: {e}", err=True)
sys.exit(1)
@main.command()
@click.option(
"--input", "-i",
type=click.Path(exists=True, file_okay=True, dir_okay=False),
required=True,
help="Path to TypeScript file"
)
@click.option(
"--count", "-n",
type=int,
default=10,
help="Number of records to generate (default: 10)"
)
@click.option(
"--format", "-f",
type=click.Choice(["json", "csv", "sql"], case_sensitive=False),
default="json",
help="Output format (default: json)"
)
@click.option(
"--seed",
type=int,
default=None,
help="Random seed for reproducibility"
)
@click.option(
"--table",
type=str,
default="generated_table",
help="Table name for SQL output (default: generated_table)"
)
def from_ts(input, count, format, seed, table):
"""Generate test data from a TypeScript type definition."""
try:
import subprocess
result = subprocess.run(
["npx", "tsc", "--declaration", "--emitDeclarationOnly", "--jsonSchemaManifest", input],
capture_output=True,
text=True,
timeout=30
)
if result.returncode != 0:
click.echo(f"Error: TypeScript compilation failed: {result.stderr}", err=True)
sys.exit(1)
schema_path = Path(input).with_suffix(".json")
if not schema_path.exists():
click.echo("Error: Could not generate schema from TypeScript file", err=True)
sys.exit(1)
with open(schema_path, "r") as f:
import json
schema_data = json.load(f)
generator = JSONSchemaGenerator(seed=seed)
records = generator.generate(schema_data, count=count)
if format.lower() == "json":
formatter = JSONFormatter()
elif format.lower() == "csv":
formatter = CSVFormatter()
elif format.lower() == "sql":
formatter = SQLFormatter(table_name=table)
else:
click.echo(f"Error: Unsupported format '{format}'", err=True)
sys.exit(1)
output = formatter.format(records)
click.echo(output)
except FileNotFoundError:
click.echo("Error: TypeScript file not found", err=True)
sys.exit(1)
except subprocess.TimeoutExpired:
click.echo("Error: TypeScript compilation timed out", err=True)
sys.exit(1)
except Exception as e:
click.echo(f"Error: {e}", err=True)
sys.exit(1)
@main.command()
@click.option(
"--input", "-i",
type=click.Path(exists=True, file_okay=True, dir_okay=False),
required=True,
help="Path to sample data file (JSON or CSV)"
)
@click.option(
"--count", "-n",
type=int,
default=10,
help="Number of records to generate (default: 10)"
)
@click.option(
"--format", "-f",
type=click.Choice(["json", "csv", "sql"], case_sensitive=False),
default="json",
help="Output format (default: json)"
)
@click.option(
"--seed",
type=int,
default=None,
help="Random seed for reproducibility"
)
@click.option(
"--table",
type=str,
default="generated_table",
help="Table name for SQL output (default: generated_table)"
)
def from_sample(input, count, format, seed, table):
"""Generate test data from a sample data file."""
try:
input_path = Path(input)
with open(input_path, "r") as f:
import json
sample_data = json.load(f)
try:
from genson import SchemaBuilder
except ImportError:
click.echo("Error: genson not installed. Run: pip install genson", err=True)
sys.exit(1)
builder = SchemaBuilder()
if isinstance(sample_data, list):
for item in sample_data:
builder.add_object(item)
else:
builder.add_object(sample_data)
schema_data = builder.to_schema()
generator = JSONSchemaGenerator(seed=seed)
records = generator.generate(schema_data, count=count)
if format.lower() == "json":
formatter = JSONFormatter()
elif format.lower() == "csv":
formatter = CSVFormatter()
elif format.lower() == "sql":
formatter = SQLFormatter(table_name=table)
else:
click.echo(f"Error: Unsupported format '{format}'", err=True)
sys.exit(1)
output = formatter.format(records)
click.echo(output)
except json.JSONDecodeError:
click.echo(f"Error: Invalid JSON in sample file: {input}", err=True)
sys.exit(1)
except FileNotFoundError:
click.echo(f"Error: Sample file not found: {input}", err=True)
sys.exit(1)
except Exception as e:
click.echo(f"Error: {e}", err=True)
sys.exit(1)
if __name__ == "__main__":
main()