Load and parse the .env file.
(self)
| 276 | self.load() |
| 277 | |
| 278 | def load(self) -> None: |
| 279 | """Load and parse the .env file.""" |
| 280 | self._values = {} |
| 281 | self._file_lines = [] |
| 282 | |
| 283 | # If .env doesn't exist, try to copy from .env.example |
| 284 | if not self.env_path.exists(): |
| 285 | if self.example_path and self.example_path.exists(): |
| 286 | shutil.copy(self.example_path, self.env_path) |
| 287 | else: |
| 288 | # Create an empty .env |
| 289 | self.env_path.touch() |
| 290 | |
| 291 | # Read the file |
| 292 | try: |
| 293 | with open(self.env_path, "r", encoding="utf-8") as f: |
| 294 | self._file_lines = f.readlines() |
| 295 | except Exception as e: |
| 296 | print(f"Error reading .env file: {e}") |
| 297 | self._file_lines = [] |
| 298 | |
| 299 | # Parse key-value pairs |
| 300 | for line in self._file_lines: |
| 301 | stripped = line.strip() |
| 302 | |
| 303 | # Skip empty lines and comments |
| 304 | if not stripped or stripped.startswith("#"): |
| 305 | continue |
| 306 | |
| 307 | # Parse key=value |
| 308 | match = re.match( |
| 309 | r"^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$", stripped, re.IGNORECASE |
| 310 | ) |
| 311 | if match: |
| 312 | key = match.group(1) |
| 313 | value = match.group(2) |
| 314 | |
| 315 | # Remove surrounding quotes if present |
| 316 | if (value.startswith('"') and value.endswith('"')) or ( |
| 317 | value.startswith("'") and value.endswith("'") |
| 318 | ): |
| 319 | value = value[1:-1] |
| 320 | |
| 321 | self._values[key] = value |
| 322 | |
| 323 | # Store original values for dirty detection |
| 324 | self._original_values = self._values.copy() |
| 325 | |
| 326 | def get(self, key: str, default: Any = None) -> Any: |
| 327 | """ |
no outgoing calls
no test coverage detected