Merge pull request #3342 from rommapp/copilot/add-copy-default-config-yml

Auto-create missing `config.yml` on startup in mounted config volume
This commit is contained in:
Georges-Antoine Assi
2026-05-09 11:00:22 -04:00
committed by GitHub
2 changed files with 36 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ import glob
import json
import os
import sys
from pathlib import Path
from typing import Final, NotRequired, TypedDict
import pydash
@@ -178,9 +179,7 @@ class ConfigManager:
# Also check if the config file is writable
self._config_file_writable = os.access(self.config_file, os.W_OK)
except FileNotFoundError:
log.critical(
"Config file not found! Any changes made to the configuration will not persist after the application restarts."
)
self._create_missing_config_file()
except PermissionError:
log.warning(
"Config file not writable! Any changes made to the configuration will not persist after the application restarts."
@@ -190,6 +189,28 @@ class ConfigManager:
self._parse_config()
self._validate_config()
def _create_missing_config_file(self) -> None:
log.warning(
f"Config file not found, creating an empty config at {hl(self.config_file, BLUE)}"
)
try:
config_file = Path(self.config_file)
config_file.parent.mkdir(parents=True, exist_ok=True)
config_file.touch(exist_ok=True)
# Reset any previously loaded singleton state so parsing reflects
# the newly created empty config file.
self._raw_config = {}
self._config_file_mounted = True
self._config_file_writable = os.access(self.config_file, os.W_OK)
except PermissionError:
self._config_file_mounted = False
self._config_file_writable = False
log.critical(
"Config file not found and could not be created! Any changes made to the configuration will not persist after the application restarts."
)
@staticmethod
def get_db_engine() -> URL:
"""Builds the database connection string using environment variables

View File

@@ -113,3 +113,15 @@ def test_empty_config_loader():
assert loader.config.EJS_CONTROLS == {}
assert loader.config.GAMELIST_MEDIA_THUMBNAIL == "box2d"
assert loader.config.GAMELIST_MEDIA_IMAGE == "screenshot"
def test_missing_config_file_is_created(tmp_path):
config_file = tmp_path / "config" / "config.yml"
loader = ConfigManager(str(config_file))
assert config_file.parent.exists()
assert config_file.exists()
assert config_file.read_text() == ""
assert loader.config.CONFIG_FILE_MOUNTED
assert loader.config.CONFIG_FILE_WRITABLE