##// END OF EJS Templates
doc: use an absolute path in sys.path...
av6 -
r50100:45e71954 stable
parent child Browse files
Show More
@@ -1,233 +1,233
1 #!/usr/bin/env python3
1 #!/usr/bin/env python3
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, os.path.abspath(".."))
14 from mercurial import demandimport
14 from mercurial import demandimport
15
15
16 demandimport.enable()
16 demandimport.enable()
17 from mercurial import (
17 from mercurial import (
18 commands,
18 commands,
19 extensions,
19 extensions,
20 help,
20 help,
21 minirst,
21 minirst,
22 ui as uimod,
22 ui as uimod,
23 )
23 )
24
24
25 table = commands.table
25 table = commands.table
26 helptable = help.helptable
26 helptable = help.helptable
27
27
28 level2mark = [b'"', b'=', b'-', b'.', b'#']
28 level2mark = [b'"', b'=', b'-', b'.', b'#']
29 reservedmarks = [b'"']
29 reservedmarks = [b'"']
30
30
31 mark2level = {}
31 mark2level = {}
32 for m, l in zip(level2mark, range(len(level2mark))):
32 for m, l in zip(level2mark, range(len(level2mark))):
33 if m not in reservedmarks:
33 if m not in reservedmarks:
34 mark2level[m] = l
34 mark2level[m] = l
35
35
36 initlevel_topic = 0
36 initlevel_topic = 0
37 initlevel_cmd = 1
37 initlevel_cmd = 1
38 initlevel_ext = 1
38 initlevel_ext = 1
39 initlevel_ext_cmd = 3
39 initlevel_ext_cmd = 3
40
40
41
41
42 def showavailables(ui, initlevel):
42 def showavailables(ui, initlevel):
43 avail = ' available marks and order of them in this help: %s\n' % (
43 avail = ' available marks and order of them in this help: %s\n' % (
44 ', '.join(['%r' % (m * 4) for m in level2mark[initlevel + 1 :]])
44 ', '.join(['%r' % (m * 4) for m in level2mark[initlevel + 1 :]])
45 )
45 )
46 ui.warn(avail.encode('utf-8'))
46 ui.warn(avail.encode('utf-8'))
47
47
48
48
49 def checkseclevel(ui, doc, name, initlevel):
49 def checkseclevel(ui, doc, name, initlevel):
50 ui.notenoi18n('checking "%s"\n' % name)
50 ui.notenoi18n('checking "%s"\n' % name)
51 if not isinstance(doc, bytes):
51 if not isinstance(doc, bytes):
52 doc = doc.encode('utf-8')
52 doc = doc.encode('utf-8')
53 blocks, pruned = minirst.parse(doc, 0, ['verbose'])
53 blocks, pruned = minirst.parse(doc, 0, ['verbose'])
54 errorcnt = 0
54 errorcnt = 0
55 curlevel = initlevel
55 curlevel = initlevel
56 for block in blocks:
56 for block in blocks:
57 if block[b'type'] != b'section':
57 if block[b'type'] != b'section':
58 continue
58 continue
59 mark = block[b'underline']
59 mark = block[b'underline']
60 title = block[b'lines'][0]
60 title = block[b'lines'][0]
61 if (mark not in mark2level) or (mark2level[mark] <= initlevel):
61 if (mark not in mark2level) or (mark2level[mark] <= initlevel):
62 ui.warn(
62 ui.warn(
63 (
63 (
64 'invalid section mark %r for "%s" of %s\n'
64 'invalid section mark %r for "%s" of %s\n'
65 % (mark * 4, title, name)
65 % (mark * 4, title, name)
66 ).encode('utf-8')
66 ).encode('utf-8')
67 )
67 )
68 showavailables(ui, initlevel)
68 showavailables(ui, initlevel)
69 errorcnt += 1
69 errorcnt += 1
70 continue
70 continue
71 nextlevel = mark2level[mark]
71 nextlevel = mark2level[mark]
72 if curlevel < nextlevel and curlevel + 1 != nextlevel:
72 if curlevel < nextlevel and curlevel + 1 != nextlevel:
73 ui.warnnoi18n(
73 ui.warnnoi18n(
74 'gap of section level at "%s" of %s\n' % (title, name)
74 'gap of section level at "%s" of %s\n' % (title, name)
75 )
75 )
76 showavailables(ui, initlevel)
76 showavailables(ui, initlevel)
77 errorcnt += 1
77 errorcnt += 1
78 continue
78 continue
79 ui.notenoi18n(
79 ui.notenoi18n(
80 'appropriate section level for "%s %s"\n'
80 'appropriate section level for "%s %s"\n'
81 % (mark * (nextlevel * 2), title)
81 % (mark * (nextlevel * 2), title)
82 )
82 )
83 curlevel = nextlevel
83 curlevel = nextlevel
84
84
85 return errorcnt
85 return errorcnt
86
86
87
87
88 def checkcmdtable(ui, cmdtable, namefmt, initlevel):
88 def checkcmdtable(ui, cmdtable, namefmt, initlevel):
89 errorcnt = 0
89 errorcnt = 0
90 for k, entry in cmdtable.items():
90 for k, entry in cmdtable.items():
91 name = k.split(b"|")[0].lstrip(b"^")
91 name = k.split(b"|")[0].lstrip(b"^")
92 if not entry[0].__doc__:
92 if not entry[0].__doc__:
93 ui.notenoi18n(
93 ui.notenoi18n(
94 'skip checking %s: no help document\n' % (namefmt % name)
94 'skip checking %s: no help document\n' % (namefmt % name)
95 )
95 )
96 continue
96 continue
97 errorcnt += checkseclevel(
97 errorcnt += checkseclevel(
98 ui, entry[0].__doc__, namefmt % name, initlevel
98 ui, entry[0].__doc__, namefmt % name, initlevel
99 )
99 )
100 return errorcnt
100 return errorcnt
101
101
102
102
103 def checkhghelps(ui):
103 def checkhghelps(ui):
104 errorcnt = 0
104 errorcnt = 0
105 for h in helptable:
105 for h in helptable:
106 names, sec, doc = h[0:3]
106 names, sec, doc = h[0:3]
107 if callable(doc):
107 if callable(doc):
108 doc = doc(ui)
108 doc = doc(ui)
109 errorcnt += checkseclevel(
109 errorcnt += checkseclevel(
110 ui, doc, '%s help topic' % names[0], initlevel_topic
110 ui, doc, '%s help topic' % names[0], initlevel_topic
111 )
111 )
112
112
113 errorcnt += checkcmdtable(ui, table, '%s command', initlevel_cmd)
113 errorcnt += checkcmdtable(ui, table, '%s command', initlevel_cmd)
114
114
115 for name in sorted(
115 for name in sorted(
116 list(extensions.enabled()) + list(extensions.disabled())
116 list(extensions.enabled()) + list(extensions.disabled())
117 ):
117 ):
118 mod = extensions.load(ui, name, None)
118 mod = extensions.load(ui, name, None)
119 if not mod.__doc__:
119 if not mod.__doc__:
120 ui.notenoi18n(
120 ui.notenoi18n(
121 'skip checking %s extension: no help document\n' % name
121 'skip checking %s extension: no help document\n' % name
122 )
122 )
123 continue
123 continue
124 errorcnt += checkseclevel(
124 errorcnt += checkseclevel(
125 ui, mod.__doc__, '%s extension' % name, initlevel_ext
125 ui, mod.__doc__, '%s extension' % name, initlevel_ext
126 )
126 )
127
127
128 cmdtable = getattr(mod, 'cmdtable', None)
128 cmdtable = getattr(mod, 'cmdtable', None)
129 if cmdtable:
129 if cmdtable:
130 errorcnt += checkcmdtable(
130 errorcnt += checkcmdtable(
131 ui,
131 ui,
132 cmdtable,
132 cmdtable,
133 '%%s command of %s extension' % name,
133 '%%s command of %s extension' % name,
134 initlevel_ext_cmd,
134 initlevel_ext_cmd,
135 )
135 )
136 return errorcnt
136 return errorcnt
137
137
138
138
139 def checkfile(ui, filename, initlevel):
139 def checkfile(ui, filename, initlevel):
140 if filename == '-':
140 if filename == '-':
141 filename = 'stdin'
141 filename = 'stdin'
142 doc = sys.stdin.read()
142 doc = sys.stdin.read()
143 else:
143 else:
144 with open(filename) as fp:
144 with open(filename) as fp:
145 doc = fp.read()
145 doc = fp.read()
146
146
147 ui.notenoi18n(
147 ui.notenoi18n(
148 'checking input from %s with initlevel %d\n' % (filename, initlevel)
148 'checking input from %s with initlevel %d\n' % (filename, initlevel)
149 )
149 )
150 return checkseclevel(ui, doc, 'input from %s' % filename, initlevel)
150 return checkseclevel(ui, doc, 'input from %s' % filename, initlevel)
151
151
152
152
153 def main():
153 def main():
154 optparser = optparse.OptionParser(
154 optparser = optparse.OptionParser(
155 """%prog [options]
155 """%prog [options]
156
156
157 This checks all help documents of Mercurial (topics, commands,
157 This checks all help documents of Mercurial (topics, commands,
158 extensions and commands of them), if no file is specified by --file
158 extensions and commands of them), if no file is specified by --file
159 option.
159 option.
160 """
160 """
161 )
161 )
162 optparser.add_option(
162 optparser.add_option(
163 "-v", "--verbose", help="enable additional output", action="store_true"
163 "-v", "--verbose", help="enable additional output", action="store_true"
164 )
164 )
165 optparser.add_option(
165 optparser.add_option(
166 "-d", "--debug", help="debug mode", action="store_true"
166 "-d", "--debug", help="debug mode", action="store_true"
167 )
167 )
168 optparser.add_option(
168 optparser.add_option(
169 "-f",
169 "-f",
170 "--file",
170 "--file",
171 help="filename to read in (or '-' for stdin)",
171 help="filename to read in (or '-' for stdin)",
172 action="store",
172 action="store",
173 default="",
173 default="",
174 )
174 )
175
175
176 optparser.add_option(
176 optparser.add_option(
177 "-t",
177 "-t",
178 "--topic",
178 "--topic",
179 help="parse file as help topic",
179 help="parse file as help topic",
180 action="store_const",
180 action="store_const",
181 dest="initlevel",
181 dest="initlevel",
182 const=0,
182 const=0,
183 )
183 )
184 optparser.add_option(
184 optparser.add_option(
185 "-c",
185 "-c",
186 "--command",
186 "--command",
187 help="parse file as help of core command",
187 help="parse file as help of core command",
188 action="store_const",
188 action="store_const",
189 dest="initlevel",
189 dest="initlevel",
190 const=1,
190 const=1,
191 )
191 )
192 optparser.add_option(
192 optparser.add_option(
193 "-e",
193 "-e",
194 "--extension",
194 "--extension",
195 help="parse file as help of extension",
195 help="parse file as help of extension",
196 action="store_const",
196 action="store_const",
197 dest="initlevel",
197 dest="initlevel",
198 const=1,
198 const=1,
199 )
199 )
200 optparser.add_option(
200 optparser.add_option(
201 "-C",
201 "-C",
202 "--extension-command",
202 "--extension-command",
203 help="parse file as help of extension command",
203 help="parse file as help of extension command",
204 action="store_const",
204 action="store_const",
205 dest="initlevel",
205 dest="initlevel",
206 const=3,
206 const=3,
207 )
207 )
208
208
209 optparser.add_option(
209 optparser.add_option(
210 "-l",
210 "-l",
211 "--initlevel",
211 "--initlevel",
212 help="set initial section level manually",
212 help="set initial section level manually",
213 action="store",
213 action="store",
214 type="int",
214 type="int",
215 default=0,
215 default=0,
216 )
216 )
217
217
218 (options, args) = optparser.parse_args()
218 (options, args) = optparser.parse_args()
219
219
220 ui = uimod.ui.load()
220 ui = uimod.ui.load()
221 ui.setconfig(b'ui', b'verbose', options.verbose, b'--verbose')
221 ui.setconfig(b'ui', b'verbose', options.verbose, b'--verbose')
222 ui.setconfig(b'ui', b'debug', options.debug, b'--debug')
222 ui.setconfig(b'ui', b'debug', options.debug, b'--debug')
223
223
224 if options.file:
224 if options.file:
225 if checkfile(ui, options.file, options.initlevel):
225 if checkfile(ui, options.file, options.initlevel):
226 sys.exit(1)
226 sys.exit(1)
227 else:
227 else:
228 if checkhghelps(ui):
228 if checkhghelps(ui):
229 sys.exit(1)
229 sys.exit(1)
230
230
231
231
232 if __name__ == "__main__":
232 if __name__ == "__main__":
233 main()
233 main()
General Comments 0
You need to be logged in to leave comments. Login now