contrib/check-code.py
author Durham Goode <durham@fb.com>
Wed, 11 Oct 2017 10:36:59 -0700
changeset 34637 5f79f5f8487a
parent 34573 3e4b7861c1c5
child 34642 a679aa582d8d
permissions -rwxr-xr-x
bundle2: immediate exit for ctrl+c (issue5692) 21c2df59a regressed bundle2 by catching all exceptions and trying to handle them. The old behavior was to allow KeyboardInterrupts to throw and not have graceful cleanup, which allowed it to exit immediately. Let's go back to that behavior. Differential Revision: https://phab.mercurial-scm.org/D960
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
#!/usr/bin/env python
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# check-code - a style and portability checker for Mercurial
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
10290
7cc60de189d7 check-code: fix copyright date
Matt Mackall <mpm@selenic.com>
parents: 10287
diff changeset
     5
# Copyright 2010 Matt Mackall <mpm@selenic.com>
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
#
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
# This software may be used and distributed according to the terms of the
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
# GNU General Public License version 2 or any later version.
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     9
20241
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    10
"""style and portability checker for Mercurial
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    11
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    12
when a rule triggers wrong, do one of the following (prefer one from top):
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    13
 * do the work-around the rule suggests
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    14
 * doublecheck that it is a false match
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    15
 * improve the rule pattern
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    16
 * add an ignore pattern to the rule (3rd arg) which matches your good line
28700
35ad5bcdeb7e py24: remove check-code py24 notation
timeless <timeless@mozdev.org>
parents: 28595
diff changeset
    17
   (you can append a short comment and match this, like: #re-raises)
20241
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    18
 * change the pattern to a warning and list the exception in test-check-code-hg
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    19
 * ONLY use no--check-code for skipping entire files from external sources
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    20
"""
8071b4eddefa check-code: explain what to do when a check-code rule mismatches
Simon Heimberg <simohe@besonet.ch>
parents: 20239
diff changeset
    21
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
    22
from __future__ import absolute_import, print_function
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
    23
import glob
13074
637627f31c74 check-code: check for gratuitous whitespace after Python keywords
Thomas Arendsen Hein <thomas@jtah.de>
parents: 13031
diff changeset
    24
import keyword
10895
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
    25
import optparse
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
    26
import os
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
    27
import re
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
    28
import sys
29145
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
    29
if sys.version_info[0] < 3:
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
    30
    opentext = open
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
    31
else:
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
    32
    def opentext(f):
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
    33
        return open(f, encoding='ascii')
19310
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    34
try:
29143
8ed693ec5398 check-code: handle range/xrange divergence
timeless <timeless@mozdev.org>
parents: 29142
diff changeset
    35
    xrange
8ed693ec5398 check-code: handle range/xrange divergence
timeless <timeless@mozdev.org>
parents: 29142
diff changeset
    36
except NameError:
8ed693ec5398 check-code: handle range/xrange divergence
timeless <timeless@mozdev.org>
parents: 29142
diff changeset
    37
    xrange = range
8ed693ec5398 check-code: handle range/xrange divergence
timeless <timeless@mozdev.org>
parents: 29142
diff changeset
    38
try:
19310
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    39
    import re2
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    40
except ImportError:
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    41
    re2 = None
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    42
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    43
def compilere(pat, multiline=False):
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    44
    if multiline:
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    45
        pat = '(?m)' + pat
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    46
    if re2:
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    47
        try:
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    48
            return re2.compile(pat)
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    49
        except re2.error:
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    50
            pass
30ea54660d14 check-code: introduce function for using re2 when available
Simon Heimberg <simohe@besonet.ch>
parents: 19309
diff changeset
    51
    return re.compile(pat)
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
29398
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    53
# check "rules depending on implementation of repquote()" in each
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    54
# patterns (especially pypats), before changing around repquote()
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    55
_repquotefixedmap = {' ': ' ', '\n': '\n', '.': 'p', ':': 'q',
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    56
                     '%': '%', '\\': 'b', '*': 'A', '+': 'P', '-': 'M'}
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    57
def _repquoteencodechr(i):
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    58
    if i > 255:
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    59
        return 'u'
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    60
    c = chr(i)
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    61
    if c in _repquotefixedmap:
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    62
        return _repquotefixedmap[c]
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    63
    if c.isalpha():
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    64
        return 'x'
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    65
    if c.isdigit():
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    66
        return 'n'
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    67
    return 'o'
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    68
_repquotett = ''.join(_repquoteencodechr(i) for i in xrange(256))
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    69
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
def repquote(m):
19999
169cb9e47f8e check-code: more replacement characters
Simon Heimberg <simohe@besonet.ch>
parents: 19998
diff changeset
    71
    t = m.group('text')
29398
2a54cf92c773 check-code: build translation table for repquote in global for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29397
diff changeset
    72
    t = t.translate(_repquotett)
10722
c4fb2103e734 check-code: improve quote detection regexp, add tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10720
diff changeset
    73
    return m.group('quote') + t + m.group('quote')
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
10727
62b8f15683f2 check-code: more tests and more robust python filtering
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10723
diff changeset
    75
def reppython(m):
62b8f15683f2 check-code: more tests and more robust python filtering
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10723
diff changeset
    76
    comment = m.group('comment')
62b8f15683f2 check-code: more tests and more robust python filtering
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10723
diff changeset
    77
    if comment:
18959
2f6418d8a4c9 check-code: catch trailing space in comments
Mads Kiilerich <madski@unity3d.com>
parents: 18835
diff changeset
    78
        l = len(comment.rstrip())
2f6418d8a4c9 check-code: catch trailing space in comments
Mads Kiilerich <madski@unity3d.com>
parents: 18835
diff changeset
    79
        return "#" * l + comment[l:]
