From ad21f638338757ac93b319a41c7b7d78db5a4688 Mon Sep 17 00:00:00 2001
From: Maximilian Moser <maximilian.moser@tuwien.ac.at>
Date: Fri, 7 Feb 2025 14:39:51 +0100
Subject: [PATCH] Add possibility to have prefixed config items override
 unprefixed ones

* this can be very useful for having a single project that is used for
  both "local" and "containerized" execution, where some configuration
  items should be slightly different for either (e.g. `SEARCH_HOSTS`)
* currently we have this functionality implemented in our `invenio.cfg`
  but there it is a bit awkward due to the fact that environment
  variables have not been translated into `app.config` yet
---
 invenio_config_tuw/config.py  | 14 ++++++++++++++
 invenio_config_tuw/startup.py | 20 ++++++++++++++++++++
 pyproject.toml                |  2 ++
 3 files changed, 36 insertions(+)

diff --git a/invenio_config_tuw/config.py b/invenio_config_tuw/config.py
index bcf2067..a72b647 100644
--- a/invenio_config_tuw/config.py
+++ b/invenio_config_tuw/config.py
@@ -100,6 +100,20 @@ Functions can be either supplied via reference, or via import string.
 A value of ``None`` disables this feature.
 """
 
+CONFIG_TUW_CONFIG_OVERRIDE_PREFIX = None
+"""Prefix to check for when overriding configuration items.
+
+If this value is set to any string, then configuration items whose keys start
+with this prefix will be used to override the values for configuration items with
+the same name (but without the prefix).
+
+Example:
+If the value is set to "CONTAINERIZED_", then the value of "CONTAINERIZED_SEARCH_HOSTS"
+will override the value of "SEARCH_HOSTS".
+
+A value of `None` (the default) will disable this feature.
+"""
+
 
 # Invenio-Mail
 # ============
diff --git a/invenio_config_tuw/startup.py b/invenio_config_tuw/startup.py
index 09e7b8b..d656ba5 100644
--- a/invenio_config_tuw/startup.py
+++ b/invenio_config_tuw/startup.py
@@ -146,6 +146,26 @@ def override_flask_config(app):
     app.add_template_global(app.config, "config")
 
 
+def override_prefixed_config(app):
+    """Override config items with their prefixed siblings' values.
+
+    The prefix is determined via the config item "CONFIG_TUW_CONFIG_OVERRIDE_PREFIX".
+    Configuration items with this prefix will override the values for
+
+    If the prefix is set to `None` (the default), then this feature will be disabled.
+    """
+    prefix = app.config.get("CONFIG_TUW_CONFIG_OVERRIDE_PREFIX", None)
+    if prefix is None:
+        return
+
+    prefix_len = len(prefix)
+    pairs = [(k, v) for k, v in app.config.items() if k.startswith(prefix)]
+
+    for key, value in pairs:
+        key = key[prefix_len:]
+        app.config[key] = value
+
+
 def patch_flask_create_url_adapter(app):
     """Patch Flask's {host,subdomain}_matching with 3.1 behavior.
 
diff --git a/pyproject.toml b/pyproject.toml
index 0248b02..426f619 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -82,6 +82,7 @@ invenio_config_tuw_search_drafts = "invenio_config_tuw.startup:override_search_d
 invenio_config_tuw_curation_settings = "invenio_config_tuw.startup:register_menu_entries"
 invenio_config_tuw_curation_request = "invenio_config_tuw.startup:customize_curation_request_type"
 invenio_config_tuw_flask_config = "invenio_config_tuw.startup:override_flask_config"
+invenio_config_tuw_override_prefixed_config = "invenio_config_tuw.startup:override_prefixed_config"
 invenio_config_tuw_patch_flask = "invenio_config_tuw.startup:patch_flask_create_url_adapter"
 
 [project.entry-points."invenio_base.api_finalize_app"]
@@ -89,6 +90,7 @@ invenio_config_tuw_mail_handler = "invenio_config_tuw.startup:register_smtp_erro
 invenio_config_tuw_search_drafts = "invenio_config_tuw.startup:override_search_drafts_options"
 invenio_config_tuw_curation_request = "invenio_config_tuw.startup:customize_curation_request_type"
 invenio_config_tuw_flask_config = "invenio_config_tuw.startup:override_flask_config"
+invenio_config_tuw_override_prefixed_config = "invenio_config_tuw.startup:override_prefixed_config"
 invenio_config_tuw_patch_flask = "invenio_config_tuw.startup:patch_flask_create_url_adapter"
 
 [project.entry-points."invenio_i18n.translations"]
-- 
GitLab