Add commands and formatters modules
Some checks failed
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.8) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / build-package (push) Has been cancelled
CI / test (3.10) (push) Has been cancelled
Some checks failed
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.8) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / build-package (push) Has been cancelled
CI / test (3.10) (push) Has been cancelled
This commit is contained in:
94
configforge/commands/generate.py
Normal file
94
configforge/commands/generate.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
"""Generate command for ConfigForge."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import click
|
||||||
|
|
||||||
|
from configforge.exceptions import (
|
||||||
|
FileOperationError,
|
||||||
|
InvalidConfigFormatError,
|
||||||
|
SchemaGenerationError,
|
||||||
|
)
|
||||||
|
from configforge.formatters import JSONHandler, TypeScriptHandler, YAMLHandler
|
||||||
|
from configforge.utils.file_parser import detect_format
|
||||||
|
|
||||||
|
|
||||||
|
@click.command("generate")
|
||||||
|
@click.argument("input_file", type=click.Path(exists=True))
|
||||||
|
@click.option(
|
||||||
|
"--output",
|
||||||
|
"-o",
|
||||||
|
type=click.Path(),
|
||||||
|
help="Output file path (default: stdout)",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--interface-name",
|
||||||
|
"-n",
|
||||||
|
default="Config",
|
||||||
|
help="Name for the generated TypeScript interface",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--from-data",
|
||||||
|
is_flag=True,
|
||||||
|
default=False,
|
||||||
|
help="Generate TypeScript interface from sample data instead of schema",
|
||||||
|
)
|
||||||
|
def generate(
|
||||||
|
input_file: str,
|
||||||
|
output: Optional[str],
|
||||||
|
interface_name: str,
|
||||||
|
from_data: bool,
|
||||||
|
) -> None:
|
||||||
|
"""Generate TypeScript interfaces from JSON Schema or config data."""
|
||||||
|
try:
|
||||||
|
format_type = detect_format(input_file)
|
||||||
|
|
||||||
|
if format_type not in ("json", "yaml", "yml"):
|
||||||
|
raise InvalidConfigFormatError(
|
||||||
|
f"Unsupported format: {format_type}. Use JSON or YAML."
|
||||||
|
)
|
||||||
|
|
||||||
|
if from_data:
|
||||||
|
data = _read_data(input_file, format_type)
|
||||||
|
ts_output = TypeScriptHandler.generate_from_data(data, interface_name)
|
||||||
|
else:
|
||||||
|
schema = _read_schema(input_file, format_type)
|
||||||
|
ts_output = TypeScriptHandler.generate_from_schema(schema, interface_name)
|
||||||
|
|
||||||
|
if output:
|
||||||
|
_write_output(output, ts_output)
|
||||||
|
click.echo(f"Generated TypeScript interface -> {output}")
|
||||||
|
else:
|
||||||
|
click.echo(ts_output)
|
||||||
|
|
||||||
|
except (InvalidConfigFormatError, FileOperationError, SchemaGenerationError) as e:
|
||||||
|
click.echo(f"Error: {e.message}", err=True)
|
||||||
|
click.get_current_context().exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def _read_data(filepath: str, format_type: str) -> dict:
|
||||||
|
"""Read configuration data from file."""
|
||||||
|
if format_type == "json":
|
||||||
|
return JSONHandler.read(filepath)
|
||||||
|
else:
|
||||||
|
return YAMLHandler.read(filepath)
|
||||||
|
|
||||||
|
|
||||||
|
def _read_schema(filepath: str, format_type: str) -> dict:
|
||||||
|
"""Read JSON Schema from file."""
|
||||||
|
if format_type == "json":
|
||||||
|
return JSONHandler.read(filepath)
|
||||||
|
else:
|
||||||
|
return YAMLHandler.read(filepath)
|
||||||
|
|
||||||
|
|
||||||
|
def _write_output(filepath: str, content: str) -> None:
|
||||||
|
"""Write content to output file."""
|
||||||
|
try:
|
||||||
|
with open(filepath, "w", encoding="utf-8") as f:
|
||||||
|
f.write(content)
|
||||||
|
except PermissionError:
|
||||||
|
raise FileOperationError(f"Permission denied: {filepath}", filepath=filepath)
|
||||||
|
except OSError as e:
|
||||||
|
raise FileOperationError(f"Failed to write {filepath}: {str(e)}", filepath=filepath)
|
||||||
Reference in New Issue
Block a user