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