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