|
| 1 | +import celery |
| 2 | +import base64 |
| 3 | +import os |
| 4 | +import subprocess |
| 5 | + |
| 6 | +from celery import bootsteps |
| 7 | + |
| 8 | +from . import util, exceptions |
| 9 | + |
| 10 | +app = celery.Celery("black_out") |
| 11 | + |
| 12 | +app.conf.update( |
| 13 | + BROKER_URL=os.environ["REDIS_URL"], CELERY_RESULT_BACKEND=os.environ["REDIS_URL"] |
| 14 | +) |
| 15 | + |
| 16 | + |
| 17 | +@app.task(rate_limit="1/m") |
| 18 | +def setup_repo(): |
| 19 | + |
| 20 | + repo_name = os.environ.get("GH_REPO_NAME") |
| 21 | + repo_full_name = os.environ.get("GH_REPO_FULL_NAME") |
| 22 | + os.mkdir("repo_checkout") |
| 23 | + os.chdir("repo_checkout") |
| 24 | + print(f"Setting up {repo_name} repository, cloning from {repo_full_name}") |
| 25 | + |
| 26 | + if repo_name not in os.listdir("."): |
| 27 | + email_address = os.environ.get("GH_EMAIL") |
| 28 | + full_name = os.environ.get("GH_FULL_NAME") |
| 29 | + subprocess.check_output( |
| 30 | + [ |
| 31 | + "git", |
| 32 | + "clone", |
| 33 | + f"https://{os.environ.get('GH_AUTH')}:x-oauth-basic@github.com/{repo_full_name}.git", |
| 34 | + ] |
| 35 | + ) |
| 36 | + subprocess.check_output( |
| 37 | + ["git", "config", "--global", "user.email", f"'{email_address}'"] |
| 38 | + ) |
| 39 | + subprocess.check_output( |
| 40 | + ["git", "config", "--global", "user.name", f"'{full_name}'"] |
| 41 | + ) |
| 42 | + os.chdir(f"./{repo_name}") |
| 43 | + print(f"Finished setting up {repo_name} Repo") |
| 44 | + else: |
| 45 | + print(f"{repo_name} directory already exists") |
| 46 | + |
| 47 | + |
| 48 | +@app.task(rate_limit="1/m") |
| 49 | +def initiate_black_task(issue_number, issue_creator): |
| 50 | + """Execute black |
| 51 | + |
| 52 | + 1. git fetch origin |
| 53 | + 2. git checkout -b issue-NNNN-initialize-black origin/master |
| 54 | + 3. black . |
| 55 | + 4. git commit -am "๐ค Format code using `black` ..." |
| 56 | + 5. git push origin issue-NNNN-initialize-black |
| 57 | + 6. create the PR |
| 58 | + 7. git checkout master |
| 59 | + 7. git branch -D issue-NNNN-initialize-black |
| 60 | + """ |
| 61 | + # cd to the checked out repo, if not already there |
| 62 | + if "repo_checkout" in os.listdir("."): |
| 63 | + os.chdir("repo_checkout") |
| 64 | + os.chdir(f"./{os.environ.get('GH_REPO_NAME')}") |
| 65 | + |
| 66 | + branch_name = f"issue-{issue_number}-initialize-black" |
| 67 | + |
| 68 | + util.exec_command(["git", "fetch", "origin"]) |
| 69 | + |
| 70 | + try: |
| 71 | + util.checkout_branch(branch_name) |
| 72 | + except exceptions.BranchCheckoutException as e: |
| 73 | + message = f""" |
| 74 | +๐ค Sorry @{issue_creator}. I was not able to check out the branch in order |
| 75 | +to create the pull request. Perhaps a pull request has been made, or |
| 76 | +black has been initiated? (I'm a bot ๐ค) |
| 77 | +""" |
| 78 | + util.comment_on_pr(issue_number, message) |
| 79 | + raise e |
| 80 | + |
| 81 | + needs_black = util.check_black(["."]) |
| 82 | + if needs_black: |
| 83 | + util.exec_command(["black", "."]) |
| 84 | + commit_title, commit_body = util.commit_changes(issue_number) |
| 85 | + util.exec_command(["git", "push", "origin", branch_name]) |
| 86 | + util.create_gh_pr("master", branch_name, title=commit_title, body=commit_body) |
| 87 | + util.exec_command(["git", "checkout", "master"]) |
| 88 | + util.delete_branch(branch_name) |
| 89 | + else: |
| 90 | + message = f""" |
| 91 | +๐ค @{issue_creator}, the repo appears to be already well formatted with `black`. |
| 92 | +Closing the issue. ๐ฎ |
| 93 | +(I'm a bot ๐ค) |
| 94 | +""" |
| 95 | + |
| 96 | + util.comment_on_pr(issue_number, message) |
| 97 | + util.close_issue(issue_number) |
| 98 | + |
| 99 | + |
| 100 | +@app.task(rate_limit="1/m") |
| 101 | +def black_pr_task(pr_number, pr_author, pr_diff_url): |
| 102 | + """Execute black on a PR |
| 103 | + |
| 104 | + 1. git fetch origin pull/{pr_number}/head:pr_{pr_number} && git checkout pr_number |
| 105 | + 2. find out all affected files |
| 106 | + 3. black <all affected files> |
| 107 | + 4. git commit -am "๐ค Format code using `black` ..." |
| 108 | + 5. git push git@github.com:<pr_author>/{repo_name} pr_{pr_number}:{branch_name} |
| 109 | + 6. comment on PR |
| 110 | + 7. git checkout master |
| 111 | + 8. git branch -D pr_{pr_number} |
| 112 | + """ |
| 113 | + # cd to the checked out repo, if not already there |
| 114 | + if "repo_checkout" in os.listdir("."): |
| 115 | + os.chdir("repo_checkout") |
| 116 | + os.chdir(f"./{os.environ.get('GH_REPO_NAME')}") |
| 117 | + |
| 118 | + util.exec_command( |
| 119 | + ["git", "fetch", "origin", f"pull/{pr_number}/head:pr_{pr_number}"] |
| 120 | + ) |
| 121 | + util.exec_command(["git", "checkout", f"pr_{pr_number}"]) |
| 122 | + files_affected = util.get_pr_diff_files(pr_diff_url) |
| 123 | + branch_name = f"pr_{pr_number}" |
| 124 | + |
| 125 | + needs_black = util.check_black(files_affected) |
| 126 | + |
| 127 | + if needs_black: |
| 128 | + commands = ["black"] |
| 129 | + commands.extend(files_affected) |
| 130 | + util.exec_command(commands) |
| 131 | + |
| 132 | + commit_title, commit_body = util.commit_changes(pr_number) |
| 133 | + util.exec_command( |
| 134 | + [ |
| 135 | + "git", |
| 136 | + "push", |
| 137 | + f"git@github.com:<{pr_author}>/{os.environ.get('GH_REPO_NAME')}", |
| 138 | + branch_name, |
| 139 | + ] |
| 140 | + ) |
| 141 | + util.create_gh_pr("master", branch_name, title=commit_title, body=commit_body) |
| 142 | + message = f""" |
| 143 | +๐ค @{pr_author}, I've reformatted the code using `black` for you. ๐ฎ |
| 144 | +(I'm a bot ๐ค) |
| 145 | +""" |
| 146 | + util.comment_on_pr(pr_number, message) |
| 147 | + util.exec_command(["git", "checkout", "master"]) |
| 148 | + util.delete_branch(branch_name) |
| 149 | + |
| 150 | + |
| 151 | +class InitRepoStep(bootsteps.StartStopStep): |
| 152 | + def start(self, c): |
| 153 | + print("Initialize the repository.") |
| 154 | + setup_repo() |
| 155 | + |
| 156 | + |
| 157 | +app.steps["worker"].add(InitRepoStep) |
0 commit comments