diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 62bf4f7..b87f0a1 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -111,6 +111,27 @@ def replyadmin(*, session, payload, arguments, local_config=None): ) +def parsepatch(patch): + """ + Attempt to parse a github patch to tell us on which lines we are able to comment. + """ + ranges = [] + for l in patch.splitlines(): + if not l.startswith("@@"): + continue + s = l.split("@@")[1].strip() + ranges.append([int(x) for x in s.split(" ")[1].split(",")]) + return [(s, s + x - 1) for s, x in ranges] + + +def in_ranges(needle, haystack): + n1, n2 = needle + for h1, h2 in haystack: + if (h1 < n1) and (n2 < h2): + return True + return False + + def _compute_pwd_changes(whitelist): import black from difflib import SequenceMatcher @@ -128,15 +149,20 @@ def _compute_pwd_changes(whitelist): if p not in whitelist: # we don't touch files not in this PR. continue + patch = whitelist[p] + ranges = parsepatch(patch) + print("patch is:\n", patch) p = Path(p) old = p.read_text() new = black.format_str(old, mode=black.FileMode()) if new != old: - print("will differ") nl = new.splitlines() ol = old.splitlines() s = SequenceMatcher(None, ol, nl) for t, a1, a2, b1, b2 in s.get_opcodes(): + if not in_ranges((a1, a2), ranges): + print(f"-- we won't be able to suggest a change on {p}:{a1}-{a2}") + continue if t == "replace": c = "```suggestion\n" @@ -155,7 +181,6 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("===== reformatting suggestions. =====") prnumber = payload["issue"]["number"] - prtitle = payload["issue"]["title"] org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] @@ -177,7 +202,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): commits_url = pr_data["commits_url"] - commits_data = session.ghrequest("GET", commits_url).json() + # commits_data = session.ghrequest("GET", commits_url).json() # that will likely fail, as if PR, we need to bypass the fact that the # requester has technically no access to committer repo. @@ -216,8 +241,9 @@ def black_suggest(*, session, payload, arguments, local_config=None): "GET", f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/files", ) - pr_files = [r["filename"] for r in files_response.json()] - print("== PR contains", len(pr_files), "files") + pr_files_patches = {r["filename"]: r["patch"] for r in files_response.json()} + + print("== PR contains", len(pr_files_patches), "files") if os.path.exists(repo_name): print("== Cleaning up previsous work... ") @@ -258,7 +284,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Computing changes....") os.chdir(repo_name) - changes = _compute_pwd_changes(pr_files) + changes = _compute_pwd_changes(pr_files_patches) os.chdir("..") print("... computed", len(changes), changes) @@ -274,7 +300,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): # ) for path, start, end, body in changes: - print(f"== will suggest the following on {path} {start+1} to {end}\n", body) + print(f"== will suggest the following on lines {path} {start+1} to {end}\n") if start + 1 != end: data = { "body": body, @@ -287,7 +313,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): } try: - resp = session.ghrequest( + session.ghrequest( "POST", f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/comments", json=data, @@ -307,7 +333,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): } try: - resp = session.ghrequest( + session.ghrequest( "POST", f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/comments", json=data, @@ -317,7 +343,9 @@ def black_suggest(*, session, payload, arguments, local_config=None): pass if os.path.exists(repo_name): print("== Cleaning up repo... ") - subprocess.run("rm -rf {}".format(repo_name).split(" ")) + import shutil + shutil.rmtree(repo_name) + # subprocess.run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ")