fix: commit semantic repair changes
This commit is contained in:
@@ -45,7 +45,9 @@ class ConfigManager:
|
||||
def __init__(self, config_path: str = "config.json"):
|
||||
with belief_scope("ConfigManager.__init__"):
|
||||
if not isinstance(config_path, str) or not config_path:
|
||||
logger.explore("Invalid config_path provided", extra={"path": config_path})
|
||||
logger.explore(
|
||||
"Invalid config_path provided", extra={"path": config_path}
|
||||
)
|
||||
raise ValueError("config_path must be a non-empty string")
|
||||
|
||||
logger.reason(f"Initializing ConfigManager with legacy path: {config_path}")
|
||||
@@ -57,10 +59,14 @@ class ConfigManager:
|
||||
configure_logger(self.config.settings.logging)
|
||||
|
||||
if not isinstance(self.config, AppConfig):
|
||||
logger.explore("Config loading resulted in invalid type", extra={"type": type(self.config)})
|
||||
logger.explore(
|
||||
"Config loading resulted in invalid type",
|
||||
extra={"type": type(self.config)},
|
||||
)
|
||||
raise TypeError("self.config must be an instance of AppConfig")
|
||||
|
||||
logger.reflect("ConfigManager initialization complete")
|
||||
|
||||
# [/DEF:__init__:Function]
|
||||
|
||||
# [DEF:_default_config:Function]
|
||||
@@ -69,6 +75,7 @@ class ConfigManager:
|
||||
with belief_scope("ConfigManager._default_config"):
|
||||
logger.reason("Building default AppConfig fallback")
|
||||
return AppConfig(environments=[], settings=GlobalSettings())
|
||||
|
||||
# [/DEF:_default_config:Function]
|
||||
|
||||
# [DEF:_sync_raw_payload_from_config:Function]
|
||||
@@ -83,14 +90,19 @@ class ConfigManager:
|
||||
logger.reason(
|
||||
"Synchronized raw payload from typed config",
|
||||
extra={
|
||||
"environments_count": len(merged_payload.get("environments", []) or []),
|
||||
"environments_count": len(
|
||||
merged_payload.get("environments", []) or []
|
||||
),
|
||||
"has_settings": "settings" in merged_payload,
|
||||
"extra_sections": sorted(
|
||||
key for key in merged_payload.keys() if key not in {"environments", "settings"}
|
||||
key
|
||||
for key in merged_payload.keys()
|
||||
if key not in {"environments", "settings"}
|
||||
),
|
||||
},
|
||||
)
|
||||
return merged_payload
|
||||
|
||||
# [/DEF:_sync_raw_payload_from_config:Function]
|
||||
|
||||
# [DEF:_load_from_legacy_file:Function]
|
||||
@@ -104,14 +116,19 @@ class ConfigManager:
|
||||
)
|
||||
return {}
|
||||
|
||||
logger.reason("Loading legacy config file", extra={"path": str(self.config_path)})
|
||||
logger.reason(
|
||||
"Loading legacy config file", extra={"path": str(self.config_path)}
|
||||
)
|
||||
with self.config_path.open("r", encoding="utf-8") as fh:
|
||||
payload = json.load(fh)
|
||||
|
||||
if not isinstance(payload, dict):
|
||||
logger.explore(
|
||||
"Legacy config payload is not a JSON object",
|
||||
extra={"path": str(self.config_path), "type": type(payload).__name__},
|
||||
extra={
|
||||
"path": str(self.config_path),
|
||||
"type": type(payload).__name__,
|
||||
},
|
||||
)
|
||||
raise ValueError("Legacy config payload must be a JSON object")
|
||||
|
||||
@@ -120,15 +137,23 @@ class ConfigManager:
|
||||
extra={"path": str(self.config_path), "keys": sorted(payload.keys())},
|
||||
)
|
||||
return payload
|
||||
|
||||
# [/DEF:_load_from_legacy_file:Function]
|
||||
|
||||
# [DEF:_get_record:Function]
|
||||
# @PURPOSE: Resolve global configuration record from DB.
|
||||
def _get_record(self, session: Session) -> Optional[AppConfigRecord]:
|
||||
with belief_scope("ConfigManager._get_record"):
|
||||
record = session.query(AppConfigRecord).filter(AppConfigRecord.id == "global").first()
|
||||
logger.reason("Resolved app config record", extra={"exists": record is not None})
|
||||
record = (
|
||||
session.query(AppConfigRecord)
|
||||
.filter(AppConfigRecord.id == "global")
|
||||
.first()
|
||||
)
|
||||
logger.reason(
|
||||
"Resolved app config record", extra={"exists": record is not None}
|
||||
)
|
||||
return record
|
||||
|
||||
# [/DEF:_get_record:Function]
|
||||
|
||||
# [DEF:_load_config:Function]
|
||||
@@ -139,7 +164,10 @@ class ConfigManager:
|
||||
try:
|
||||
record = self._get_record(session)
|
||||
if record and isinstance(record.payload, dict):
|
||||
logger.reason("Loading configuration from database", extra={"record_id": record.id})
|
||||
logger.reason(
|
||||
"Loading configuration from database",
|
||||
extra={"record_id": record.id},
|
||||
)
|
||||
self.raw_payload = dict(record.payload)
|
||||
config = AppConfig.model_validate(
|
||||
{
|
||||
@@ -182,7 +210,9 @@ class ConfigManager:
|
||||
self._save_config_to_db(config, session=session)
|
||||
return config
|
||||
|
||||
logger.reason("No persisted config found; falling back to default configuration")
|
||||
logger.reason(
|
||||
"No persisted config found; falling back to default configuration"
|
||||
)
|
||||
config = self._default_config()
|
||||
self.raw_payload = config.model_dump()
|
||||
self._save_config_to_db(config, session=session)
|
||||
@@ -203,6 +233,7 @@ class ConfigManager:
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
# [/DEF:_load_config:Function]
|
||||
|
||||
# [DEF:_sync_environment_records:Function]
|
||||
@@ -210,29 +241,32 @@ class ConfigManager:
|
||||
def _sync_environment_records(self, session: Session, config: AppConfig) -> None:
|
||||
with belief_scope("ConfigManager._sync_environment_records"):
|
||||
configured_envs = list(config.environments or [])
|
||||
configured_ids = {
|
||||
str(environment.id or "").strip()
|
||||
for environment in configured_envs
|
||||
if str(environment.id or "").strip()
|
||||
}
|
||||
|
||||
persisted_records = session.query(EnvironmentRecord).all()
|
||||
persisted_by_id = {str(record.id or "").strip(): record for record in persisted_records}
|
||||
persisted_by_id = {
|
||||
str(record.id or "").strip(): record for record in persisted_records
|
||||
}
|
||||
|
||||
for environment in configured_envs:
|
||||
normalized_id = str(environment.id or "").strip()
|
||||
if not normalized_id:
|
||||
continue
|
||||
|
||||
display_name = str(environment.name or normalized_id).strip() or normalized_id
|
||||
display_name = (
|
||||
str(environment.name or normalized_id).strip() or normalized_id
|
||||
)
|
||||
normalized_url = str(environment.url or "").strip()
|
||||
credentials_id = str(environment.username or "").strip() or normalized_id
|
||||
credentials_id = (
|
||||
str(environment.username or "").strip() or normalized_id
|
||||
)
|
||||
|
||||
record = persisted_by_id.get(normalized_id)
|
||||
if record is None:
|
||||
logger.reason(
|
||||
"Creating relational environment record from typed config",
|
||||
extra={"environment_id": normalized_id, "environment_name": display_name},
|
||||
extra={
|
||||
"environment_id": normalized_id,
|
||||
"environment_name": display_name,
|
||||
},
|
||||
)
|
||||
session.add(
|
||||
EnvironmentRecord(
|
||||
@@ -248,20 +282,13 @@ class ConfigManager:
|
||||
record.url = normalized_url
|
||||
record.credentials_id = credentials_id
|
||||
|
||||
for record in persisted_records:
|
||||
normalized_id = str(record.id or "").strip()
|
||||
if normalized_id and normalized_id not in configured_ids:
|
||||
logger.reason(
|
||||
"Removing stale relational environment record absent from typed config",
|
||||
extra={"environment_id": normalized_id},
|
||||
)
|
||||
session.delete(record)
|
||||
|
||||
# [/DEF:_sync_environment_records:Function]
|
||||
|
||||
# [DEF:_save_config_to_db:Function]
|
||||
# @PURPOSE: Persist provided AppConfig into the global DB configuration record.
|
||||
def _save_config_to_db(self, config: AppConfig, session: Optional[Session] = None) -> None:
|
||||
def _save_config_to_db(
|
||||
self, config: AppConfig, session: Optional[Session] = None
|
||||
) -> None:
|
||||
with belief_scope("ConfigManager._save_config_to_db"):
|
||||
owns_session = session is None
|
||||
db = session or SessionLocal()
|
||||
@@ -274,7 +301,10 @@ class ConfigManager:
|
||||
record = AppConfigRecord(id="global", payload=payload)
|
||||
db.add(record)
|
||||
else:
|
||||
logger.reason("Updating existing global app config record", extra={"record_id": record.id})
|
||||
logger.reason(
|
||||
"Updating existing global app config record",
|
||||
extra={"record_id": record.id},
|
||||
)
|
||||
record.payload = payload
|
||||
|
||||
self._sync_environment_records(db, config)
|
||||
@@ -283,7 +313,9 @@ class ConfigManager:
|
||||
logger.reason(
|
||||
"Configuration persisted to database",
|
||||
extra={
|
||||
"environments_count": len(payload.get("environments", []) or []),
|
||||
"environments_count": len(
|
||||
payload.get("environments", []) or []
|
||||
),
|
||||
"payload_keys": sorted(payload.keys()),
|
||||
},
|
||||
)
|
||||
@@ -294,6 +326,7 @@ class ConfigManager:
|
||||
finally:
|
||||
if owns_session:
|
||||
db.close()
|
||||
|
||||
# [/DEF:_save_config_to_db:Function]
|
||||
|
||||
# [DEF:save:Function]
|
||||
@@ -302,6 +335,7 @@ class ConfigManager:
|
||||
with belief_scope("ConfigManager.save"):
|
||||
logger.reason("Persisting current in-memory configuration")
|
||||
self._save_config_to_db(self.config)
|
||||
|
||||
# [/DEF:save:Function]
|
||||
|
||||
# [DEF:get_config:Function]
|
||||
@@ -309,6 +343,7 @@ class ConfigManager:
|
||||
def get_config(self) -> AppConfig:
|
||||
with belief_scope("ConfigManager.get_config"):
|
||||
return self.config
|
||||
|
||||
# [/DEF:get_config:Function]
|
||||
|
||||
# [DEF:get_payload:Function]
|
||||
@@ -316,6 +351,7 @@ class ConfigManager:
|
||||
def get_payload(self) -> dict[str, Any]:
|
||||
with belief_scope("ConfigManager.get_payload"):
|
||||
return self._sync_raw_payload_from_config()
|
||||
|
||||
# [/DEF:get_payload:Function]
|
||||
|
||||
# [DEF:save_config:Function]
|
||||
@@ -345,8 +381,12 @@ class ConfigManager:
|
||||
self._save_config_to_db(typed_config)
|
||||
return self.config
|
||||
|
||||
logger.explore("Unsupported config type supplied to save_config", extra={"type": type(config).__name__})
|
||||
logger.explore(
|
||||
"Unsupported config type supplied to save_config",
|
||||
extra={"type": type(config).__name__},
|
||||
)
|
||||
raise TypeError("config must be AppConfig or dict")
|
||||
|
||||
# [/DEF:save_config:Function]
|
||||
|
||||
# [DEF:update_global_settings:Function]
|
||||
@@ -357,6 +397,7 @@ class ConfigManager:
|
||||
self.config.settings = settings
|
||||
self.save()
|
||||
return self.config
|
||||
|
||||
# [/DEF:update_global_settings:Function]
|
||||
|
||||
# [DEF:validate_path:Function]
|
||||
@@ -381,8 +422,11 @@ class ConfigManager:
|
||||
logger.reason("Path validation succeeded", extra={"path": str(target)})
|
||||
return True, "OK"
|
||||
except Exception as exc:
|
||||
logger.explore("Path validation failed", extra={"path": path, "error": str(exc)})
|
||||
logger.explore(
|
||||
"Path validation failed", extra={"path": path, "error": str(exc)}
|
||||
)
|
||||
return False, str(exc)
|
||||
|
||||
# [/DEF:validate_path:Function]
|
||||
|
||||
# [DEF:get_environments:Function]
|
||||
@@ -390,6 +434,7 @@ class ConfigManager:
|
||||
def get_environments(self) -> List[Environment]:
|
||||
with belief_scope("ConfigManager.get_environments"):
|
||||
return list(self.config.environments)
|
||||
|
||||
# [/DEF:get_environments:Function]
|
||||
|
||||
# [DEF:has_environments:Function]
|
||||
@@ -397,6 +442,7 @@ class ConfigManager:
|
||||
def has_environments(self) -> bool:
|
||||
with belief_scope("ConfigManager.has_environments"):
|
||||
return len(self.config.environments) > 0
|
||||
|
||||
# [/DEF:has_environments:Function]
|
||||
|
||||
# [DEF:get_environment:Function]
|
||||
@@ -411,13 +457,21 @@ class ConfigManager:
|
||||
if env.id == normalized or env.name == normalized:
|
||||
return env
|
||||
return None
|
||||
|
||||
# [/DEF:get_environment:Function]
|
||||
|
||||
# [DEF:add_environment:Function]
|
||||
# @PURPOSE: Upsert environment by id into configuration and persist.
|
||||
def add_environment(self, env: Environment) -> AppConfig:
|
||||
with belief_scope("ConfigManager.add_environment", f"env_id={env.id}"):
|
||||
existing_index = next((i for i, item in enumerate(self.config.environments) if item.id == env.id), None)
|
||||
existing_index = next(
|
||||
(
|
||||
i
|
||||
for i, item in enumerate(self.config.environments)
|
||||
if item.id == env.id
|
||||
),
|
||||
None,
|
||||
)
|
||||
if env.is_default:
|
||||
for item in self.config.environments:
|
||||
item.is_default = False
|
||||
@@ -426,14 +480,20 @@ class ConfigManager:
|
||||
logger.reason("Appending new environment", extra={"env_id": env.id})
|
||||
self.config.environments.append(env)
|
||||
else:
|
||||
logger.reason("Replacing existing environment during add", extra={"env_id": env.id})
|
||||
logger.reason(
|
||||
"Replacing existing environment during add",
|
||||
extra={"env_id": env.id},
|
||||
)
|
||||
self.config.environments[existing_index] = env
|
||||
|
||||
if len(self.config.environments) == 1 and not any(item.is_default for item in self.config.environments):
|
||||
if len(self.config.environments) == 1 and not any(
|
||||
item.is_default for item in self.config.environments
|
||||
):
|
||||
self.config.environments[0].is_default = True
|
||||
|
||||
self.save()
|
||||
return self.config
|
||||
|
||||
# [/DEF:add_environment:Function]
|
||||
|
||||
# [DEF:update_environment:Function]
|
||||
@@ -461,8 +521,11 @@ class ConfigManager:
|
||||
self.save()
|
||||
return True
|
||||
|
||||
logger.explore("Environment update skipped; env not found", extra={"env_id": env_id})
|
||||
logger.explore(
|
||||
"Environment update skipped; env not found", extra={"env_id": env_id}
|
||||
)
|
||||
return False
|
||||
|
||||
# [/DEF:update_environment:Function]
|
||||
|
||||
# [DEF:delete_environment:Function]
|
||||
@@ -471,22 +534,35 @@ class ConfigManager:
|
||||
with belief_scope("ConfigManager.delete_environment", f"env_id={env_id}"):
|
||||
before = len(self.config.environments)
|
||||
removed = [env for env in self.config.environments if env.id == env_id]
|
||||
self.config.environments = [env for env in self.config.environments if env.id != env_id]
|
||||
self.config.environments = [
|
||||
env for env in self.config.environments if env.id != env_id
|
||||
]
|
||||
|
||||
if len(self.config.environments) == before:
|
||||
logger.explore("Environment delete skipped; env not found", extra={"env_id": env_id})
|
||||
logger.explore(
|
||||
"Environment delete skipped; env not found",
|
||||
extra={"env_id": env_id},
|
||||
)
|
||||
return False
|
||||
|
||||
if removed and removed[0].is_default and self.config.environments:
|
||||
self.config.environments[0].is_default = True
|
||||
|
||||
if self.config.settings.default_environment_id == env_id:
|
||||
replacement = next((env.id for env in self.config.environments if env.is_default), None)
|
||||
replacement = next(
|
||||
(env.id for env in self.config.environments if env.is_default), None
|
||||
)
|
||||
self.config.settings.default_environment_id = replacement
|
||||
|
||||
logger.reason("Environment deleted", extra={"env_id": env_id, "remaining": len(self.config.environments)})
|
||||
logger.reason(
|
||||
"Environment deleted",
|
||||
extra={"env_id": env_id, "remaining": len(self.config.environments)},
|
||||
)
|
||||
self.save()
|
||||
return True
|
||||
|
||||
# [/DEF:delete_environment:Function]
|
||||
|
||||
|
||||
# [/DEF:ConfigManager:Class]
|
||||
# [/DEF:ConfigManager:Module]
|
||||
|
||||
Reference in New Issue
Block a user