##// END OF EJS Templates
doc: port check-seclevel.py to be Python 2/3 portable
Augie Fackler -
r32544:e9f45618 default
parent child Browse files
Show More
@@ -1,173 +1,176
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # checkseclevel - checking section title levels in each online help document
3 # checkseclevel - checking section title levels in each online help document
4
4
5 from __future__ import absolute_import
5 from __future__ import absolute_import
6
6
7 import optparse
7 import optparse
8 import os
8 import os
9 import sys
9 import sys
10
10
11 # import from the live mercurial repo
11 # import from the live mercurial repo
12 os.environ['HGMODULEPOLICY'] = 'py'
12 os.environ['HGMODULEPOLICY'] = 'py'
13 sys.path.insert(0, "..")
13 sys.path.insert(0, "..")
14 from mercurial import demandimport; demandimport.enable()
14 from mercurial import demandimport; demandimport.enable()
15 from mercurial import (
15 from mercurial import (
16 commands,
16 commands,
17 extensions,
17 extensions,
18 help,
18 help,
19 minirst,
19 minirst,
20 ui as uimod,
20 ui as uimod,
21 )
21 )
22
22
23 table = commands.table
23 table = commands.table
24 helptable = help.helptable
24 helptable = help.helptable
25
25
26 level2mark = ['"', '=', '-', '.', '#']
26 level2mark = [b'"', b'=', b'-', b'.', b'#']
27 reservedmarks = ['"']
27 reservedmarks = [b'"']
28
28
29 mark2level = {}
29 mark2level = {}
30 for m, l in zip(level2mark, xrange(len(level2mark))):
30 for m, l in zip(level2mark, range(len(level2mark))):
31 if m not in reservedmarks:
31 if m not in reservedmarks:
32 mark2level[m] = l
32 mark2level[m] = l
33
33
34 initlevel_topic = 0
34 initlevel_topic = 0
35 initlevel_cmd = 1
35 initlevel_cmd = 1
36 initlevel_ext = 1
36 initlevel_ext = 1
37 initlevel_ext_cmd = 3
37 initlevel_ext_cmd = 3
38
38
39 def showavailables(ui, initlevel):
39 def showavailables(ui, initlevel):
40 ui.warn((' available marks and order of them in this help: %s\n') %
40 avail = (' available marks and order of them in this help: %s\n') % (
41 (', '.join(['%r' % (m * 4) for m in level2mark[initlevel + 1:]])))
41 ', '.join(['%r' % (m * 4) for m in level2mark[initlevel + 1:]]))
42 ui.warn(avail.encode('utf-8'))
42
43
43 def checkseclevel(ui, doc, name, initlevel):
44 def checkseclevel(ui, doc, name, initlevel):
44 ui.note(('checking "%s"\n') % name)
45 ui.note(('checking "%s"\n') % name)
46 if not isinstance(doc, bytes):
47 doc = doc.encode('utf-8')
45 blocks, pruned = minirst.parse(doc, 0, ['verbose'])
48 blocks, pruned = minirst.parse(doc, 0, ['verbose'])
46 errorcnt = 0
49 errorcnt = 0
47 curlevel = initlevel
50 curlevel = initlevel
48 for block in blocks:
51 for block in blocks:
49 if block['type'] != 'section':
52 if block[b'type'] != b'section':
50 continue
53 continue
51 mark = block['underline']
54 mark = block[b'underline']
52 title = block['lines'][0]
55 title = block[b'lines'][0]
53 if (mark not in mark2level) or (mark2level[mark] <= initlevel):
56 if (mark not in mark2level) or (mark2level[mark] <= initlevel):
54 ui.warn(('invalid section mark %r for "%s" of %s\n') %
57 ui.warn((('invalid section mark %r for "%s" of %s\n') %
55 (mark * 4, title, name))
58 (mark * 4, title, name)).encode('utf-8'))
56 showavailables(ui, initlevel)
59 showavailables(ui, initlevel)
57 errorcnt += 1
60 errorcnt += 1
58 continue
61 continue
59 nextlevel = mark2level[mark]
62 nextlevel = mark2level[mark]
60 if curlevel < nextlevel and curlevel + 1 != nextlevel:
63 if curlevel < nextlevel and curlevel + 1 != nextlevel:
61 ui.warn(('gap of section level at "%s" of %s\n') %
64 ui.warn(('gap of section level at "%s" of %s\n') %
62 (title, name))
65 (title, name))
63 showavailables(ui, initlevel)
66 showavailables(ui, initlevel)
64 errorcnt += 1
67 errorcnt += 1
65 continue
68 continue
66 ui.note(('appropriate section level for "%s %s"\n') %
69 ui.note(('appropriate section level for "%s %s"\n') %
67 (mark * (nextlevel * 2), title))
70 (mark * (nextlevel * 2), title))
68 curlevel = nextlevel
71 curlevel = nextlevel
69
72
70 return errorcnt
73 return errorcnt
71
74
72 def checkcmdtable(ui, cmdtable, namefmt, initlevel):
75 def checkcmdtable(ui, cmdtable, namefmt, initlevel):
73 errorcnt = 0
76 errorcnt = 0
74 for k, entry in cmdtable.items():
77 for k, entry in cmdtable.items():
75 name = k.split("|")[0].lstrip("^")
78 name = k.split(b"|")[0].lstrip(b"^")
76 if not entry[0].__doc__:
79 if not entry[0].__doc__:
77 ui.note(('skip checking %s: no help document\n') %
80 ui.note(('skip checking %s: no help document\n') %
78 (namefmt % name))
81 (namefmt % name))
79 continue
82 continue
80 errorcnt += checkseclevel(ui, entry[0].__doc__,
83 errorcnt += checkseclevel(ui, entry[0].__doc__,
81 namefmt % name,
84 namefmt % name,
82 initlevel)
85 initlevel)
83 return errorcnt
86 return errorcnt
84
87
85 def checkhghelps(ui):
88 def checkhghelps(ui):
86 errorcnt = 0
89 errorcnt = 0
87 for names, sec, doc in helptable:
90 for names, sec, doc in helptable:
88 if callable(doc):
91 if callable(doc):
89 doc = doc(ui)
92 doc = doc(ui)
90 errorcnt += checkseclevel(ui, doc,
93 errorcnt += checkseclevel(ui, doc,
91 '%s help topic' % names[0],
94 '%s help topic' % names[0],
92 initlevel_topic)
95 initlevel_topic)
93
96
94 errorcnt += checkcmdtable(ui, table, '%s command', initlevel_cmd)
97 errorcnt += checkcmdtable(ui, table, '%s command', initlevel_cmd)
95
98
96 for name in sorted(extensions.enabled().keys() +
99 for name in sorted(list(extensions.enabled()) +
97 extensions.disabled().keys()):
100 list(extensions.disabled())):
98 mod = extensions.load(ui, name, None)
101 mod = extensions.load(ui, name, None)
99 if not mod.__doc__:
102 if not mod.__doc__:
100 ui.note(('skip checking %s extension: no help document\n') % name)
103 ui.note(('skip checking %s extension: no help document\n') % name)
101 continue
104 continue
102 errorcnt += checkseclevel(ui, mod.__doc__,
105 errorcnt += checkseclevel(ui, mod.__doc__,
103 '%s extension' % name,
106 '%s extension' % name,
104 initlevel_ext)
107 initlevel_ext)
105
108
106 cmdtable = getattr(mod, 'cmdtable', None)
109 cmdtable = getattr(mod, 'cmdtable', None)
107 if cmdtable:
110 if cmdtable:
108 errorcnt += checkcmdtable(ui, cmdtable,
111 errorcnt += checkcmdtable(ui, cmdtable,
109 '%s command of ' + name + ' extension',
112 '%%s command of %s extension' % name,
110 initlevel_ext_cmd)
113 initlevel_ext_cmd)
111 return errorcnt
114 return errorcnt
112
115
113 def checkfile(ui, filename, initlevel):
116 def checkfile(ui, filename, initlevel):
114 if filename == '-':
117 if filename == '-':
115 filename = 'stdin'
118 filename = 'stdin'
116 doc = sys.stdin.read()
119 doc = sys.stdin.read()
117 else:
120 else:
118 with open(filename) as fp:
121 with open(filename) as fp:
119 doc = fp.read()
122 doc = fp.read()
120
123
121 ui.note(('checking input from %s with initlevel %d\n') %
124 ui.note(('checking input from %s with initlevel %d\n') %
122 (filename, initlevel))
125 (filename, initlevel))
123 return checkseclevel(ui, doc, 'input from %s' % filename, initlevel)
126 return checkseclevel(ui, doc, 'input from %s' % filename, initlevel)
124
127
125 def main():
128 def main():
126 optparser = optparse.OptionParser("""%prog [options]
129 optparser = optparse.OptionParser("""%prog [options]
127
130
128 This checks all help documents of Mercurial (topics, commands,
131 This checks all help documents of Mercurial (topics, commands,
129 extensions and commands of them), if no file is specified by --file
132 extensions and commands of them), if no file is specified by --file
130 option.
133 option.
131 """)
134 """)
132 optparser.add_option("-v", "--verbose",
135 optparser.add_option("-v", "--verbose",
133 help="enable additional output",
136 help="enable additional output",
134 action="store_true")
137 action="store_true")
135 optparser.add_option("-d", "--debug",
138 optparser.add_option("-d", "--debug",
136 help="debug mode",
139 help="debug mode",
137 action="store_true")
140 action="store_true")
138 optparser.add_option("-f", "--file",
141 optparser.add_option("-f", "--file",
139 help="filename to read in (or '-' for stdin)",
142 help="filename to read in (or '-' for stdin)",
140 action="store", default="")
143 action="store", default="")
141
144
142 optparser.add_option("-t", "--topic",
145 optparser.add_option("-t", "--topic",
143 help="parse file as help topic",
146 help="parse file as help topic",
144 action="store_const", dest="initlevel", const=0)
147 action="store_const", dest="initlevel", const=0)
145 optparser.add_option("-c", "--command",
148 optparser.add_option("-c", "--command",
146 help="parse file as help of core command",
149 help="parse file as help of core command",
147 action="store_const", dest="initlevel", const=1)
150 action="store_const", dest="initlevel", const=1)
148 optparser.add_option("-e", "--extension",
151 optparser.add_option("-e", "--extension",
149 help="parse file as help of extension",
152 help="parse file as help of extension",
150 action="store_const", dest="initlevel", const=1)
153 action="store_const", dest="initlevel", const=1)
151 optparser.add_option("-C", "--extension-command",
154 optparser.add_option("-C", "--extension-command",
152 help="parse file as help of extension command",
155 help="parse file as help of extension command",
153 action="store_const", dest="initlevel", const=3)
156 action="store_const", dest="initlevel", const=3)
154
157
155 optparser.add_option("-l", "--initlevel",
158 optparser.add_option("-l", "--initlevel",
156 help="set initial section level manually",
159 help="set initial section level manually",
157 action="store", type="int", default=0)
160 action="store", type="int", default=0)
158
161
159 (options, args) = optparser.parse_args()
162 (options, args) = optparser.parse_args()
160
163
161 ui = uimod.ui.load()
164 ui = uimod.ui.load()
162 ui.setconfig('ui', 'verbose', options.verbose, '--verbose')
165 ui.setconfig('ui', 'verbose', options.verbose, '--verbose')
163 ui.setconfig('ui', 'debug', options.debug, '--debug')
166 ui.setconfig('ui', 'debug', options.debug, '--debug')
164
167
165 if options.file:
168 if options.file:
166 if checkfile(ui, options.file, options.initlevel):
169 if checkfile(ui, options.file, options.initlevel):
167 sys.exit(1)
170 sys.exit(1)
168 else:
171 else:
169 if checkhghelps(ui):
172 if checkhghelps(ui):
170 sys.exit(1)
173 sys.exit(1)
171
174
172 if __name__ == "__main__":
175 if __name__ == "__main__":
173 main()
176 main()
General Comments 0
You need to be logged in to leave comments. Login now