Add formatters, utils, schemas and version
Some checks failed
CI / test (3.10) (push) Has been cancelled
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

This commit is contained in:
2026-01-29 10:50:34 +00:00
parent 6470e7fe5c
commit d9e02a553c

View File

@@ -0,0 +1,99 @@
"""Output formatting utilities for ConfigForge."""
import json
from typing import Any, Dict, List, Optional
import yaml
class Formatters:
"""Collection of output formatters for different output formats."""
@staticmethod
def json(data: Any, indent: int = 2) -> str:
"""Format data as JSON."""
return json.dumps(data, indent=indent, ensure_ascii=False)
@staticmethod
def yaml(data: Any) -> str:
"""Format data as YAML."""
return yaml.safe_dump(data, default_flow_style=False, allow_unicode=True)
@staticmethod
def table(data: List[Dict[str, Any]], columns: Optional[List[str]] = None) -> str:
"""Format data as a table."""
if not data:
return ""
if columns is None:
columns = list(data[0].keys()) if data else []
if not columns:
return ""
col_widths = {col: len(col) for col in columns}
for row in data:
for col in columns:
if col in row:
col_widths[col] = max(col_widths[col], len(str(row.get(col, ""))))
header = " ".join(col.ljust(col_widths[col]) for col in columns)
separator = " ".join("-" * col_widths[col] for col in columns)
rows = []
for row in data:
row_str = " ".join(
str(row.get(col, "")).ljust(col_widths[col]) for col in columns
)
rows.append(row_str)
return "\n".join([header, separator] + rows)
@staticmethod
def validation_error(error: Dict[str, Any], verbose: bool = False) -> str:
"""Format a validation error."""
path = error.get("path", [])
path_str = ".".join(path) if path else "root"
message = error.get("message", "Unknown error")
severity = error.get("severity", "error")
lines = []
lines.append(f"[{severity.upper()}] {path_str}")
lines.append(f" Message: {message}")
if verbose:
if "validator" in error:
lines.append(f" Validator: {error['validator']}")
if "validator_value" in error:
lines.append(f" Value: {error['validator_value']}")
if "constraint" in error:
lines.append(f" Constraint: {error['constraint']}")
return "\n".join(lines)
@staticmethod
def summary(
total: int,
passed: int,
failed: int,
errors: Optional[List[Dict[str, Any]]] = None,
) -> str:
"""Format a validation summary."""
lines = []
lines.append("=" * 50)
lines.append("Validation Summary")
lines.append("=" * 50)
lines.append(f"Total: {total}")
lines.append(f"Passed: {passed}")
lines.append(f"Failed: {failed}")
lines.append("-" * 50)
if failed > 0 and errors:
lines.append("\nValidation Errors:")
lines.append("-" * 50)
for i, error in enumerate(errors, 1):
lines.append(f"{i}. {Formatters.validation_error(error)}")
lines.append("")
return "\n".join(lines)