Skip to content

Commit 33d20dc

Browse files
neiljpPIG208
authored andcommitted
bots: Find external packaged bots via 'zulip_bots.registry' entry_point.
Added dependency upon supporting small 'entrypoints' package. Add test case.
1 parent c602121 commit 33d20dc

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

zulip_bots/setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"lxml",
6767
"BeautifulSoup4",
6868
"typing_extensions",
69+
"entrypoints",
6970
],
7071
)
7172

zulip_bots/zulip_bots/finder.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from pathlib import Path
66
from typing import Any, Optional, Tuple
77

8+
import entrypoints
9+
810
current_dir = os.path.dirname(os.path.abspath(__file__))
911

1012

@@ -25,6 +27,23 @@ def import_module_by_name(name: str) -> Any:
2527
return None
2628

2729

30+
class DuplicateRegisteredBotName(Exception):
31+
pass
32+
33+
34+
def import_module_from_zulip_bot_registry(name: str) -> Any:
35+
registered_bots = entrypoints.get_group_all("zulip_bots.registry")
36+
matching_bots = [bot for bot in registered_bots if bot.name == name]
37+
38+
if len(matching_bots) == 1: # Unique matching entrypoint
39+
return matching_bots[0].load()
40+
41+
if len(matching_bots) > 1:
42+
raise DuplicateRegisteredBotName(name)
43+
44+
return None # no matches in registry
45+
46+
2847
def resolve_bot_path(name: str) -> Optional[Tuple[Path, str]]:
2948
if os.path.isfile(name):
3049
bot_path = Path(name)

zulip_bots/zulip_bots/run.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ def main() -> None:
139139
if args.provision:
140140
print("ERROR: Could not load bot's module for '{}'. Exiting now.")
141141
sys.exit(1)
142+
else:
143+
try:
144+
lib_module = finder.import_module_from_zulip_bot_registry(args.bot)
145+
except finder.DuplicateRegisteredBotName:
146+
print(
147+
"ERROR: Found duplicate entries for bot name in zulip bot registry. Exiting now."
148+
)
149+
sys.exit(1)
150+
if lib_module:
151+
bot_name = args.bot
142152

143153
if lib_module is None:
144154
print("ERROR: Could not load bot module. Exiting now.")

zulip_bots/zulip_bots/tests/test_run.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from unittest import TestCase, mock
88
from unittest.mock import patch
99

10+
import entrypoints
11+
1012
import zulip_bots.run
1113
from zulip_bots.lib import extract_query_without_mention
1214

@@ -15,6 +17,7 @@ class TestDefaultArguments(TestCase):
1517

1618
our_dir = os.path.dirname(__file__)
1719
path_to_bot = os.path.abspath(os.path.join(our_dir, "../bots/giphy/giphy.py"))
20+
packaged_bot_entrypoint = entrypoints.EntryPoint("packaged_bot", "module_name", None)
1821

1922
@patch("sys.argv", ["zulip-run-bot", "giphy", "--config-file", "/foo/bar/baz.conf"])
2023
@patch("zulip_bots.run.run_message_handler_for_bot")
@@ -48,6 +51,27 @@ def test_argument_parsing_with_bot_path(
4851
quiet=False,
4952
)
5053

54+
@patch("sys.argv", ["zulip-run-bot", "packaged_bot", "--config-file", "/foo/bar/baz.conf"])
55+
@patch("zulip_bots.run.run_message_handler_for_bot")
56+
def test_argument_parsing_with_zulip_bot_registry(
57+
self, mock_run_message_handler_for_bot: mock.Mock
58+
) -> None:
59+
with patch("zulip_bots.run.exit_gracefully_if_zulip_config_is_missing"):
60+
with patch("zulip_bots.finder.entrypoints.EntryPoint.load"):
61+
with patch(
62+
"zulip_bots.finder.entrypoints.get_group_all",
63+
return_value=[self.packaged_bot_entrypoint],
64+
):
65+
zulip_bots.run.main()
66+
67+
mock_run_message_handler_for_bot.assert_called_with(
68+
bot_name="packaged_bot",
69+
config_file="/foo/bar/baz.conf",
70+
bot_config_file=None,
71+
lib_module=mock.ANY,
72+
quiet=False,
73+
)
74+
5175
def test_adding_bot_parent_dir_to_sys_path_when_bot_name_specified(self) -> None:
5276
bot_name = "helloworld" # existing bot's name
5377
expected_bot_dir_path = Path(

0 commit comments

Comments
 (0)