Spaces:
Sleeping
Sleeping
File size: 2,296 Bytes
2415446 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | """Admin config source loading and source precedence."""
import os
from io import StringIO
from pathlib import Path
from typing import Literal
from dotenv import dotenv_values
from free_claude_code.config.env_files import (
explicit_env_path as configured_explicit_env_path,
)
from free_claude_code.config.env_files import (
repo_env_path as configured_repo_env_path,
)
from free_claude_code.config.env_files import (
settings_env_files,
)
from free_claude_code.config.env_template import load_env_template_or_empty
from .manifest import FIELDS
SourceType = Literal[
"default",
"template",
"repo_env",
"managed_env",
"explicit_env_file",
"process",
]
def repo_env_path() -> Path:
"""Return the repo-local env path."""
return configured_repo_env_path()
def explicit_env_path() -> Path | None:
"""Return the explicit FCC_ENV_FILE path, when configured."""
return configured_explicit_env_path(os.environ)
def configured_env_files() -> tuple[tuple[SourceType, Path], ...]:
"""Return dotenv files in low-to-high precedence order."""
source_names: tuple[SourceType, ...] = (
"repo_env",
"managed_env",
"explicit_env_file",
)
return tuple(zip(source_names, settings_env_files(), strict=False))
def dotenv_values_from_text(text: str) -> dict[str, str]:
"""Parse dotenv text into string values."""
values = dotenv_values(stream=StringIO(text))
return {key: "" if value is None else value for key, value in values.items()}
def template_values() -> dict[str, str]:
"""Return .env.example values plus manifest defaults for newer fields."""
values = dotenv_values_from_text(load_env_template_or_empty())
for field in FIELDS:
values.setdefault(field.key, field.default)
return values
def dotenv_values_from_file(path: Path) -> dict[str, str]:
"""Return dotenv values from a file, or an empty mapping when absent."""
if not path.is_file():
return {}
values = dotenv_values(path)
return {key: "" if value is None else value for key, value in values.items()}
def is_locked_source(source: SourceType) -> bool:
"""Return whether an admin value source must not be overwritten."""
return source in {"process", "explicit_env_file"}
|