Show More
@@ -7,7 +7,7 b'' | |||||
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 re, glob |
|
10 | import re, glob, os | |
11 | import optparse |
|
11 | import optparse | |
12 |
|
12 | |||
13 | def repquote(m): |
|
13 | def repquote(m): | |
@@ -160,7 +160,7 b' class norepeatlogger(object):' | |||||
160 | def __init__(self): |
|
160 | def __init__(self): | |
161 | self._lastseen = None |
|
161 | self._lastseen = None | |
162 |
|
162 | |||
163 | def log(self, fname, lineno, line, msg): |
|
163 | def log(self, fname, lineno, line, msg, blame): | |
164 | """print error related a to given line of a given file. |
|
164 | """print error related a to given line of a given file. | |
165 |
|
165 | |||
166 | The faulty line will also be printed but only once in the case |
|
166 | The faulty line will also be printed but only once in the case | |
@@ -173,14 +173,26 b' class norepeatlogger(object):' | |||||
173 | """ |
|
173 | """ | |
174 | msgid = fname, lineno, line |
|
174 | msgid = fname, lineno, line | |
175 | if msgid != self._lastseen: |
|
175 | if msgid != self._lastseen: | |
176 | print "%s:%d:" % (fname, lineno) |
|
176 | if blame: | |
|
177 | print "%s:%d (%s):" % (fname, lineno, blame) | |||
|
178 | else: | |||
|
179 | print "%s:%d:" % (fname, lineno) | |||
177 | print " > %s" % line |
|
180 | print " > %s" % line | |
178 | self._lastseen = msgid |
|
181 | self._lastseen = msgid | |
179 | print " " + msg |
|
182 | print " " + msg | |
180 |
|
183 | |||
181 | _defaultlogger = norepeatlogger() |
|
184 | _defaultlogger = norepeatlogger() | |
182 |
|
185 | |||
183 | def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False): |
|
186 | def getblame(f): | |
|
187 | lines = [] | |||
|
188 | for l in os.popen('hg annotate -un %s' % f): | |||
|
189 | start, line = l.split(':', 1) | |||
|
190 | user, rev = start.split() | |||
|
191 | lines.append((line[1:-1], user, rev)) | |||
|
192 | return lines | |||
|
193 | ||||
|
194 | def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False, | |||
|
195 | blame=False): | |||
184 | """checks style and portability of a given file |
|
196 | """checks style and portability of a given file | |
185 |
|
197 | |||
186 | :f: filepath |
|
198 | :f: filepath | |
@@ -191,6 +203,7 b' def checkfile(f, logfunc=_defaultlogger.' | |||||
191 |
|
203 | |||
192 | return True if no error is found, False otherwise. |
|
204 | return True if no error is found, False otherwise. | |
193 | """ |
|
205 | """ | |
|
206 | blamecache = None | |||
194 | result = True |
|
207 | result = True | |
195 | for name, match, filters, pats in checks: |
|
208 | for name, match, filters, pats in checks: | |
196 | fc = 0 |
|
209 | fc = 0 | |
@@ -210,7 +223,16 b' def checkfile(f, logfunc=_defaultlogger.' | |||||
210 | if not warnings and msg.startswith("warning"): |
|
223 | if not warnings and msg.startswith("warning"): | |
211 | continue |
|
224 | continue | |
212 | if re.search(p, l[1]): |
|
225 | if re.search(p, l[1]): | |
213 | logfunc(f, n + 1, l[0], msg) |
|
226 | bd = "" | |
|
227 | if blame: | |||
|
228 | bd = 'working directory' | |||
|
229 | if not blamecache: | |||
|
230 | blamecache = getblame(f) | |||
|
231 | if n < len(blamecache): | |||
|
232 | bl, bu, br = blamecache[n] | |||
|
233 | if bl == l[0]: | |||
|
234 | bd = '%s@%s' % (bu, br) | |||
|
235 | logfunc(f, n + 1, l[0], msg, bd) | |||
214 | fc += 1 |
|
236 | fc += 1 | |
215 | result = False |
|
237 | result = False | |
216 | if maxerr is not None and fc >= maxerr: |
|
238 | if maxerr is not None and fc >= maxerr: | |
@@ -219,15 +241,16 b' def checkfile(f, logfunc=_defaultlogger.' | |||||
219 | break |
|
241 | break | |
220 | return result |
|
242 | return result | |
221 |
|
243 | |||
222 |
|
||||
223 | if __name__ == "__main__": |
|
244 | if __name__ == "__main__": | |
224 | parser = optparse.OptionParser("%prog [options] [files]") |
|
245 | parser = optparse.OptionParser("%prog [options] [files]") | |
225 | parser.add_option("-w", "--warnings", action="store_true", |
|
246 | parser.add_option("-w", "--warnings", action="store_true", | |
226 | help="include warning-level checks") |
|
247 | help="include warning-level checks") | |
227 | parser.add_option("-p", "--per-file", type="int", |
|
248 | parser.add_option("-p", "--per-file", type="int", | |
228 | help="max warnings per file") |
|
249 | help="max warnings per file") | |
|
250 | parser.add_option("-b", "--blame", action="store_true", | |||
|
251 | help="use annotate to generate blame info") | |||
229 |
|
252 | |||
230 | parser.set_defaults(per_file=15, warnings=False) |
|
253 | parser.set_defaults(per_file=15, warnings=False, blame=False) | |
231 | (options, args) = parser.parse_args() |
|
254 | (options, args) = parser.parse_args() | |
232 |
|
255 | |||
233 | if len(args) == 0: |
|
256 | if len(args) == 0: | |
@@ -236,4 +259,5 b' if __name__ == "__main__":' | |||||
236 | check = args |
|
259 | check = args | |
237 |
|
260 | |||
238 | for f in check: |
|
261 | for f in check: | |
239 |
checkfile(f, maxerr=options.per_file, warnings=options.warnings |
|
262 | checkfile(f, maxerr=options.per_file, warnings=options.warnings, | |
|
263 | blame=options.blame) |
General Comments 0
You need to be logged in to leave comments.
Login now