2019-04-25 12:23:26 +02:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
#
|
|
|
|
|
# Copyright © 2019 Endless Mobile, Inc.
|
|
|
|
|
#
|
|
|
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
|
#
|
|
|
|
|
# Original author: Philip Withnall
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
Checks that a merge request doesn’t add any instances of the string ‘todo’
|
|
|
|
|
(in uppercase), or similar keywords. It may remove instances of that keyword,
|
|
|
|
|
or move them around, according to the logic of `git log -S`.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import re
|
|
|
|
|
import subprocess
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# We have to specify these keywords obscurely to avoid the script matching
|
|
|
|
|
# itself. The keyword ‘fixme’ (in upper case) is explicitly allowed because
|
|
|
|
|
# that’s conventionally used as a way of marking a workaround which needs to
|
|
|
|
|
# be merged for now, but is to be grepped for and reverted or reworked later.
|
|
|
|
|
BANNED_KEYWORDS = [
|
2020-11-17 16:07:09 +01:00
|
|
|
|
"TO" + "DO",
|
|
|
|
|
"X" + "XX",
|
|
|
|
|
"W" + "IP",
|
2019-04-25 12:23:26 +02:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
parser = argparse.ArgumentParser(
|
2020-11-17 16:07:09 +01:00
|
|
|
|
description="Check a range of commits to ensure they don’t contain "
|
|
|
|
|
"banned keywords."
|
|
|
|
|
)
|
|
|
|
|
parser.add_argument("commits", help="SHA to diff from, or range of commits to diff")
|
2019-04-25 12:23:26 +02:00
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
banned_words_seen = set()
|
|
|
|
|
seen_in_log = False
|
|
|
|
|
seen_in_diff = False
|
|
|
|
|
|
|
|
|
|
# Check the log messages for banned words.
|
|
|
|
|
log_process = subprocess.run(
|
2020-11-17 16:07:09 +01:00
|
|
|
|
["git", "log", "--no-color", args.commits + "..HEAD"],
|
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
|
encoding="utf-8",
|
|
|
|
|
check=True,
|
|
|
|
|
)
|
|
|
|
|
log_lines = log_process.stdout.strip().split("\n")
|
2019-04-25 12:23:26 +02:00
|
|
|
|
|
|
|
|
|
for line in log_lines:
|
|
|
|
|
for keyword in BANNED_KEYWORDS:
|
2020-11-17 16:32:10 +01:00
|
|
|
|
if re.search(r"(^|\W+){}(\W+|$)".format(keyword), line):
|
2019-04-25 12:23:26 +02:00
|
|
|
|
banned_words_seen.add(keyword)
|
|
|
|
|
seen_in_log = True
|
|
|
|
|
|
|
|
|
|
# Check the diff for banned words.
|
|
|
|
|
diff_process = subprocess.run(
|
2020-11-17 16:07:09 +01:00
|
|
|
|
["git", "diff", "-U0", "--no-color", args.commits],
|
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
|
encoding="utf-8",
|
|
|
|
|
check=True,
|
|
|
|
|
)
|
|
|
|
|
diff_lines = diff_process.stdout.strip().split("\n")
|
2019-04-25 12:23:26 +02:00
|
|
|
|
|
|
|
|
|
for line in diff_lines:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
if not line.startswith("+ "):
|
2019-04-25 12:23:26 +02:00
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
for keyword in BANNED_KEYWORDS:
|
2020-11-17 16:32:10 +01:00
|
|
|
|
if re.search(r"(^|\W+){}(\W+|$)".format(keyword), line):
|
2019-04-25 12:23:26 +02:00
|
|
|
|
banned_words_seen.add(keyword)
|
|
|
|
|
seen_in_diff = True
|
|
|
|
|
|
|
|
|
|
if banned_words_seen:
|
|
|
|
|
if seen_in_log and seen_in_diff:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
where = "commit message and diff"
|
2019-04-25 12:23:26 +02:00
|
|
|
|
elif seen_in_log:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
where = "commit message"
|
2019-04-25 12:23:26 +02:00
|
|
|
|
elif seen_in_diff:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
where = "commit diff"
|
|
|
|
|
|
|
|
|
|
print(
|
|
|
|
|
"Saw banned keywords in a {}: {}. "
|
|
|
|
|
"This indicates the branch is a work in progress and should not "
|
|
|
|
|
"be merged in its current "
|
|
|
|
|
"form.".format(where, ", ".join(banned_words_seen))
|
|
|
|
|
)
|
2019-04-25 12:23:26 +02:00
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
2020-11-17 16:07:09 +01:00
|
|
|
|
if __name__ == "__main__":
|
2019-04-25 12:23:26 +02:00
|
|
|
|
main()
|