Skip to content

Commit 85e61fd

Browse files
committed
Refactored msg handler and moved github handler to dedicated directory
Signed-off-by: Michael Engel <mengel@redhat.com>
1 parent e930121 commit 85e61fd

File tree

7 files changed

+212
-104
lines changed

7 files changed

+212
-104
lines changed

sync2jira/handler/github.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import logging
2+
3+
# Local Modules
4+
import sync2jira.downstream_issue as d_issue
5+
import sync2jira.downstream_pr as d_pr
6+
import sync2jira.handler.github_upstream_issue as u_issue
7+
import sync2jira.handler.github_upstream_pr as u_pr
8+
from sync2jira.intermediary import matcher
9+
10+
log = logging.getLogger("sync2jira")
11+
12+
13+
def handle_issue_msg(body, suffix, config):
14+
"""
15+
Function to handle incoming github issue message
16+
:param Dict body: Incoming message body
17+
:param String suffix: Incoming suffix
18+
:param Dict config: Config dict
19+
"""
20+
# GitHub '.issue*' is used for both PR and Issue; check if this update
21+
# is actually for a PR
22+
if "pull_request" in body["issue"]:
23+
if body["action"] == "deleted":
24+
# I think this gets triggered when someone deletes a comment
25+
# from a PR. Since we don't capture PR comments (only Issue
26+
# comments), we don't need to react if one is deleted.
27+
log.debug("Not handling PR 'action' == 'deleted'")
28+
return
29+
# Handle this PR update as though it were an Issue, if that's
30+
# acceptable to the configuration.
31+
if not (pr := u_issue.handle_github_message(body, config, is_pr=True)):
32+
log.info("Not handling PR issue update -- not configured")
33+
return
34+
# PRs require additional handling (Issues do not have suffix, and
35+
# reporter needs to be reformatted).
36+
pr.suffix = suffix
37+
pr.reporter = pr.reporter.get("fullname")
38+
setattr(pr, "match", matcher(pr.content, pr.comments))
39+
d_pr.sync_with_jira(pr, config)
40+
else:
41+
if issue := u_issue.handle_github_message(body, config):
42+
d_issue.sync_with_jira(issue, config)
43+
else:
44+
log.info("Not handling Issue update -- not configured")
45+
46+
47+
def handle_pr_msg(body, suffix, config):
48+
"""
49+
Function to handle incoming github PR message
50+
:param Dict body: Incoming message body
51+
:param String suffix: Incoming suffix
52+
:param Dict config: Config dict
53+
"""
54+
if pr := u_pr.handle_github_message(body, config, suffix):
55+
d_pr.sync_with_jira(pr, config)
56+
else:
57+
log.info("Not handling PR update -- not configured")
58+
59+
60+
# Issue related handlers
61+
issue_handlers = {
62+
# GitHub
63+
# New webhook-2fm topics
64+
"github.issues": handle_issue_msg,
65+
"github.issue_comment": handle_issue_msg,
66+
# Old github2fedmsg topics
67+
"github.issue.opened": handle_issue_msg,
68+
"github.issue.reopened": handle_issue_msg,
69+
"github.issue.labeled": handle_issue_msg,
70+
"github.issue.assigned": handle_issue_msg,
71+
"github.issue.unassigned": handle_issue_msg,
72+
"github.issue.closed": handle_issue_msg,
73+
"github.issue.comment": handle_issue_msg,
74+
"github.issue.unlabeled": handle_issue_msg,
75+
"github.issue.milestoned": handle_issue_msg,
76+
"github.issue.demilestoned": handle_issue_msg,
77+
"github.issue.edited": handle_issue_msg,
78+
}
79+
80+
# PR related handlers
81+
pr_handlers = {
82+
# GitHub
83+
# New webhook-2fm topics
84+
"github.pull_request": handle_pr_msg,
85+
"github.issue_comment": handle_pr_msg,
86+
# Old github2fedmsg topics
87+
"github.pull_request.opened": handle_pr_msg,
88+
"github.pull_request.edited": handle_pr_msg,
89+
"github.issue.comment": handle_pr_msg,
90+
"github.pull_request.reopened": handle_pr_msg,
91+
"github.pull_request.closed": handle_pr_msg,
92+
}
93+
94+
95+
def get_handler_for(suffix, topic, idx):
96+
"""
97+
Function to check if a handler for given suffix is configured
98+
:param String suffix: Incoming suffix
99+
:param String topic: Topic of incoming message
100+
:param String idx: Id of incoming message
101+
:returns: Handler function if configured for suffix. Otherwise None.
102+
"""
103+
if suffix in issue_handlers:
104+
return issue_handlers.get(suffix)
105+
elif suffix in pr_handlers:
106+
return pr_handlers.get(suffix)
107+
log.info("No handler for %r %r %r", suffix, topic, idx)
108+
return None
File renamed without changes.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121

2222
from github import Github, UnknownObjectException
2323

24+
import sync2jira.handler.github_upstream_issue as u_issue
2425
import sync2jira.intermediary as i
25-
import sync2jira.upstream_issue as u_issue
2626

2727
log = logging.getLogger("sync2jira")
2828

sync2jira/main.py

Lines changed: 32 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
# Local Modules
3737
import sync2jira.downstream_issue as d_issue
3838
import sync2jira.downstream_pr as d_pr
39-
from sync2jira.intermediary import matcher
39+
import sync2jira.handler.github as gh_handler
40+
import sync2jira.handler.github_upstream_issue as u_issue
41+
import sync2jira.handler.github_upstream_pr as u_pr
4042
from sync2jira.mailer import send_mail
41-
import sync2jira.upstream_issue as u_issue
42-
import sync2jira.upstream_pr as u_pr
4343

