##// END OF EJS Templates
py3: make contrib/check-commit use print_function
Pulkit Goyal -
r29164:91f35b1a default
parent child Browse files
Show More
@@ -1,102 +1,102 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # Copyright 2014 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # A tool/hook to run basic sanity checks on commits/patches for
6 6 # submission to Mercurial. Install by adding the following to your
7 7 # .hg/hgrc:
8 8 #
9 9 # [hooks]
10 10 # pretxncommit = contrib/check-commit
11 11 #
12 12 # The hook can be temporarily bypassed with:
13 13 #
14 14 # $ BYPASS= hg commit
15 15 #
16 16 # See also: https://mercurial-scm.org/wiki/ContributingChanges
17 17
18 from __future__ import absolute_import
18 from __future__ import absolute_import, print_function
19 19
20 20 import os
21 21 import re
22 22 import sys
23 23
24 24 commitheader = r"^(?:# [^\n]*\n)*"
25 25 afterheader = commitheader + r"(?!#)"
26 26 beforepatch = afterheader + r"(?!\n(?!@@))"
27 27
28 28 errors = [
29 29 (beforepatch + r".*[(]bc[)]", "(BC) needs to be uppercase"),
30 30 (beforepatch + r".*[(]issue \d\d\d",
31 31 "no space allowed between issue and number"),
32 32 (beforepatch + r".*[(]bug(\d|\s)", "use (issueDDDD) instead of bug"),
33 33 (commitheader + r"# User [^@\n]+\n", "username is not an email address"),
34 34 (commitheader + r"(?!merge with )[^#]\S+[^:] ",
35 35 "summary line doesn't start with 'topic: '"),
36 36 (afterheader + r"[A-Z][a-z]\S+", "don't capitalize summary lines"),
37 37 (afterheader + r"[^\n]*: *[A-Z][a-z]\S+", "don't capitalize summary lines"),
38 38 (afterheader + r"\S*[^A-Za-z0-9-]\S*: ",
39 39 "summary keyword should be most user-relevant one-word command or topic"),
40 40 (afterheader + r".*\.\s*\n", "don't add trailing period on summary line"),
41 41 (afterheader + r".{79,}", "summary line too long (limit is 78)"),
42 42 (r"\n\+\n( |\+)\n", "adds double empty line"),
43 43 (r"\n \n\+\n", "adds double empty line"),
44 44 (r"\n\+[ \t]+def [a-z]+_[a-z]", "adds a function with foo_bar naming"),
45 45 ]
46 46
47 47 word = re.compile('\S')
48 48 def nonempty(first, second):
49 49 if word.search(first):
50 50 return first
51 51 return second
52 52
53 53 def checkcommit(commit, node=None):
54 54 exitcode = 0
55 55 printed = node is None
56 56 hits = []
57 57 for exp, msg in errors:
58 58 for m in re.finditer(exp, commit):
59 59 end = m.end()
60 60 trailing = re.search(r'(\\n)+$', exp)
61 61 if trailing:
62 62 end -= len(trailing.group()) / 2
63 63 hits.append((end, exp, msg))
64 64 if hits:
65 65 hits.sort()
66 66 pos = 0
67 67 last = ''
68 68 for n, l in enumerate(commit.splitlines(True)):
69 69 pos += len(l)
70 70 while len(hits):
71 71 end, exp, msg = hits[0]
72 72 if pos < end:
73 73 break
74 74 if not printed:
75 75 printed = True
76 print "node: %s" % node
77 print "%d: %s" % (n, msg)
78 print " %s" % nonempty(l, last)[:-1]
76 print("node: %s" % node)
77 print("%d: %s" % (n, msg))
78 print(" %s" % nonempty(l, last)[:-1])
79 79 if "BYPASS" not in os.environ:
80 80 exitcode = 1
81 81 del hits[0]
82 82 last = nonempty(l, last)
83 83
84 84 return exitcode
85 85
86 86 def readcommit(node):
87 87 return os.popen("hg export %s" % node).read()
88 88
89 89 if __name__ == "__main__":
90 90 exitcode = 0
91 91 node = os.environ.get("HG_NODE")
92 92
93 93 if node:
94 94 commit = readcommit(node)
95 95 exitcode = checkcommit(commit)
96 96 elif sys.argv[1:]:
97 97 for node in sys.argv[1:]:
98 98 exitcode |= checkcommit(readcommit(node), node)
99 99 else:
100 100 commit = sys.stdin.read()
101 101 exitcode = checkcommit(commit)
102 102 sys.exit(exitcode)
General Comments 0
You need to be logged in to leave comments. Login now