There's a fair number of errors right now, some of which could be false
positives, but I am going to take care of those in subsequent commits.
---
Makefile | 3 +
python-blivet.spec | 2 +
tests/pylint/intl.py | 63 ---------
tests/pylint/pointless-override.py | 273 ------------------------------------
tests/pylint/pylint-false-positives | 28 ----
tests/pylint/pylint-one.sh | 33 -----
tests/pylint/runpylint.py | 34 +++++
tests/pylint/runpylint.sh | 125 -----------------
8 files changed, 39 insertions(+), 522 deletions(-)
delete mode 100644 tests/pylint/intl.py
delete mode 100644 tests/pylint/pointless-override.py
delete mode 100644 tests/pylint/pylint-false-positives
delete mode 100755 tests/pylint/pylint-one.sh
create mode 100755 tests/pylint/runpylint.py
delete mode 100755 tests/pylint/runpylint.sh
diff --git a/Makefile b/Makefile
index 9f60551..a55f500 100644
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,9 @@ coverage:
PYTHONPATH=.:tests/ coverage run --branch -m unittest discover -v -s tests/ -p
'*_test.py'
coverage report --include="blivet/*"
+check:
+ PYTHONPATH=. tests/pylint/runpylint.py
+
clean:
-rm *.tar.gz blivet/*.pyc blivet/*/*.pyc ChangeLog
$(MAKE) -C po clean
diff --git a/python-blivet.spec b/python-blivet.spec
index eeaaba8..ef4bacb 100644
--- a/python-blivet.spec
+++ b/python-blivet.spec
@@ -13,6 +13,7 @@ Source0:
http://github.com/dwlehman/blivet/archive/%{realname}-%{version}.tar.gz
# Versions of required components (done so we make sure the buildrequires
# match the requires versions of things).
%define pykickstartver 1.99.22
+%define pocketlintver 0.4
%define partedver 1.8.1
%define pypartedver 3.10.3
%define e2fsver 1.41.0
@@ -22,6 +23,7 @@ Source0:
http://github.com/dwlehman/blivet/archive/%{realname}-%{version}.tar.gz
BuildArch: noarch
BuildRequires: gettext
BuildRequires: python-setuptools
+BuildRequires: python3-pocketlint >= %{pocketlintver}
%if 0%{with_python3}
BuildRequires: python3-devel python3-setuptools
diff --git a/tests/pylint/intl.py b/tests/pylint/intl.py
deleted file mode 100644
index 3052680..0000000
--- a/tests/pylint/intl.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# I18N-related pylint module
-#
-# Copyright (C) 2013 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Chris Lumens <clumens(a)redhat.com>
-#
-
-import astroid
-
-from pylint.checkers import BaseChecker
-from pylint.checkers.utils import check_messages
-from pylint.interfaces import IAstroidChecker
-
-translationMethods = ["_", "N_", "P_", "C_",
"CN_", "CP_"]
-
-class IntlChecker(BaseChecker):
- __implements__ = (IAstroidChecker, )
- name = "internationalization"
- msgs = {"W9901": ("Found % in a call to a _() method",
- "found-percent-in-_",
- "% in a call to one of the _() methods results in incorrect
translations"),
- "W9902": ("Found _ call at module/class level",
- "found-_-in-module-class",
- "Calling _ at the module or class level results in
translations to the wrong language")
- }
-
- @check_messages("W9901")
- def visit_binop(self, node):
- if node.op != "%":
- return
-
- curr = node
- while curr.parent:
- if isinstance(curr.parent, astroid.CallFunc) and getattr(curr.parent.func,
"name", "") in translationMethods:
- self.add_message("W9901", node=node)
- break
-
- curr = curr.parent
-
- @check_messages("W9902")
- def visit_callfunc(self, node):
- # The first test skips internal functions like getattr.
- if isinstance(node.func, astroid.Name) and node.func.name == "_":
- if isinstance(node.scope(), astroid.Module) or isinstance(node.scope(),
astroid.Class):
- self.add_message("W9902", node=node)
-
-def register(linter):
- """required method to auto register this checker """
- linter.register_checker(IntlChecker(linter))
diff --git a/tests/pylint/pointless-override.py b/tests/pylint/pointless-override.py
deleted file mode 100644
index e5f0fd8..0000000
--- a/tests/pylint/pointless-override.py
+++ /dev/null
@@ -1,273 +0,0 @@
-# Pylint checker for pointless class attributes overrides.
-#
-# Copyright (C) 2014 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Anne Mulhern <amulhern(a)redhat.com>
-#
-
-import abc
-
-from six import add_metaclass
-
-import astroid
-
-from pylint.checkers import BaseChecker
-from pylint.checkers.utils import check_messages
-from pylint.interfaces import IAstroidChecker
-
-(a)add_metaclass(abc.ABCMeta)
-class PointlessData(object):
-
- _DEF_CLASS = abc.abstractproperty(doc="Class of interesting definitions.")
- message_id = abc.abstractproperty(doc="Pylint message identifier.")
-
- @classmethod
- @abc.abstractmethod
- def _retain_node(cls, node, restrict=True):
- """ Determines whether to retain a node for the analysis.
-
- :param node: an AST node
- :type node: astroid.Class
- :param restrict bool: True if results returned should be restricted
- :returns: True if the node should be kept, otherwise False
- :rtype: bool
-
- Restricted nodes are candidates for being marked as overridden.
- Only restricted nodes are put into the initial pool of candidates.
- """
- raise NotImplementedError()
-
- @staticmethod
- @abc.abstractmethod
- def _extract_value(node):
- """ Return the node that contains the assignment's value.
-
- :param node: an AST node
- :type node: astroid.Class
- :returns: the node corresponding to the value
- :rtype: bool
- """
- raise NotImplementedError()
-
- @staticmethod
- @abc.abstractmethod
- def _extract_targets(node):
- """ Generates the names being assigned to.
-
- :param node: an AST node
- :type node: astroid.Class
- :returns: a list of assignment target names
- :rtype: generator of str
- """
- raise NotImplementedError()
-
- @classmethod
- def get_data(cls, node, restrict=True):
- """ Find relevant nodes for this analysis.
-
- :param node: an AST node
- :type node: astroid.Class
- :param restrict bool: True if results returned should be restricted
-
- :rtype: generator of astroid.Class
- :returns: a generator of interesting nodes.
-
- Note that all nodes returned are guaranteed to be instances of
- some class in self._DEF_CLASS.
- """
- nodes = (n for n in node.body if isinstance(n, cls._DEF_CLASS))
- for n in nodes:
- if cls._retain_node(n, restrict):
- for name in cls._extract_targets(n):
- yield (name, cls._extract_value(n))
-
- @classmethod
- @abc.abstractmethod
- def check_equal(cls, node, other):
- """ Check whether the two nodes are considered equal.
-
- :param node: some ast node
- :param other: some ast node
-
- :rtype: bool
- :returns: True if the nodes are considered equal, otherwise False
-
- If the method returns True, the nodes are actually equal, but it
- may return False when the nodes are equal.
- """
- raise NotImplementedError()
-
-class PointlessFunctionDefinition(PointlessData):
- """ Looking for pointless function definitions. """
-
- _DEF_CLASS = astroid.Function
- message_id = "W9952"
-
- @classmethod
- def _retain_node(cls, node, restrict=True):
- return not restrict or \
- (len(node.body) == 1 and isinstance(node.body[0], astroid.Pass))
-
- @classmethod
- def check_equal(cls, node, other):
- return len(node.body) == 1 and isinstance(node.body[0], astroid.Pass) and \
- len(other.body) == 1 and isinstance(other.body[0], astroid.Pass)
-
- @staticmethod
- def _extract_value(node):
- return node
-
- @staticmethod
- def _extract_targets(node):
- yield node.name
-
-class PointlessAssignment(PointlessData):
-
- _DEF_CLASS = astroid.Assign
- message_id = "W9951"
-
- _VALUE_CLASSES = (
- astroid.CallFunc,
- astroid.Const,
- astroid.Dict,
- astroid.List,
- astroid.Tuple
- )
-
- @classmethod
- def _retain_node(cls, node, restrict=True):
- return not restrict or isinstance(node.value, cls._VALUE_CLASSES)
-
- @classmethod
- def check_equal(cls, node, other):
- if type(node) != type(other):
- return False
- if isinstance(node, astroid.Const):
- return node.value == other.value
- if isinstance(node, (astroid.List, astroid.Tuple)):
- return len(node.elts) == len(other.elts) and \
- all(cls.check_equal(n, o) for (n, o) in zip(node.elts, other.elts))
- if isinstance(node, astroid.Dict):
- return len(node.items) == len(other.items) and \
- all(cls.check_equal(n, o) for (n, o) in zip(sorted(node.items),
sorted(other.items)))
- if isinstance(node, astroid.CallFunc):
- if type(node.func) != type(other.func):
- return False
-
- if isinstance(node.func, astroid.Getattr):
- if node.func.attrname != other.func.attrname or \
- type(node.func.expr) != type(other.func.expr) or \
- node.func.expr.name != other.func.expr.name:
- return False
- elif isinstance(node.func, astroid.Name):
- if node.func.name != other.func.name:
- return False
- else:
- return False
-
- return node.starargs == other.starargs and \
- node.kwargs == other.kwargs and \
- node.args == other.args
-
- return False
-
- @staticmethod
- def _extract_value(node):
- return node.value
-
- @staticmethod
- def _extract_targets(node):
- for target in node.targets:
- yield target.name
-
-class PointlessClassAttributeOverrideChecker(BaseChecker):
- """ If the nearest definition of the class attribute in the MRO
assigns
- it the same value, then the overriding definition is said to be
- pointless.
-
- The algorithm for detecting a pointless attribute override is the following.
-
- * For each class, C:
- - For each attribute assignment,
- name_1 = name_2 ... name_n = l (where l is a literal):
- * For each n in (n_1, n_2):
- - Traverse the linearization of the MRO until the first
- matching assignment n = l' is identified. If l is equal to
l',
- then consider that the assignment to l in C is a
- pointless override.
-
- The algorithm for detecting a pointless method override has the same
- general structure, and the same defects discussed below.
-
- Note that this analysis is neither sound nor complete. It is unsound
- under multiple inheritance. Consider the following class hierarchy::
-
- class A(object):
- _attrib = False
-
- class B(A):
- _attrib = False
-
- class C(A):
- _attrib = True
-
- class D(B,C):
- pass
-
- In this case, starting from B, B._attrib = False would be considered
- pointless. However, for D the MRO is B, C, A, and removing the assignment
- B._attrib = False would change the inherited value of D._attrib from
- False to True.
-
- The analysis is incomplete because it will find some values unequal when
- actually they are equal.
-
- The analysis is both incomplete and unsound because it expects that
- assignments will always be made by means of the same syntax.
- """
-
- __implements__ = (IAstroidChecker,)
-
- name = "pointless class attribute override checker"
- msgs = {
- "W9951":
- (
- "Assignment to class attribute %s overrides identical assignment in
ancestor %s.",
- "pointless-class-attribute-override",
- "Assignment to class attribute that overrides assignment in ancestor that
assigns identical value has no effect."
- ),
- "W9952":
- (
- "Definition of %s method overrides identical method definition in ancestor
%s.",
- "pointless-method-definition-override",
- "Overriding empty method definition with another empty method definition
has no effect."
- )
- }
-
- @check_messages("W9951", "W9952")
- def visit_class(self, node):
- for checker in (PointlessAssignment, PointlessFunctionDefinition):
- for (name, value) in checker.get_data(node):
- for a in node.ancestors():
- match = next((v for (n, v) in checker.get_data(a, False) if n ==
name), None)
- if match is not None:
- if checker.check_equal(value, match):
- self.add_message(checker.message_id, node=value,
args=(name,a.name))
- break
-
-def register(linter):
- linter.register_checker(PointlessClassAttributeOverrideChecker(linter))
diff --git a/tests/pylint/pylint-false-positives b/tests/pylint/pylint-false-positives
deleted file mode 100644
index 9037510..0000000
--- a/tests/pylint/pylint-false-positives
+++ /dev/null
@@ -1,28 +0,0 @@
-^(blivet|tests)/.*: \[E1101\(no-member\).*\] Instance of 'int' has no .* member
-^blivet/.*: \[E0611\(no\-name\-in\-module\).*\] No name 'blockdev' in module
'gi.repository'$
-^blivet/.*: \[E0712\(catching\-non\-exception\).*\] Catching an exception which
doesn't inherit from BaseException: (BlockDev|DM|Crypto|Swap|LVM|Btrfs|MDRaid|)Error$
-^blivet/.*: \[E0712\(catching\-non\-exception\).*\] Catching an exception which
doesn't inherit from BaseException: GError$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'BootLoaderError' but no assignment is
done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'ERROR_RAISE' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'ROOT_PATH' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'errorHandler' but no assignment is
done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'get_bootloader' but no assignment is
done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'isys' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'iutil' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'productName' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\),
enable_installer_mode\] Using global for 'shortProductName' but no assignment is
done$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\]
Unused variable 'ERROR_RAISE'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\]
Unused variable 'ROOT_PATH'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\]
Unused variable 'errorHandler'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\]
Unused variable 'get_bootloader'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\]
Unused variable 'isys'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\]
Unused variable 'productName'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\]
Unused variable 'shortProductName'$
-^blivet/arch.py:[[:digit:]]+: \[F0401\(import\-error\), numBits\] Unable to import
'platform'$
-^blivet/blivet.py:[[:digit:]]+: \[E1101\(no\-member\), Blivet.savePassphrase\] Instance
of 'DeviceTree' has no '_DeviceTree__luksDevs' member$
-^blivet/blivet.py:[[:digit:]]+: \[E1101\(no\-member\), Blivet.savePassphrase\] Instance
of 'DeviceTree' has no '_DeviceTree__passphrases' member$
-^blivet/formats/__init__.py:[[:digit:]]+: \[W0201\(attribute\-defined\-outside\-init\),
DeviceFormat._setDevice\] Attribute '_device' defined outside __init__$
-^dm.c: [[:digit:]]+: not running as root returning empty list$
-^tests/devicelibs_test/mdraid_test.py:[[:digit:]]+: \[E1003\(bad\-super\-call\),
([[:alnum:]\.]+).__init__\] Bad first argument YES given to super\(\)$
-^tests/devicelibs_test/raid_test.py:[[:digit:]]+: \[E1120\(no\-value\-for\-parameter\),
[[:alnum:]\.]+\] No value [[:alnum:] ]+ 'member_count' in [[:alnum:] ]+ call$
-^tests/devicelibs_test/raid_test.py:[[:digit:]]+: \[E1120\(no\-value\-for\-parameter\),
[[:alnum:]\.]+\] No value [[:alnum:] ]+ 'smallest_member_size' in [[:alnum:] ]+
call$
diff --git a/tests/pylint/pylint-one.sh b/tests/pylint/pylint-one.sh
deleted file mode 100755
index 9b1e79b..0000000
--- a/tests/pylint/pylint-one.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-#
-# $1 -- python source to run pylint on
-#
-
-if [ $# -lt 1 ]; then
- # no source, just exit
- exit 1
-fi
-
-file_suffix="$(eval echo \$$#|sed s?/?_?g)"
-
-pylint_output="$(pylint \
- --msg-template='{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}' \
- -r n --disable=C,R --rcfile=/dev/null \
- --dummy-variables-rgx=_ \
- --ignored-classes=Popen,TransactionSet \
- --defining-attr-methods=__init__,_grabObjects,initialize,reset,start,setUp \
- --load-plugins=intl,pointless-override \
- $DISABLED_WARN_OPTIONS \
- $DISABLED_ERR_OPTIONS \
- $NON_STRICT_OPTIONS "$@" 2>&1 | \
- egrep -v -f "$FALSE_POSITIVES" \
- )"
-
-# I0011 is the informational "Locally disabling ...." message
-if [ -n "$(echo "$pylint_output" | fgrep -v '************* Module
' |\
- grep -v '^I0011:')" ]; then
- # Replace the Module line with the actual filename
- pylint_output="$(echo "$pylint_output" | sed "s|\* Module .*|*
Module $(eval echo \$$#)|")"
- echo "$pylint_output" > pylint-out_$file_suffix
- touch "pylint-$file_suffix-failed"
-fi
diff --git a/tests/pylint/runpylint.py b/tests/pylint/runpylint.py
new file mode 100755
index 0000000..859c3ea
--- /dev/null
+++ b/tests/pylint/runpylint.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python3
+
+import os
+
+from pocketlint import FalsePositive, PocketLintConfig, PocketLinter
+
+class BlivetLintConfig(PocketLintConfig):
+ def __init__(self):
+ PocketLintConfig.__init__(self)
+
+ self.falsePositives = [ FalsePositive(r"Catching an exception which
doesn't inherit from BaseException:
(BlockDev|DM|Crypto|Swap|LVM|Btrfs|MDRaid|)Error$"),
+ FalsePositive(r"Instance of 'int' has no .*
member$"),
+ FalsePositive(r"No value for argument
'member_count' in unbound method call$"),
+ FalsePositive(r"No value for argument
'smallest_member_size' in unbound method call$"),
+ ]
+
+ @property
+ def disabledOptions(self):
+ return [ "W0105", # String statement has no effect
+ "W0110", # map/filter on lambda could be replaced by
comprehension
+ "W0141", # Used builtin function %r
+ "W0142", # Used * or ** magic
+ "W0212", # Access to a protected member of a client
class
+ "W0511", # Used when a warning note as FIXME or XXX
is detected.
+ "W0603", # Using the global statement
+ "W0614", # Unused import %s from wildcard import
+ "I0011", # Locally disabling %s
+ ]
+
+if __name__ == "__main__":
+ conf = BlivetLintConfig()
+ linter = PocketLinter(conf)
+ rc = linter.run()
+ os._exit(rc)
diff --git a/tests/pylint/runpylint.sh b/tests/pylint/runpylint.sh
deleted file mode 100755
index 18200bf..0000000
--- a/tests/pylint/runpylint.sh
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/bin/bash
-
-# This script will check for any pylint warning and errors using a set
-# of options minimizing false positives, in combination with filtering of any
-# warning regularexpressions listed in pylint-false-positives.
-#
-# If any warnings are found they will be stored in pylint-log and printed
-# to stdout and this script will exit with a status of 1, if no (non filtered)
-# warnings are found it exits with a status of 0
-
-# If $top_srcdir is set, assume this is being run from automake and we don't
-# need to keep a separate log
-export pylint_log=0
-if [ -z "$top_srcdir" ]; then
- export pylint_log=1
-fi
-
-# Unset TERM so that things that use readline don't output terminal garbage
-unset TERM
-
-# Don't try to connect to the accessibility socket
-export NO_AT_BRIDGE=1
-
-# If $top_srcdir has not been set by automake, import the test environment
-if [ -z "$top_srcdir" ]; then
- top_srcdir="$(dirname "$0")/../.."
- . ${top_srcdir}/tests/testenv.sh
-fi
-
-. ${top_srcdir}/tests/lib/testlib.sh
-
-srcdir="${top_srcdir}/tests/pylint"
-builddir="${top_builddir}/tests/pylint"
-
-# Need to add the pylint module directory to PYTHONPATH as well.
-export PYTHONPATH="${PYTHONPATH}:${srcdir}"
-
-# Save analysis data in the pylint directory
-export PYLINTHOME="${builddir}/.pylint.d"
-[ -d "$PYLINTHOME" ] || mkdir "$PYLINTHOME"
-
-export FALSE_POSITIVES="${srcdir}"/pylint-false-positives
-
-# W0212 - Access to a protected member %s of a client class
-export NON_STRICT_OPTIONS="--disable=W0212"
-
-# E1103 - %s %r has no %r member (but some types could not be inferred)
-export DISABLED_ERR_OPTIONS="--disable=E1103"
-
-# W0105 - String statement has no effect
-# W0110 - map/filter on lambda could be replaced by comprehension
-# W0141 - Used builtin function %r
-# W0142 - Used * or ** magic
-# W0511 - Used when a warning note as FIXME or XXX is detected.
-# W0603 - Using the global statement
-# W0614 - Unused import %s from wildcard import
-# I0011 - Locally disabling %s (i.e., pylint: disable)
-export
DISABLED_WARN_OPTIONS="--disable=W0105,W0110,W0141,W0142,W0511,W0603,W0614,I0011"
-
-usage () {
- echo "usage: `basename $0` [--strict] [--help] [files...]"
- exit $1
-}
-
-# Separate the module parameters from the files list
-ARGS=
-FILES=
-while [ $# -gt 0 ]; do
- case $1 in
- --strict)
- export NON_STRICT_OPTIONS=
- ;;
- --help)
- usage 0
- ;;
- -*)
- ARGS="$ARGS $1"
- ;;
- *)
- FILES=$@
- break
- esac
- shift
-done
-
-exit_status=0
-
-if [ -s pylint-log ]; then
- rm pylint-log
-fi
-
-# run pylint one file / module at a time, otherwise it sometimes gets
-# confused
-if [ -z "$FILES" ]; then
- # Test any file that either ends in .py or contains #!/usr/bin/python in
- # the first line. Scan everything except old_tests
- FILES=$(findtestfiles \( -name '*.py' -o \
- -exec /bin/sh -c "head -1 {} | grep -q
'#!/usr/bin/python'" \; \) -print | \
- egrep -v '(|/)doc/conf.py')
-fi
-
-num_cpus=$(getconf _NPROCESSORS_ONLN)
-# run pylint in paralel
-echo $FILES | xargs --max-procs=$num_cpus -n 1 "$srcdir"/pylint-one.sh $ARGS ||
exit 1
-
-for file in $(find -name 'pylint-out*'); do
- cat "$file" >> pylint-log
- rm "$file"
-done
-
-fails=$(find -name 'pylint*failed' -print -exec rm '{}' \;)
-if [ -z "$fails" ]; then
- exit_status=0
-else
- exit_status=1
-fi
-
-if [ -s pylint-log ]; then
- echo "pylint reports the following issues:"
- cat pylint-log
-elif [ -e pylint-log ]; then
- rm pylint-log
-fi
-
-exit "$exit_status"
--
2.2.2