d5bae868a4
core/env.py dual-read helper (D-108); 21 ACDL_*→NOVA_* env vars migrated across core/scripts/adapters/tests/workflows + .env/.env.secrets (key rename, values stay). G-106 binding: run_platform.sh:288-289 + regression_verify.py:309-312 dual-read (NOVA first, ACDL fallback). G-108 binding: Gitea NOVA_* secrets created via API + workflow secrets: refs updated (deploy.yml + modules-lifecycle.yml, .gitea + .github). acdl_tagging.py→nova_tagging.py (D-109 warn mode, nova:* enforced). .acdl/→.nova/ consumer path (resolver + deploy workflow + schema + tests + docs). Test fixtures updated; pytest + run_ci.sh PASS. ---ci--- project: acdl phase: 2 milestone: v1.15 status: execute ---/ci---
48 lines
1.7 KiB
Python
48 lines
1.7 KiB
Python
"""Dual-read environment helper (D-108, REQ-159, G-106).
|
||
|
||
During the Nova rebrand transition window (P2–P4), every `NOVA_*`
|
||
environment variable is the preferred source, with the legacy `ACDL_*`
|
||
name as the fallback. This keeps deployments from breaking while the
|
||
keys are rotated across `.env`, `.env.secrets`, Gitea repo secrets, and
|
||
operator-managed process environments.
|
||
|
||
`get_env(name, default=None)` resolves `NOVA_<name>` first, then falls
|
||
back to `ACDL_<name>`, then returns `default` if neither is set.
|
||
|
||
This helper is removed (NOVA-only) in P5 (REQ-164). Direct-read paths
|
||
that bypass this helper (the `.env.secrets` shell export in
|
||
`scripts/run_platform.sh` and the Python parser in
|
||
`core/regression_verify.py`) mirror this contract inline per the G-106
|
||
binding — see those sites for the dual-read shell/Python forms.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import os
|
||
from typing import Optional
|
||
|
||
__all__ = ["get_env"]
|
||
|
||
|
||
def get_env(name: str, default: Optional[str] = None) -> Optional[str]:
|
||
"""Resolve a config value with a NOVA-preferred / ACDL-fallback read.
|
||
|
||
`name` is the bare key WITHOUT the prefix (e.g. ``"AWS_ACCOUNT_ID"``).
|
||
The lookup order is:
|
||
|
||
1. ``NOVA_<name>`` (preferred)
|
||
2. ``ACDL_<name>`` (legacy fallback, removed in P5)
|
||
3. ``default``
|
||
|
||
Returns the first value that is present and non-empty, or ``default``
|
||
if neither env var is set. An explicitly-set empty string is treated
|
||
as "unset" so an operator cannot accidentally shadow the fallback
|
||
with a blank NOVA key.
|
||
"""
|
||
nova_val = os.environ.get(f"NOVA_{name}")
|
||
if nova_val:
|
||
return nova_val
|
||
acdl_val = os.environ.get(f"ACDL_{name}")
|
||
if acdl_val:
|
||
return acdl_val
|
||
return default |