blob: 515814a41f345ef4bd49a3e4260056d5ab1e9afd [file] [log] [blame]
mbligh99d2ded2008-06-23 16:17:36 +00001#!/usr/bin/python -u
2
3import os, sys, fnmatch
4import common
5
mbligh65e06b12008-08-22 18:12:49 +00006# do a basic check to see if pylint is even installed
7try:
8 import pylint
Eric Li861b2d52011-02-04 14:50:35 -08009 from pylint.__pkginfo__ import version as pylint_version
mbligh65e06b12008-08-22 18:12:49 +000010except ImportError:
11 print "Unable to import pylint, it may need to be installed"
12 sys.exit(1)
13
Eric Li861b2d52011-02-04 14:50:35 -080014major, minor, release = pylint_version.split('.')
15pylint_version = float("%s.%s" % (major, minor))
mbligh99d2ded2008-06-23 16:17:36 +000016pylintrc_path = os.path.expanduser('~/.pylintrc')
17if not os.path.exists(pylintrc_path):
18 open(pylintrc_path, 'w').close()
19
jadmanski94a64932008-07-22 14:03:10 +000020
21# patch up the logilab module lookup tools to understand autotest_lib.* trash
22import logilab.common.modutils
23_ffm = logilab.common.modutils.file_from_modpath
24def 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)
29logilab.common.modutils.file_from_modpath = file_from_modpath
30
31
mbligh99d2ded2008-06-23 16:17:36 +000032import pylint.lint
33from pylint.checkers import imports
34
35ROOT_MODULE = 'autotest_lib.'
36
37# need to put autotest root dir on sys.path so pylint will be happy
38autotest_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
39sys.path.insert(0, autotest_root)
40
41# patch up pylint import checker to handle our importing magic
42RealImportsChecker = imports.ImportsChecker
43
44class 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
50imports.ImportsChecker = CustomImportsChecker
51
52# some files make pylint blow up, so make sure we ignore them
53blacklist = ['/contrib/*', '/frontend/afe/management.py']
54
55# only show errors
Dale Curtis8adf7892011-09-08 16:13:36 -070056# there are three major sources of E1101/E1103/E1120 false positives:
lmr2d6decc2009-12-02 00:05:54 +000057# * common_lib.enum.Enum objects
58# * DB model objects (scheduler models are the worst, but Django models also
59# generate some errors)
Eric Li861b2d52011-02-04 14:50:35 -080060if pylint_version >= 0.21:
Dale Curtis8adf7892011-09-08 16:13:36 -070061 pylint_base_opts = ['--disable=W,R,C,E1101,E1103,E1120']
Eric Li861b2d52011-02-04 14:50:35 -080062else:
63 pylint_base_opts = ['--disable-msg-cat=warning,refactor,convention',
Dale Curtis8adf7892011-09-08 16:13:36 -070064 '--disable-msg=E1101,E1103,E1120']
Eric Li861b2d52011-02-04 14:50:35 -080065pylint_base_opts += ['--reports=no',
66 '--include-ids=y']
mbligh99d2ded2008-06-23 16:17:36 +000067
68file_list = sys.argv[1:]
69if '--' 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
75def 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
85def visit(arg, dirname, filenames):
86 for filename in filenames:
87 check_file(os.path.join(dirname, filename))
88
89
90def check_dir(dir_path):
91 os.path.walk(dir_path, visit, None)
92
93
94if 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)
100else:
101 check_dir('.')