Skip to content

Commit

Permalink
Change: Extract checking a plugin for validity to a separate function
Browse files Browse the repository at this point in the history
Add a reusable function to check if a Python module is a valid autohooks
precommit plugin.
  • Loading branch information
bjoernricks authored and y0urself committed Aug 15, 2022
1 parent fdcb537 commit 7d92bdd
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 23 deletions.
35 changes: 12 additions & 23 deletions autohooks/cli/check.py
Expand Up @@ -25,10 +25,10 @@
)
from autohooks.hooks import PreCommitHook
from autohooks.precommit.run import (
CheckPluginError,
CheckPluginWarning,
autohooks_module_path,
has_precommit_function,
has_precommit_parameters,
load_plugin,
check_plugin,
)
from autohooks.settings import Mode
from autohooks.terminal import Terminal
Expand Down Expand Up @@ -134,24 +134,13 @@ def check_config(
else:
with autohooks_module_path():
for name in plugins:
try:
plugin = load_plugin(name)
if not has_precommit_function(plugin):
term.error(
f'Plugin "{name}" has no precommit '
"function. The function is required to run"
" the plugin as git pre commit hook."
)
elif not has_precommit_parameters(plugin):
term.warning(
f'Plugin "{name}" uses a deprecated '
"signature for its precommit function. It "
"is missing the **kwargs parameter."
)
result = check_plugin(name)
if result:
if isinstance(result, CheckPluginError):
term.error(str(result))
elif isinstance(result, CheckPluginWarning):
term.warning(str(result))
else:
term.ok(f'Plugin "{name}" active and loadable.')
except ImportError as e:
term.error(
f'"{name}" is not a valid autohooks '
f"plugin. {e}"
)
term.info(str(result))
else:
term.ok(f'Plugin "{name}" active and loadable.')
47 changes: 47 additions & 0 deletions autohooks/precommit/run.py
Expand Up @@ -75,6 +75,53 @@ def check_hook_mode(term: Terminal, config_mode: Mode, hook_mode: Mode) -> None:
)


class CheckPluginResult:
def __init__(self, message: str) -> None:
self.message = message

def __str__(self) -> str:
return self.message


class CheckPluginError(CheckPluginResult):
"""
Raised if a plugin check failed
"""


class CheckPluginWarning(CheckPluginResult):
"""
Used if a plugin check raises a warning
"""


def check_plugin(plugin_name: str) -> Optional[CheckPluginResult]:
"""
Check if a plugin (Python module) is a valid and can be used
Returns:
A CheckPluginResult in case of an issue with the plugin
"""
try:
plugin = load_plugin(plugin_name)
if not has_precommit_function(plugin):
return CheckPluginError(
f'Plugin "{plugin_name}" has no precommit '
"function. The function is required to run"
" the plugin as git pre commit hook."
)
elif not has_precommit_parameters(plugin):
return CheckPluginWarning(
f'Plugin "{plugin_name}" uses a deprecated '
"signature for its precommit function. It "
"is missing the **kwargs parameter."
)
except ImportError as e:
return CheckPluginError(
f'"{plugin_name}" is not a valid autohooks plugin. {e}'
)


class ReportProgress:
"""
A class to report progress of a plugin
Expand Down
16 changes: 16 additions & 0 deletions tests/precommit/__init__.py
@@ -0,0 +1,16 @@
# Copyright (C) 2022 Greenbone Networks GmbH
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty 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, see <http://www.gnu.org/licenses/>.
77 changes: 77 additions & 0 deletions tests/precommit/test_run.py
@@ -0,0 +1,77 @@
# Copyright (C) 2022 Greenbone Networks GmbH
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty 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, see <http://www.gnu.org/licenses/>.


import unittest

from autohooks.precommit.run import (
CheckPluginError,
CheckPluginWarning,
check_plugin,
)
from tests import temp_python_module, tempdir


class CheckPluginTestCase(unittest.TestCase):
def test_plugin_not_found(self):
with tempdir(change_into=True):
result = check_plugin("foo.bar")

self.assertIsInstance(result, CheckPluginError)
self.assertIn(
'"foo.bar" is not a valid autohooks plugin.', result.message
)

def test_no_precommit_function(self):
content = """print()"""
with temp_python_module(
content,
name="foo",
):
result = check_plugin("foo")

self.assertIsInstance(result, CheckPluginError)
self.assertEqual(
result.message,
'Plugin "foo" has no precommit function. The function is '
"required to run the plugin as git pre commit hook.",
)

def test_no_precommit_function_arguments(self):
content = """def precommit():
print()"""
with temp_python_module(
content,
name="foo",
):
result = check_plugin("foo")

self.assertIsInstance(result, CheckPluginWarning)
self.assertEqual(
'Plugin "foo" uses a deprecated signature for its precommit '
"function. It is missing the **kwargs parameter.",
result.message,
)

def test_success(self):
content = """def precommit(**kwargs):
print()"""
with temp_python_module(
content,
name="foo",
):
self.assertIsNone(check_plugin("foo"))

0 comments on commit 7d92bdd

Please sign in to comment.