changeset 0:ae8465e44eec

Script to check for inappropriate whitespace.
author Sjoerd Mullender <sjoerd@acm.org>
date Thu, 22 Apr 2010 16:50:31 +0200 (2010-04-22)
parents
children c3189b033899
files check_whitespace.py
diffstat 1 files changed, 65 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/check_whitespace.py	Thu Apr 22 16:50:31 2010 +0200
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# Mercurial hook to check for inappropriate whitespace.  Currently it
+# only checks Python files.
+#
+# This script is based on the code in the Mercurial book
+# <http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html#id403945>
+
+import re
+
+def trailing_whitespace(difflines):
+    linenum = 0
+    header = False
+    filename = ''
+    fnre = re.compile(r'(?:---|\+\+\+) (?P<filename>[^\t\r\n]+)')
+    lnre = re.compile(r'@@ -\d+,\d+ \+(?P<lineno>\d+),')
+    wsre = re.compile(r'\+.*[ \t]$')
+    tbre = re.compile(r'\+.*\t')
+
+    for line in difflines:
+        if header:
+            # remember the name of the file that this diff affects
+            m = fnre.match(line)
+            if m is not None and m.group('filename') != '/dev/null':
+                filename = m.group('filename').split('/', 1)[-1]
+            if line.startswith('+++ '):
+                header = False
+            continue
+        if line.startswith('diff '):
+            header = True
+            continue
+        # hunk header - save the line number
+        m = lnre.match(line)
+        if m is not None:
+            linenum = int(m.group('lineno'))
+            continue
+        if header or not filename:
+            continue
+        # hunk body - check for an added line with bad whitespace
+        if filename[-3:] == '.py' or filename[-5:] == '.py.in':
+            m = tbre.match(line)
+            if m is not None:
+                yield filename, linenum, 'TABs'
+        m = wsre.match(line)
+        if m is not None:
+            if filename[-3:] == '.py' or filename[-5:] == '.py.in':
+                yield filename, linenum, 'trailing whitespace'
+        if line and line[0] in ' +':
+            linenum += 1
+
+if __name__ == '__main__':
+    import os, sys, subprocess
+
+    added = 0
+    for filename, linenum, msg in trailing_whitespace(subprocess.Popen(['hg', 'export', 'tip'], stdout=subprocess.PIPE).stdout):
+        print >> sys.stderr, ('%s, line %d: %s added' %
+                              (filename, linenum, msg))
+        added += 1
+    if added:
+        # save the commit message so we don't need to retype it
+        cmtsv = os.path.join('.hg','commit.save')
+        subprocess.call(['hg', 'tip', '--template', '{desc}'],
+                        stdout=open(cmtsv, 'w'))
+        print >> sys.stderr, 'commit message saved to %s' % cmtsv
+        sys.exit(1)