##// END OF EJS Templates
check-code: add --blame switch
Matt Mackall -
r11604:c5d40818 default
parent child Browse files
Show More
@@ -7,7 +7,7 b''
7 7 # This software may be used and distributed according to the terms of the
8 8 # GNU General Public License version 2 or any later version.
9 9
10 import re, glob
10 import re, glob, os
11 11 import optparse
12 12
13 13 def repquote(m):
@@ -160,7 +160,7 b' class norepeatlogger(object):'
160 160 def __init__(self):
161 161 self._lastseen = None
162 162
163 def log(self, fname, lineno, line, msg):
163 def log(self, fname, lineno, line, msg, blame):
164 164 """print error related a to given line of a given file.
165 165
166 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 174 msgid = fname, lineno, line
175 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 180 print " > %s" % line
178 181 self._lastseen = msgid
179 182 print " " + msg
180 183
181 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 196 """checks style and portability of a given file
185 197
186 198 :f: filepath
@@ -191,6 +203,7 b' def checkfile(f, logfunc=_defaultlogger.'
191 203
192 204 return True if no error is found, False otherwise.
193 205 """
206 blamecache = None
194 207 result = True
195 208 for name, match, filters, pats in checks:
196 209 fc = 0
@@ -210,7 +223,16 b' def checkfile(f, logfunc=_defaultlogger.'
210 223 if not warnings and msg.startswith("warning"):
211 224 continue
212 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 236 fc += 1
215 237 result = False
216 238 if maxerr is not None and fc >= maxerr:
@@ -219,15 +241,16 b' def checkfile(f, logfunc=_defaultlogger.'
219 241 break
220 242 return result
221 243
222
223 244 if __name__ == "__main__":
224 245 parser = optparse.OptionParser("%prog [options] [files]")
225 246 parser.add_option("-w", "--warnings", action="store_true",
226 247 help="include warning-level checks")
227 248 parser.add_option("-p", "--per-file", type="int",
228 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 254 (options, args) = parser.parse_args()
232 255
233 256 if len(args) == 0:
@@ -236,4 +259,5 b' if __name__ == "__main__":'
236 259 check = args
237 260
238 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