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