Zelalem | 917b43e | 2020-08-04 11:39:55 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # |
| 3 | # Copyright (c) 2019-2020, Arm Limited. All rights reserved. |
| 4 | # |
| 5 | # SPDX-License-Identifier: BSD-3-Clause |
| 6 | # |
| 7 | |
| 8 | import argparse |
| 9 | import datetime |
| 10 | import sys |
| 11 | import os.path |
| 12 | import logging |
| 13 | |
| 14 | try: |
| 15 | from github import Github |
| 16 | except ImportError: |
| 17 | print( |
| 18 | "Can not import from github. PyGitHub may be missing. Check requirements.txt." |
| 19 | ) |
| 20 | sys.exit(1) |
| 21 | |
| 22 | SCRIPT_DIR = os.path.dirname(__file__) |
| 23 | logger = logging.getLogger() |
| 24 | |
| 25 | |
| 26 | def commented_already(comments, bots): |
| 27 | """Check if our bots have left a comment.""" |
| 28 | return any(comment.user.login in bots for comment in comments) |
| 29 | |
| 30 | |
| 31 | def readfile(path): |
| 32 | """Read a file into a python string""" |
| 33 | with open(os.path.join(SCRIPT_DIR, path), "r") as textfile: |
| 34 | return textfile.read() |
| 35 | |
| 36 | |
| 37 | def reply_to_issues(repo, bots, dry_run): |
| 38 | """Reply to all new issues without a bot reply""" |
| 39 | body = readfile("issue_comment.md") |
| 40 | logging.info("Replying to new issues on {}/{}".format(repo.owner.login, repo.name)) |
| 41 | for issue in repo.get_issues(since=datetime.datetime(2019, 10, 17, 12)): |
| 42 | if not commented_already(issue.get_comments(), bots): |
| 43 | logging.info("Repliyng to issue #{}: {}".format(issue.number, issue.title)) |
| 44 | if not dry_run: |
| 45 | issue.create_comment(body.format(user_name=issue.user.login)) |
| 46 | |
| 47 | |
| 48 | def reply_to_pull_requests(repo, bots, dry_run): |
| 49 | """Reply to all new Pull Requests without a bot reply""" |
| 50 | body = readfile("pull_comment.md") |
| 51 | logging.info("Replying to PRs on {}/{}".format(repo.owner.login, repo.name)) |
| 52 | for pr in repo.get_pulls("status=open"): |
| 53 | # get_issue_comments() returns top-level PR comments. |
| 54 | # While get_comments() or get_review_comments() |
| 55 | # return comments against diff in the PR. |
| 56 | if not commented_already(pr.get_issue_comments(), bots): |
| 57 | logging.info("Repling to pull request #{}: {}".format(pr.number, pr.title)) |
| 58 | if not dry_run: |
| 59 | pr.create_issue_comment(body.format(user_name=pr.user.login)) |
| 60 | |
| 61 | |
| 62 | def to_repo(gh, owner, name): |
| 63 | """Construct a Repo from a logged in Github object an owner and a repo name""" |
| 64 | return gh.get_user(owner).get_repo(name) |
| 65 | |
| 66 | |
| 67 | if __name__ == "__main__": |
| 68 | parser = argparse.ArgumentParser() |
| 69 | parser.add_argument("user", help="Username to login to GitHub") |
| 70 | parser.add_argument("pass", help="Password of the GitHub user") |
| 71 | parser.add_argument( |
| 72 | "--dry-run", |
| 73 | help="Just print what would be done", |
| 74 | default=False, |
| 75 | action="store_true", |
| 76 | ) |
| 77 | parser.add_argument('--verbose', '-v', action='count', default=0, help="Increase verbosity of the printing") |
| 78 | args = parser.parse_args() |
| 79 | |
| 80 | if args.verbose <= 0: |
| 81 | logger.setLevel(logging.ERROR) |
| 82 | elif args.verbose <= 1: |
| 83 | logger.setLevel(logging.INFO) |
| 84 | else: |
| 85 | logger.setLevel(logging.DEBUG) |
| 86 | |
| 87 | repository_owner = "ARM-software" |
| 88 | repository_name = "arm-trusted-firmware" |
| 89 | issues_name = "tf-issues" |
| 90 | bots = {"arm-tf-bot", "ssg-bot", args.user} |
| 91 | |
| 92 | gh = Github(args.user, getattr(args, "pass")) |
| 93 | pr_repo = to_repo(gh, repository_owner, repository_name) |
| 94 | reply_to_pull_requests(pr_repo, bots, args.dry_run) |
| 95 | issue_repo = to_repo(gh, repository_owner, issues_name) |
| 96 | reply_to_pull_requests(issue_repo, bots, args.dry_run) |
| 97 | reply_to_issues(issue_repo, bots, args.dry_run) |