Initial upload: ConfigConvert CLI with full test suite and CI/CD
This commit is contained in:
58
config_convert/converters/env_converter.py
Normal file
58
config_convert/converters/env_converter.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
"""ENV format converter for KEY=value style files."""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
from config_convert.converters.base import Converter
|
||||||
|
from config_convert.utils.type_inference import convert_value
|
||||||
|
|
||||||
|
|
||||||
|
ENV_LINE_PATTERN = re.compile(r"^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$")
|
||||||
|
|
||||||
|
|
||||||
|
class ENVConverter(Converter):
|
||||||
|
"""Converter for ENV (KEY=value) format."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
return "env"
|
||||||
|
|
||||||
|
def loads(self, data: str) -> Dict[str, Any]:
|
||||||
|
result: Dict[str, Any] = {}
|
||||||
|
for line_num, line in enumerate(data.splitlines(), 1):
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
match = ENV_LINE_PATTERN.match(line)
|
||||||
|
if not match:
|
||||||
|
raise ValueError(f"Invalid ENV format at line {line_num}: {line}")
|
||||||
|
key = match.group(1)
|
||||||
|
value = match.group(2).strip()
|
||||||
|
if value.startswith('"') and value.endswith('"'):
|
||||||
|
value = value[1:-1]
|
||||||
|
result[key] = convert_value(value)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def dumps(self, data: Dict[str, Any], indent: Optional[int] = None) -> str:
|
||||||
|
lines = []
|
||||||
|
for key, value in data.items():
|
||||||
|
if isinstance(value, bool):
|
||||||
|
str_value = "true" if value else "false"
|
||||||
|
elif isinstance(value, list):
|
||||||
|
str_value = ",".join(str(v) for v in value)
|
||||||
|
elif value is None:
|
||||||
|
str_value = ""
|
||||||
|
else:
|
||||||
|
str_value = str(value)
|
||||||
|
lines.append(f"{key}={str_value}")
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
def load(self, file_path: str) -> Dict[str, Any]:
|
||||||
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
|
return self.loads(f.read())
|
||||||
|
|
||||||
|
def dump(self, data: Dict[str, Any], file_path: str, indent: Optional[int] = None) -> None:
|
||||||
|
Path(file_path).parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with open(file_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write(self.dumps(data))
|
||||||
Reference in New Issue
Block a user