##// END OF EJS Templates
tests: glob copyright years in test-extension.t...
tests: glob copyright years in test-extension.t Other tests already do this.

File last commit:

r33571:e470f12d default
r35791:eb878d86 default
Show More
check-config.py
142 lines | 4.6 KiB | text/x-python | PythonLexer
Matt Mackall
check-config: add config option checker...
r25790 #!/usr/bin/env python
#
# check-config - a config flag documentation checker for Mercurial
#
# Copyright 2015 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Pulkit Goyal
check-config: use absolute_import and print_function
r28352 from __future__ import absolute_import, print_function
Matt Mackall
check-config: add config option checker...
r25790 import re
import sys
foundopts = {}
documented = {}
Gregory Szorc
check-config: syntax to allow inconsistent config values...
r33192 allowinconsistent = set()
Matt Mackall
check-config: add config option checker...
r25790
Gregory Szorc
check-config: use compiled regexp...
r32847 configre = re.compile(r'''
# Function call
Gregory Szorc
check-config: use named groups in regexp...
r32848 ui\.config(?P<ctype>|int|bool|list)\(
Gregory Szorc
check-config: use compiled regexp...
r32847 # First argument.
Gregory Szorc
check-config: use named groups in regexp...
r32848 ['"](?P<section>\S+)['"],\s*
Gregory Szorc
check-config: use compiled regexp...
r32847 # Second argument
Gregory Szorc
check-config: use named groups in regexp...
r32848 ['"](?P<option>\S+)['"](,\s+
(?:default=)?(?P<default>\S+?))?
Gregory Szorc
check-config: use compiled regexp...
r32847 \)''', re.VERBOSE | re.MULTILINE)
Gregory Szorc
check-config: look for ui.configwith...
r32849 configwithre = re.compile('''
ui\.config(?P<ctype>with)\(
# First argument is callback function. This doesn't parse robustly
# if it is e.g. a function call.
[^,]+,\s*
['"](?P<section>\S+)['"],\s*
['"](?P<option>\S+)['"](,\s+
(?:default=)?(?P<default>\S+?))?
\)''', re.VERBOSE | re.MULTILINE)
timeless
check-config: handle multiline config
r27313 configpartialre = (r"""ui\.config""")
Matt Mackall
check-config: add config option checker...
r25790
Gregory Szorc
check-config: syntax to allow inconsistent config values...
r33192 ignorere = re.compile(r'''
\#\s(?P<reason>internal|experimental|deprecated|developer|inconsistent)\s
config:\s(?P<config>\S+\.\S+)$
''', re.VERBOSE | re.MULTILINE)
Matt Mackall
check-config: add config option checker...
r25790 def main(args):
for f in args:
sect = ''
prevname = ''
confsect = ''
timeless
check-config: handle multiline config
r27313 carryover = ''
Ryan McElroy
check-config: mention the file and line of the error...
r33571 linenum = 0
Matt Mackall
check-config: add config option checker...
r25790 for l in open(f):
Ryan McElroy
check-config: mention the file and line of the error...
r33571 linenum += 1
Matt Mackall
check-config: add config option checker...
r25790
# check topic-like bits
m = re.match('\s*``(\S+)``', l)
if m:
prevname = m.group(1)
if re.match('^\s*-+$', l):
sect = prevname
prevname = ''
if sect and prevname:
name = sect + '.' + prevname
documented[name] = 1
# check docstring bits
m = re.match(r'^\s+\[(\S+)\]', l)
if m:
confsect = m.group(1)
continue
timeless
check-config: allow numbers in configs...
r27311 m = re.match(r'^\s+(?:#\s*)?(\S+) = ', l)
Matt Mackall
check-config: add config option checker...
r25790 if m:
name = confsect + '.' + m.group(1)
documented[name] = 1
# like the bugzilla extension
timeless
check-config: allow numbers in configs...
r27311 m = re.match(r'^\s*(\S+\.\S+)$', l)
Matt Mackall
check-config: add config option checker...
r25790 if m:
documented[m.group(1)] = 1
timeless
check-config: recognize convert style documentation
r27310 # like convert
m = re.match(r'^\s*:(\S+\.\S+):\s+', l)
if m:
documented[m.group(1)] = 1
Matt Mackall
check-config: add config option checker...
r25790 # quoted in help or docstrings
timeless
check-config: allow numbers in configs...
r27311 m = re.match(r'.*?``(\S+\.\S+)``', l)
Matt Mackall
check-config: add config option checker...
r25790 if m:
documented[m.group(1)] = 1
# look for ignore markers
Gregory Szorc
check-config: syntax to allow inconsistent config values...
r33192 m = ignorere.search(l)
Matt Mackall
check-config: add config option checker...
r25790 if m:
Gregory Szorc
check-config: syntax to allow inconsistent config values...
r33192 if m.group('reason') == 'inconsistent':
allowinconsistent.add(m.group('config'))
else:
documented[m.group('config')] = 1
Matt Mackall
check-config: add config option checker...
r25790
# look for code-like bits
timeless
check-config: handle multiline config
r27313 line = carryover + l
Gregory Szorc
check-config: look for ui.configwith...
r32849 m = configre.search(line) or configwithre.search(line)
Matt Mackall
check-config: add config option checker...
r25790 if m:
Gregory Szorc
check-config: use named groups in regexp...
r32848 ctype = m.group('ctype')
Matt Mackall
check-config: add config option checker...
r25790 if not ctype:
ctype = 'str'
Gregory Szorc
check-config: use named groups in regexp...
r32848 name = m.group('section') + "." + m.group('option')
default = m.group('default')
Matt Mackall
check-config: add config option checker...
r25790 if default in (None, 'False', 'None', '0', '[]', '""', "''"):
default = ''
if re.match('[a-z.]+$', default):
default = '<variable>'
Gregory Szorc
check-config: syntax to allow inconsistent config values...
r33192 if (name in foundopts and (ctype, default) != foundopts[name]
and name not in allowinconsistent):
Ryan McElroy
check-config: mention the file and line of the error...
r33571 print(l.rstrip())
Pulkit Goyal
check-config: use absolute_import and print_function
r28352 print("conflict on %s: %r != %r" % (name, (ctype, default),
foundopts[name]))
Ryan McElroy
check-config: mention the file and line of the error...
r33571 print("at %s:%d:" % (f, linenum))
Matt Mackall
check-config: add config option checker...
r25790 foundopts[name] = (ctype, default)
timeless
check-config: handle multiline config
r27313 carryover = ''
else:
m = re.search(configpartialre, line)
if m:
carryover = line
else:
carryover = ''
Matt Mackall
check-config: add config option checker...
r25790
for name in sorted(foundopts):
if name not in documented:
if not (name.startswith("devel.") or
name.startswith("experimental.") or
name.startswith("debug.")):
ctype, default = foundopts[name]
if default:
default = ' [%s]' % default
Pulkit Goyal
check-config: use absolute_import and print_function
r28352 print("undocumented: %s (%s)%s" % (name, ctype, default))
Matt Mackall
check-config: add config option checker...
r25790
if __name__ == "__main__":
FUJIWARA Katsunori
tests: execute check-config.py without xargs...
r27992 if len(sys.argv) > 1:
sys.exit(main(sys.argv[1:]))
else:
sys.exit(main([l.rstrip() for l in sys.stdin]))