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:28 +00:00
parent 7b4d4ef8c7
commit 8fa0ee82c1

View File

@@ -0,0 +1,114 @@
"""ENV format handler for ConfigForge."""
import re
from typing import Any, Dict, List, Optional
from configforge.exceptions import ConversionError
class ENVHandler:
"""Handler for ENV (environment variable) configuration files."""
@staticmethod
def loads(content: str) -> Dict[str, Any]:
"""Parse ENV file content."""
result: Dict[str, Any] = {}
current_section: Optional[str] = None
for line_num, line in enumerate(content.splitlines(), 1):
stripped = line.strip()
if not stripped or stripped.startswith("#"):
continue
if stripped.startswith("[") and stripped.endswith("]"):
current_section = stripped[1:-1].strip()
continue
if "=" in stripped:
key, _, value = stripped.partition("=")
key = key.strip()
value = value.strip()
if not key:
continue
value = ENVHandler._parse_value(value)
if current_section:
if current_section not in result:
result[current_section] = {}
result[current_section][key] = value
else:
result[key] = value
return result
@staticmethod
def _parse_value(value: str) -> Any:
"""Parse a value from ENV format."""
value = value.strip('"').strip("'")
if value.lower() == "true":
return True
if value.lower() == "false":
return False
if value.lower() == "null":
return None
try:
if "." in value:
return float(value)
return int(value)
except ValueError:
return value
@staticmethod
def dumps(data: Dict[str, Any], section_name: Optional[str] = None) -> str:
"""Serialize dictionary to ENV format."""
lines = []
if section_name:
lines.append(f"[{section_name}]")
for key, value in data.items():
lines.append(f"{key}={ENVHandler._format_value(value)}")
return "\n".join(lines)
@staticmethod
def _format_value(value: Any) -> str:
"""Format a value for ENV output."""
if isinstance(value, bool):
return str(value).lower()
if value is None:
return ""
if isinstance(value, str):
if " " in value or '"' in value or "'" in value:
return f'"{value}"'
return value
return str(value)
@staticmethod
def read(filepath: str) -> Dict[str, Any]:
"""Read and parse ENV file."""
try:
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
return ENVHandler.loads(content)
except FileNotFoundError:
raise ConversionError(f"File not found: {filepath}")
except PermissionError:
raise ConversionError(f"Permission denied: {filepath}")
@staticmethod
def write(filepath: str, data: Dict[str, Any], section_name: Optional[str] = None) -> None:
"""Write data to ENV file."""
try:
content = ENVHandler.dumps(data, section_name)
with open(filepath, "w", encoding="utf-8") as f:
f.write(content)
except FileNotFoundError:
raise ConversionError(f"Directory not found for: {filepath}")
except PermissionError:
raise ConversionError(f"Permission denied to write: {filepath}")