[PATCH 3 of 3] RFC check-code: try to detect @command/def errors
timeless
timeless at mozdev.org
Wed Nov 25 00:31:40 CST 2015
# HG changeset patch
# User timeless <timeless at mozdev.org>
# Date 1448432398 0
# Wed Nov 25 06:19:58 2015 +0000
# Node ID c572fb376061421d6fec149a5876b155607d04ad
# Parent a6abc5a4a6f757cca55f6db68520f934e0fa4057
RFC check-code: try to detect @command/def errors
This would have caught the bugs that were fixed in:
3836a70f1fa5
0fb08fcd5af8
It's admittedly a bit heavy-handed, but...
I'd also like to reduce the number of whitelisted warnings in
the .t -- just as I did by offering a patch for gpg
diff --git a/contrib/check-code.py b/contrib/check-code.py
--- a/contrib/check-code.py
+++ b/contrib/check-code.py
@@ -84,6 +84,40 @@
t = re.sub(r"\S", "x", m.group(2))
return m.group(1) + t
+repcommandstr = '^@command\\(.([^,)]+).[,)]|^def ([^(]*)\('
+repcommandre = re.compile(repcommandstr)
+cmdbitsre = re.compile(r'\^?([^|]+)')
+
+def repcommandchecker(l, state):
+ if not 'cmd' in state:
+ state['commands'] = {}
+ state['defs'] = {}
+ state['cmd'] = None
+ match = repcommandre.search(l)
+ cmdname, defname = match.group(1), match.group(2)
+ result = []
+ if cmdname:
+ state['cmd'] = cmdname
+ cmdname = cmdbitsre.search(cmdname).group(1)
+ if cmdname in state['commands']:
+ result.append("duplicate @command: %s" % cmdname)
+ state['commands'][cmdname] = True
+ elif defname:
+ if defname in state['defs']:
+ result.append("duplicate def: %s" % defname)
+ cmd = state['cmd']
+ if cmd:
+ cmd_ = re.sub('[^a-z]', '', cmd)
+ defname_ = re.sub('[^a-z]', '', defname)
+ if not (re.search('%s(?:|_|cmd)' % cmd_, defname_) or
+ re.search(defname_, cmd_)):
+ result.append("@command %s does not match def %s" %
+ (cmd, defname))
+ state['cmd'] = ''
+ state['defs'][defname] = True
+ if len(result) == 0:
+ return None
+ return result
testpats = [
[
@@ -299,6 +333,11 @@
# warnings
[
(r'(^| )pp +xxxxqq[ \n][^\n]', "add two newlines after '.. note::'"),
+ (repcommandstr,
+ "@command function should be unique and match function definition",
+ None,
+ repcommandchecker
+ ),
]
]
@@ -494,16 +533,21 @@
prelines = None
errors = []
for i, pat in enumerate(pats):
- if len(pat) == 3:
+ if len(pat) == 4:
+ p, msg, ignore, callback = pat
+ elif len(pat) == 3:
p, msg, ignore = pat
+ callback = None
else:
p, msg = pat
ignore = None
+ callback = None
if i >= nerrs:
msg = "warning: " + msg
pos = 0
n = 0
+ state = {}
for m in p.finditer(post):
if prelines is None:
prelines = pre.splitlines()
@@ -523,6 +567,17 @@
print "Skipping %s for %s:%s (ignore pattern)" % (
name, f, n)
continue
+
+ if callback:
+ result = callback(l, state)
+ if not result:
+ if debug:
+ print "Skipping %s for %s:%s (bad match)" % (
+ name, f, n)
+ continue
+ if debug:
+ for e in result:
+ errors.append((f, lineno and n + 1, l, e, ""))
bd = ""
if blame:
bd = 'working directory'
diff --git a/tests/test-check-code-hg.t b/tests/test-check-code-hg.t
--- a/tests/test-check-code-hg.t
+++ b/tests/test-check-code-hg.t
@@ -8,8 +8,15 @@
$ hg locate | sed 's-\\-/-g' |
> xargs "$check_code" $HGTEST_DEBUG --warnings --per-file=0 || false
+ hgext/graphlog.py:52:
+ > def graphlog(ui, repo, *pats, **opts):
+ warning: @command function should be unique and match function definition
+ hgext/patchbomb.py:406:
+ > def patchbomb(ui, repo, *revs, **opts):
+ warning: @command function should be unique and match function definition
Skipping hgext/zeroconf/Zeroconf.py it has no-che?k-code (glob)
Skipping i18n/polib.py it has no-che?k-code (glob)
Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob)
Skipping mercurial/httpclient/socketutil.py it has no-che?k-code (glob)
+ [1]
More information about the Mercurial-devel
mailing list