comparison contrib/check-code.py @ 10895:217557b26bc7

check-code: add a warnings level - demote "unwrapped ui message"
author Matt Mackall <mpm@selenic.com>
date Mon, 12 Apr 2010 17:41:32 -0700
parents cd0c49bdbfd9
children 13a1b2fb7ef2
comparison
equal deleted inserted replaced
10894:26cf11f9f322 10895:217557b26bc7
6 # 6 #
7 # This software may be used and distributed according to the terms of the 7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version. 8 # GNU General Public License version 2 or any later version.
9 9
10 import sys, re, glob 10 import sys, re, glob
11 import optparse
11 12
12 def repquote(m): 13 def repquote(m):
13 t = re.sub(r"\w", "x", m.group('text')) 14 t = re.sub(r"\w", "x", m.group('text'))
14 t = re.sub(r"[^\sx]", "o", t) 15 t = re.sub(r"[^\sx]", "o", t)
15 return m.group('quote') + t + m.group('quote') 16 return m.group('quote') + t + m.group('quote')
97 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"), 98 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"),
98 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\s', "missing whitespace around operator"), 99 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\s', "missing whitespace around operator"),
99 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"), 100 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"),
100 (r'[^+=*!<>&| -](\s=|=\s)[^= ]', "wrong whitespace around ="), 101 (r'[^+=*!<>&| -](\s=|=\s)[^= ]', "wrong whitespace around ="),
101 (r'raise Exception', "don't raise generic exceptions"), 102 (r'raise Exception', "don't raise generic exceptions"),
102 (r'ui\.(status|progress|write|note)\([\'\"]x', "unwrapped ui message"), 103 (r'ui\.(status|progress|write|note)\([\'\"]x',
104 "warning: unwrapped ui message"),
103 ] 105 ]
104 106
105 pyfilters = [ 107 pyfilters = [
106 (r"""(?msx)(?P<comment>\#.*?$)| 108 (r"""(?msx)(?P<comment>\#.*?$)|
107 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!"))) 109 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
162 self._lastseen = msgid 164 self._lastseen = msgid
163 print " " + msg 165 print " " + msg
164 166
165 _defaultlogger = norepeatlogger() 167 _defaultlogger = norepeatlogger()
166 168
167 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None): 169 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False):
168 """checks style and portability of a given file 170 """checks style and portability of a given file
169 171
170 :f: filepath 172 :f: filepath
171 :logfunc: function used to report error 173 :logfunc: function used to report error
172 logfunc(filename, linenumber, linecontent, errormessage) 174 logfunc(filename, linenumber, linecontent, errormessage)
189 z = enumerate(zip(pre.splitlines(), post.splitlines(True))) 191 z = enumerate(zip(pre.splitlines(), post.splitlines(True)))
190 for n, l in z: 192 for n, l in z:
191 if "check-code" + "-ignore" in l[0]: 193 if "check-code" + "-ignore" in l[0]:
192 continue 194 continue
193 for p, msg in pats: 195 for p, msg in pats:
196 if not warnings and msg.startswith("warning"):
197 continue
194 if re.search(p, l[1]): 198 if re.search(p, l[1]):
195 logfunc(f, n + 1, l[0], msg) 199 logfunc(f, n + 1, l[0], msg)
196 fc += 1 200 fc += 1
197 result = False 201 result = False
198 if maxerr is not None and fc >= maxerr: 202 if maxerr is not None and fc >= maxerr:
201 break 205 break
202 return result 206 return result
203 207
204 208
205 if __name__ == "__main__": 209 if __name__ == "__main__":
206 if len(sys.argv) == 1: 210 parser = optparse.OptionParser("%prog [options] [files]")
211 parser.add_option("-w", "--warnings", action="store_true",
212 help="include warning-level checks")
213 parser.add_option("-p", "--per-file", type="int",
214 help="max warnings per file")
215
216 parser.set_defaults(per_file=15, warnings=False)
217 (options, args) = parser.parse_args()
218
219 if len(args) == 0:
207 check = glob.glob("*") 220 check = glob.glob("*")
208 else: 221 else:
209 check = sys.argv[1:] 222 check = args
210 223
211 for f in check: 224 for f in check:
212 checkfile(f, maxerr=15) 225 checkfile(f, maxerr=options.per_file, warnings=options.warnings)