Mercurial > public > mercurial-scm > hg
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, |