Files
recipe-maintainer/lib/env.py
autonomic-bot f283a371bb recipe-maintainer: public snapshot (secrets + deployment plans removed, single commit)
Sanitized single-commit public mirror of recipe-maintainer.
- Removed test-ssh/.testenv (live creds); added test-ssh/.testenv.example placeholders.
- Removed plans/ and planned-updates/ (deployment-planning docs) so no client/
  deployment domains appear in the public repo.
- All other secret stores were already gitignored.
- docs.coopcloud.tech retained as a submodule (public upstream).
2026-06-16 20:18:24 +00:00

84 lines
2.5 KiB
Python

"""Read and write abra .env files and recipe-info config files.
Handles the specific format of abra .env files: KEY=VALUE lines,
with support for comments (#) and uncommenting keys.
"""
from pathlib import Path
def read_env_file(path: str | Path) -> dict[str, str]:
"""Read a KEY=VALUE env file into a dict.
Ignores empty lines and comments (#).
"""
result = {}
p = Path(path)
if not p.exists():
return result
with open(p) as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" in line:
key, value = line.split("=", 1)
result[key.strip()] = value.strip()
return result
def write_env_file(path: str | Path, data: dict[str, str]) -> None:
"""Write a dict as a KEY=VALUE env file."""
p = Path(path)
p.parent.mkdir(parents=True, exist_ok=True)
with open(p, "w") as f:
for key, value in data.items():
f.write(f"{key}={value}\n")
def apply_env_overrides(env_path: str | Path,
overrides: dict[str, str]) -> None:
"""Set or uncomment values in an abra .env file.
For each key in overrides:
- If the key exists (even commented out), replace the line
- If the key doesn't exist, append it
"""
p = Path(env_path)
if not p.exists():
write_env_file(p, overrides)
return
with open(p) as f:
lines = f.readlines()
remaining = dict(overrides)
new_lines = []
for line in lines:
stripped = line.strip()
matched = False
for key, value in list(remaining.items()):
# Match "KEY=...", "#KEY=...", or "# KEY=..."
if stripped.lstrip("#").strip().startswith(f"{key}="):
new_lines.append(f"{key}={value}\n")
remaining.pop(key)
matched = True
print(f" env: {key}={value}", flush=True)
break
if not matched:
new_lines.append(line)
# Append any keys that weren't found in the file
for key, value in remaining.items():
new_lines.append(f"{key}={value}\n")
print(f" env: {key}={value} (appended)", flush=True)
with open(p, "w") as f:
f.writelines(new_lines)
def get_abra_env_path(server: str, domain: str) -> Path:
"""Return the path to an abra app's .env file."""
from lib.config import paths
return paths.ABRA_SERVERS_DIR / server / f"{domain}.env"