From d0eb3ddd343bc944c6599dd35710fa2032569ed4 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Wed, 4 Feb 2026 07:05:22 +0000 Subject: [PATCH] Initial upload: ConfigConvert CLI with full test suite and CI/CD --- config_convert/converters/env_converter.py | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 config_convert/converters/env_converter.py diff --git a/config_convert/converters/env_converter.py b/config_convert/converters/env_converter.py new file mode 100644 index 0000000..a3d385a --- /dev/null +++ b/config_convert/converters/env_converter.py @@ -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))