10727
62b8f15683f2 check-code: more tests and more robust python filtering
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10723
diff changeset
    80
    return repquote(m)
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
def repcomment(m):
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
    return m.group(1) + "#" * len(m.group(2))
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
def repccomment(m):
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
    t = re.sub(r"((?<=\n) )|\S", "x", m.group(2))
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
    return m.group(1) + t + "*/"
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    88
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
def repcallspaces(m):
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
    t = re.sub(r"\n\s+", "\n", m.group(2))
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
    return m.group(1) + t
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
def repinclude(m):
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
    return m.group(1) + "<foo>"
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    96
def rephere(m):
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
    t = re.sub(r"\S", "x", m.group(2))
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
    return m.group(1) + t
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
testpats = [
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   102
  [
31877
14c5a7637ecc checkcode: only match pushd/popd as word
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31824
diff changeset
   103
    (r'\b(push|pop)d\b', "don't use 'pushd' or 'popd', use 'cd'"),
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   104
    (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"),
10374
3aa35db5e38c check-code.py: make help strings consistent
Martin Geisler <mg@lazybytes.net>
parents: 10373
diff changeset
   105
    (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
27989
e77ac31b64a1 check-code: allow "grep pattern filename-containing-dash-a"
Martin von Zweigbergk <martinvonz@google.com>
parents: 27791
diff changeset
   106
    (r'(?<!hg )grep.* -a', "don't use 'grep -a', use in-line python"),
16332
42e95631887d tests: remove sed -i from test-record
Matt Mackall <mpm@selenic.com>
parents: 16249
diff changeset
   107
    (r'sed.*-i', "don't use 'sed -i', use a temporary file"),
16965
91284af53508 test-alias: adapt for Windows
Mads Kiilerich <mads@kiilerich.com>
parents: 16705
diff changeset
   108
    (r'\becho\b.*\\n', "don't use 'echo \\n', use printf"),
11884
932448701e7d check-code: catch "echo -n" in tests
Martin Geisler <mg@lazybytes.net>
parents: 11599
diff changeset
   109
    (r'echo -n', "don't use 'echo -n', use printf"),
23134
22e76e370611 test-revert.t: fix wc check-code false positive
Matt Mackall <mpm@selenic.com>
parents: 22448
diff changeset
   110
    (r'(^|\|\s*)\bwc\b[^|]*$\n(?!.*\(re\))', "filter wc output"),
10374
3aa35db5e38c check-code.py: make help strings consistent
Martin Geisler <mg@lazybytes.net>
parents: 10373
diff changeset
   111
    (r'head -c', "don't use 'head -c', use 'dd'"),
19628
3193b23eec61 solaris: tests can't use tail -n
Danek Duvall <danek.duvall@oracle.com>
parents: 19626
diff changeset
   112
    (r'tail -n', "don't use the '-n' option to tail, just use '-<num>'"),
15389
3bece03bf3c6 tests: use md5sum.py instead of sha1sum, add check
Matt Mackall <mpm@selenic.com>
parents: 15372
diff changeset
   113
    (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
10374
3aa35db5e38c check-code.py: make help strings consistent
Martin Geisler <mg@lazybytes.net>
parents: 10373
diff changeset
   114
    (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
29142
c07be448028b check-code: fix py3 complaint about \NNN being invalid unicode
timeless <timeless@mozdev.org>
parents: 29136
diff changeset
   115
    (r'printf.*[^\\]\\([1-9]|0\d)', r"don't use 'printf \NNN', use Python"),
19380
ee07f9d142c9 check-code: do not warn on printf \\x or \\[1-9]
Simon Heimberg <simohe@besonet.ch>
parents: 19378
diff changeset
   116
    (r'printf.*[^\\]\\x', "don't use printf \\x, use Python"),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
    (r'\$\(.*\)', "don't use $(expr), use `expr`"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   118
    (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
32293
ca727147ff9f style: ban [ foo == bar] bashism in tests
Augie Fackler <augie@google.com>
parents: 32184
diff changeset
   119
    (r'\[[^\]]+==', '[ foo == bar ] is a bashism, use [ foo = bar ] instead'),
15372
695ac6aca77f check-code: fix issues with finding patterns in unified tests, fix tests
Matt Mackall <mpm@selenic.com>
parents: 15364
diff changeset
   120
    (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   121
     "use egrep for extended grep syntax"),
34061
11499bad0359 check-code: forbid "\S" in egrep regular expression
Jun Wu <quark@fb.com>
parents: 34060
diff changeset
   122
    (r'(^|\|\s*)e?grep .*\\S', "don't use \\S in regular expression"),
34060
e267d4ee4f2d check-code: forbid using bash in shebang
Jun Wu <quark@fb.com>
parents: 33369
diff changeset
   123
    (r'(?<!!)/bin/', "don't use explicit paths for tools"),
e267d4ee4f2d check-code: forbid using bash in shebang
Jun Wu <quark@fb.com>
parents: 33369
diff changeset
   124
    (r'#!.*/bash', "don't use bash in shebang, use sh"),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   125
    (r'[^\n]\Z', "no trailing newline"),
27791
0029c2bebc23 check-code: export needs a space to avoid false positives
timeless <timeless@mozdev.org>
parents: 27693
diff changeset
   126
    (r'export .*=', "don't export and assign at once"),
15372
695ac6aca77f check-code: fix issues with finding patterns in unified tests, fix tests
Matt Mackall <mpm@selenic.com>
parents: 15364
diff changeset
   127
    (r'^source\b', "don't use 'source', use '.'"),
12367
3acd5f7ab9d0 tests: compatibility fix.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12366
diff changeset
   128
    (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
29330
12c97985ddeb check-code: make 'ls' pattern less invasive
Yuya Nishihara <yuya@tcha.org>
parents: 29279
diff changeset
   129
    (r'\bls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   130
    (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
15372
695ac6aca77f check-code: fix issues with finding patterns in unified tests, fix tests
Matt Mackall <mpm@selenic.com>
parents: 15364
diff changeset
   131
    (r'^stop\(\)', "don't use 'stop' as a shell function name"),
15282
d4addef0ec74 tests: don't use 'test -e'
Mads Kiilerich <mads@kiilerich.com>
parents: 14978
diff changeset
   132
    (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
25588
b40071379c5b check-code: ban use of '[[ ]]' in tests
Yuya Nishihara <yuya@tcha.org>
parents: 25212
diff changeset
   133
    (r'\[\[\s+[^\]]*\]\]', "don't use '[[ ]]', use '[ ]'"),
16013
2a1d97630f7f tests: don't use alias
Mads Kiilerich <mads@kiilerich.com>
parents: 15873
diff changeset
   134
    (r'^alias\b.*=', "don't use alias, use a function"),
16485
f48b075ff088 tests: solaris sh can not negate exit status with '!'
Mads Kiilerich <mads@kiilerich.com>
parents: 16483
diff changeset
   135
    (r'if\s*!', "don't use '!' to negate exit status"),
16494
e1f0305eabe4 tests: don't use /dev/urandom for largefiles testing
Mads Kiilerich <mads@kiilerich.com>
parents: 16487
diff changeset
   136
    (r'/dev/u?random', "don't use entropy, use /dev/zero"),
16496
abbabbbe4ec2 tests: use 'do sleep 0' instead of 'do true', also on first line of command
Mads Kiilerich <mads@kiilerich.com>
parents: 16495
diff changeset
   137
    (r'do\s*true;\s*done', "don't use true as loop body, use sleep 0"),
16497
c326fe884daa tests: avoid tab indent on all kinds of lines of sh commands
Mads Kiilerich <mads@kiilerich.com>
parents: 16496
diff changeset
   138
    (r'^( *)\t', "don't use tabs to indent"),
19083
12f15e4b2ca0 check-code: fix sed 'i' command rule newline matching
Kevin Bullock <kbullock@ringworld.org>
parents: 19081
diff changeset
   139
    (r'sed (-e )?\'(\d+|/[^/]*/)i(?!\\\n)',
19080
5e4491c114b2 check-code: add a rule against a GNU sed-ism
Kevin Bullock <kbullock@ringworld.org>
parents: 19031
diff changeset
   140
     "put a backslash-escaped newline after sed 'i' command"),
27557
28b5c4fcf48d tests: Solaris diff -U also emits "No differences encountered"
Danek Duvall <danek.duvall@oracle.com>
parents: 26808
diff changeset
   141
    (r'^diff *-\w*[uU].*$\n(^  \$ |^$)', "prefix diff -u/-U with cmp"),
28b5c4fcf48d tests: Solaris diff -U also emits "No differences encountered"
Danek Duvall <danek.duvall@oracle.com>
parents: 26808
diff changeset
   142
    (r'^\s+(if)? diff *-\w*[uU]', "prefix diff -u/-U with cmp"),
33288
f08a178adadf contrib: widen "direct use of `python`" net again
Augie Fackler <augie@google.com>
parents: 33285
diff changeset
   143
    (r'[\s="`\']python\s(?!bindings)', "don't use 'python', use '$PYTHON'"),
26588
b3f7516fa50e check-code: detect and ban 'util.Abort'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26348
diff changeset
   144
    (r'seq ', "don't use 'seq', use $TESTDIR/seq.py"),
b3f7516fa50e check-code: detect and ban 'util.Abort'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26348
diff changeset
   145
    (r'\butil\.Abort\b', "directly use error.Abort"),
26777
df1a29ec45bf check-code: block non-portable pipe-and
timeless <timeless@mozdev.org>
parents: 26588
diff changeset
   146
    (r'\|&', "don't use |&, use 2>&1"),
27640
8d0a09162d0f check-code: enforce strict spacing around assignment
timeless <timeless@mozdev.org>
parents: 27560
diff changeset
   147
    (r'\w =  +\w', "only one space after = allowed"),
28781
c042b98a6ff8 check-code: reject sed ... \\n
timeless <timeless@mozdev.org>
parents: 28700
diff changeset
   148
    (r'\bsed\b.*[^\\]\\n', "don't use 'sed ... \\n', use a \\ and a newline"),
30557
cbeb54ec0481 check-code: add a rule to forbid "cp -r"
Jun Wu <quark@fb.com>
parents: 30246
diff changeset
   149
    (r'env.*-u', "don't use 'env -u VAR', use 'unset VAR'"),
cbeb54ec0481 check-code: add a rule to forbid "cp -r"
Jun Wu <quark@fb.com>
parents: 30246
diff changeset
   150
    (r'cp.* -r ', "don't use 'cp -r', use 'cp -R'"),
32696
0c09afdf5704 check-code: ban grep's context flags (-A/-B/-C) since they're not on Solaris
Danek Duvall <danek.duvall@oracle.com>
parents: 32604
diff changeset
   151
    (r'grep.* -[ABC] ', "don't use grep's context flags"),
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   152
  ],
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   153
  # warnings
16672
d046eb97d21e tests: run most check-code sh checks on continued lines too
Mads Kiilerich <mads@kiilerich.com>
parents: 16590
diff changeset
   154
  [
d046eb97d21e tests: run most check-code sh checks on continued lines too
Mads Kiilerich <mads@kiilerich.com>
parents: 16590
diff changeset
   155
    (r'^function', "don't use 'function', use old style"),
d046eb97d21e tests: run most check-code sh checks on continued lines too
Mads Kiilerich <mads@kiilerich.com>
parents: 16590
diff changeset
   156
    (r'^diff.*-\w*N', "don't use 'diff -N'"),
18508
813b7a1f7036 tests: use `pwd` instead of ${PWD} in test-convert-git.t - because of Solaris
Mads Kiilerich <mads@kiilerich.com>
parents: 18183
diff changeset
   157
    (r'\$PWD|\${PWD}', "don't use $PWD, use `pwd`"),
16672
d046eb97d21e tests: run most check-code sh checks on continued lines too
Mads Kiilerich <mads@kiilerich.com>
parents: 16590
diff changeset
   158
    (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\^', "^ must be quoted"),
18575
667063b22a69 check-code: warn to use killdaemons instead of kill `cat PIDFILE`
Kevin Bullock <kbullock@ringworld.org>
parents: 18508
diff changeset
   159
    (r'kill (`|\$\()', "don't use kill, use killdaemons.py")
16672
d046eb97d21e tests: run most check-code sh checks on continued lines too
Mads Kiilerich <mads@kiilerich.com>
parents: 16590
diff changeset
   160
  ]
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   161
]
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   162
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   163
testfilters = [
34060
e267d4ee4f2d check-code: forbid using bash in shebang
Jun Wu <quark@fb.com>
parents: 33369
diff changeset
   164
    (r"( *)(#([^!][^\n]*\S)?)", repcomment),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   165
    (r"<<(\S+)((.|\n)*?\n\1)", rephere),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   166
]
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   167
18832
a911e5dc2b00 check-code: extract windows glob warning message
Simon Heimberg <simohe@besonet.ch>
parents: 18762
diff changeset
   168
winglobmsg = "use (glob) to match Windows paths too"
15372
695ac6aca77f check-code: fix issues with finding patterns in unified tests, fix tests
Matt Mackall <mpm@selenic.com>
parents: 15364
diff changeset
   169
uprefix = r"^  \$ "
12364
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   170
utestpats = [
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   171
  [
27693
2b9126d6588b check-code: allow only-whitespace lines in tests
Matt Mackall <mpm@selenic.com>
parents: 27640
diff changeset
   172
    (r'^(\S.*||  [$>] \S.*)[ \t]\n', "trailing whitespace on non-output"),
16673
775a8d33e6f0 tests: unify the last sh tests
Mads Kiilerich <mads@kiilerich.com>
parents: 16672
diff changeset
   173
    (uprefix + r'.*\|\s*sed[^|>\n]*\n',
775a8d33e6f0 tests: unify the last sh tests
Mads Kiilerich <mads@kiilerich.com>
parents: 16672
diff changeset
   174
     "use regex test output patterns instead of sed"),
12364
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   175
    (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
15607
fab28a577a38 test-svn-subrepo: fix reference output for svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15389
diff changeset
   176
    (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"),
12364
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   177
    (uprefix + r'.*\|\| echo.*(fail|error)',
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   178
     "explicit exit code checks unnecessary"),
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   179
    (uprefix + r'set -e', "don't use set -e"),
19873
b3de50b0c7aa check-code: check that '>' is used for continued lines
Mads Kiilerich <madski@unity3d.com>
parents: 19872
diff changeset
   180
    (uprefix + r'(\s|fi\b|done\b)', "use > for continued lines"),
20423
ada289dfceb0 tests: rewrite path in test-shelve.t for not being mangled on msys
Simon Heimberg <simohe@besonet.ch>
parents: 20243
diff changeset
   181
    (uprefix + r'.*:\.\S*/', "x:.y in a path does not work on msys, rewrite "
ada289dfceb0 tests: rewrite path in test-shelve.t for not being mangled on msys
Simon Heimberg <simohe@besonet.ch>
parents: 20243
diff changeset
   182
     "as x://.y, or see `hg log -k msys` for alternatives", r'-\S+:\.|' #-Rxxx
24205
abcb1ee3b20a check-code: allow disabling msys path check
Matt Mackall <mpm@selenic.com>
parents: 23936
diff changeset
   183
     '# no-msys'), # in test-pull.t which is skipped on windows
18832
a911e5dc2b00 check-code: extract windows glob warning message
Simon Heimberg <simohe@besonet.ch>
parents: 18762
diff changeset
   184
    (r'^  saved backup bundle to \$TESTTMP.*\.hg$', winglobmsg),
18835
4e7498a586e8 check-code: fix a check-code failure in check-code
Bryan O'Sullivan <bryano@fb.com>
parents: 18834
diff changeset
   185
    (r'^  changeset .* references (corrupted|missing) \$TESTTMP/.*[^)]$',
4e7498a586e8 check-code: fix a check-code failure in check-code
Bryan O'Sullivan <bryano@fb.com>
parents: 18834
diff changeset
   186
     winglobmsg),
20014
30eced973b28 check-code: document last ignore regexp
Simon Heimberg <simohe@besonet.ch>
parents: 20013
diff changeset
   187
    (r'^  pulling from \$TESTTMP/.*[^)]$', winglobmsg,
30eced973b28 check-code: document last ignore regexp
Simon Heimberg <simohe@besonet.ch>
parents: 20013
diff changeset
   188
     '\$TESTTMP/unix-repo$'), # in test-issue1802.t which skipped on windows
23936
30b016ef4bd8 check-code.py: avoid warning against "reverting subrepo ..." lines
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23139
diff changeset
   189
    (r'^  reverting (?!subrepo ).*/.*[^)]$', winglobmsg),
20013
38acecdd016c check-code: drop unneeded ignore patterns
Simon Heimberg <simohe@besonet.ch>
parents: 20012
diff changeset
   190
    (r'^  cloning subrepo \S+/.*[^)]$', winglobmsg),
38acecdd016c check-code: drop unneeded ignore patterns
Simon Heimberg <simohe@besonet.ch>
parents: 20012
diff changeset
   191
    (r'^  pushing to \$TESTTMP/.*[^)]$', winglobmsg),
38acecdd016c check-code: drop unneeded ignore patterns
Simon Heimberg <simohe@besonet.ch>
parents: 20012
diff changeset
   192
    (r'^  pushing subrepo \S+/\S+ to.*[^)]$', winglobmsg),
19133
101b80eb7364 tests: check path separator in moves
Brendan Cully <brendan@kublai.com>
parents: 19123
diff changeset
   193
    (r'^  moving \S+/.*[^)]$', winglobmsg),
20013
38acecdd016c check-code: drop unneeded ignore patterns
Simon Heimberg <simohe@besonet.ch>
parents: 20012
diff changeset
   194
    (r'^  no changes made to subrepo since.*/.*[^)]$', winglobmsg),
38acecdd016c check-code: drop unneeded ignore patterns
Simon Heimberg <simohe@besonet.ch>
parents: 20012
diff changeset
   195
    (r'^  .*: largefile \S+ not available from file:.*/.*[^)]$', winglobmsg),
20471
ea005e754c9c tests: lines with largefile .* file://$TESTTMP also match on windows
Simon Heimberg <simohe@besonet.ch>
parents: 20423
diff changeset
   196
    (r'^  .*file://\$TESTTMP',
ea005e754c9c tests: lines with largefile .* file://$TESTTMP also match on windows
Simon Heimberg <simohe@besonet.ch>
parents: 20423
diff changeset
   197
     'write "file:/*/$TESTTMP" + (glob) to match on windows too'),
31816
2a865df042b7 check-code: update test IP address enforcement checks
Augie Fackler <augie@google.com>
parents: 31786
diff changeset
   198
    (r'^  [^$>].*27\.0\.0\.1',
2a865df042b7 check-code: update test IP address enforcement checks
Augie Fackler <augie@google.com>
parents: 31786
diff changeset
   199
     'use $LOCALIP not an explicit loopback address'),
2a865df042b7 check-code: update test IP address enforcement checks
Augie Fackler <augie@google.com>
parents: 31786
diff changeset
   200
    (r'^  [^$>].*\$LOCALIP.*[^)]$',
2a865df042b7 check-code: update test IP address enforcement checks
Augie Fackler <augie@google.com>
parents: 31786
diff changeset
   201
     'mark $LOCALIP output lines with (glob) to help tests in BSD jails'),
21930
a5168eb9b2bc tests: cat error messages are different on Solaris
Danek Duvall <danek.duvall@oracle.com>
parents: 21791
diff changeset
   202
    (r'^  (cat|find): .*: No such file or directory',
a5168eb9b2bc tests: cat error messages are different on Solaris
Danek Duvall <danek.duvall@oracle.com>
parents: 21791
diff changeset
   203
     'use test -f to test for file existence'),
28033
0707bbec682d tests: omit -p for external diff via extdiff extension for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27989
diff changeset
   204
    (r'^  diff -[^ -]*p',
0707bbec682d tests: omit -p for external diff via extdiff extension for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27989
diff changeset
   205
     "don't use (external) diff with -p for portability"),
34573
3e4b7861c1c5 contrib: add check-code rule banning use of readlink
Augie Fackler <augie@google.com>
parents: 34508
diff changeset
   206
    (r' readlink ', 'use readlink.py instead of readlink'),
28034
e7ff258f71df tests: make timezone in diff output glob-ed for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28033
diff changeset
   207
    (r'^  [-+][-+][-+] .* [-+]0000 \(glob\)',
e7ff258f71df tests: make timezone in diff output glob-ed for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28033
diff changeset
   208
     "glob timezone field in diff output for portability"),
28035
c65da6892ae5 tests: make chunk header of external diff glob-ed for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28034
diff changeset
   209
    (r'^  @@ -[0-9]+ [+][0-9]+,[0-9]+ @@',
c65da6892ae5 tests: make chunk header of external diff glob-ed for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28034
diff changeset
   210
     "use '@@ -N* +N,n @@ (glob)' style chunk header for portability"),
c65da6892ae5 tests: make chunk header of external diff glob-ed for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28034
diff changeset
   211
    (r'^  @@ -[0-9]+,[0-9]+ [+][0-9]+ @@',
c65da6892ae5 tests: make chunk header of external diff glob-ed for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28034
diff changeset
   212
     "use '@@ -N,n +N* @@ (glob)' style chunk header for portability"),
c65da6892ae5 tests: make chunk header of external diff glob-ed for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28034
diff changeset
   213
    (r'^  @@ -[0-9]+ [+][0-9]+ @@',
c65da6892ae5 tests: make chunk header of external diff glob-ed for portability
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28034
diff changeset
   214
     "use '@@ -N* +N* @@ (glob)' style chunk header for portability"),
28053
34a2944aac9b check-code: add rule to detect usage of external diff via extdiff
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28050
diff changeset
   215
    (uprefix + r'hg( +-[^ ]+( +[^ ]+)?)* +extdiff'
34a2944aac9b check-code: add rule to detect usage of external diff via extdiff
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28050
diff changeset
   216
     r'( +(-[^ po-]+|--(?!program|option)[^ ]+|[^-][^ ]*))*$',
34a2944aac9b check-code: add rule to detect usage of external diff via extdiff
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28050
diff changeset
   217
     "use $RUNTESTDIR/pdiff via extdiff (or -o/-p for false-positives)"),
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   218
  ],
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   219
  # warnings
18683
a343eccd5ee2 check-code: warn about line glob match with no glob character (?*/)
Simon Heimberg <simohe@besonet.ch>
parents: 18575
diff changeset
   220
  [
31673
6a2959acae1a runtests: change local IP glob pattern from "127.0.0.1" to "$LOCALIP"
Jun Wu <quark@fb.com>
parents: 31602
diff changeset
   221
    (r'^  (?!.*\$LOCALIP)[^*?/\n]* \(glob\)$',
6a2959acae1a runtests: change local IP glob pattern from "127.0.0.1" to "$LOCALIP"
Jun Wu <quark@fb.com>
parents: 31602
diff changeset
   222
     "glob match with no glob string (?, *, /, and $LOCALIP)"),
18683
a343eccd5ee2 check-code: warn about line glob match with no glob character (?*/)
Simon Heimberg <simohe@besonet.ch>
parents: 18575
diff changeset
   223
  ]
12364
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   224
]
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   225
14203
b230922eb0c3 check-code: fix checking for sh style in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 14169
diff changeset
   226
for i in [0, 1]:
22101
6fa40bd78bc8 check-code: allow an escape pattern to be specified for testpattern
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22100
diff changeset
   227
    for tp in testpats[i]:
6fa40bd78bc8 check-code: allow an escape pattern to be specified for testpattern
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22100
diff changeset
   228
        p = tp[0]
6fa40bd78bc8 check-code: allow an escape pattern to be specified for testpattern
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22100
diff changeset
   229
        m = tp[1]
15372
695ac6aca77f check-code: fix issues with finding patterns in unified tests, fix tests
Matt Mackall <mpm@selenic.com>
parents: 15364
diff changeset
   230
        if p.startswith(r'^'):
16672
d046eb97d21e tests: run most check-code sh checks on continued lines too
Mads Kiilerich <mads@kiilerich.com>
parents: 16590
diff changeset
   231
            p = r"^  [$>] (%s)" % p[1:]
14203
b230922eb0c3 check-code: fix checking for sh style in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 14169
diff changeset
   232
        else:
16672
d046eb97d21e tests: run most check-code sh checks on continued lines too
Mads Kiilerich <mads@kiilerich.com>
parents: 16590
diff changeset
   233
            p = r"^  [$>] .*(%s)" % p
22101
6fa40bd78bc8 check-code: allow an escape pattern to be specified for testpattern
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22100
diff changeset
   234
        utestpats[i].append((p, m) + tp[2:])
12364
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   235
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   236
utestfilters = [
17711
cf204e9829f4 check-code: replace heredocs in unified tests
Idan Kamara <idankk86@gmail.com>
parents: 17620
diff changeset
   237
    (r"<<(\S+)((.|\n)*?\n  > \1)", rephere),
34060
e267d4ee4f2d check-code: forbid using bash in shebang
Jun Wu <quark@fb.com>
parents: 33369
diff changeset
   238
    (r"( +)(#([^!][^\n]*\S)?)", repcomment),
12364
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   239
]
e128fa4615f2 check-code: add some basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11886
diff changeset
   240
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   241
pypats = [
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   242
  [
11568
d5d4e6a30613 check-code: check for tuple parameter unpacking (missing in py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11522
diff changeset
   243
    (r'^\s*def\s*\w+\s*\(.*,\s*\(',
d5d4e6a30613 check-code: check for tuple parameter unpacking (missing in py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11522
diff changeset
   244
     "tuple parameter unpacking not available in Python 3+"),
d5d4e6a30613 check-code: check for tuple parameter unpacking (missing in py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11522
diff changeset
   245
    (r'lambda\s*\(.*,.*\)',
d5d4e6a30613 check-code: check for tuple parameter unpacking (missing in py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11522
diff changeset
   246
     "tuple parameter unpacking not available in Python 3+"),
11764
16723af520b0 check-code: added a check for calls to the builtin cmp function
Renato Cunha <renatoc@gmail.com>
parents: 11672
diff changeset
   247
    (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
30883
fe8ded72e17c check-code: permit functools.reduce
Yedidya Feldblum <yfeldblum@fb.com>
parents: 30820
diff changeset
   248
    (r'(?<!\.)\breduce\s*\(.*', "reduce is not available in Python 3+"),
29793
24991e7f775f check-code: make dict() pattern less invasive
Yuya Nishihara <yuya@tcha.org>
parents: 29569
diff changeset
   249
    (r'\bdict\(.*=', 'dict() is different in Py2 and 3 and is slower than {}',
20688
a61ed1c2d7a7 check-code: disallow use of dict(key=value) construction
Augie Fackler <raf@durin42.com>
parents: 20598
diff changeset
   250
     'dict-from-generator'),
11602
ba2520dd1e29 check-code: catch dict.has_key
Martin Geisler <mg@lazybytes.net>
parents: 11601
diff changeset
   251
    (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
18183
e1caaeb5a2ed check-code: disallow defunct <> operator
Augie Fackler <raf@durin42.com>
parents: 18180
diff changeset
   252
    (r'\s<>\s', '<> operator is not available in Python 3+, use !='),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   253
    (r'^\s*\t', "don't use tabs"),
10412
5326800d6937 check-code: import some pylint checks
Matt Mackall <mpm@selenic.com>
parents: 10374
diff changeset
   254
    (r'\S;\s*\n', "semicolon"),
21097
e8ef59b351c3 check-code: detect "% inside _()" when there are leading whitespaces
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20870
diff changeset
   255
    (r'[^_]_\([ \t\n]*(?:"[^"]+"[ \t\n+]*)+%', "don't use % inside _()"),
e8ef59b351c3 check-code: detect "% inside _()" when there are leading whitespaces
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20870
diff changeset
   256
    (r"[^_]_\([ \t\n]*(?:'[^']+'[ \t\n+]*)+%", "don't use % inside _()"),
18054
b35e3364f94a check-code: there must also be whitespace between ')' and operator
Mads Kiilerich <madski@unity3d.com>
parents: 17957
diff changeset
   257
    (r'(\w|\)),\w', "missing whitespace after ,"),
b35e3364f94a check-code: there must also be whitespace between ')' and operator
Mads Kiilerich <madski@unity3d.com>
parents: 17957
diff changeset
   258
    (r'(\w|\))[+/*\-<>]\w', "missing whitespace in expression"),
18055
e440a2c0d944 check-code: make 'missing whitespace in assignment' more aggressive
Mads Kiilerich <madski@unity3d.com>
parents: 18054
diff changeset
   259
    (r'^\s+(\w|\.)+=\w[^,()\n]*$', "missing whitespace in assignment"),
27640
8d0a09162d0f check-code: enforce strict spacing around assignment
timeless <timeless@mozdev.org>
parents: 27560
diff changeset
   260
    (r'\w\s=\s\s+\w', "gratuitous whitespace after ="),
34384
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   261
    ((
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   262
        # a line ending with a colon, potentially with trailing comments
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   263
        r':([ \t]*#[^\n]*)?\n'
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   264
        # one that is not a pass and not only a comment
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   265
        r'(?P<indent>[ \t]+)[^#][^\n]+\n'
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   266
        # more lines at the same indent level
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   267
        r'((?P=indent)[^\n]+\n)*'
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   268
        # a pass at the same indent level, which is bogus
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   269
        r'(?P=indent)pass[ \t\n#]'
b52f22d9afa5 contrib: add a check to check-code to ban superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34082
diff changeset
   270
      ), 'omit superfluous pass'),
16702
1751d96d324f check-code: promote 80+ character line warning to an error
Brodie Rao <brodie@sf.io>
parents: 16683
diff changeset
   271
    (r'.{81}', "line too long"),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   272
    (r'[^\n]\Z', "no trailing newline"),
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   273
    (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16673
diff changeset
   274
#    (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=',
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16673
diff changeset
   275
#     "don't use underbars in identifiers"),
34082
ba6e14f9a2d8 check-code: fix incorrect capitalization in camelcase regex
Martin von Zweigbergk <martinvonz@google.com>
parents: 34061
diff changeset
   276
    (r'^\s+(self\.)?[A-Za-z][a-z0-9]+[A-Z]\w* = ',
34429
b332c01247d8 check-code: allow an exception for camelcase where required
Siddharth Agarwal <sid0@fb.com>
parents: 34384
diff changeset
   277
     "don't use camelcase in identifiers", r'#.*camelcase-required'),
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   278
    (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
10286
cc0340ef47f7 check-code: check thyself
Matt Mackall <mpm@selenic.com>
parents: 10281
diff changeset
   279
     "linebreak after :"),
28219
97fe88806f6f check-code: allow old style class with special comments
Jun Wu <quark@fb.com>
parents: 28053
diff changeset
   280
    (r'class\s[^( \n]+:', "old-style class, use class foo(object)",
97fe88806f6f check-code: allow old style class with special comments
Jun Wu <quark@fb.com>
parents: 28053
diff changeset
   281
     r'#.*old-style'),
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   282
    (r'class\s[^( \n]+\(\):',
28219
97fe88806f6f check-code: allow old style class with special comments
Jun Wu <quark@fb.com>
parents: 28053
diff changeset
   283
     "class foo() creates old style object, use class foo(object)",
97fe88806f6f check-code: allow old style class with special comments
Jun Wu <quark@fb.com>
parents: 28053
diff changeset
   284
     r'#.*old-style'),
25028
62c2786b4327 check-code: allow print and exec as a function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25010
diff changeset
   285
    (r'\b(%s)\(' % '|'.join(k for k in keyword.kwlist
62c2786b4327 check-code: allow print and exec as a function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25010
diff changeset
   286
                            if k not in ('print', 'exec')),
13076
a861c7155f09 check-code: single check for Python keywords used as a function
Thomas Arendsen Hein <thomas@jtah.de>
parents: 13074
diff changeset
   287
     "Python keyword is not a function"),
10412
5326800d6937 check-code: import some pylint checks
Matt Mackall <mpm@selenic.com>
parents: 10374
diff changeset
   288
    (r',]', "unneeded trailing ',' in list"),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   289
#    (r'class\s[A-Z][^\(]*\((?!Exception)',
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   290
#     "don't capitalize non-exception classes"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   291
#    (r'in range\(', "use xrange"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   292
#    (r'^\s*print\s+', "avoid using print in core and extensions"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   293
    (r'[\x80-\xff]', "non-ASCII character literal"),
25212
a39c35e8e559 check-code: reintroduce str.format() ban for 3.x porting
Matt Mackall <mpm@selenic.com>
parents: 25200
diff changeset
   294
    (r'("\')\.format\(', "str.format() has no bytes counterpart, use %"),
13074
637627f31c74 check-code: check for gratuitous whitespace after Python keywords
Thomas Arendsen Hein <thomas@jtah.de>
parents: 13031
diff changeset
   295
    (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
637627f31c74 check-code: check for gratuitous whitespace after Python keywords
Thomas Arendsen Hein <thomas@jtah.de>
parents: 13031
diff changeset
   296
     "gratuitous whitespace after Python keyword"),
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   297
    (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   298
#    (r'\s\s=', "gratuitous whitespace before ="),
17167
5f131ae05905 check-code: recognise %= as an operator
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17111
diff changeset
   299
    (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
11345
4b81f82b03e3 check-code: reformat long lines
Martin Geisler <mg@aragost.com>
parents: 11343
diff changeset
   300
     "missing whitespace around operator"),
17167
5f131ae05905 check-code: recognise %= as an operator
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17111
diff changeset
   301
    (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\s',
11345
4b81f82b03e3 check-code: reformat long lines
Martin Geisler <mg@aragost.com>
parents: 11343
diff changeset
   302
     "missing whitespace around operator"),
17167
5f131ae05905 check-code: recognise %= as an operator
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17111
diff changeset
   303
    (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
11345
4b81f82b03e3 check-code: reformat long lines
Martin Geisler <mg@aragost.com>
parents: 11343
diff changeset
   304
     "missing whitespace around operator"),
17167
5f131ae05905 check-code: recognise %= as an operator
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17111
diff changeset
   305
    (r'[^^+=*/!<>&| %-](\s=|=\s)[^= ]',
11345
4b81f82b03e3 check-code: reformat long lines
Martin Geisler <mg@aragost.com>
parents: 11343
diff changeset
   306
     "wrong whitespace around ="),
19872
681f7b9213a4 check-code: check for spaces around = for named parameters
Mads Kiilerich <madski@unity3d.com>
parents: 19793
diff changeset
   307
    (r'\([^()]*( =[^=]|[^<>!=]= )',
681f7b9213a4 check-code: check for spaces around = for named parameters
Mads Kiilerich <madski@unity3d.com>
parents: 19793
diff changeset
   308
     "no whitespace around = for named parameters"),
10451
63a9bfad50ff check-code: two more rules
Matt Mackall <mpm@selenic.com>
parents: 10412
diff changeset
   309
    (r'raise Exception', "don't raise generic exceptions"),
18180
c582a71457e5 check-code: disallow two-argument form of raise
Augie Fackler <raf@durin42.com>
parents: 18055
diff changeset
   310
    (r'raise [^,(]+, (\([^\)]+\)|[^,\(\)]+)$',
c582a71457e5 check-code: disallow two-argument form of raise
Augie Fackler <raf@durin42.com>
parents: 18055
diff changeset
   311
     "don't use old-style two-argument raise, use Exception(message)"),
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   312
    (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   313
    (r' [=!]=\s+(True|False|None)',
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   314
     "comparison with singleton, use 'is' or 'is not' instead"),
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 14303
diff changeset
   315
    (r'^\s*(while|if) [01]:',
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 14303
diff changeset
   316
     "use True/False for constant Boolean expression"),
33369
d36bcba91845 check-code: prohibit `if False` antipattern
Augie Fackler <raf@durin42.com>
parents: 33288
diff changeset
   317
    (r'^\s*if False(:| +and)', 'Remove code instead of using `if False`'),
29796
6ab838b20359 check-code: allow assignment to hasattr variable
Yuya Nishihara <yuya@tcha.org>
parents: 29793
diff changeset
   318
    (r'(?:(?<!def)\s+|\()hasattr\(',
32418
1651977596c0 check-code: allow skipping hasattr check in py3-only code
Siddharth Agarwal <sid0@fb.com>
parents: 32293
diff changeset
   319
     'hasattr(foo, bar) is broken on py2, use util.safehasattr(foo, bar) '
1651977596c0 check-code: allow skipping hasattr check in py3-only code
Siddharth Agarwal <sid0@fb.com>
parents: 32293
diff changeset
   320
     'instead', r'#.*hasattr-py3-only'),
14169
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   321
    (r'opener\([^)]*\).read\(',
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   322
     "use opener.read() instead"),
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   323
    (r'opener\([^)]*\).write\(',
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   324
     "use opener.write() instead"),
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   325
    (r'[\s\(](open|file)\([^)]*\)\.read\(',
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   326
     "use util.readfile() instead"),
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   327
    (r'[\s\(](open|file)\([^)]*\)\.write\(',
19981
d1e14e7e5b40 check-code: fix an error message
Simon Heimberg <simohe@besonet.ch>
parents: 19873
diff changeset
   328
     "use util.writefile() instead"),
14169
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   329
    (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   330
     "always assign an opened file to a variable, and close it afterwards"),
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   331
    (r'[\s\(](open|file)\([^)]*\)\.',
1b4b82063ce2 check-code: disallow calling opener(...).read() and opener(..).write()
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14137
diff changeset
   332
     "always assign an opened file to a variable, and close it afterwards"),
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23134
diff changeset
   333
    (r'(?i)descend[e]nt', "the proper spelling is descendAnt"),
14709
6c7283faa967 check-code: don't mark debug messages for translation
Matt Mackall <mpm@selenic.com>
parents: 14549
diff changeset
   334
    (r'\.debug\(\_', "don't mark debug messages for translation"),
16590
7f76c97361e0 check-code: catch unnecessary s.strip().split() calls
Martin Geisler <mg@aragost.com>
parents: 16497
diff changeset
   335
    (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"),
18762
a91387a37f05 check-code: do not prepend "warning" to a failure message
Simon Heimberg <simohe@besonet.ch>
parents: 18683
diff changeset
   336
    (r'^\s*except\s*:', "naked except clause", r'#.*re-raises'),
25661
20de1ace07a9 check-code: detect legacy exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   337
    (r'^\s*except\s([^\(,]+|\([^\)]+\))\s*,',
20de1ace07a9 check-code: detect legacy exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   338
     'legacy exception syntax; use "as" instead of ","'),
17299
e51d4aedace9 check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents: 17167
diff changeset
   339
    (r':\n(    )*( ){1,3}[^ ]', "must indent 4 spaces"),
19031
341083b02d1b check-code: add check for lock release order
Matt Mackall <mpm@selenic.com>
parents: 18960
diff changeset
   340
    (r'release\(.*wlock, .*lock\)', "wrong lock release order"),
31476
413b44003462 py3: add __bool__ to every class defining __nonzero__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30916
diff changeset
   341
    (r'\bdef\s+__bool__\b', "__bool__ should be __nonzero__ in Python 2"),
24836
1f9127c9239b check-code: check os.path.join(*, '') not working correctly with Python 2.7.9
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24453
diff changeset
   342
    (r'os\.path\.join\(.*, *(""|\'\')\)',
1f9127c9239b check-code: check os.path.join(*, '') not working correctly with Python 2.7.9
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24453
diff changeset
   343
     "use pathutil.normasprefix(path) instead of os.path.join(path, '')"),
25659
d60678a567a9 check-code: detect legacy octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25588
diff changeset
   344
    (r'\s0[0-7]+\b', 'legacy octal syntax; use "0o" prefix instead of "0"'),
26348
b80b2ee71a08 check-code: forbid mutable value for default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25661
diff changeset
   345
    # XXX only catch mutable arguments on the first line of the definition
b80b2ee71a08 check-code: forbid mutable value for default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25661
diff changeset
   346
    (r'def.*[( ]\w+=\{\}', "don't use mutable default arguments"),
26588
b3f7516fa50e check-code: detect and ban 'util.Abort'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26348
diff changeset
   347
    (r'\butil\.Abort\b', "directly use error.Abort"),
30810
df5d3734b3df check-code: reject module-level @cachefunc
Martin von Zweigbergk <martinvonz@google.com>
parents: 30665
diff changeset
   348
    (r'^@(\w*\.)?cachefunc', "module-level @cachefunc is risky, please avoid"),
34508
b521b3a79afd test-check-code: fail new commits which use 'atexit' instead of 'ui.atexit'
Saurabh Singh <singhsrb@fb.com>
parents: 34429
diff changeset
   349
    (r'^import atexit', "don't use atexit, use ui.atexit"),
28820
9848a6c77a9b check-code: reject import Queue, suggest util.queue class for py3 compat
timeless <timeless@mozdev.org>
parents: 28781
diff changeset
   350
    (r'^import Queue', "don't use Queue, use util.queue + util.empty"),
28884
75309badb485 check-code: reject import urllib
timeless <timeless@mozdev.org>
parents: 28820
diff changeset
   351
    (r'^import cStringIO', "don't use cStringIO.StringIO, use util.stringio"),
75309badb485 check-code: reject import urllib
timeless <timeless@mozdev.org>
parents: 28820
diff changeset
   352
    (r'^import urllib', "don't use urllib, use util.urlreq/util.urlerr"),
29434
7dce56174916 py3: add tests in check-code to load modules from util.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29398
diff changeset
   353
    (r'^import SocketServer', "don't use SockerServer, use util.socketserver"),
31572
c0c4e14ee597 check-code: recommend util.urlreq when importing urlparse
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31476
diff changeset
   354
    (r'^import urlparse', "don't use urlparse, use util.urlreq"),
29434
7dce56174916 py3: add tests in check-code to load modules from util.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29398
diff changeset
   355
    (r'^import xmlrpclib', "don't use xmlrpclib, use util.xmlrpclib"),
7dce56174916 py3: add tests in check-code to load modules from util.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29398
diff changeset
   356
    (r'^import cPickle', "don't use cPickle, use util.pickle"),
7dce56174916 py3: add tests in check-code to load modules from util.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29398
diff changeset
   357
    (r'^import pickle', "don't use pickle, use util.pickle"),
29455
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29434
diff changeset
   358
    (r'^import httplib', "don't use httplib, use util.httplib"),
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29520
diff changeset
   359
    (r'^import BaseHTTPServer', "use util.httpserver instead"),
32604
071423d0a584 check-code: suggest policy.importmod
Jun Wu <quark@fb.com>
parents: 32418
diff changeset
   360
    (r'^(from|import) mercurial\.(cext|pure|cffi)',
071423d0a584 check-code: suggest policy.importmod
Jun Wu <quark@fb.com>
parents: 32418
diff changeset
   361
     "use mercurial.policy.importmod instead"),
29217
2f9ad6ca19c2 check-code: reject .next(...)
timeless <timeless@mozdev.org>
parents: 29145
diff changeset
   362
    (r'\.next\(\)', "don't use .next(), use next(...)"),
31721
be8a866a2c44 check-code: detect r.revision(r.node(rev))
Jun Wu <quark@fb.com>
parents: 31673
diff changeset
   363
    (r'([a-z]*).revision\(\1\.node\(',
31786
0e4f70f63aaa check-code: fix "covert" typo
Martin von Zweigbergk <martinvonz@google.com>
parents: 31721
diff changeset
   364
     "don't convert rev to node before passing to revision(nodeorrev)"),
29278
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   365
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   366
    # rules depending on implementation of repquote()
29279
438caf194160 check-code: make repquote distinguish more characters for exact detection
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29278
diff changeset
   367
    (r' x+[xpqo%APM][\'"]\n\s+[\'"]x',
438caf194160 check-code: make repquote distinguish more characters for exact detection
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29278
diff changeset
   368
     'string join across lines with no space'),
29397
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   369
    (r'''(?x)ui\.(status|progress|write|note|warn)\(
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   370
         [ \t\n#]*
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   371
         (?# any strings/comments might precede a string, which
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   372
           # contains translatable message)
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   373
         ((['"]|\'\'\'|""")[ \npq%bAPMxno]*(['"]|\'\'\'|""")[ \t\n#]+)*
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   374
         (?# sequence consisting of below might precede translatable message
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   375
           # - formatting string: "% 10s", "%05d", "% -3.2f", "%*s", "%%" ...
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   376
           # - escaped character: "\\", "\n", "\0" ...
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   377
           # - character other than '%', 'b' as '\', and 'x' as alphabet)
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   378
         (['"]|\'\'\'|""")
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   379
         ((%([ n]?[PM]?([np]+|A))?x)|%%|b[bnx]|[ \nnpqAPMo])*x
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   380
         (?# this regexp can't use [^...] style,
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   381
           # because _preparepats forcibly adds "\n" into [^...],
844f72885fb9 check-code: detect "missing _() in ui message" more exactly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29330
diff changeset
   382
           # even though this regexp wants match it against "\n")''',
29278
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   383
     "missing _() in ui message (use () to hide false-positives)"),
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   384
  ],
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   385
  # warnings
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   386
  [
29278
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   387
    # rules depending on implementation of repquote()
19999
169cb9e47f8e check-code: more replacement characters
Simon Heimberg <simohe@besonet.ch>
parents: 19998
diff changeset
   388
    (r'(^| )pp +xxxxqq[ \n][^\n]', "add two newlines after '.. note::'"),
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   389
  ]
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   390
]
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   391
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   392
pyfilters = [
10727
62b8f15683f2 check-code: more tests and more robust python filtering
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10723
diff changeset
   393
    (r"""(?msx)(?P<comment>\#.*?$)|
62b8f15683f2 check-code: more tests and more robust python filtering
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10723
diff changeset
   394
         ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
62b8f15683f2 check-code: more tests and more robust python filtering
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10723
diff changeset
   395
          (?P<text>(([^\\]|\\.)*?))
62b8f15683f2 check-code: more tests and more robust python filtering
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10723
diff changeset
   396
          (?P=quote))""", reppython),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   397
]
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   398
31602
772878ac930e checkcode: enforce lowercase for extension docstring title
Jun Wu <quark@fb.com>
parents: 31572
diff changeset
   399
# extension non-filter patterns
772878ac930e checkcode: enforce lowercase for extension docstring title
Jun Wu <quark@fb.com>
parents: 31572
diff changeset
   400
pyextnfpats = [
772878ac930e checkcode: enforce lowercase for extension docstring title
Jun Wu <quark@fb.com>
parents: 31572
diff changeset
   401
    [(r'^"""\n?[A-Z]', "don't capitalize docstring title")],
772878ac930e checkcode: enforce lowercase for extension docstring title
Jun Wu <quark@fb.com>
parents: 31572
diff changeset
   402
    # warnings
772878ac930e checkcode: enforce lowercase for extension docstring title
Jun Wu <quark@fb.com>
parents: 31572
diff changeset
   403
    [],
772878ac930e checkcode: enforce lowercase for extension docstring title
Jun Wu <quark@fb.com>
parents: 31572
diff changeset
   404
]
772878ac930e checkcode: enforce lowercase for extension docstring title
Jun Wu <quark@fb.com>
parents: 31572
diff changeset
   405
18960
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   406
txtfilters = []
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   407
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   408
txtpats = [
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   409
  [
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   410
    ('\s$', 'trailing whitespace'),
20532
f1a3ae7c15df help: remove last occurrences of ".. note::" without two newlines
Simon Heimberg <simohe@besonet.ch>
parents: 20471
diff changeset
   411
    ('.. note::[ \n][^\n]', 'add two newlines after note::')
18960
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   412
  ],
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   413
  []
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   414
]
170fc0949fb6 check-code: check txt files for trailing whitespace
Mads Kiilerich <madski@unity3d.com>
parents: 18959
diff changeset
   415
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   416
cpats = [
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   417
  [
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   418
    (r'//', "don't use //-style comments"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   419
    (r'^  ', "don't use spaces to indent"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   420
    (r'\S\t', "don't use tabs except for indent"),
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   421
    (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
16702
1751d96d324f check-code: promote 80+ character line warning to an error
Brodie Rao <brodie@sf.io>
parents: 16683
diff changeset
   422
    (r'.{81}', "line too long"),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   423
    (r'(while|if|do|for)\(', "use space after while/if/do/for"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   424
    (r'return\(', "return is not a function"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   425
    (r' ;', "no space before ;"),
24453
65f1a29685ab check-code: in C code, prevent space before closing parenthesis
Laurent Charignon <lcharignon@fb.com>
parents: 24362
diff changeset
   426
    (r'[^;] \)', "no space before )"),
19745
22a70f31e3e9 check-code: add bracket style check
Matt Mackall <mpm@selenic.com>
parents: 19732
diff changeset
   427
    (r'[)][{]', "space between ) and {"),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   428
    (r'\w+\* \w+', "use int *foo, not int* foo"),
19731
436a3f728375 check-code: make casting style check more precise
Matt Mackall <mpm@selenic.com>
parents: 19628
diff changeset
   429
    (r'\W\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
16413
1a420761fcb7 check-code: avoid false-positive on ++
Matt Mackall <mpm@selenic.com>
parents: 16373
diff changeset
   430
    (r'\w+ (\+\+|--)', "use foo++, not foo ++"),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   431
    (r'\w,\w', "missing whitespace after ,"),
13736
f3c4421e121c osutil: fix up check-code issues
Matt Mackall <mpm@selenic.com>
parents: 13524
diff changeset
   432
    (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
27640
8d0a09162d0f check-code: enforce strict spacing around assignment
timeless <timeless@mozdev.org>
parents: 27560
diff changeset
   433
    (r'\w\s=\s\s+\w', "gratuitous whitespace after ="),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   434
    (r'^#\s+\w', "use #foo, not # foo"),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   435
    (r'[^\n]\Z', "no trailing newline"),
13748
26f8844d1757 osutil: replace #import with #include, and add a check for it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13736
diff changeset
   436
    (r'^\s*#import\b', "use only #include in standard C code"),
28594
d3990da51637 check-code: prevent use of strcpy
Augie Fackler <augie@google.com>
parents: 28509
diff changeset
   437
    (r'strcpy\(', "don't use strcpy, use strlcpy or memcpy"),
28595
adda6dee600e check-code: also ban strcat
Augie Fackler <augie@google.com>
parents: 28594
diff changeset
   438
    (r'strcat\(', "don't use strcat"),
29278
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   439
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   440
    # rules depending on implementation of repquote()
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   441
  ],
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   442
  # warnings
29278
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   443
  [
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   444
    # rules depending on implementation of repquote()
5eda83fb09fc check-code: centralize rules depending on implementation of repquote
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29277
diff changeset
   445
  ]
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   446
]
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   447
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   448
cfilters = [
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   449
    (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
10722
c4fb2103e734 check-code: improve quote detection regexp, add tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10720
diff changeset
   450
    (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   451
    (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   452
    (r'(\()([^)]+\))', repcallspaces),
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   453
]
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   454
14137
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   455
inutilpats = [
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   456
  [
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   457
    (r'\bui\.', "don't use ui in util"),
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   458
  ],
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   459
  # warnings
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   460
  []
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   461
]
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   462
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   463
inrevlogpats = [
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   464
  [
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   465
    (r'\brepo\.', "don't use repo in revlog"),
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   466
  ],
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   467
  # warnings
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   468
  []
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   469
]
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   470
21487
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   471
webtemplatefilters = []
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   472
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   473
webtemplatepats = [
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   474
  [],
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   475
  [
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   476
    (r'{desc(\|(?!websub|firstline)[^\|]*)+}',
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   477
     'follow desc keyword with either firstline or websub'),
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   478
  ]
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   479
]
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   480
30246
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   481
allfilesfilters = []
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   482
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   483
allfilespats = [
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   484
  [
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   485
    (r'(http|https)://[a-zA-Z0-9./]*selenic.com/',
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   486
     'use mercurial-scm.org domain URL'),
30888
561a019c0268 misc: replace domain of mercurial ML address by mercurial-scm.org
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30820
diff changeset
   487
    (r'mercurial@selenic\.com',
561a019c0268 misc: replace domain of mercurial ML address by mercurial-scm.org
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30820
diff changeset
   488
     'use mercurial-scm.org domain for mercurial ML address'),
30890
22a4f664c1a5 misc: replace domain of mercurial-devel ML address by mercurial-scm.org
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30888
diff changeset
   489
    (r'mercurial-devel@selenic\.com',
22a4f664c1a5 misc: replace domain of mercurial-devel ML address by mercurial-scm.org
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30888
diff changeset
   490
     'use mercurial-scm.org domain for mercurial-devel ML address'),
30246
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   491
  ],
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   492
  # warnings
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   493
  [],
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   494
]
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   495
30665
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   496
py3pats = [
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   497
  [
32184
cf424dae5dc7 check-code: ignore re-exports of os.environ in encoding.py
Yuya Nishihara <yuya@tcha.org>
parents: 32183
diff changeset
   498
    (r'os\.environ', "use encoding.environ instead (py3)", r'#.*re-exports'),
30665
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   499
    (r'os\.name', "use pycompat.osname instead (py3)"),
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   500
    (r'os\.getcwd', "use pycompat.getcwd instead (py3)"),
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   501
    (r'os\.sep', "use pycompat.ossep instead (py3)"),
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   502
    (r'os\.pathsep', "use pycompat.ospathsep instead (py3)"),
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   503
    (r'os\.altsep', "use pycompat.osaltsep instead (py3)"),
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   504
    (r'sys\.platform', "use pycompat.sysplatform instead (py3)"),
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   505
    (r'getopt\.getopt', "use pycompat.getoptb instead (py3)"),
30820
6a70cf94d1b5 py3: replace pycompat.getenv with encoding.environ.get
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30810
diff changeset
   506
    (r'os\.getenv', "use encoding.environ.get instead"),
6a70cf94d1b5 py3: replace pycompat.getenv with encoding.environ.get
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30810
diff changeset
   507
    (r'os\.setenv', "modifying the environ dict is not preferred"),
30665
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   508
  ],
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   509
  # warnings
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   510
  [],
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   511
]
01721d382c16 py3: add warnings in check-code related to py3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30557
diff changeset
   512
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   513
checks = [
21222
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   514
    ('python', r'.*\.(py|cgi)$', r'^#!.*python', pyfilters, pypats),
31602
772878ac930e checkcode: enforce lowercase for extension docstring title
Jun Wu <quark@fb.com>
parents: 31572
diff changeset
   515
    ('python', r'.*hgext.*\.py$', '', [], pyextnfpats),
32183
41d79475d440 check-code: exclude demandimport.py and policy.py from Python 3 checks
Yuya Nishihara <yuya@tcha.org>
parents: 32182
diff changeset
   516
    ('python 3', r'.*(hgext|mercurial)/(?!demandimport|policy|pycompat).*\.py',
41d79475d440 check-code: exclude demandimport.py and policy.py from Python 3 checks
Yuya Nishihara <yuya@tcha.org>
parents: 32182
diff changeset
   517
     '', pyfilters, py3pats),
21222
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   518
    ('test script', r'(.*/)?test-[^.~]*$', '', testfilters, testpats),
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   519
    ('c', r'.*\.[ch]$', '', cfilters, cpats),
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   520
    ('unified test', r'.*\.t$', '', utestfilters, utestpats),
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   521
    ('layering violation repo in revlog', r'mercurial/revlog\.py', '',
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   522
     pyfilters, inrevlogpats),
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   523
    ('layering violation ui in util', r'mercurial/util\.py', '', pyfilters,
14137
83a94c2fe6f4 check-code: check for repo in revlog and ui in util
timeless <timeless@mozdev.org>
parents: 14136
diff changeset
   524
     inutilpats),
21222
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   525
    ('txt', r'.*\.txt$', '', txtfilters, txtpats),
21487
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   526
    ('web template', r'mercurial/templates/.*\.tmpl', '',
c26464ce0781 check-code: check for consistent usage of the websub filter in hgweb templates
Steven Brown <StevenGBrown@gmail.com>
parents: 21222
diff changeset
   527
     webtemplatefilters, webtemplatepats),
30246
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   528
    ('all except for .po', r'.*(?<!\.po)$', '',
b4c0f8d5edd2 contrib: check reference to old selenic.com domain
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30245
diff changeset
   529
     allfilesfilters, allfilespats),
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   530
]
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   531
19307
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   532
def _preparepats():
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   533
    for c in checks:
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   534
        failandwarn = c[-1]
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   535
        for pats in failandwarn:
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   536
            for i, pseq in enumerate(pats):
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   537
                # fix-up regexes for multi-line searches
19378
9de689d20230 cleanup: drop unused variables and an unused import
Simon Heimberg <simohe@besonet.ch>
parents: 19310
diff changeset
   538
                p = pseq[0]
19307
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   539
                # \s doesn't match \n
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   540
                p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   541
                # [^...] doesn't match newline
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   542
                p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   543
19308
84faaacbd3fa check-code: compile all patterns on initialisation
Simon Heimberg <simohe@besonet.ch>
parents: 19307
diff changeset
   544
                pats[i] = (re.compile(p, re.MULTILINE),) + pseq[1:]
21222
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   545
        filters = c[3]
19309
7d77fa1cd537 check-code: compile filters when loading
Simon Heimberg <simohe@besonet.ch>
parents: 19308
diff changeset
   546
        for i, flt in enumerate(filters):
7d77fa1cd537 check-code: compile filters when loading
Simon Heimberg <simohe@besonet.ch>
parents: 19308
diff changeset
   547
            filters[i] = re.compile(flt[0]), flt[1]
19307
5443d40d524b check-code: only fix patterns once
Simon Heimberg <simohe@besonet.ch>
parents: 19168
diff changeset
   548
10719
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   549
class norepeatlogger(object):
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   550
    def __init__(self):
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   551
        self._lastseen = None
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   552
11604
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   553
    def log(self, fname, lineno, line, msg, blame):
10719
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   554
        """print error related a to given line of a given file.
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   555
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   556
        The faulty line will also be printed but only once in the case
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   557
        of multiple errors.
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   558
10719
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   559
        :fname: filename
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   560
        :lineno: line number
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   561
        :line: actual content of the line
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   562
        :msg: error message
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   563
        """
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   564
        msgid = fname, lineno, line
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   565
        if msgid != self._lastseen:
11604
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   566
            if blame:
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   567
                print("%s:%d (%s):" % (fname, lineno, blame))
11604
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   568
            else:
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   569
                print("%s:%d:" % (fname, lineno))
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   570
            print(" > %s" % line)
10719
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   571
            self._lastseen = msgid
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   572
        print(" " + msg)
10719
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   573
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   574
_defaultlogger = norepeatlogger()
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   575
11604
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   576
def getblame(f):
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   577
    lines = []
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   578
    for l in os.popen('hg annotate -un %s' % f):
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   579
        start, line = l.split(':', 1)
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   580
        user, rev = start.split()
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   581
        lines.append((line[1:-1], user, rev))
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   582
    return lines
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   583
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   584
def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
15502
7917a104a285 check-code: add --nolineno option for hiding line numbers
Mads Kiilerich <mads@kiilerich.com>
parents: 15457
diff changeset
   585
              blame=False, debug=False, lineno=True):
10719
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   586
    """checks style and portability of a given file
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   587
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   588
    :f: filepath
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   589
    :logfunc: function used to report error
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   590
              logfunc(filename, linenumber, linecontent, errormessage)
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17347
diff changeset
   591
    :maxerr: number of error to display before aborting.
15873
a153a86a472c tests: keep track of all check-code.py warnings
Mads Kiilerich <mads@kiilerich.com>
parents: 15611
diff changeset
   592
             Set to false (default) to report all errors
10720
fbcccf9ec58f check-code: add a return value to checkfile function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10719
diff changeset
   593
fbcccf9ec58f check-code: add a return value to checkfile function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10719
diff changeset
   594
    return True if no error is found, False otherwise.
10719
3be9ae49b628 code-code: Add a logfunc argument to checkfile
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10718
diff changeset
   595
    """
11604
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   596
    blamecache = None
10720
fbcccf9ec58f check-code: add a return value to checkfile function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10719
diff changeset
   597
    result = True
21222
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   598
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   599
    try:
29145
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
   600
        with opentext(f) as fp:
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
   601
            try:
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
   602
                pre = post = fp.read()
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
   603
            except UnicodeDecodeError as e:
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
   604
                print("%s while reading %s" % (e, f))
c641b8dfb98c check-code: handle py3 open divergence
timeless <timeless@mozdev.org>
parents: 29144
diff changeset
   605
                return result
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25659
diff changeset
   606
    except IOError as e:
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   607
        print("Skipping %s, %s" % (f, str(e).split(':', 1)[0]))
21222
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   608
        return result
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   609
4840abc83970 check-code: look at shebang to identify Python scripts
Matt Mackall <mpm@selenic.com>
parents: 21097
diff changeset
   610
    for name, match, magic, filters, pats in checks:
30245
01703a8b8a46 check-code: discard filtering result of previous check for independence
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29796
diff changeset
   611
        post = pre # discard filtering result of previous check
14135
673abd432104 check-code: adding debug flag
timeless <timeless@mozdev.org>
parents: 14009
diff changeset
   612
        if debug:
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   613
            print(name, f)
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   614
        fc = 0
28050
7e9e39228de6 check-code: examine magic pattern matching against contents of a file
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28035
diff changeset
   615
        if not (re.match(match, f) or (magic and re.search(magic, pre))):
14135
673abd432104 check-code: adding debug flag
timeless <timeless@mozdev.org>
parents: 14009
diff changeset
   616
            if debug:
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   617
                print("Skipping %s for %s it doesn't match %s" % (
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   618
                       name, match, f))
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   619
            continue
19382
5aeb03b48ab4 check-code: concatenate "check-code" on compile time
Simon Heimberg <simohe@besonet.ch>
parents: 19380
diff changeset
   620
        if "no-" "check-code" in pre:
27560
15b06f306c1f check-code: improve test-check-code error diffs
timeless <timeless@mozdev.org>
parents: 27557
diff changeset
   621
            # If you're looking at this line, it's because a file has:
15b06f306c1f check-code: improve test-check-code error diffs
timeless <timeless@mozdev.org>
parents: 27557
diff changeset
   622
            # no- check- code
15b06f306c1f check-code: improve test-check-code error diffs
timeless <timeless@mozdev.org>
parents: 27557
diff changeset
   623
            # but the reason to output skipping is to make life for
15b06f306c1f check-code: improve test-check-code error diffs
timeless <timeless@mozdev.org>
parents: 27557
diff changeset
   624
            # tests easier. So, instead of writing it with a normal
15b06f306c1f check-code: improve test-check-code error diffs
timeless <timeless@mozdev.org>
parents: 27557
diff changeset
   625
            # spelling, we write it with the expected spelling from
15b06f306c1f check-code: improve test-check-code error diffs
timeless <timeless@mozdev.org>
parents: 27557
diff changeset
   626
            # tests/test-check-code.t
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   627
            print("Skipping %s it has no-che?k-code (glob)" % f)
20239
16b5f498f49c check-code: always report when a file is skipped by "no-check-code"
Simon Heimberg <simohe@besonet.ch>
parents: 20238
diff changeset
   628
            return "Skip" # skip checking this file
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   629
        for p, r in filters:
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   630
            post = re.sub(p, r, post)
19422
d9e86d656017 check-code: automatically preppend "warning: " to all warning messages
Simon Heimberg <simohe@besonet.ch>
parents: 19382
diff changeset
   631
        nerrs = len(pats[0]) # nerr elements are errors
14009
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   632
        if warnings:
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   633
            pats = pats[0] + pats[1]
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   634
        else:
64de9ca66511 check-code: separate warnings to avoid repetitive str.startswith
Idan Kamara <idankk86@gmail.com>
parents: 14005
diff changeset
   635
            pats = pats[0]
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   636
        # print post # uncomment to show filtered version
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   637
14135
673abd432104 check-code: adding debug flag
timeless <timeless@mozdev.org>
parents: 14009
diff changeset
   638
        if debug:
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   639
            print("Checking %s for %s" % (name, f))
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   640
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   641
        prelines = None
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   642
        errors = []
19422
d9e86d656017 check-code: automatically preppend "warning: " to all warning messages
Simon Heimberg <simohe@besonet.ch>
parents: 19382
diff changeset
   643
        for i, pat in enumerate(pats):
16705
c2d9ef43ff6c check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents: 16704
diff changeset
   644
            if len(pat) == 3:
c2d9ef43ff6c check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents: 16704
diff changeset
   645
                p, msg, ignore = pat
c2d9ef43ff6c check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents: 16704
diff changeset
   646
            else:
c2d9ef43ff6c check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents: 16704
diff changeset
   647
                p, msg = pat
c2d9ef43ff6c check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents: 16704
diff changeset
   648
                ignore = None
20005
22154ec6fb8b check-code: prepend warning prefix only once, but for each warning
Simon Heimberg <simohe@besonet.ch>
parents: 19999
diff changeset
   649
            if i >= nerrs:
22154ec6fb8b check-code: prepend warning prefix only once, but for each warning
Simon Heimberg <simohe@besonet.ch>
parents: 19999
diff changeset
   650
                msg = "warning: " + msg
16705
c2d9ef43ff6c check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents: 16704
diff changeset
   651
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   652
            pos = 0
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   653
            n = 0
19308
84faaacbd3fa check-code: compile all patterns on initialisation
Simon Heimberg <simohe@besonet.ch>
parents: 19307
diff changeset
   654
            for m in p.finditer(post):
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   655
                if prelines is None:
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   656
                    prelines = pre.splitlines()
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   657
                    postlines = post.splitlines(True)
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   658
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   659
                start = m.start()
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   660
                while n < len(postlines):
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   661
                    step = len(postlines[n])
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   662
                    if pos + step > start:
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   663
                        break
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   664
                    pos += step
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   665
                    n += 1
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   666
                l = prelines[n]
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   667
20242
2dad90bdf29d check-code: drop now unused check-code-ignore
Simon Heimberg <simohe@besonet.ch>
parents: 20241
diff changeset
   668
                if ignore and re.search(ignore, l, re.MULTILINE):
20243
cc09cfea3dd4 check-code: print debug output when an ignore pattern matches
Simon Heimberg <simohe@besonet.ch>
parents: 20242
diff changeset
   669
                    if debug:
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   670
                        print("Skipping %s for %s:%s (ignore pattern)" % (
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   671
                            name, f, n))
16705
c2d9ef43ff6c check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents: 16704
diff changeset
   672
                    continue
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   673
                bd = ""
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   674
                if blame:
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   675
                    bd = 'working directory'
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   676
                    if not blamecache:
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   677
                        blamecache = getblame(f)
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   678
                    if n < len(blamecache):
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   679
                        bl, bu, br = blamecache[n]
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   680
                        if bl == l:
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   681
                            bd = '%s@%s' % (bu, br)
20005
22154ec6fb8b check-code: prepend warning prefix only once, but for each warning
Simon Heimberg <simohe@besonet.ch>
parents: 19999
diff changeset
   682
15502
7917a104a285 check-code: add --nolineno option for hiding line numbers
Mads Kiilerich <mads@kiilerich.com>
parents: 15457
diff changeset
   683
                errors.append((f, lineno and n + 1, l, msg, bd))
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   684
                result = False
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   685
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   686
        errors.sort()
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   687
        for e in errors:
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   688
            logfunc(*e)
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   689
            fc += 1
15873
a153a86a472c tests: keep track of all check-code.py warnings
Mads Kiilerich <mads@kiilerich.com>
parents: 15611
diff changeset
   690
            if maxerr and fc >= maxerr:
28509
9e3ecb6f4995 check-code: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28399
diff changeset
   691
                print(" (too many errors, giving up)")
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   692
                break
15281
aeeb2afcdc25 check-code: support multiline matches like try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 14978
diff changeset
   693
10720
fbcccf9ec58f check-code: add a return value to checkfile function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10719
diff changeset
   694
    return result
10717
b1f4fcef99b3 check-code: Add a ``checkfile`` function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10716
diff changeset
   695
29568
7825f6154a65 check-code: factor out boot procedure into main
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29566
diff changeset
   696
def main():
31824
4804644489cf check-code: use "-" to specify a list of files from stdin
Jun Wu <quark@fb.com>
parents: 31816
diff changeset
   697
    parser = optparse.OptionParser("%prog [options] [files | -]")
10895
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   698
    parser.add_option("-w", "--warnings", action="store_true",
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   699
                      help="include warning-level checks")
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   700
    parser.add_option("-p", "--per-file", type="int",
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   701
                      help="max warnings per file")
11604
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   702
    parser.add_option("-b", "--blame", action="store_true",
c5d40818b270 check-code: add --blame switch
Matt Mackall <mpm@selenic.com>
parents: 11602
diff changeset
   703
                      help="use annotate to generate blame info")
14135
673abd432104 check-code: adding debug flag
timeless <timeless@mozdev.org>
parents: 14009
diff changeset
   704
    parser.add_option("", "--debug", action="store_true",
673abd432104 check-code: adding debug flag
timeless <timeless@mozdev.org>
parents: 14009
diff changeset
   705
                      help="show debug information")
15502
7917a104a285 check-code: add --nolineno option for hiding line numbers
Mads Kiilerich <mads@kiilerich.com>
parents: 15457
diff changeset
   706
    parser.add_option("", "--nolineno", action="store_false",
7917a104a285 check-code: add --nolineno option for hiding line numbers
Mads Kiilerich <mads@kiilerich.com>
parents: 15457
diff changeset
   707
                      dest='lineno', help="don't show line numbers")
10895
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   708
15502
7917a104a285 check-code: add --nolineno option for hiding line numbers
Mads Kiilerich <mads@kiilerich.com>
parents: 15457
diff changeset
   709
    parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
7917a104a285 check-code: add --nolineno option for hiding line numbers
Mads Kiilerich <mads@kiilerich.com>
parents: 15457
diff changeset
   710
                        lineno=True)
10895
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   711
    (options, args) = parser.parse_args()
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   712
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   713
    if len(args) == 0:
10716
5f92bde72eef check-code: Only call check-code if __name__ = "__main__".
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10707
diff changeset
   714
        check = glob.glob("*")
31824
4804644489cf check-code: use "-" to specify a list of files from stdin
Jun Wu <quark@fb.com>
parents: 31816
diff changeset
   715
    elif args == ['-']:
4804644489cf check-code: use "-" to specify a list of files from stdin
Jun Wu <quark@fb.com>
parents: 31816
diff changeset
   716
        # read file list from stdin
4804644489cf check-code: use "-" to specify a list of files from stdin
Jun Wu <quark@fb.com>
parents: 31816
diff changeset
   717
        check = sys.stdin.read().splitlines()
10716
5f92bde72eef check-code: Only call check-code if __name__ = "__main__".
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10707
diff changeset
   718
    else:
10895
217557b26bc7 check-code: add a warnings level
Matt Mackall <mpm@selenic.com>
parents: 10814
diff changeset
   719
        check = args
10281
e7d3b509af8b Introduce check-code.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   720
29569
3d52e7c78a6b check-code: move fixing up regexp into main procedure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29568
diff changeset
   721
    _preparepats()
3d52e7c78a6b check-code: move fixing up regexp into main procedure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29568
diff changeset
   722
15544
53ef627cda30 check-code: fix return code initialization
Mads Kiilerich <mads@kiilerich.com>
parents: 15502
diff changeset
   723
    ret = 0
10716
5f92bde72eef check-code: Only call check-code if __name__ = "__main__".
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 10707
diff changeset
   724
    for f in check:
11816
e1359ad582f6 check-code: add exit status
Alecs King <alecsk@gmail.com>
parents: 11764
diff changeset
   725
        if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
15502
7917a104a285 check-code: add --nolineno option for hiding line numbers
Mads Kiilerich <mads@kiilerich.com>
parents: 15457
diff changeset
   726
                         blame=options.blame, debug=options.debug,
7917a104a285 check-code: add --nolineno option for hiding line numbers
Mads Kiilerich <mads@kiilerich.com>
parents: 15457
diff changeset
   727
                         lineno=options.lineno):
11816
e1359ad582f6 check-code: add exit status
Alecs King <alecsk@gmail.com>
parents: 11764
diff changeset
   728
            ret = 1
29568
7825f6154a65 check-code: factor out boot procedure into main
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29566
diff changeset
   729
    return ret
7825f6154a65 check-code: factor out boot procedure into main
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29566
diff changeset
   730
7825f6154a65 check-code: factor out boot procedure into main
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29566
diff changeset
   731
if __name__ == "__main__":
7825f6154a65 check-code: factor out boot procedure into main
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29566
diff changeset
   732
    sys.exit(main())