check-commit
57 lines
| 1.7 KiB
| text/plain
|
TextLexer
/ contrib / check-commit
Matt Mackall
|
r22043 | #!/usr/bin/env python | ||
# | ||||
# Copyright 2014 Matt Mackall <mpm@selenic.com> | ||||
# | ||||
# A tool/hook to run basic sanity checks on commits/patches for | ||||
# submission to Mercurial. Install by adding the following to your | ||||
# .hg/hgrc: | ||||
# | ||||
# [hooks] | ||||
# pretxncommit = contrib/check-commit | ||||
# | ||||
# The hook can be temporarily bypassed with: | ||||
# | ||||
# $ BYPASS= hg commit | ||||
# | ||||
Matt Mackall
|
r26421 | # See also: https://mercurial-scm.org/wiki/ContributingChanges | ||
Matt Mackall
|
r22043 | |||
import re, sys, os | ||||
errors = [ | ||||
(r"[(]bc[)]", "(BC) needs to be uppercase"), | ||||
(r"[(]issue \d\d\d", "no space allowed between issue and number"), | ||||
Pierre-Yves David
|
r24703 | (r"[(]bug(\d|\s)", "use (issueDDDD) instead of bug"), | ||
Matt Mackall
|
r22043 | (r"^# User [^@\n]+$", "username is not an email address"), | ||
(r"^# .*\n(?!merge with )[^#]\S+[^:] ", | ||||
"summary line doesn't start with 'topic: '"), | ||||
(r"^# .*\n[A-Z][a-z]\S+", "don't capitalize summary lines"), | ||||
Eric Sumner
|
r24049 | (r"^# .*\n[^\n]*: *[A-Z][a-z]\S+", "don't capitalize summary lines"), | ||
Matt Mackall
|
r22043 | (r"^# .*\n.*\.\s+$", "don't add trailing period on summary line"), | ||
Augie Fackler
|
r25137 | (r"^# .*\n.{78,}", "summary line too long (limit is 78)"), | ||
Matt Mackall
|
r22058 | (r"^\+\n \n", "adds double empty line"), | ||
Yuya Nishihara
|
r25643 | (r"^ \n\+\n", "adds double empty line"), | ||
Gregory Szorc
|
r25379 | (r"^\+[ \t]+def [a-z]+_[a-z]", "adds a function with foo_bar naming"), | ||
Matt Mackall
|
r22043 | ] | ||
node = os.environ.get("HG_NODE") | ||||
if node: | ||||
commit = os.popen("hg export %s" % node).read() | ||||
else: | ||||
commit = sys.stdin.read() | ||||
exitcode = 0 | ||||
for exp, msg in errors: | ||||
m = re.search(exp, commit, re.MULTILINE) | ||||
if m: | ||||
pos = 0 | ||||
for n, l in enumerate(commit.splitlines(True)): | ||||
pos += len(l) | ||||
if pos >= m.end(): | ||||
print "%d: %s" % (n, msg) | ||||
print " %s" % l[:-1] | ||||
if "BYPASS" not in os.environ: | ||||
exitcode = 1 | ||||
break | ||||
sys.exit(exitcode) | ||||