diff options
Diffstat (limited to 'scripts/maint/lintChanges.py')
-rwxr-xr-x | scripts/maint/lintChanges.py | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/scripts/maint/lintChanges.py b/scripts/maint/lintChanges.py new file mode 100755 index 0000000000..48edd06fde --- /dev/null +++ b/scripts/maint/lintChanges.py @@ -0,0 +1,82 @@ +#!/usr/bin/python + +from __future__ import print_function +from __future__ import with_statement +import sys +import re +import os + + +KNOWN_GROUPS=set([ + "Minor bugfix", + "Minor bugfixes", + "Major bugfix", + "Major bugfixes", + "Minor feature", + "Minor features", + "Major feature", + "Major features", + "New system requirements", + "Testing", + "Documentation", + "Code simplification and refactoring", + "Removed features"]) + +def lintfile(fname): + have_warned = [] + + def warn(s): + if not have_warned: + have_warned.append(1) + print("{}:".format(fname)) + print("\t{}".format(s)) + + m = re.search(r'(\d{3,})', os.path.basename(fname)) + if m: + bugnum = m.group(1) + else: + bugnum = None + + with open(fname) as f: + contents = f.read() + + if bugnum and bugnum not in contents: + warn("bug number {} does not appear".format(bugnum)) + + lines = contents.split("\n") + isBug = ("bug" in lines[0] or "fix" in lines[0]) + + m = re.match(r'^[ ]{2}o ([^\(:]*)([^:]*):', contents) + if not m: + warn("header not in format expected") + elif m.group(1).strip() not in KNOWN_GROUPS: + warn("Weird header: %r"%m.group(1)) + elif ( ("bugfix" in m.group(1) or "feature" in m.group(1)) and + ("Removed" not in m.group(1)) and + '(' not in m.group(2)): + warn("Missing subcategory on %s"%m.group(1)) + + + contents = " ".join(contents.split()) + + if re.search(r'\#\d{2,}', contents): + warn("don't use a # before ticket numbers") + + if isBug and not re.search(r'(\d+)', contents): + warn("bugfix does not mention a number") + elif isBug and not re.search(r'Fixes ([a-z ]*)bug (\d+)', contents): + warn("bugfix does not say 'Fixes bug XXX'") + + if re.search(r'[bB]ug (\d+)', contents): + if not re.search(r'[Bb]ugfix on ', contents): + warn("bugfix does not say 'bugfix on X.Y.Z'") + elif not re.search('[fF]ixes ([a-z ]*)bug (\d+); bugfix on ', + contents): + warn("bugfix incant is not semicoloned") + + +if __name__ == '__main__': + for fname in sys.argv[1:]: + if fname.endswith("~"): + continue + lintfile(fname) |