##// END OF EJS Templates
check-config: don't continue prematurely...
Matt Mackall -
r25849:d1cb185b default
parent child Browse files
Show More
@@ -1,95 +1,93 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # check-config - a config flag documentation checker for Mercurial
3 # check-config - a config flag documentation checker for Mercurial
4 #
4 #
5 # Copyright 2015 Matt Mackall <mpm@selenic.com>
5 # Copyright 2015 Matt Mackall <mpm@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 import re
10 import re
11 import sys
11 import sys
12
12
13 foundopts = {}
13 foundopts = {}
14 documented = {}
14 documented = {}
15
15
16 configre = (r"""ui\.config(|int|bool|list)\(['"](\S+)['"], ?"""
16 configre = (r"""ui\.config(|int|bool|list)\(['"](\S+)['"], ?"""
17 r"""['"](\S+)['"](,\s(?:default=)?(\S+?))?\)""")
17 r"""['"](\S+)['"](,\s(?:default=)?(\S+?))?\)""")
18
18
19 def main(args):
19 def main(args):
20 for f in args:
20 for f in args:
21 sect = ''
21 sect = ''
22 prevname = ''
22 prevname = ''
23 confsect = ''
23 confsect = ''
24 for l in open(f):
24 for l in open(f):
25
25
26 # check topic-like bits
26 # check topic-like bits
27 m = re.match('\s*``(\S+)``', l)
27 m = re.match('\s*``(\S+)``', l)
28 if m:
28 if m:
29 prevname = m.group(1)
29 prevname = m.group(1)
30 continue
31 if re.match('^\s*-+$', l):
30 if re.match('^\s*-+$', l):
32 sect = prevname
31 sect = prevname
33 prevname = ''
32 prevname = ''
34 continue
35
33
36 if sect and prevname:
34 if sect and prevname:
37 name = sect + '.' + prevname
35 name = sect + '.' + prevname
38 documented[name] = 1
36 documented[name] = 1
39
37
40 # check docstring bits
38 # check docstring bits
41 m = re.match(r'^\s+\[(\S+)\]', l)
39 m = re.match(r'^\s+\[(\S+)\]', l)
42 if m:
40 if m:
43 confsect = m.group(1)
41 confsect = m.group(1)
44 continue
42 continue
45 m = re.match(r'^\s+(?:#\s*)?([a-z._]+) = ', l)
43 m = re.match(r'^\s+(?:#\s*)?([a-z._]+) = ', l)
46 if m:
44 if m:
47 name = confsect + '.' + m.group(1)
45 name = confsect + '.' + m.group(1)
48 documented[name] = 1
46 documented[name] = 1
49
47
50 # like the bugzilla extension
48 # like the bugzilla extension
51 m = re.match(r'^\s*([a-z]+\.[a-z]+)$', l)
49 m = re.match(r'^\s*([a-z]+\.[a-z]+)$', l)
52 if m:
50 if m:
53 documented[m.group(1)] = 1
51 documented[m.group(1)] = 1
54
52
55 # quoted in help or docstrings
53 # quoted in help or docstrings
56 m = re.match(r'.*?``([-a-z_]+\.[-a-z_]+)``', l)
54 m = re.match(r'.*?``([-a-z_]+\.[-a-z_]+)``', l)
57 if m:
55 if m:
58 documented[m.group(1)] = 1
56 documented[m.group(1)] = 1
59
57
60 # look for ignore markers
58 # look for ignore markers
61 m = re.search(r'# (?:internal|experimental|deprecated|developer)'
59 m = re.search(r'# (?:internal|experimental|deprecated|developer)'
62 ' config: (\S+.\S+)$', l)
60 ' config: (\S+.\S+)$', l)
63 if m:
61 if m:
64 documented[m.group(1)] = 1
62 documented[m.group(1)] = 1
65
63
66 # look for code-like bits
64 # look for code-like bits
67 m = re.search(configre, l)
65 m = re.search(configre, l)
68 if m:
66 if m:
69 ctype = m.group(1)
67 ctype = m.group(1)
70 if not ctype:
68 if not ctype:
71 ctype = 'str'
69 ctype = 'str'
72 name = m.group(2) + "." + m.group(3)
70 name = m.group(2) + "." + m.group(3)
73 default = m.group(5)
71 default = m.group(5)
74 if default in (None, 'False', 'None', '0', '[]', '""', "''"):
72 if default in (None, 'False', 'None', '0', '[]', '""', "''"):
75 default = ''
73 default = ''
76 if re.match('[a-z.]+$', default):
74 if re.match('[a-z.]+$', default):
77 default = '<variable>'
75 default = '<variable>'
78 if name in foundopts and (ctype, default) != foundopts[name]:
76 if name in foundopts and (ctype, default) != foundopts[name]:
79 print l
77 print l
80 print "conflict on %s: %r != %r" % (name, (ctype, default),
78 print "conflict on %s: %r != %r" % (name, (ctype, default),
81 foundopts[name])
79 foundopts[name])
82 foundopts[name] = (ctype, default)
80 foundopts[name] = (ctype, default)
83
81
84 for name in sorted(foundopts):
82 for name in sorted(foundopts):
85 if name not in documented:
83 if name not in documented:
86 if not (name.startswith("devel.") or
84 if not (name.startswith("devel.") or
87 name.startswith("experimental.") or
85 name.startswith("experimental.") or
88 name.startswith("debug.")):
86 name.startswith("debug.")):
89 ctype, default = foundopts[name]
87 ctype, default = foundopts[name]
90 if default:
88 if default:
91 default = ' [%s]' % default
89 default = ' [%s]' % default
92 print "undocumented: %s (%s)%s" % (name, ctype, default)
90 print "undocumented: %s (%s)%s" % (name, ctype, default)
93
91
94 if __name__ == "__main__":
92 if __name__ == "__main__":
95 sys.exit(main(sys.argv[1:]))
93 sys.exit(main(sys.argv[1:]))
General Comments 0
You need to be logged in to leave comments. Login now