diff options
author | Joris Roovers <joris.roovers@gmail.com> | 2019-06-17 22:16:45 +0200 |
---|---|---|
committer | Joris Roovers <joris.roovers@gmail.com> | 2019-06-17 22:50:38 +0200 |
commit | 0190fe18dfb27125615fc35a9ec559544881553b (patch) | |
tree | 423dccb90feea4454f6b4d0861127812abf7b4e5 | |
parent | 07738b3bd34f91977888a954f95527411babae1c (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.py | 9 | ||||
-rw-r--r-- | gitlint/tests/rules/test_user_rules.py | 14 | ||||
-rw-r--r-- | gitlint/tests/samples/user_rules/parent_package/__init__.py | 13 | ||||
-rw-r--r-- | gitlint/tests/samples/user_rules/parent_package/my_commit_rules.py | 12 | ||||
-rwxr-xr-x | run_tests.sh | 4 |
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 |