in notifier.py [0:0]
def get_recipient(self, repository, itype, action="comment", userid=None):
m = RE_PROJECT.match(repository)
if m:
project = m.group(1)
else:
project = "infra"
repo_path = None
scheme = {}
for root_dir in self.config["repository_paths"]:
for path in glob.glob(root_dir):
if os.path.basename(path) == f"{repository}.git":
repo_path = path
break
if repo_path:
scheme_path = os.path.join(repo_path, self.config["scheme_file"])
if os.path.exists(scheme_path):
try:
scheme = yaml.safe_load(open(scheme_path))
except Exception: # TODO: narrow further to expected Exceptions
pass
# Check standard git config
cfg_path = os.path.join(repo_path, "config")
cfg = git.GitConfigParser(cfg_path)
# If the yaml scheme is missing parts, weave in the defaults from the git config in their place
# Commits mailing list
if "commits" not in scheme:
scheme["commits"] = cfg.get("hooks.asfgit", "recips") or self.config["default_recipient"]
# Issues and Pull Requests
if cfg.has_option("apache", "dev"):
default_issue = cfg.get("apache", "dev")
if "issues" not in scheme:
scheme["issues"] = default_issue
if "pullrequests" not in scheme:
scheme["pullrequests"] = default_issue
# Jira notification options
if cfg.has_option("apache", "jira"):
default_jira = cfg.get("apache", "jira")
if "jira_options" not in scheme:
scheme["jira_options"] = default_jira
if scheme:
if itype not in ("commit", "jira") and userid:
# Work out whether issue or pullrequest
github_issue_type = itype == "issue" and "issues" or "pullrequests"
# Work out the type of event (ticket status change, or comment)
event_category = "unknown"
if action in ("comment", "diffcomment", "diffcomment_collated", "edited", "deleted", "created"):
event_category = "comment"
elif action in ("open", "close", "merge"):
event_category = "status"
# Order of preference for scheme (most specific -> least specific)
# Special rules that are only valid for bots like dependabot
rule_order_bots = (
"{issue_type}_{event_category}_bot_{userid}", # e.g. pullrequests_comment_bot_dependabot
"{issue_type}_bot_{userid}", # e.g. pullrequests_bot_dependabot
)
# Humans (and bots with no bot-specific rules)
rule_order_humans = (
"{issue_type}_{event_category}", # e.g. pullrequests_comment
"{issue_type}", # e.g. pullrequests
)
rule_dict = {
"issue_type": github_issue_type,
"event_category": event_category,
"userid": userid.replace("[bot]", ""), # Only bot rules use this, so the bot tag is implied anyway.
}
# If bot, we remove the [bot] in the user ID and check the bot rules
if is_bot(userid):
print(f"{userid} is a known bot, expanding rule-set")
for rule in rule_order_bots:
key = rule.format(**rule_dict)
if key in scheme and scheme[key]: # If we have this scheme and it is non-empty, return it
return scheme[key]
# Human rules (also applies to bots with no specific rules for them)
for rule in rule_order_humans:
key = rule.format(**rule_dict)
if key in scheme and scheme[key]: # If we have this scheme and it is non-empty, return it
return scheme[key]
# return self.config["default_recipient"] # No (non-empty) scheme found, return default git recipient
elif itype == "commit" and "commits" in scheme:
return scheme["commits"]
elif itype == "jira":
return scheme.get("jira_options", self.config["jira"]["default_options"])
if itype == "jira":
return self.config["jira"]["default_options"]
return "dev@%s.apache.org" % project