diff --git a/keg/cli.py b/keg/cli.py index 3aa4f58..874a868 100644 --- a/keg/cli.py +++ b/keg/cli.py @@ -37,28 +37,16 @@ def __init__(self, create_app, add_default_commands=True, load_dotenv=True, *arg def _load_plugin_commands(self): if self._loaded_plugin_commands: return - entry_point_iterables = [] - # older Flask try: - import pkg_resources - entry_point_iterables.extend([ - pkg_resources.iter_entry_points('flask.commands'), - pkg_resources.iter_entry_points('keg.commands'), - ]) + from flask.cli import metadata except ImportError: return - # newer Flask - try: - # uses importlib, but python has some API variations. Let flask handle that. - from flask.cli import metadata - entry_point_iterables.extend([ - metadata.entry_points(group="flask.commands"), - metadata.entry_points(group="keg.commands"), - ]) - except ImportError: - pass + entry_point_iterables = [ + metadata.entry_points(group="flask.commands"), + metadata.entry_points(group="keg.commands"), + ] for ep in chain.from_iterable(entry_point_iterables): self.add_command(ep.load(), ep.name) diff --git a/keg/tests/test_cli.py b/keg/tests/test_cli.py index 6fa051e..141790d 100644 --- a/keg/tests/test_cli.py +++ b/keg/tests/test_cli.py @@ -1,9 +1,15 @@ import os from unittest import mock +import click import pytest -from keg.cli import dotenv, get_load_dotenv +try: + from flask.cli import metadata as flask_cli_metadata +except ImportError: + flask_cli_metadata = None + +from keg.cli import KegAppGroup, dotenv, get_load_dotenv from keg.testing import CLIBase, app_config from keg_apps.cli import CLIApp from keg_apps.cli2.app import CLI2App @@ -19,6 +25,36 @@ class TestCLI(CLIBase): app_cls = CLIApp cmd_name = 'hello' + @pytest.mark.skipif(flask_cli_metadata is None, reason='Flask CLI metadata not supported') + def test_load_plugin_commands_with_flask_metadata(self): + @click.command('plugin') + def plugin_command(): + pass + + class EntryPoint: + name = 'plugin' + + def load(self): + return plugin_command + + def entry_points(group): + if group == 'keg.commands': + return [EntryPoint()] + return [] + + app_group = KegAppGroup(lambda: None, add_default_commands=False) + + with mock.patch( + 'flask.cli.metadata.entry_points', side_effect=entry_points + ) as m_entry_points: + app_group._load_plugin_commands() + + assert app_group.commands['plugin'] is plugin_command + assert [call.kwargs['group'] for call in m_entry_points.call_args_list] == [ + 'flask.commands', + 'keg.commands', + ] + def test_class_command(self): result = self.invoke() assert 'hello keg test' in result.output