From f023b24aa7d0e7d92651fcc5fb0d5a83ce91cf13 Mon Sep 17 00:00:00 2001 From: Francwa Date: Mon, 5 Jan 2026 09:35:04 +0100 Subject: [PATCH] fix: fixed bootstrap overwrtting .env file and improved bool handling for js use --- alfred/settings_bootstrap.py | 29 ++++++++++++----------- tests/test_settings_bootstrap_advanced.py | 4 +++- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/alfred/settings_bootstrap.py b/alfred/settings_bootstrap.py index 5147703..a66564d 100644 --- a/alfred/settings_bootstrap.py +++ b/alfred/settings_bootstrap.py @@ -311,7 +311,7 @@ class SettingsBootstrap: def _write_env(self) -> None: """ Write .env file using .env.example as template. - + This preserves the structure, comments, and formatting of .env.example while updating only the values of variables defined in the schema. Custom variables from existing .env are appended at the end. @@ -335,43 +335,44 @@ class SettingsBootstrap: output_lines = [] for line in template_lines: stripped = line.strip() - + # Keep comments and empty lines as-is if not stripped or stripped.startswith("#"): output_lines.append(line) continue - + # Check if line contains a variable assignment if "=" in line: key, _ = line.split("=", 1) key = key.strip() processed_keys.add(key) - + # Check if this variable is in our schema definition = self.schema.get(key) - + if definition: # Update with resolved value (including computed settings) value = self.resolved_settings.get(key, "") - + # Convert Python booleans to lowercase for .env compatibility if isinstance(value, bool): value = "true" if value else "false" - + output_lines.append(f"{key}={value}\n") + # Variable not in schema + # If it exists in current .env, use that value, otherwise keep template + elif key in self.existing_env: + output_lines.append(f"{key}={self.existing_env[key]}\n") else: - # Variable not in schema - # If it exists in current .env, use that value, otherwise keep template - if key in self.existing_env: - output_lines.append(f"{key}={self.existing_env[key]}\n") - else: - output_lines.append(line) + output_lines.append(line) else: # Keep any other lines as-is output_lines.append(line) # Append custom variables from existing .env that aren't in .env.example - custom_vars = {k: v for k, v in self.existing_env.items() if k not in processed_keys} + custom_vars = { + k: v for k, v in self.existing_env.items() if k not in processed_keys + } if custom_vars: output_lines.append("\n# --- CUSTOM VARIABLES ---\n") output_lines.append("# Variables added manually (not in .env.example)\n") diff --git a/tests/test_settings_bootstrap_advanced.py b/tests/test_settings_bootstrap_advanced.py index 512fa21..747e96b 100644 --- a/tests/test_settings_bootstrap_advanced.py +++ b/tests/test_settings_bootstrap_advanced.py @@ -150,7 +150,9 @@ class TestTemplatePreservation: class TestSecretPreservation: """Test that secrets are never overwritten.""" - def test_preserves_existing_secrets(self, test_toml_with_all_types, test_env_example): + def test_preserves_existing_secrets( + self, test_toml_with_all_types, test_env_example + ): """Test that existing secrets are preserved across multiple bootstraps.""" from alfred.settings_schema import load_schema