##// END OF EJS Templates
check-code: replace heredocs in unified tests...
Idan Kamara -
r17711:cf204e98 default
parent child Browse files
Show More
@@ -1,453 +1,454
1 1 #!/usr/bin/env python
2 2 #
3 3 # check-code - a style and portability checker for Mercurial
4 4 #
5 5 # Copyright 2010 Matt Mackall <mpm@selenic.com>
6 6 #
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 10 import re, glob, os, sys
11 11 import keyword
12 12 import optparse
13 13
14 14 def repquote(m):
15 15 t = re.sub(r"\w", "x", m.group('text'))
16 16 t = re.sub(r"[^\s\nx]", "o", t)
17 17 return m.group('quote') + t + m.group('quote')
18 18
19 19 def reppython(m):
20 20 comment = m.group('comment')
21 21 if comment:
22 22 return "#" * len(comment)
23 23 return repquote(m)
24 24
25 25 def repcomment(m):
26 26 return m.group(1) + "#" * len(m.group(2))
27 27
28 28 def repccomment(m):
29 29 t = re.sub(r"((?<=\n) )|\S", "x", m.group(2))
30 30 return m.group(1) + t + "*/"
31 31
32 32 def repcallspaces(m):
33 33 t = re.sub(r"\n\s+", "\n", m.group(2))
34 34 return m.group(1) + t
35 35
36 36 def repinclude(m):
37 37 return m.group(1) + "<foo>"
38 38
39 39 def rephere(m):
40 40 t = re.sub(r"\S", "x", m.group(2))
41 41 return m.group(1) + t
42 42
43 43
44 44 testpats = [
45 45 [
46 46 (r'pushd|popd', "don't use 'pushd' or 'popd', use 'cd'"),
47 47 (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"),
48 48 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
49 49 (r'sed.*-i', "don't use 'sed -i', use a temporary file"),
50 50 (r'\becho\b.*\\n', "don't use 'echo \\n', use printf"),
51 51 (r'echo -n', "don't use 'echo -n', use printf"),
52 52 (r'(^| )wc[^|]*$\n(?!.*\(re\))', "filter wc output"),
53 53 (r'head -c', "don't use 'head -c', use 'dd'"),
54 54 (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
55 55 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
56 56 (r'printf.*\\([1-9]|0\d)', "don't use 'printf \NNN', use Python"),
57 57 (r'printf.*\\x', "don't use printf \\x, use Python"),
58 58 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
59 59 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
60 60 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
61 61 "use egrep for extended grep syntax"),
62 62 (r'/bin/', "don't use explicit paths for tools"),
63 63 (r'[^\n]\Z', "no trailing newline"),
64 64 (r'export.*=', "don't export and assign at once"),
65 65 (r'^source\b', "don't use 'source', use '.'"),
66 66 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
67 67 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
68 68 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
69 69 (r'^stop\(\)', "don't use 'stop' as a shell function name"),
70 70 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
71 71 (r'^alias\b.*=', "don't use alias, use a function"),
72 72 (r'if\s*!', "don't use '!' to negate exit status"),
73 73 (r'/dev/u?random', "don't use entropy, use /dev/zero"),
74 74 (r'do\s*true;\s*done', "don't use true as loop body, use sleep 0"),
75 75 (r'^( *)\t', "don't use tabs to indent"),
76 76 ],
77 77 # warnings
78 78 [
79 79 (r'^function', "don't use 'function', use old style"),
80 80 (r'^diff.*-\w*N', "don't use 'diff -N'"),
81 81 (r'\$PWD', "don't use $PWD, use `pwd`"),
82 82 (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\^', "^ must be quoted"),
83 83 ]
84 84 ]
85 85
86 86 testfilters = [
87 87 (r"( *)(#([^\n]*\S)?)", repcomment),
88 88 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
89 89 ]
90 90
91 91 uprefix = r"^ \$ "
92 92 utestpats = [
93 93 [
94 94 (r'^(\S.*|| [$>] .*)[ \t]\n', "trailing whitespace on non-output"),
95 95 (uprefix + r'.*\|\s*sed[^|>\n]*\n',
96 96 "use regex test output patterns instead of sed"),
97 97 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
98 98 (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"),
99 99 (uprefix + r'.*\|\| echo.*(fail|error)',
100 100 "explicit exit code checks unnecessary"),
101 101 (uprefix + r'set -e', "don't use set -e"),
102 102 (uprefix + r'\s', "don't indent commands, use > for continued lines"),
103 103 (r'^ saved backup bundle to \$TESTTMP.*\.hg$',
104 104 "use (glob) to match Windows paths too"),
105 105 ],
106 106 # warnings
107 107 []
108 108 ]
109 109
110 110 for i in [0, 1]:
111 111 for p, m in testpats[i]:
112 112 if p.startswith(r'^'):
113 113 p = r"^ [$>] (%s)" % p[1:]
114 114 else:
115 115 p = r"^ [$>] .*(%s)" % p
116 116 utestpats[i].append((p, m))
117 117
118 118 utestfilters = [
119 (r"<<(\S+)((.|\n)*?\n > \1)", rephere),
119 120 (r"( *)(#([^\n]*\S)?)", repcomment),
120 121 ]
121 122
122 123 pypats = [
123 124 [
124 125 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
125 126 "tuple parameter unpacking not available in Python 3+"),
126 127 (r'lambda\s*\(.*,.*\)',
127 128 "tuple parameter unpacking not available in Python 3+"),
128 129 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
129 130 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
130 131 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
131 132 (r'^\s*\t', "don't use tabs"),
132 133 (r'\S;\s*\n', "semicolon"),
133 134 (r'[^_]_\("[^"]+"\s*%', "don't use % inside _()"),
134 135 (r"[^_]_\('[^']+'\s*%", "don't use % inside _()"),
135 136 (r'\w,\w', "missing whitespace after ,"),
136 137 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
137 138 (r'^\s+\w+=\w+[^,)\n]$', "missing whitespace in assignment"),
138 139 (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n'
139 140 r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Python 2.4'),
140 141 (r'(\s+)try:\n((?:\n|\1\s.*\n)*?)\1\s*yield\b.*?'
141 142 r'((?:\n|\1\s.*\n)+?)\1finally:',
142 143 'no yield inside try/finally in Python 2.4'),
143 144 (r'.{81}', "line too long"),
144 145 (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
145 146 (r'[^\n]\Z', "no trailing newline"),
146 147 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
147 148 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=',
148 149 # "don't use underbars in identifiers"),
149 150 (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ',
150 151 "don't use camelcase in identifiers"),
151 152 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
152 153 "linebreak after :"),
153 154 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
154 155 (r'class\s[^( \n]+\(\):',
155 156 "class foo() not available in Python 2.4, use class foo(object)"),
156 157 (r'\b(%s)\(' % '|'.join(keyword.kwlist),
157 158 "Python keyword is not a function"),
158 159 (r',]', "unneeded trailing ',' in list"),
159 160 # (r'class\s[A-Z][^\(]*\((?!Exception)',
160 161 # "don't capitalize non-exception classes"),
161 162 # (r'in range\(', "use xrange"),
162 163 # (r'^\s*print\s+', "avoid using print in core and extensions"),
163 164 (r'[\x80-\xff]', "non-ASCII character literal"),
164 165 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
165 166 (r'^\s*with\s+', "with not available in Python 2.4"),
166 167 (r'\.isdisjoint\(', "set.isdisjoint not available in Python 2.4"),
167 168 (r'^\s*except.* as .*:', "except as not available in Python 2.4"),
168 169 (r'^\s*os\.path\.relpath', "relpath not available in Python 2.4"),
169 170 (r'(?<!def)\s+(any|all|format)\(',
170 171 "any/all/format not available in Python 2.4"),
171 172 (r'(?<!def)\s+(callable)\(',
172 173 "callable not available in Python 3, use getattr(f, '__call__', None)"),
173 174 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
174 175 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
175 176 "gratuitous whitespace after Python keyword"),
176 177 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
177 178 # (r'\s\s=', "gratuitous whitespace before ="),
178 179 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
179 180 "missing whitespace around operator"),
180 181 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\s',
181 182 "missing whitespace around operator"),
182 183 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
183 184 "missing whitespace around operator"),
184 185 (r'[^^+=*/!<>&| %-](\s=|=\s)[^= ]',
185 186 "wrong whitespace around ="),
186 187 (r'raise Exception', "don't raise generic exceptions"),
187 188 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
188 189 (r' [=!]=\s+(True|False|None)',
189 190 "comparison with singleton, use 'is' or 'is not' instead"),
190 191 (r'^\s*(while|if) [01]:',
191 192 "use True/False for constant Boolean expression"),
192 193 (r'(?:(?<!def)\s+|\()hasattr',
193 194 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
194 195 (r'opener\([^)]*\).read\(',
195 196 "use opener.read() instead"),
196 197 (r'BaseException', 'not in Python 2.4, use Exception'),
197 198 (r'os\.path\.relpath', 'os.path.relpath is not in Python 2.5'),
198 199 (r'opener\([^)]*\).write\(',
199 200 "use opener.write() instead"),
200 201 (r'[\s\(](open|file)\([^)]*\)\.read\(',
201 202 "use util.readfile() instead"),
202 203 (r'[\s\(](open|file)\([^)]*\)\.write\(',
203 204 "use util.readfile() instead"),
204 205 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
205 206 "always assign an opened file to a variable, and close it afterwards"),
206 207 (r'[\s\(](open|file)\([^)]*\)\.',
207 208 "always assign an opened file to a variable, and close it afterwards"),
208 209 (r'(?i)descendent', "the proper spelling is descendAnt"),
209 210 (r'\.debug\(\_', "don't mark debug messages for translation"),
210 211 (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"),
211 212 (r'^\s*except\s*:', "warning: naked except clause", r'#.*re-raises'),
212 213 (r':\n( )*( ){1,3}[^ ]', "must indent 4 spaces"),
213 214 ],
214 215 # warnings
215 216 [
216 217 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
217 218 "warning: unwrapped ui message"),
218 219 ]
219 220 ]
220 221
221 222 pyfilters = [
222 223 (r"""(?msx)(?P<comment>\#.*?$)|
223 224 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
224 225 (?P<text>(([^\\]|\\.)*?))
225 226 (?P=quote))""", reppython),
226 227 ]
227 228
228 229 cpats = [
229 230 [
230 231 (r'//', "don't use //-style comments"),
231 232 (r'^ ', "don't use spaces to indent"),
232 233 (r'\S\t', "don't use tabs except for indent"),
233 234 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
234 235 (r'.{81}', "line too long"),
235 236 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
236 237 (r'return\(', "return is not a function"),
237 238 (r' ;', "no space before ;"),
238 239 (r'\w+\* \w+', "use int *foo, not int* foo"),
239 240 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
240 241 (r'\w+ (\+\+|--)', "use foo++, not foo ++"),
241 242 (r'\w,\w', "missing whitespace after ,"),
242 243 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
243 244 (r'^#\s+\w', "use #foo, not # foo"),
244 245 (r'[^\n]\Z', "no trailing newline"),
245 246 (r'^\s*#import\b', "use only #include in standard C code"),
246 247 ],
247 248 # warnings
248 249 []
249 250 ]
250 251
251 252 cfilters = [
252 253 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
253 254 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
254 255 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
255 256 (r'(\()([^)]+\))', repcallspaces),
256 257 ]
257 258
258 259 inutilpats = [
259 260 [
260 261 (r'\bui\.', "don't use ui in util"),
261 262 ],
262 263 # warnings
263 264 []
264 265 ]
265 266
266 267 inrevlogpats = [
267 268 [
268 269 (r'\brepo\.', "don't use repo in revlog"),
269 270 ],
270 271 # warnings
271 272 []
272 273 ]
273 274
274 275 checks = [
275 276 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
276 277 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
277 278 ('c', r'.*\.c$', cfilters, cpats),
278 279 ('unified test', r'.*\.t$', utestfilters, utestpats),
279 280 ('layering violation repo in revlog', r'mercurial/revlog\.py', pyfilters,
280 281 inrevlogpats),
281 282 ('layering violation ui in util', r'mercurial/util\.py', pyfilters,
282 283 inutilpats),
283 284 ]
284 285
285 286 class norepeatlogger(object):
286 287 def __init__(self):
287 288 self._lastseen = None
288 289
289 290 def log(self, fname, lineno, line, msg, blame):
290 291 """print error related a to given line of a given file.
291 292
292 293 The faulty line will also be printed but only once in the case
293 294 of multiple errors.
294 295
295 296 :fname: filename
296 297 :lineno: line number
297 298 :line: actual content of the line
298 299 :msg: error message
299 300 """
300 301 msgid = fname, lineno, line
301 302 if msgid != self._lastseen:
302 303 if blame:
303 304 print "%s:%d (%s):" % (fname, lineno, blame)
304 305 else:
305 306 print "%s:%d:" % (fname, lineno)
306 307 print " > %s" % line
307 308 self._lastseen = msgid
308 309 print " " + msg
309 310
310 311 _defaultlogger = norepeatlogger()
311 312
312 313 def getblame(f):
313 314 lines = []
314 315 for l in os.popen('hg annotate -un %s' % f):
315 316 start, line = l.split(':', 1)
316 317 user, rev = start.split()
317 318 lines.append((line[1:-1], user, rev))
318 319 return lines
319 320
320 321 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
321 322 blame=False, debug=False, lineno=True):
322 323 """checks style and portability of a given file
323 324
324 325 :f: filepath
325 326 :logfunc: function used to report error
326 327 logfunc(filename, linenumber, linecontent, errormessage)
327 328 :maxerr: number of error to display before aborting.
328 329 Set to false (default) to report all errors
329 330
330 331 return True if no error is found, False otherwise.
331 332 """
332 333 blamecache = None
333 334 result = True
334 335 for name, match, filters, pats in checks:
335 336 if debug:
336 337 print name, f
337 338 fc = 0
338 339 if not re.match(match, f):
339 340 if debug:
340 341 print "Skipping %s for %s it doesn't match %s" % (
341 342 name, match, f)
342 343 continue
343 344 fp = open(f)
344 345 pre = post = fp.read()
345 346 fp.close()
346 347 if "no-" + "check-code" in pre:
347 348 if debug:
348 349 print "Skipping %s for %s it has no- and check-code" % (
349 350 name, f)
350 351 break
351 352 for p, r in filters:
352 353 post = re.sub(p, r, post)
353 354 if warnings:
354 355 pats = pats[0] + pats[1]
355 356 else:
356 357 pats = pats[0]
357 358 # print post # uncomment to show filtered version
358 359
359 360 if debug:
360 361 print "Checking %s for %s" % (name, f)
361 362
362 363 prelines = None
363 364 errors = []
364 365 for pat in pats:
365 366 if len(pat) == 3:
366 367 p, msg, ignore = pat
367 368 else:
368 369 p, msg = pat
369 370 ignore = None
370 371
371 372 # fix-up regexes for multi-line searches
372 373 po = p
373 374 # \s doesn't match \n
374 375 p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
375 376 # [^...] doesn't match newline
376 377 p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
377 378
378 379 #print po, '=>', p
379 380
380 381 pos = 0
381 382 n = 0
382 383 for m in re.finditer(p, post, re.MULTILINE):
383 384 if prelines is None:
384 385 prelines = pre.splitlines()
385 386 postlines = post.splitlines(True)
386 387
387 388 start = m.start()
388 389 while n < len(postlines):
389 390 step = len(postlines[n])
390 391 if pos + step > start:
391 392 break
392 393 pos += step
393 394 n += 1
394 395 l = prelines[n]
395 396
396 397 if "check-code" + "-ignore" in l:
397 398 if debug:
398 399 print "Skipping %s for %s:%s (check-code -ignore)" % (
399 400 name, f, n)
400 401 continue
401 402 elif ignore and re.search(ignore, l, re.MULTILINE):
402 403 continue
403 404 bd = ""
404 405 if blame:
405 406 bd = 'working directory'
406 407 if not blamecache:
407 408 blamecache = getblame(f)
408 409 if n < len(blamecache):
409 410 bl, bu, br = blamecache[n]
410 411 if bl == l:
411 412 bd = '%s@%s' % (bu, br)
412 413 errors.append((f, lineno and n + 1, l, msg, bd))
413 414 result = False
414 415
415 416 errors.sort()
416 417 for e in errors:
417 418 logfunc(*e)
418 419 fc += 1
419 420 if maxerr and fc >= maxerr:
420 421 print " (too many errors, giving up)"
421 422 break
422 423
423 424 return result
424 425
425 426 if __name__ == "__main__":
426 427 parser = optparse.OptionParser("%prog [options] [files]")
427 428 parser.add_option("-w", "--warnings", action="store_true",
428 429 help="include warning-level checks")
429 430 parser.add_option("-p", "--per-file", type="int",
430 431 help="max warnings per file")
431 432 parser.add_option("-b", "--blame", action="store_true",
432 433 help="use annotate to generate blame info")
433 434 parser.add_option("", "--debug", action="store_true",
434 435 help="show debug information")
435 436 parser.add_option("", "--nolineno", action="store_false",
436 437 dest='lineno', help="don't show line numbers")
437 438
438 439 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
439 440 lineno=True)
440 441 (options, args) = parser.parse_args()
441 442
442 443 if len(args) == 0:
443 444 check = glob.glob("*")
444 445 else:
445 446 check = args
446 447
447 448 ret = 0
448 449 for f in check:
449 450 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
450 451 blame=options.blame, debug=options.debug,
451 452 lineno=options.lineno):
452 453 ret = 1
453 454 sys.exit(ret)
@@ -1,183 +1,170
1 1 $ check_code="$TESTDIR"/../contrib/check-code.py
2 2 $ cd "$TESTDIR"/..
3 3 $ if hg identify -q > /dev/null; then :
4 4 > else
5 5 > echo "skipped: not a Mercurial working dir" >&2
6 6 > exit 80
7 7 > fi
8 8 $ hg manifest | xargs "$check_code" || echo 'FAILURE IS NOT AN OPTION!!!'
9 9
10 10 $ hg manifest | xargs "$check_code" --warnings --nolineno --per-file=0 || true
11 11 hgext/convert/cvsps.py:0:
12 12 > ui.write('Ancestors: %s\n' % (','.join(r)))
13 13 warning: unwrapped ui message
14 14 hgext/convert/cvsps.py:0:
15 15 > ui.write('Parent: %d\n' % cs.parents[0].id)
16 16 warning: unwrapped ui message
17 17 hgext/convert/cvsps.py:0:
18 18 > ui.write('Parents: %s\n' %
19 19 warning: unwrapped ui message
20 20 hgext/convert/cvsps.py:0:
21 21 > ui.write('Branchpoints: %s \n' % ', '.join(branchpoints))
22 22 warning: unwrapped ui message
23 23 hgext/convert/cvsps.py:0:
24 24 > ui.write('Author: %s\n' % cs.author)
25 25 warning: unwrapped ui message
26 26 hgext/convert/cvsps.py:0:
27 27 > ui.write('Branch: %s\n' % (cs.branch or 'HEAD'))
28 28 warning: unwrapped ui message
29 29 hgext/convert/cvsps.py:0:
30 30 > ui.write('Date: %s\n' % util.datestr(cs.date,
31 31 warning: unwrapped ui message
32 32 hgext/convert/cvsps.py:0:
33 33 > ui.write('Log:\n')
34 34 warning: unwrapped ui message
35 35 hgext/convert/cvsps.py:0:
36 36 > ui.write('Members: \n')
37 37 warning: unwrapped ui message
38 38 hgext/convert/cvsps.py:0:
39 39 > ui.write('PatchSet %d \n' % cs.id)
40 40 warning: unwrapped ui message
41 41 hgext/convert/cvsps.py:0:
42 42 > ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags) > 1],
43 43 warning: unwrapped ui message
44 44 hgext/hgk.py:0:
45 45 > ui.write("parent %s\n" % p)
46 46 warning: unwrapped ui message
47 47 hgext/hgk.py:0:
48 48 > ui.write('k=%s\nv=%s\n' % (name, value))
49 49 warning: unwrapped ui message
50 50 hgext/hgk.py:0:
51 51 > ui.write("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1]))
52 52 warning: unwrapped ui message
53 53 hgext/hgk.py:0:
54 54 > ui.write("branch %s\n\n" % ctx.branch())
55 55 warning: unwrapped ui message
56 56 hgext/hgk.py:0:
57 57 > ui.write("committer %s %s %s\n" % (committer, int(date[0]), date[1]))
58 58 warning: unwrapped ui message
59 59 hgext/hgk.py:0:
60 60 > ui.write("revision %d\n" % ctx.rev())
61 61 warning: unwrapped ui message
62 62 hgext/hgk.py:0:
63 63 > ui.write("tree %s\n" % short(ctx.changeset()[0]))
64 64 warning: unwrapped ui message
65 65 hgext/mq.py:0:
66 66 > ui.write("mq: %s\n" % ', '.join(m))
67 67 warning: unwrapped ui message
68 68 hgext/patchbomb.py:0:
69 69 > ui.write('Subject: %s\n' % subj)
70 70 warning: unwrapped ui message
71 71 hgext/patchbomb.py:0:
72 72 > ui.write('From: %s\n' % sender)
73 73 warning: unwrapped ui message
74 74 mercurial/commands.py:0:
75 75 > ui.note('branch %s\n' % data)
76 76 warning: unwrapped ui message
77 77 mercurial/commands.py:0:
78 78 > ui.note('node %s\n' % str(data))
79 79 warning: unwrapped ui message
80 80 mercurial/commands.py:0:
81 81 > ui.note('tag %s\n' % name)
82 82 warning: unwrapped ui message
83 83 mercurial/commands.py:0:
84 84 > ui.write("unpruned common: %s\n" % " ".join([short(n)
85 85 warning: unwrapped ui message
86 86 mercurial/commands.py:0:
87 87 > ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
88 88 warning: unwrapped ui message
89 89 mercurial/commands.py:0:
90 90 > ui.write("local is subset\n")
91 91 warning: unwrapped ui message
92 92 mercurial/commands.py:0:
93 93 > ui.write("remote is subset\n")
94 94 warning: unwrapped ui message
95 95 mercurial/commands.py:0:
96 96 > ui.write('deltas against other : ' + fmt % pcfmt(numother,
97 97 warning: unwrapped ui message
98 98 mercurial/commands.py:0:
99 99 > ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
100 100 warning: unwrapped ui message
101 101 mercurial/commands.py:0:
102 102 > ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
103 103 warning: unwrapped ui message
104 104 mercurial/commands.py:0:
105 105 > ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
106 106 warning: unwrapped ui message
107 107 mercurial/commands.py:0:
108 108 > ui.write("match: %s\n" % m(d[0]))
109 109 warning: unwrapped ui message
110 110 mercurial/commands.py:0:
111 111 > ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
112 112 warning: unwrapped ui message
113 113 mercurial/commands.py:0:
114 114 > ui.write('path %s\n' % k)
115 115 warning: unwrapped ui message
116 116 mercurial/commands.py:0:
117 117 > ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
118 118 warning: unwrapped ui message
119 119 mercurial/commands.py:0:
120 120 > ui.write("digraph G {\n")
121 121 warning: unwrapped ui message
122 122 mercurial/commands.py:0:
123 123 > ui.write("internal: %s %s\n" % d)
124 124 warning: unwrapped ui message
125 125 mercurial/commands.py:0:
126 126 > ui.write("standard: %s\n" % util.datestr(d))
127 127 warning: unwrapped ui message
128 128 mercurial/commands.py:0:
129 129 > ui.write('avg chain length : ' + fmt % avgchainlen)
130 130 warning: unwrapped ui message
131 131 mercurial/commands.py:0:
132 132 > ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
133 133 warning: unwrapped ui message
134 134 mercurial/commands.py:0:
135 135 > ui.write('compression ratio : ' + fmt % compratio)
136 136 warning: unwrapped ui message
137 137 mercurial/commands.py:0:
138 138 > ui.write('delta size (min/max/avg) : %d / %d / %d\n'
139 139 warning: unwrapped ui message
140 140 mercurial/commands.py:0:
141 141 > ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
142 142 warning: unwrapped ui message
143 143 mercurial/commands.py:0:
144 144 > ui.write('flags : %s\n' % ', '.join(flags))
145 145 warning: unwrapped ui message
146 146 mercurial/commands.py:0:
147 147 > ui.write('format : %d\n' % format)
148 148 warning: unwrapped ui message
149 149 mercurial/commands.py:0:
150 150 > ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
151 151 warning: unwrapped ui message
152 152 mercurial/commands.py:0:
153 153 > ui.write('revision size : ' + fmt2 % totalsize)
154 154 warning: unwrapped ui message
155 155 mercurial/commands.py:0:
156 156 > ui.write('revisions : ' + fmt2 % numrevs)
157 157 warning: unwrapped ui message
158 158 warning: unwrapped ui message
159 159 mercurial/commands.py:0:
160 160 > ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
161 161 warning: unwrapped ui message
162 162 tests/autodiff.py:0:
163 163 > ui.write('data lost for: %s\n' % fn)
164 164 warning: unwrapped ui message
165 tests/test-convert-mtn.t:0:
166 > > function get_passphrase(keypair_id)
167 don't use 'function', use old style
168 tests/test-import-git.t:0:
169 > > Mc\${NkU|\`?^000jF3jhEB
170 ^ must be quoted
171 tests/test-import.t:0:
172 > > diff -Naur proj-orig/foo proj-new/foo
173 don't use 'diff -N'
174 don't use 'diff -N'
175 tests/test-schemes.t:0:
176 > > z = file:\$PWD/
177 don't use $PWD, use `pwd`
178 165 tests/test-ui-color.py:0:
179 166 > testui.warn('warning\n')
180 167 warning: unwrapped ui message
181 168 tests/test-ui-color.py:0:
182 169 > testui.write('buffered\n')
183 170 warning: unwrapped ui message
General Comments 0
You need to be logged in to leave comments. Login now