from src import ModuleManager, utils from . import colors EVENT_CATEGORIES = { "ping": [ "ping" # new webhook received ], "code": ["push"], "pr-minimal": [ "merge_request/opened", "merge_request/closed", "merge_request/reopened" ], "pr": [ "merge_request/opened", "merge_request/closed", "merge_request/reopened", "merge_request/edited", "merge_request/assigned", "merge_request/unassigned" ], "pr-all": ["merge_request"], "issue-minimal": [ "issue/opened", "issue/closed", "issue/reopened", "issue/deleted" ], "issues": [ "issue/opened", "issue/closed", "issue/reopened", "issue/deleted", "issue/edited", "issue/assigned", "issue/unassigned", "issue_comment" ], "issue-all": [ "issue", "issue_comment" ], "issue-comment-minimal": [ "issue_comment/created", "issue_comment/deleted" ], "repo": [ "create", # a repository, branch or tag has been created "delete", # same as above but deleted "release", "fork", "repository" ] } COMMENT_ACTIONS = { "created": "commented", "edited": "edited a comment", "deleted": "deleted a comment" } ISSUE_ACTIONS = { "open": "opened", "close": "closed", "reopen": "reopened", "update": "updated" } class GitLab(object): def is_private(self, data, headers): if "project" in data: return not data["project"]["visibility_level"] == 20 return False def names(self, data, headers): full_name = data["project"]["path_with_namespace"] repo_username = data["project"]["namespace"] repo_name = data["project"]["name"] return full_name, repo_username, repo_name, None def branch(self, data, headers): if "ref" in data: return data["ref"].rpartition("/")[2] return None def event(self, data, headers): event = headers["X-GitLab-Event"].rsplit(" ", 1)[0].lower() event = event.replace(" ", "_") event_action = None if ("object_attributes" in data and "action" in data["object_attributes"]): event_action = "%s/%s" % ( event, data["object_attributes"]["action"]) return event, event_action def event_categories(self, event): return EVENT_CATEGORIES.get(event, [event]) def webhook(self, full_name, event, data, headers): if event == "push": return self.push(full_name, data) elif event == "merge_request": return self.merge_request(full_name, data) elif event == "issue": return self.issues(full_name, data) elif event == "note": return self.note(full_name, data) def _short_hash(self, hash): return hash[:8] def push(self, full_name, data): outputs = [] branch = data["ref"].rpartition("/")[2] branch = utils.irc.color(branch, colors.COLOR_BRANCH) author = utils.irc.bold(data["user_username"]) if len(data["commits"]) <= 3: for commit in data["commits"]: hash = commit["id"] hash_colored = utils.irc.color(self._short_hash(hash), colors.COLOR_ID) message = commit["message"].split("\n")[0].strip() url = commit["url"] outputs.append( "%s pushed %s to %s: %s - %s" % (author, hash_colored, branch, message, url)) else: first_id = data["before"] last_id = data["after"] url = data["compare_url"] outputs.append("%s pushed %d commits to %s" % (author, len(data["commits"]), branch)) return outputs def merge_request(self, full_name, data): number = utils.irc.color("#%s" % data["object_attributes"]["iid"], colors.COLOR_ID) action = data["object_attributes"]["action"] action_desc = "%s %s" % (action, number) branch = data["object_attributes"]["target_branch"] colored_branch = utils.irc.color(branch, colors.COLOR_BRANCH) if action == "open": action_desc = "requested %s merge into %s" % (number, colored_branch) elif action == "close": if data["pull_request"]["merged"]: action_desc = "%s %s into %s" % ( utils.irc.color("merged", colors.COLOR_POSITIVE), number, colored_branch) else: action_desc = "%s %s" % ( utils.irc.color("closed", colors.COLOR_NEGATIVE), number) pr_title = data["object_attributes"]["title"] author = utils.irc.bold(data["user"]["username"]) url = data["object_attributes"]["url"] return ["[PR] %s %s: %s - %s" % ( author, action_desc, pr_title, url)] def issues(self, full_name, data): number = utils.irc.color("#%s" % data["object_attributes"]["iid"], colors.COLOR_ID) action = ISSUE_ACTIONS[data["object_attributes"]["action"]] issue_title = data["object_attributes"]["title"] author = utils.irc.bold(data["user"]["username"]) url = data["object_attributes"]["url"] return ["[issue] %s %s %s: %s - %s" % (author, action, number, issue_title, url)] def note(self, full_name, data): type = data["object_attributes"]["noteable_type"] if type in ["Issue", "MergeRequest"]: return self.issue_comment(full_name, data) def issue_note(self, full_name, data): number = utils.irc.color("#%s" % data["object_attributes"]["iid"], colors.COLOR_ID) type = data["object_attributes"]["noteable_type"] type == "issue" if type == "Issue" else "PR" issue_title = data["issue"]["title"] commenter = utils.irc.bold(data["user"]["username"]) url = data["object_attributes"]["url"] return ["[%s] %s commented on %s: %s - %s" % (type, commenter, number, issue_title, url)]