annotate contrib/check-config.py @ 33197:5d8942dbe49e

check-config: syntax to allow inconsistent config values The ignore regular expression has been updated to detect "inconsistent config." If present, we track which configs have that set and we suppress the conflicting defaults error for those options. I also added named groups to the regexp to aid readability. A comment was added to profiling.py to make a desired inconsistent value error go away.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 01 Jul 2017 20:34:27 -0700
parents e9fc5550be46
children e470f12d7d05
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 #!/usr/bin/env python
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # check-config - a config flag documentation checker for Mercurial
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # Copyright 2015 Matt Mackall <mpm@selenic.com>
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 #
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7 # This software may be used and distributed according to the terms of the
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
8 # GNU General Public License version 2 or any later version.
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
9
28352
a92ee4d8a574 check-config: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27992
diff changeset
10 from __future__ import absolute_import, print_function
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
11 import re
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
12 import sys
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
13
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
14 foundopts = {}
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
15 documented = {}
33197
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
16 allowinconsistent = set()
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
17
32865
e5a6a540ae63 check-config: use compiled regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28352
diff changeset
18 configre = re.compile(r'''
e5a6a540ae63 check-config: use compiled regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28352
diff changeset
19 # Function call
32866
485b8e87e244 check-config: use named groups in regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32865
diff changeset
20 ui\.config(?P<ctype>|int|bool|list)\(
32865
e5a6a540ae63 check-config: use compiled regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28352
diff changeset
21 # First argument.
32866
485b8e87e244 check-config: use named groups in regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32865
diff changeset
22 ['"](?P<section>\S+)['"],\s*
32865
e5a6a540ae63 check-config: use compiled regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28352
diff changeset
23 # Second argument
32866
485b8e87e244 check-config: use named groups in regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32865
diff changeset
24 ['"](?P<option>\S+)['"](,\s+
485b8e87e244 check-config: use named groups in regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32865
diff changeset
25 (?:default=)?(?P<default>\S+?))?
32865
e5a6a540ae63 check-config: use compiled regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28352
diff changeset
26 \)''', re.VERBOSE | re.MULTILINE)
e5a6a540ae63 check-config: use compiled regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28352
diff changeset
27
32867
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
28 configwithre = re.compile('''
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
29 ui\.config(?P<ctype>with)\(
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
30 # First argument is callback function. This doesn't parse robustly
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
31 # if it is e.g. a function call.
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
32 [^,]+,\s*
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
33 ['"](?P<section>\S+)['"],\s*
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
34 ['"](?P<option>\S+)['"](,\s+
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
35 (?:default=)?(?P<default>\S+?))?
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
36 \)''', re.VERBOSE | re.MULTILINE)
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
37
27313
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
38 configpartialre = (r"""ui\.config""")
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
39
33197
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
40 ignorere = re.compile(r'''
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
41 \#\s(?P<reason>internal|experimental|deprecated|developer|inconsistent)\s
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
42 config:\s(?P<config>\S+\.\S+)$
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
43 ''', re.VERBOSE | re.MULTILINE)
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
44
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
45 def main(args):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
46 for f in args:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
47 sect = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
48 prevname = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
49 confsect = ''
27313
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
50 carryover = ''
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
51 for l in open(f):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
52
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 # check topic-like bits
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
54 m = re.match('\s*``(\S+)``', l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
55 if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
56 prevname = m.group(1)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
57 if re.match('^\s*-+$', l):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
58 sect = prevname
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
59 prevname = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
60
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
61 if sect and prevname:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
62 name = sect + '.' + prevname
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
63 documented[name] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
64
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
65 # check docstring bits
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
66 m = re.match(r'^\s+\[(\S+)\]', l)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
67 if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68 confsect = m.group(1)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
69 continue
27311
24a1c24fad6e check-config: allow numbers in configs
timeless <timeless@mozdev.org>
parents: 27310
diff changeset
70 m = re.match(r'^\s+(?:#\s*)?(\S+) = ', l)
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71 if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72 name = confsect + '.' + m.group(1)
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73 documented[name] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
74
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 # like the bugzilla extension
27311
24a1c24fad6e check-config: allow numbers in configs
timeless <timeless@mozdev.org>
parents: 27310
diff changeset
76 m = re.match(r'^\s*(\S+\.\S+)$', l)
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77 if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78 documented[m.group(1)] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
79
27310
9c98fe1416c2 check-config: recognize convert style documentation
timeless <timeless@mozdev.org>
parents: 25849
diff changeset
80 # like convert
9c98fe1416c2 check-config: recognize convert style documentation
timeless <timeless@mozdev.org>
parents: 25849
diff changeset
81 m = re.match(r'^\s*:(\S+\.\S+):\s+', l)
9c98fe1416c2 check-config: recognize convert style documentation
timeless <timeless@mozdev.org>
parents: 25849
diff changeset
82 if m:
9c98fe1416c2 check-config: recognize convert style documentation
timeless <timeless@mozdev.org>
parents: 25849
diff changeset
83 documented[m.group(1)] = 1
9c98fe1416c2 check-config: recognize convert style documentation
timeless <timeless@mozdev.org>
parents: 25849
diff changeset
84
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
85 # quoted in help or docstrings
27311
24a1c24fad6e check-config: allow numbers in configs
timeless <timeless@mozdev.org>
parents: 27310
diff changeset
86 m = re.match(r'.*?``(\S+\.\S+)``', l)
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87 if m:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
88 documented[m.group(1)] = 1
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
89
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 # look for ignore markers
33197
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
91 m = ignorere.search(l)
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 if m:
33197
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
93 if m.group('reason') == 'inconsistent':
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
94 allowinconsistent.add(m.group('config'))
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
95 else:
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
96 documented[m.group('config')] = 1
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
97
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
98 # look for code-like bits
27313
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
99 line = carryover + l
32867
e9fc5550be46 check-config: look for ui.configwith
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32866
diff changeset
100 m = configre.search(line) or configwithre.search(line)
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
101 if m:
32866
485b8e87e244 check-config: use named groups in regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32865
diff changeset
102 ctype = m.group('ctype')
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 if not ctype:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
104 ctype = 'str'
32866
485b8e87e244 check-config: use named groups in regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32865
diff changeset
105 name = m.group('section') + "." + m.group('option')
485b8e87e244 check-config: use named groups in regexp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32865
diff changeset
106 default = m.group('default')
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
107 if default in (None, 'False', 'None', '0', '[]', '""', "''"):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
108 default = ''
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
109 if re.match('[a-z.]+$', default):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
110 default = '<variable>'
33197
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
111 if (name in foundopts and (ctype, default) != foundopts[name]
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32867
diff changeset
112 and name not in allowinconsistent):
28352
a92ee4d8a574 check-config: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27992
diff changeset
113 print(l)
a92ee4d8a574 check-config: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27992
diff changeset
114 print("conflict on %s: %r != %r" % (name, (ctype, default),
a92ee4d8a574 check-config: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27992
diff changeset
115 foundopts[name]))
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
116 foundopts[name] = (ctype, default)
27313
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
117 carryover = ''
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
118 else:
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
119 m = re.search(configpartialre, line)
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
120 if m:
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
121 carryover = line
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
122 else:
9d155accd8f1 check-config: handle multiline config
timeless <timeless@mozdev.org>
parents: 27312
diff changeset
123 carryover = ''
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
124
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
125 for name in sorted(foundopts):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
126 if name not in documented:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
127 if not (name.startswith("devel.") or
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
128 name.startswith("experimental.") or
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
129 name.startswith("debug.")):
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
130 ctype, default = foundopts[name]
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
131 if default:
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
132 default = ' [%s]' % default
28352
a92ee4d8a574 check-config: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27992
diff changeset
133 print("undocumented: %s (%s)%s" % (name, ctype, default))
25790
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
134
db5b6a1c064d check-config: add config option checker
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
135 if __name__ == "__main__":
27992
8f244b75cc5e tests: execute check-config.py without xargs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27313
diff changeset
136 if len(sys.argv) > 1:
8f244b75cc5e tests: execute check-config.py without xargs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27313
diff changeset
137 sys.exit(main(sys.argv[1:]))
8f244b75cc5e tests: execute check-config.py without xargs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27313
diff changeset
138 else:
8f244b75cc5e tests: execute check-config.py without xargs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27313
diff changeset
139 sys.exit(main([l.rstrip() for l in sys.stdin]))