diff --git a/CHANGES/pulp-glue/+load_plugins.feature b/CHANGES/pulp-glue/+load_plugins.feature new file mode 100644 index 000000000..1f3de35ed --- /dev/null +++ b/CHANGES/pulp-glue/+load_plugins.feature @@ -0,0 +1 @@ +Added `load_plugins` to `pulp_glue.common` so plugins providing a "pulp_glue.plugins" entrypoint can be enumerated and loaded. diff --git a/docs/glue_reference/common.md b/docs/glue_reference/common.md new file mode 100644 index 000000000..4275e2836 --- /dev/null +++ b/docs/glue_reference/common.md @@ -0,0 +1,3 @@ +# pulp_glue.common + +::: pulp_glue.common diff --git a/mkdocs.yml b/mkdocs.yml index 85a4f1bcb..ff2fc2f3d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -46,6 +46,7 @@ nav: - "contributing.md" - "architecture.md" - "Pulp Glue API Reference": + - "glue_reference/common.md" - "glue_reference/common_openapi.md" - "glue_reference/common_context.md" - "glue_reference/common_i18n.md" diff --git a/pulp-glue/pulp_glue/common/__init__.py b/pulp-glue/pulp_glue/common/__init__.py index 28bba72ca..e9a844b98 100644 --- a/pulp-glue/pulp_glue/common/__init__.py +++ b/pulp-glue/pulp_glue/common/__init__.py @@ -1 +1,32 @@ +import sys +import typing as t + +if sys.version_info >= (3, 10): + from importlib.metadata import entry_points +else: + from importlib_metadata import entry_points + __version__ = "0.25.0.dev" + +# Keep track to prevent loading plugins twice +loaded_plugins: t.Set[str] = set() + + +def load_plugins(enabled_plugins: t.Optional[t.List[str]] = None) -> None: + """ + Load glue plugins that provide a `pulp_glue.plugins` entrypoint. + This may be needed when you rely on the `TYPE_REGISTRY` attributes but cannot load the modules + explicitely. + + Parameters: + enabled_plugins: Optional list of plugins to consider for loading. + """ + for entry_point in entry_points(group="pulp_glue.plugins"): + name = entry_point.name + if ( + enabled_plugins is None or entry_point.name in enabled_plugins + ) and entry_point.name not in loaded_plugins: + plugin = entry_point.load() + if hasattr(plugin, "mount"): + plugin.mount() + loaded_plugins.add(name) diff --git a/pulp-glue/pyproject.toml b/pulp-glue/pyproject.toml index 0cccf32cc..09633aedb 100644 --- a/pulp-glue/pyproject.toml +++ b/pulp-glue/pyproject.toml @@ -33,6 +33,15 @@ documentation = "https://docs.pulpproject.org/pulp_cli/" repository = "https://github.com/pulp/pulp-cli" changelog = "https://docs.pulpproject.org/pulp_cli/CHANGES/" +[project.entry-points."pulp_glue.plugins"] +ansible = "pulp_glue.ansible" +certguard = "pulp_glue.certguard" +container = "pulp_glue.container" +core = "pulp_glue.core" +file = "pulp_glue.file" +python = "pulp_glue.python" +rpm = "pulp_glue.rpm" + [tool.setuptools.packages.find] where = ["."] include = ["pulp_glue.*"] diff --git a/pulp-glue/tests/test_entity_context.py b/pulp-glue/tests/test_entity_context.py index 62491367c..baa9a927a 100644 --- a/pulp-glue/tests/test_entity_context.py +++ b/pulp-glue/tests/test_entity_context.py @@ -4,6 +4,7 @@ import pytest +from pulp_glue.common import load_plugins, loaded_plugins from pulp_glue.common.context import PulpContext, PulpRepositoryContext from pulp_glue.file.context import PulpFileRepositoryContext @@ -18,6 +19,15 @@ def file_repository(pulp_ctx: PulpContext) -> t.Dict[str, t.Any]: file_repository_ctx.delete() +def test_plugin_loading() -> None: + load_plugins() + assert "core" in loaded_plugins + + +def test_type_registry() -> None: + assert "file:file" in PulpRepositoryContext.TYPE_REGISTRY + + def test_detail_context(pulp_ctx: PulpContext, file_repository: t.Dict[str, t.Any]) -> None: master_ctx = PulpRepositoryContext(pulp_ctx) detail_ctx = master_ctx.detail_context(pulp_href=file_repository["pulp_href"])