aboutsummaryrefslogtreecommitdiff
path: root/scripts/maint/lintChanges.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/maint/lintChanges.py')
-rwxr-xr-xscripts/maint/lintChanges.py82
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)