mbligh | 99d2ded | 2008-06-23 16:17:36 +0000 | [diff] [blame] | 1 | #!/usr/bin/python -u |
| 2 | |
| 3 | import os, sys, fnmatch |
| 4 | import common |
| 5 | |
mbligh | 65e06b1 | 2008-08-22 18:12:49 +0000 | [diff] [blame] | 6 | # do a basic check to see if pylint is even installed |
| 7 | try: |
| 8 | import pylint |
Eric Li | 861b2d5 | 2011-02-04 14:50:35 -0800 | [diff] [blame] | 9 | from pylint.__pkginfo__ import version as pylint_version |
mbligh | 65e06b1 | 2008-08-22 18:12:49 +0000 | [diff] [blame] | 10 | except ImportError: |
| 11 | print "Unable to import pylint, it may need to be installed" |
| 12 | sys.exit(1) |
| 13 | |
Eric Li | 861b2d5 | 2011-02-04 14:50:35 -0800 | [diff] [blame] | 14 | major, minor, release = pylint_version.split('.') |
| 15 | pylint_version = float("%s.%s" % (major, minor)) |
mbligh | 99d2ded | 2008-06-23 16:17:36 +0000 | [diff] [blame] | 16 | pylintrc_path = os.path.expanduser('~/.pylintrc') |
| 17 | if not os.path.exists(pylintrc_path): |
| 18 | open(pylintrc_path, 'w').close() |
| 19 | |
jadmanski | 94a6493 | 2008-07-22 14:03:10 +0000 | [diff] [blame] | 20 | |
| 21 | # patch up the logilab module lookup tools to understand autotest_lib.* trash |
| 22 | import logilab.common.modutils |
| 23 | _ffm = logilab.common.modutils.file_from_modpath |
| 24 | def file_from_modpath(modpath, path=None, context_file=None): |
| 25 | if modpath[0] == "autotest_lib": |
| 26 | return _ffm(modpath[1:], path, context_file) |
| 27 | else: |
| 28 | return _ffm(modpath, path, context_file) |
| 29 | logilab.common.modutils.file_from_modpath = file_from_modpath |
| 30 | |
| 31 | |
mbligh | 99d2ded | 2008-06-23 16:17:36 +0000 | [diff] [blame] | 32 | import pylint.lint |
| 33 | from pylint.checkers import imports |
| 34 | |
| 35 | ROOT_MODULE = 'autotest_lib.' |
| 36 | |
| 37 | # need to put autotest root dir on sys.path so pylint will be happy |
| 38 | autotest_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) |
| 39 | sys.path.insert(0, autotest_root) |
| 40 | |
| 41 | # patch up pylint import checker to handle our importing magic |
| 42 | RealImportsChecker = imports.ImportsChecker |
| 43 | |
| 44 | class CustomImportsChecker(imports.ImportsChecker): |
| 45 | def visit_from(self, node): |
| 46 | if node.modname.startswith(ROOT_MODULE): |
| 47 | node.modname = node.modname[len(ROOT_MODULE):] |
| 48 | return RealImportsChecker.visit_from(self, node) |
| 49 | |
| 50 | imports.ImportsChecker = CustomImportsChecker |
| 51 | |
| 52 | # some files make pylint blow up, so make sure we ignore them |
| 53 | blacklist = ['/contrib/*', '/frontend/afe/management.py'] |
| 54 | |
| 55 | # only show errors |
Dale Curtis | 8adf789 | 2011-09-08 16:13:36 -0700 | [diff] [blame] | 56 | # there are three major sources of E1101/E1103/E1120 false positives: |
lmr | 2d6decc | 2009-12-02 00:05:54 +0000 | [diff] [blame] | 57 | # * common_lib.enum.Enum objects |
| 58 | # * DB model objects (scheduler models are the worst, but Django models also |
| 59 | # generate some errors) |
Eric Li | 861b2d5 | 2011-02-04 14:50:35 -0800 | [diff] [blame] | 60 | if pylint_version >= 0.21: |
Dale Curtis | 8adf789 | 2011-09-08 16:13:36 -0700 | [diff] [blame] | 61 | pylint_base_opts = ['--disable=W,R,C,E1101,E1103,E1120'] |
Eric Li | 861b2d5 | 2011-02-04 14:50:35 -0800 | [diff] [blame] | 62 | else: |
| 63 | pylint_base_opts = ['--disable-msg-cat=warning,refactor,convention', |
Dale Curtis | 8adf789 | 2011-09-08 16:13:36 -0700 | [diff] [blame] | 64 | '--disable-msg=E1101,E1103,E1120'] |
Eric Li | 861b2d5 | 2011-02-04 14:50:35 -0800 | [diff] [blame] | 65 | pylint_base_opts += ['--reports=no', |
| 66 | '--include-ids=y'] |
mbligh | 99d2ded | 2008-06-23 16:17:36 +0000 | [diff] [blame] | 67 | |
| 68 | file_list = sys.argv[1:] |
| 69 | if '--' in file_list: |
| 70 | index = file_list.index('--') |
| 71 | pylint_base_opts.extend(file_list[index+1:]) |
| 72 | file_list = file_list[:index] |
| 73 | |
| 74 | |
| 75 | def check_file(file_path): |
| 76 | if not file_path.endswith('.py'): |
| 77 | return |
| 78 | for blacklist_pattern in blacklist: |
| 79 | if fnmatch.fnmatch(os.path.abspath(file_path), |
| 80 | '*' + blacklist_pattern): |
| 81 | return |
| 82 | pylint.lint.Run(pylint_base_opts + [file_path]) |
| 83 | |
| 84 | |
| 85 | def visit(arg, dirname, filenames): |
| 86 | for filename in filenames: |
| 87 | check_file(os.path.join(dirname, filename)) |
| 88 | |
| 89 | |
| 90 | def check_dir(dir_path): |
| 91 | os.path.walk(dir_path, visit, None) |
| 92 | |
| 93 | |
| 94 | if len(file_list) > 0: |
| 95 | for path in file_list: |
| 96 | if os.path.isdir(path): |
| 97 | check_dir(path) |
| 98 | else: |
| 99 | check_file(path) |
| 100 | else: |
| 101 | check_dir('.') |