comparison contrib/check-code.py @ 41826:867883d454ea

contrib: make check-code.py check code fragments embedded in test scripts
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Fri, 01 Mar 2019 02:53:09 +0900
parents 6d6bd9039ecd
children 4257c33e24b7
comparison
equal deleted inserted replaced
41825:6d6bd9039ecd 41826:867883d454ea
37 xrange = range 37 xrange = range
38 try: 38 try:
39 import re2 39 import re2
40 except ImportError: 40 except ImportError:
41 re2 = None 41 re2 = None
42
43 import testparseutil
42 44
43 def compilere(pat, multiline=False): 45 def compilere(pat, multiline=False):
44 if multiline: 46 if multiline:
45 pat = '(?m)' + pat 47 pat = '(?m)' + pat
46 if re2: 48 if re2:
400 # rules depending on implementation of repquote() 402 # rules depending on implementation of repquote()
401 (r'(^| )pp +xxxxqq[ \n][^\n]', "add two newlines after '.. note::'"), 403 (r'(^| )pp +xxxxqq[ \n][^\n]', "add two newlines after '.. note::'"),
402 ] + commonpypats[1] 404 ] + commonpypats[1]
403 ] 405 ]
404 406
407 # patterns to check *.py for embedded ones in test script
408 embeddedpypats = [
409 [
410 ] + commonpypats[0],
411 # warnings
412 [
413 ] + commonpypats[1]
414 ]
415
405 # common filters to convert *.py 416 # common filters to convert *.py
406 commonpyfilters = [ 417 commonpyfilters = [
407 (r"""(?msx)(?P<comment>\#.*?$)| 418 (r"""(?msx)(?P<comment>\#.*?$)|
408 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!"))) 419 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
409 (?P<text>(([^\\]|\\.)*?)) 420 (?P<text>(([^\\]|\\.)*?))
423 "use pycompat.isdarwin"), 434 "use pycompat.isdarwin"),
424 ], 435 ],
425 # warnings 436 # warnings
426 [], 437 [],
427 ] 438 ]
439
440 # filters to convert *.py for embedded ones in test script
441 embeddedpyfilters = [
442 ] + commonpyfilters
428 443
429 # extension non-filter patterns 444 # extension non-filter patterns
430 pyextnfpats = [ 445 pyextnfpats = [
431 [(r'^"""\n?[A-Z]', "don't capitalize docstring title")], 446 [(r'^"""\n?[A-Z]', "don't capitalize docstring title")],
432 # warnings 447 # warnings
558 webtemplatefilters, webtemplatepats), 573 webtemplatefilters, webtemplatepats),
559 ('all except for .po', r'.*(?<!\.po)$', '', 574 ('all except for .po', r'.*(?<!\.po)$', '',
560 allfilesfilters, allfilespats), 575 allfilesfilters, allfilespats),
561 ] 576 ]
562 577
578 # (desc,
579 # func to pick up embedded code fragments,
580 # list of patterns to convert target files
581 # list of patterns to detect errors/warnings)
582 embeddedchecks = [
583 ('embedded python',
584 testparseutil.pyembedded, embeddedpyfilters, embeddedpypats)
585 ]
586
563 def _preparepats(): 587 def _preparepats():
564 def preparefailandwarn(failandwarn): 588 def preparefailandwarn(failandwarn):
565 for pats in failandwarn: 589 for pats in failandwarn:
566 for i, pseq in enumerate(pats): 590 for i, pseq in enumerate(pats):
567 # fix-up regexes for multi-line searches 591 # fix-up regexes for multi-line searches
578 602
579 def preparefilters(filters): 603 def preparefilters(filters):
580 for i, flt in enumerate(filters): 604 for i, flt in enumerate(filters):
581 filters[i] = re.compile(flt[0]), flt[1] 605 filters[i] = re.compile(flt[0]), flt[1]
582 606
583 for cs in (checks,): 607 for cs in (checks, embeddedchecks):
584 for c in cs: 608 for c in cs:
585 failandwarn = c[-1] 609 failandwarn = c[-1]
586 preparefailandwarn(failandwarn) 610 preparefailandwarn(failandwarn)
587 611
588 filters = c[-2] 612 filters = c[-2]
671 695
672 fc = _checkfiledata(name, f, pre, filters, pats, context, 696 fc = _checkfiledata(name, f, pre, filters, pats, context,
673 logfunc, maxerr, warnings, blame, debug, lineno) 697 logfunc, maxerr, warnings, blame, debug, lineno)
674 if fc: 698 if fc:
675 result = False 699 result = False
700
701 if f.endswith('.t') and "no-" "check-code" not in pre:
702 if debug:
703 print("Checking embedded code in %s" % (f))
704
705 prelines = pre.splitlines()
706 embeddederros = []
707 for name, embedded, filters, pats in embeddedchecks:
708 # "reset curmax at each repetition" treats maxerr as "max
709 # nubmer of errors in an actual file per entry of
710 # (embedded)checks"
711 curmaxerr = maxerr
712
713 for found in embedded(f, prelines, embeddederros):
714 filename, starts, ends, code = found
715 fc = _checkfiledata(name, f, code, filters, pats, context,
716 logfunc, curmaxerr, warnings, blame, debug,
717 lineno, offset=starts - 1)
718 if fc:
719 result = False
720 if curmaxerr:
721 if fc >= curmaxerr:
722 break
723 curmaxerr -= fc
676 724
677 return result 725 return result
678 726
679 def _checkfiledata(name, f, filedata, filters, pats, context, 727 def _checkfiledata(name, f, filedata, filters, pats, context,
680 logfunc, maxerr, warnings, blame, debug, lineno, 728 logfunc, maxerr, warnings, blame, debug, lineno,