##// END OF EJS Templates
check-seclevel: use a context manager for file I/O
Bryan O'Sullivan -
r27770:1b8c7d59 default
parent child Browse files
Show More
@@ -1,168 +1,165 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(ui, name, None)
90 mod = extensions.load(ui, 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 with open(filename) as fp:
111 try:
112 doc = fp.read()
111 doc = fp.read()
113 finally:
114 fp.close()
115
112
116 ui.note(('checking input from %s with initlevel %d\n') %
113 ui.note(('checking input from %s with initlevel %d\n') %
117 (filename, initlevel))
114 (filename, initlevel))
118 return checkseclevel(ui, doc, 'input from %s' % filename, initlevel)
115 return checkseclevel(ui, doc, 'input from %s' % filename, initlevel)
119
116
120 def main():
117 def main():
121 optparser = optparse.OptionParser("""%prog [options]
118 optparser = optparse.OptionParser("""%prog [options]
122
119
123 This checks all help documents of Mercurial (topics, commands,
120 This checks all help documents of Mercurial (topics, commands,
124 extensions and commands of them), if no file is specified by --file
121 extensions and commands of them), if no file is specified by --file
125 option.
122 option.
126 """)
123 """)
127 optparser.add_option("-v", "--verbose",
124 optparser.add_option("-v", "--verbose",
128 help="enable additional output",
125 help="enable additional output",
129 action="store_true")
126 action="store_true")
130 optparser.add_option("-d", "--debug",
127 optparser.add_option("-d", "--debug",
131 help="debug mode",
128 help="debug mode",
132 action="store_true")
129 action="store_true")
133 optparser.add_option("-f", "--file",
130 optparser.add_option("-f", "--file",
134 help="filename to read in (or '-' for stdin)",
131 help="filename to read in (or '-' for stdin)",
135 action="store", default="")
132 action="store", default="")
136
133
137 optparser.add_option("-t", "--topic",
134 optparser.add_option("-t", "--topic",
138 help="parse file as help topic",
135 help="parse file as help topic",
139 action="store_const", dest="initlevel", const=0)
136 action="store_const", dest="initlevel", const=0)
140 optparser.add_option("-c", "--command",
137 optparser.add_option("-c", "--command",
141 help="parse file as help of core command",
138 help="parse file as help of core command",
142 action="store_const", dest="initlevel", const=1)
139 action="store_const", dest="initlevel", const=1)
143 optparser.add_option("-e", "--extension",
140 optparser.add_option("-e", "--extension",
144 help="parse file as help of extension",
141 help="parse file as help of extension",
145 action="store_const", dest="initlevel", const=1)
142 action="store_const", dest="initlevel", const=1)
146 optparser.add_option("-C", "--extension-command",
143 optparser.add_option("-C", "--extension-command",
147 help="parse file as help of extension command",
144 help="parse file as help of extension command",
148 action="store_const", dest="initlevel", const=3)
145 action="store_const", dest="initlevel", const=3)
149
146
150 optparser.add_option("-l", "--initlevel",
147 optparser.add_option("-l", "--initlevel",
151 help="set initial section level manually",
148 help="set initial section level manually",
152 action="store", type="int", default=0)
149 action="store", type="int", default=0)
153
150
154 (options, args) = optparser.parse_args()
151 (options, args) = optparser.parse_args()
155
152
156 ui = uimod.ui()
153 ui = uimod.ui()
157 ui.setconfig('ui', 'verbose', options.verbose, '--verbose')
154 ui.setconfig('ui', 'verbose', options.verbose, '--verbose')
158 ui.setconfig('ui', 'debug', options.debug, '--debug')
155 ui.setconfig('ui', 'debug', options.debug, '--debug')
159
156
160 if options.file:
157 if options.file:
161 if checkfile(ui, options.file, options.initlevel):
158 if checkfile(ui, options.file, options.initlevel):
162 sys.exit(1)
159 sys.exit(1)
163 else:
160 else:
164 if checkhghelps(ui):
161 if checkhghelps(ui):
165 sys.exit(1)
162 sys.exit(1)
166
163
167 if __name__ == "__main__":
164 if __name__ == "__main__":
168 main()
165 main()
General Comments 0
You need to be logged in to leave comments. Login now