Mercurial > public > mercurial-scm > hg-stable
comparison contrib/check-code.py @ 14009:64de9ca66511
check-code: separate warnings to avoid repetitive str.startswith
author | Idan Kamara <idankk86@gmail.com> |
---|---|
date | Mon, 25 Apr 2011 13:03:26 +0300 |
parents | bb391e0515ba |
children | 673abd432104 |
comparison
equal
deleted
inserted
replaced
14008:da65edcac72a | 14009:64de9ca66511 |
---|---|
40 t = re.sub(r"\S", "x", m.group(2)) | 40 t = re.sub(r"\S", "x", m.group(2)) |
41 return m.group(1) + t | 41 return m.group(1) + t |
42 | 42 |
43 | 43 |
44 testpats = [ | 44 testpats = [ |
45 [ | |
45 (r'(pushd|popd)', "don't use 'pushd' or 'popd', use 'cd'"), | 46 (r'(pushd|popd)', "don't use 'pushd' or 'popd', use 'cd'"), |
46 (r'\W\$?\(\([^\)]*\)\)', "don't use (()) or $(()), use 'expr'"), | 47 (r'\W\$?\(\([^\)]*\)\)', "don't use (()) or $(()), use 'expr'"), |
47 (r'^function', "don't use 'function', use old style"), | 48 (r'^function', "don't use 'function', use old style"), |
48 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"), | 49 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"), |
49 (r'echo.*\\n', "don't use 'echo \\n', use printf"), | 50 (r'echo.*\\n', "don't use 'echo \\n', use printf"), |
65 ('^([^"\']|("[^"]*")|(\'[^\']*\'))*\\^', "^ must be quoted"), | 66 ('^([^"\']|("[^"]*")|(\'[^\']*\'))*\\^', "^ must be quoted"), |
66 (r'^source\b', "don't use 'source', use '.'"), | 67 (r'^source\b', "don't use 'source', use '.'"), |
67 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"), | 68 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"), |
68 (r'ls\s+[^|-]+\s+-', "options to 'ls' must come before filenames"), | 69 (r'ls\s+[^|-]+\s+-', "options to 'ls' must come before filenames"), |
69 (r'[^>]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"), | 70 (r'[^>]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"), |
71 ], | |
72 # warnings | |
73 [] | |
70 ] | 74 ] |
71 | 75 |
72 testfilters = [ | 76 testfilters = [ |
73 (r"( *)(#([^\n]*\S)?)", repcomment), | 77 (r"( *)(#([^\n]*\S)?)", repcomment), |
74 (r"<<(\S+)((.|\n)*?\n\1)", rephere), | 78 (r"<<(\S+)((.|\n)*?\n\1)", rephere), |
75 ] | 79 ] |
76 | 80 |
77 uprefix = r"^ \$ " | 81 uprefix = r"^ \$ " |
78 uprefixc = r"^ > " | 82 uprefixc = r"^ > " |
79 utestpats = [ | 83 utestpats = [ |
84 [ | |
80 (r'^(\S| $ ).*(\S\s+|^\s+)\n', "trailing whitespace on non-output"), | 85 (r'^(\S| $ ).*(\S\s+|^\s+)\n', "trailing whitespace on non-output"), |
81 (uprefix + r'.*\|\s*sed', "use regex test output patterns instead of sed"), | 86 (uprefix + r'.*\|\s*sed', "use regex test output patterns instead of sed"), |
82 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"), | 87 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"), |
83 (uprefix + r'.*\$\?', "explicit exit code checks unnecessary"), | 88 (uprefix + r'.*\$\?', "explicit exit code checks unnecessary"), |
84 (uprefix + r'.*\|\| echo.*(fail|error)', | 89 (uprefix + r'.*\|\| echo.*(fail|error)', |
85 "explicit exit code checks unnecessary"), | 90 "explicit exit code checks unnecessary"), |
86 (uprefix + r'set -e', "don't use set -e"), | 91 (uprefix + r'set -e', "don't use set -e"), |
87 (uprefixc + r'( *)\t', "don't use tabs to indent"), | 92 (uprefixc + r'( *)\t', "don't use tabs to indent"), |
88 ] | 93 ], |
89 | 94 # warnings |
90 for p, m in testpats: | 95 [] |
96 ] | |
97 | |
98 for p, m in testpats[0] + testpats[1]: | |
91 if p.startswith('^'): | 99 if p.startswith('^'): |
92 p = uprefix + p[1:] | 100 p = uprefix + p[1:] |
93 else: | 101 else: |
94 p = uprefix + p | 102 p = uprefix + p |
95 utestpats.append((p, m)) | 103 utestpats.append((p, m)) |
97 utestfilters = [ | 105 utestfilters = [ |
98 (r"( *)(#([^\n]*\S)?)", repcomment), | 106 (r"( *)(#([^\n]*\S)?)", repcomment), |
99 ] | 107 ] |
100 | 108 |
101 pypats = [ | 109 pypats = [ |
110 [ | |
102 (r'^\s*def\s*\w+\s*\(.*,\s*\(', | 111 (r'^\s*def\s*\w+\s*\(.*,\s*\(', |
103 "tuple parameter unpacking not available in Python 3+"), | 112 "tuple parameter unpacking not available in Python 3+"), |
104 (r'lambda\s*\(.*,.*\)', | 113 (r'lambda\s*\(.*,.*\)', |
105 "tuple parameter unpacking not available in Python 3+"), | 114 "tuple parameter unpacking not available in Python 3+"), |
106 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"), | 115 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"), |
110 (r'\S;\s*\n', "semicolon"), | 119 (r'\S;\s*\n', "semicolon"), |
111 (r'\w,\w', "missing whitespace after ,"), | 120 (r'\w,\w', "missing whitespace after ,"), |
112 (r'\w[+/*\-<>]\w', "missing whitespace in expression"), | 121 (r'\w[+/*\-<>]\w', "missing whitespace in expression"), |
113 (r'^\s+\w+=\w+[^,)]$', "missing whitespace in assignment"), | 122 (r'^\s+\w+=\w+[^,)]$', "missing whitespace in assignment"), |
114 (r'.{85}', "line too long"), | 123 (r'.{85}', "line too long"), |
115 (r'.{81}', "warning: line over 80 characters"), | |
116 (r'[^\n]\Z', "no trailing newline"), | 124 (r'[^\n]\Z', "no trailing newline"), |
117 (r'(\S\s+|^\s+)\n', "trailing whitespace"), | 125 (r'(\S\s+|^\s+)\n', "trailing whitespace"), |
118 # (r'^\s+[^_ ][^_. ]+_[^_]+\s*=', "don't use underbars in identifiers"), | 126 # (r'^\s+[^_ ][^_. ]+_[^_]+\s*=', "don't use underbars in identifiers"), |
119 # (r'\w*[a-z][A-Z]\w*\s*=', "don't use camelcase in identifiers"), | 127 # (r'\w*[a-z][A-Z]\w*\s*=', "don't use camelcase in identifiers"), |
120 (r'^\s*(if|while|def|class|except|try)\s[^[]*:\s*[^\]#\s]+', | 128 (r'^\s*(if|while|def|class|except|try)\s[^[]*:\s*[^\]#\s]+', |
148 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', | 156 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', |
149 "missing whitespace around operator"), | 157 "missing whitespace around operator"), |
150 (r'[^+=*!<>&| -](\s=|=\s)[^= ]', | 158 (r'[^+=*!<>&| -](\s=|=\s)[^= ]', |
151 "wrong whitespace around ="), | 159 "wrong whitespace around ="), |
152 (r'raise Exception', "don't raise generic exceptions"), | 160 (r'raise Exception', "don't raise generic exceptions"), |
161 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"), | |
162 (r' [=!]=\s+(True|False|None)', | |
163 "comparison with singleton, use 'is' or 'is not' instead"), | |
164 ], | |
165 # warnings | |
166 [ | |
167 (r'.{81}', "warning: line over 80 characters"), | |
153 (r'^\s*except:$', "warning: naked except clause"), | 168 (r'^\s*except:$', "warning: naked except clause"), |
154 (r'ui\.(status|progress|write|note|warn)\([\'\"]x', | 169 (r'ui\.(status|progress|write|note|warn)\([\'\"]x', |
155 "warning: unwrapped ui message"), | 170 "warning: unwrapped ui message"), |
156 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"), | 171 ] |
157 (r' [=!]=\s+(True|False|None)', | |
158 "comparison with singleton, use 'is' or 'is not' instead"), | |
159 ] | 172 ] |
160 | 173 |
161 pyfilters = [ | 174 pyfilters = [ |
162 (r"""(?msx)(?P<comment>\#.*?$)| | 175 (r"""(?msx)(?P<comment>\#.*?$)| |
163 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!"))) | 176 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!"))) |
164 (?P<text>(([^\\]|\\.)*?)) | 177 (?P<text>(([^\\]|\\.)*?)) |
165 (?P=quote))""", reppython), | 178 (?P=quote))""", reppython), |
166 ] | 179 ] |
167 | 180 |
168 cpats = [ | 181 cpats = [ |
182 [ | |
169 (r'//', "don't use //-style comments"), | 183 (r'//', "don't use //-style comments"), |
170 (r'^ ', "don't use spaces to indent"), | 184 (r'^ ', "don't use spaces to indent"), |
171 (r'\S\t', "don't use tabs except for indent"), | 185 (r'\S\t', "don't use tabs except for indent"), |
172 (r'(\S\s+|^\s+)\n', "trailing whitespace"), | 186 (r'(\S\s+|^\s+)\n', "trailing whitespace"), |
173 (r'.{85}', "line too long"), | 187 (r'.{85}', "line too long"), |
180 (r'\w,\w', "missing whitespace after ,"), | 194 (r'\w,\w', "missing whitespace after ,"), |
181 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"), | 195 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"), |
182 (r'^#\s+\w', "use #foo, not # foo"), | 196 (r'^#\s+\w', "use #foo, not # foo"), |
183 (r'[^\n]\Z', "no trailing newline"), | 197 (r'[^\n]\Z', "no trailing newline"), |
184 (r'^\s*#import\b', "use only #include in standard C code"), | 198 (r'^\s*#import\b', "use only #include in standard C code"), |
199 ], | |
200 # warnings | |
201 [] | |
185 ] | 202 ] |
186 | 203 |
187 cfilters = [ | 204 cfilters = [ |
188 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment), | 205 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment), |
189 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote), | 206 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote), |
256 fp.close() | 273 fp.close() |
257 if "no-" + "check-code" in pre: | 274 if "no-" + "check-code" in pre: |
258 break | 275 break |
259 for p, r in filters: | 276 for p, r in filters: |
260 post = re.sub(p, r, post) | 277 post = re.sub(p, r, post) |
278 if warnings: | |
279 pats = pats[0] + pats[1] | |
280 else: | |
281 pats = pats[0] | |
261 # print post # uncomment to show filtered version | 282 # print post # uncomment to show filtered version |
262 z = enumerate(zip(pre.splitlines(), post.splitlines(True))) | 283 z = enumerate(zip(pre.splitlines(), post.splitlines(True))) |
263 for n, l in z: | 284 for n, l in z: |
264 if "check-code" + "-ignore" in l[0]: | 285 if "check-code" + "-ignore" in l[0]: |
265 continue | 286 continue |
266 for p, msg in pats: | 287 for p, msg in pats: |
267 if not warnings and msg.startswith("warning"): | |
268 continue | |
269 if re.search(p, l[1]): | 288 if re.search(p, l[1]): |
270 bd = "" | 289 bd = "" |
271 if blame: | 290 if blame: |
272 bd = 'working directory' | 291 bd = 'working directory' |
273 if not blamecache: | 292 if not blamecache: |