diff --git a/env.d/development/common.e2e.dist b/env.d/development/common.e2e.dist index ff9c1f0..5cb7075 100644 --- a/env.d/development/common.e2e.dist +++ b/env.d/development/common.e2e.dist @@ -5,4 +5,4 @@ BURST_THROTTLE_RATES="200/minute" OAUTH2_PROVIDER_OIDC_ENABLED = True OAUTH2_PROVIDER_VALIDATOR_CLASS: "mailbox_oauth2.validators.ProConnectValidator" -INSTALLED_PLUGINS=plugins.la_suite.apps.LaSuitePluginConfig +INSTALLED_PLUGINS=plugins.la_suite diff --git a/env.d/development/france.dist b/env.d/development/france.dist index 63a13a3..4ae20fc 100644 --- a/env.d/development/france.dist +++ b/env.d/development/france.dist @@ -1,2 +1,2 @@ -INSTALLED_PLUGINS=plugins.la_suite.apps.LaSuitePluginConfig +INSTALLED_PLUGINS=plugins.la_suite DNS_PROVISIONING_TARGET_ZONE=test.collectivite.fr diff --git a/src/backend/core/management/commands/list_plugins.py b/src/backend/core/management/commands/list_plugins.py new file mode 100644 index 0000000..fd8cbc9 --- /dev/null +++ b/src/backend/core/management/commands/list_plugins.py @@ -0,0 +1,22 @@ +"""Management command to list all plugins and their hooks.""" + +from django.conf import settings +from django.core.management.base import BaseCommand + +from core.plugins.registry import registry + + +class Command(BaseCommand): + """Management command to list all plugins and their hooks.""" + + help = "List all plugins and their hooks" + + def handle(self, *args, **options): + """Print plugin information.""" + self.stdout.write(self.style.NOTICE("# Listing plugins\n")) + for plugin_app in settings.INSTALLED_PLUGINS: + self.stdout.write(self.style.NOTICE(f" - {plugin_app}\n")) + + self.stdout.write(self.style.NOTICE("# Listing loaded hooks\n")) + for hook_name, callbacks in registry.get_registered_hooks(): + self.stdout.write(self.style.NOTICE(f" - {hook_name}: {callbacks}\n")) diff --git a/src/backend/core/plugins/base.py b/src/backend/core/plugins/base.py index a9e00ba..466d2f6 100644 --- a/src/backend/core/plugins/base.py +++ b/src/backend/core/plugins/base.py @@ -1,10 +1,17 @@ """Base Django Application Configuration for plugins.""" -from django.apps import AppConfig +class BasePluginAppConfigMixIn: + """ + Configuration for the La Suite plugin application. -class BasePluginAppConfig(AppConfig): - """Configuration for the La Suite plugin application.""" + We cannot use the `AppConfig` class directly because it is not compatible with + the Django way to discover default AppConfig (see `AppConfig.create`). + We use a mixin then, to be able to list plugins using `plugins.la_suite` instead + of `plugins.la_suite.apps.LaSuitePluginConfig`. + + Another way would be to force `default` attribute on plugin AppConfig. + """ def ready(self): """ @@ -13,4 +20,4 @@ class BasePluginAppConfig(AppConfig): """ from .registry import registry # pylint: disable=import-outside-toplevel - registry.register_app(self.name) + registry.register_app(self.name) # pylint: disable=no-member diff --git a/src/backend/core/plugins/registry.py b/src/backend/core/plugins/registry.py index fee15cf..410fd8a 100644 --- a/src/backend/core/plugins/registry.py +++ b/src/backend/core/plugins/registry.py @@ -37,6 +37,10 @@ class HooksRegistry: ) logger.info("Registered hook %s: %s", hook_name, callback) + def get_registered_hooks(self): + """Get all registered hooks.""" + return self._hooks.items() + def register_app(self, app_name: str) -> None: """ Register an app as having hooks. diff --git a/src/backend/plugins/la_suite/apps.py b/src/backend/plugins/la_suite/apps.py index c0c830e..0ff0d04 100644 --- a/src/backend/plugins/la_suite/apps.py +++ b/src/backend/plugins/la_suite/apps.py @@ -1,9 +1,11 @@ """La Suite plugin application configuration.""" -from core.plugins.base import BasePluginAppConfig +from django.apps import AppConfig + +from core.plugins.base import BasePluginAppConfigMixIn -class LaSuitePluginConfig(BasePluginAppConfig): +class LaSuitePluginConfig(BasePluginAppConfigMixIn, AppConfig): """Configuration for the La Suite plugin application.""" name = "plugins.la_suite"