3 # Copyright © 2019 Endless Mobile, Inc.
5 # SPDX-License-Identifier: LGPL-2.1-or-later
7 # Original author: Philip Withnall
10 Checks that a merge request doesn’t add any instances of the string ‘todo’
11 (in uppercase), or similar keywords. It may remove instances of that keyword,
12 or move them around, according to the logic of `git log -S`.
21 # We have to specify these keywords obscurely to avoid the script matching
22 # itself. The keyword ‘fixme’ (in upper case) is explicitly allowed because
23 # that’s conventionally used as a way of marking a workaround which needs to
24 # be merged for now, but is to be grepped for and reverted or reworked later.
25 BANNED_KEYWORDS = ["TO" + "DO", "X" + "XX", "W" + "IP"]
29 parser = argparse.ArgumentParser(
30 description="Check a range of commits to ensure they don’t contain "
33 parser.add_argument("commits", help="SHA to diff from, or range of commits to diff")
34 args = parser.parse_args()
36 banned_words_seen = set()
40 # Check the log messages for banned words.
41 log_process = subprocess.run(
42 ["git", "log", "--no-color", args.commits + "..HEAD"],
43 stdout=subprocess.PIPE,
44 stderr=subprocess.PIPE,
48 log_lines = log_process.stdout.strip().split("\n")
50 for line in log_lines:
51 for keyword in BANNED_KEYWORDS:
52 if re.search(r"(^|\W+){}(\W+|$)".format(keyword), line):
53 banned_words_seen.add(keyword)
56 # Check the diff for banned words.
57 diff_process = subprocess.run(
58 ["git", "diff", "-U0", "--no-color", args.commits],
59 stdout=subprocess.PIPE,
60 stderr=subprocess.PIPE,
64 diff_lines = diff_process.stdout.strip().split("\n")
66 for line in diff_lines:
67 if not line.startswith("+ "):
70 for keyword in BANNED_KEYWORDS:
71 if re.search(r"(^|\W+){}(\W+|$)".format(keyword), line):
72 banned_words_seen.add(keyword)
76 if seen_in_log and seen_in_diff:
77 where = "commit message and diff"
79 where = "commit message"
84 "Saw banned keywords in a {}: {}. "
85 "This indicates the branch is a work in progress and should not "
86 "be merged in its current "
87 "form.".format(where, ", ".join(banned_words_seen))
92 if __name__ == "__main__":