4444
# Set up our logging
4545
FORMAT = "[%(asctime)s] %(levelname)s: %(message)s"
@@ -148,20 +148,18 @@ def callback(msg):
148148
idx = msg.id
149149
suffix = ".".join(topic.split(".")[3:])
150150

151-
if suffix not in issue_handlers and suffix not in pr_handlers:
152-
log.info("No handler for %r %r %r", suffix, topic, idx)
153-
return
154-
155-
config = load_config()
156-
body = msg.body.get("body") or msg.body
157-
try:
158-
handle_msg(body, suffix, config)
159-
except GithubException as e:
160-
log.error("Unexpected GitHub error: %s", e)
161-
except JIRAError as e:
162-
log.error("Unexpected Jira error: %s", e)
163-
except Exception as e:
164-
log.exception("Unexpected error.", exc_info=e)
151+
handler = gh_handler.get_handler_for(suffix, topic, idx)
152+
if handler:
153+
config = load_config()
154+
body = msg.body.get("body") or msg.body
155+
try:
156+
handler(body, suffix, config)
157+
except GithubException as e:
158+
log.error("Unexpected GitHub error: %s", e)
159+
except JIRAError as e:
160+
log.error("Unexpected Jira error: %s", e)
161+
except Exception as e:
162+
log.exception("Unexpected error.", exc_info=e)
165163

166164

167165
def listen(config):
@@ -188,18 +186,26 @@ def listen(config):
188186
"arguments": {},
189187
},
190188
}
189+
190+
# The topics that should be delivered to the queue
191+
github_topics = [
192+
# New style
193+
"org.fedoraproject.prod.github.issues",
194+
"org.fedoraproject.prod.github.issue_comment",
195+
"org.fedoraproject.prod.github.pull_request",
196+
# Old style
197+
"org.fedoraproject.prod.github.issue.#",
198+
"org.fedoraproject.prod.github.pull_request.#",
199+
]
200+
gitlab_topics = [
201+
# mytodo: add all topics here
202+
"org.fedoraproject.prod.gitlab.merge_request",
203+
]
204+
191205
bindings = {
192206
"exchange": "amq.topic", # The AMQP exchange to bind our queue to
193207
"queue": queue,
194-
"routing_keys": [ # The topics that should be delivered to the queue
195-
# New style
196-
"org.fedoraproject.prod.github.issues",
197-
"org.fedoraproject.prod.github.issue_comment",
198-
"org.fedoraproject.prod.github.pull_request",
199-
# Old style
200-
"org.fedoraproject.prod.github.issue.#",
201-
"org.fedoraproject.prod.github.pull_request.#",
202-
],
208+
"routing_keys": github_topics + gitlab_topics,
203209
}
204210

205211
log.info("Waiting for a relevant fedmsg message to arrive...")
@@ -299,46 +305,6 @@ def initialize_pr(config, testing=False, repo_name=None):
299305
log.info("Done with GitHub PR initialization.")
300306

301307

302-
def handle_msg(body, suffix, config):
303-
"""
304-
Function to handle incoming message
305-
:param Dict body: Incoming message body
306-
:param String suffix: Incoming suffix
307-
:param Dict config: Config dict
308-
"""
309-
if handler := issue_handlers.get(suffix):
310-
# GitHub '.issue*' is used for both PR and Issue; check if this update
311-
# is actually for a PR
312-
if "pull_request" in body["issue"]:
313-
if body["action"] == "deleted":
314-
# I think this gets triggered when someone deletes a comment
315-
# from a PR. Since we don't capture PR comments (only Issue
316-
# comments), we don't need to react if one is deleted.
317-
log.debug("Not handling PR 'action' == 'deleted'")
318-
return
319-
# Handle this PR update as though it were an Issue, if that's
320-
# acceptable to the configuration.
321-
if not (pr := handler(body, config, is_pr=True)):
322-
log.info("Not handling PR issue update -- not configured")
323-
return
324-
# PRs require additional handling (Issues do not have suffix, and
325-
# reporter needs to be reformatted).
326-
pr.suffix = suffix
327-
pr.reporter = pr.reporter.get("fullname")
328-
setattr(pr, "match", matcher(pr.content, pr.comments))
329-
d_pr.sync_with_jira(pr, config)
330-
else:
331-
if issue := handler(body, config):
332-
d_issue.sync_with_jira(issue, config)
333-
else:
334-
log.info("Not handling Issue update -- not configured")
335-
elif handler := pr_handlers.get(suffix):
336-
if pr := handler(body, config, suffix):
337-
d_pr.sync_with_jira(pr, config)
338-
else:
339-
log.info("Not handling PR update -- not configured")
340-
341-
342308
def main(runtime_test=False, runtime_config=None):
343309
"""
344310
Main function to check for initial sync
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import unittest.mock as mock
44
from unittest.mock import MagicMock
55

6-
import sync2jira.upstream_issue as u
6+
import sync2jira.handler.github_upstream_issue as u
77

8-
PATH = "sync2jira.upstream_issue."
8+
PATH = "sync2jira.handler.github_upstream_issue."
99

1010

1111
class TestUpstreamIssue(unittest.TestCase):
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import unittest.mock as mock
44
from unittest.mock import MagicMock
55

6-
import sync2jira.upstream_pr as u
6+
import sync2jira.handler.github_upstream_pr as u
77

8-
PATH = "sync2jira.upstream_pr."
8+
PATH = "sync2jira.handler.github_upstream_pr."
99

1010

1111
class TestUpstreamPR(unittest.TestCase):

0 commit comments

Comments
 (0)