summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoris Roovers <joris.roovers@gmail.com>2019-06-17 22:16:45 +0200
committerJoris Roovers <joris.roovers@gmail.com>2019-06-17 22:50:38 +0200
commit0190fe18dfb27125615fc35a9ec559544881553b (patch)
tree423dccb90feea4454f6b4d0861127812abf7b4e5
parent07738b3bd34f91977888a954f95527411babae1c (diff)
Contrib rule fix for pypy
When using pypy2, using Contrib rules would crash gitlint due to an issue with importlib and importing __init__.py files. This patchset fixes that problem and adds a test case that tests for this condition and the related use-case of importing user-defined rules from python packages. Also: updated pypy2 test version in run_tests.sh to v7.1.1
-rw-r--r--gitlint/rule_finder.py9
-rw-r--r--gitlint/tests/rules/test_user_rules.py14
-rw-r--r--gitlint/tests/samples/user_rules/parent_package/__init__.py13
-rw-r--r--gitlint/tests/samples/user_rules/parent_package/my_commit_rules.py12
-rwxr-xr-xrun_tests.sh4
5 files changed, 48 insertions, 4 deletions
diff --git a/gitlint/rule_finder.py b/gitlint/rule_finder.py
index 3dbef2c..2b8b293 100644
--- a/gitlint/rule_finder.py
+++ b/gitlint/rule_finder.py
@@ -33,7 +33,13 @@ def find_rule_classes(extra_path):
# Filter out files that are not python modules
for filename in files:
if fnmatch.fnmatch(filename, '*.py'):
- modules.append(os.path.splitext(filename)[0])
+ # We have to treat __init__ files a bit special: add the parent dir instead of the filename, and also
+ # add their parent dir to the sys.path (this fixes import issues with pypy2).
+ if filename == "__init__.py":
+ modules.append(os.path.basename(directory))
+ sys.path.append(os.path.dirname(directory))
+ else:
+ modules.append(os.path.splitext(filename)[0])
# No need to continue if there are no modules specified
if not modules:
@@ -48,6 +54,7 @@ def find_rule_classes(extra_path):
# Import the module
try:
importlib.import_module(module)
+
except Exception as e:
raise rules.UserRuleError(u"Error while importing extra-path module '{0}': {1}".format(module, ustr(e)))
diff --git a/gitlint/tests/rules/test_user_rules.py b/gitlint/tests/rules/test_user_rules.py
index 8672cb0..57c03a0 100644
--- a/gitlint/tests/rules/test_user_rules.py
+++ b/gitlint/tests/rules/test_user_rules.py
@@ -31,7 +31,7 @@ class UserRuleTests(BaseTestCase):
self.assertIn(user_rule_path, sys.path)
self.assertIn("my_commit_rules", sys.modules)
- # # Do some basic asserts on our user rule
+ # Do some basic asserts on our user rule
self.assertEqual(classes[0].id, "UC1")
self.assertEqual(classes[0].name, u"my-üser-commit-rule")
expected_option = options.IntOption('violation-count', 1, u"Number of violåtions to return")
@@ -60,6 +60,18 @@ class UserRuleTests(BaseTestCase):
violations = rule_class.validate("false-commit-object (ignored)")
self.assertListEqual(violations, [rules.RuleViolation("UC1", u"Commit violåtion 1", u"Contënt 1", 1)])
+ def test_rules_from_init_file(self):
+ # Test that we can import rules that are defined in __init__.py files
+ # This also tests that we can import rules from python packages. This use to cause issues with pypy
+ # So this is also a regression test for that.
+ user_rule_path = self.get_sample_path(os.path.join("user_rules", "parent_package"))
+ classes = find_rule_classes(user_rule_path)
+
+ # convert classes to strings and sort them so we can compare them
+ class_strings = sorted([ustr(clazz) for clazz in classes])
+ expected = [u"<class 'my_commit_rules.MyUserCommitRule'>", u"<class 'parent_package.InitFileRule'>"]
+ self.assertListEqual(class_strings, expected)
+
def test_empty_user_classes(self):
# Test that we don't find rules if we scan a different directory
user_rule_path = self.get_sample_path("config")
diff --git a/gitlint/tests/samples/user_rules/parent_package/__init__.py b/gitlint/tests/samples/user_rules/parent_package/__init__.py
new file mode 100644
index 0000000..32c05fc
--- /dev/null
+++ b/gitlint/tests/samples/user_rules/parent_package/__init__.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# This file is meant to test that we can also load rules from __init__.py files, this was an issue with pypy before.
+
+from gitlint.rules import CommitRule
+
+
+class InitFileRule(CommitRule):
+ name = u"my-init-cömmit-rule"
+ id = "UC1"
+ options_spec = []
+
+ def validate(self, _commit):
+ return []
diff --git a/gitlint/tests/samples/user_rules/parent_package/my_commit_rules.py b/gitlint/tests/samples/user_rules/parent_package/my_commit_rules.py
new file mode 100644
index 0000000..b73a305
--- /dev/null
+++ b/gitlint/tests/samples/user_rules/parent_package/my_commit_rules.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+
+from gitlint.rules import CommitRule
+
+
+class MyUserCommitRule(CommitRule):
+ name = u"my-user-cömmit-rule"
+ id = "UC2"
+ options_spec = []
+
+ def validate(self, _commit):
+ return []
diff --git a/run_tests.sh b/run_tests.sh
index f8bb6b1..6017036 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -249,13 +249,13 @@ install_virtualenv(){
# For pypy: custom path + fetch from the web if not installed (=distro agnostic)
if [[ $version == *"pypy"* ]]; then
- python_binary="/opt/pypy2-v5.6.0-linux64/bin/pypy"
+ python_binary="/opt/pypy2.7-v7.1.1-linux64/bin/pypy"
# download
if [ ! -f $python_binary ]; then
assert_root "Must be root to install pypy, use sudo"
title "### DOWNLOADING PYPY ($pypy_archive) ###"
pushd "/opt"
- pypy_archive="pypy2-v5.6.0-linux64.tar.bz2"
+ pypy_archive="pypy2.7-v7.1.1-linux64.tar.bz2"
wget "https://bitbucket.org/pypy/pypy/downloads/$pypy_archive"
title "### EXTRACTING PYPY TARBALL ($pypy_archive) ###"
tar xvf $pypy_archive