Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Terminal output #39

Merged
merged 11 commits into from Nov 20, 2019
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -25,6 +25,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Enhanced autohooks activate cli to show additional information if a autohooks
git hook is already installed
[#30](https://github.com/greenbone/autohooks/pull/30)
* Added plugin API for additional info status output
[#39](https://github.com/greenbone/autohooks/pull/39)
* Added plugin API for additional message printing
[#39](https://github.com/greenbone/autohooks/pull/39)

### Changed

Expand All @@ -40,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#30](https://github.com/greenbone/autohooks/pull/30)
* A warning is raised during git hook execution if the current mode is different
to the configured mode [#30](https://github.com/greenbone/autohooks/pull/30)
* Improved output formatting [#39](https://github.com/greenbone/autohooks/pull/39)

### Deprecated
### Fixed
Expand Down
40 changes: 38 additions & 2 deletions autohooks/api/__init__.py
Expand Up @@ -17,8 +17,44 @@

import sys

from autohooks.terminal import ok, fail, error, warning
from autohooks.terminal import Terminal

__term = None # pylint: disable=invalid-name

__all__ = [
'error',
'fail',
'info',
'ok',
'out',
'warning',
]


def ok(message: str) -> None:
__term.ok(message)


def fail(message: str) -> None:
__term.fail(message)


def error(message: str) -> None:
__term.error(message)


def warning(message: str) -> None:
__term.warning(message)


def info(message: str) -> None:
__term.info(message)


def out(message: str):
print(message)
__term.print(message)


def _set_terminal(term: Terminal):
global __term # pylint: disable=global-statement, invalid-name
__term = term
6 changes: 4 additions & 2 deletions autohooks/cli/__init__.py
Expand Up @@ -17,6 +17,7 @@

import argparse

from autohooks.terminal import Terminal
from autohooks.settings import Mode
from autohooks.version import get_version

Expand Down Expand Up @@ -60,10 +61,11 @@ def main():
if not args.command:
parser.print_usage()

term = Terminal()
if args.command == 'activate':
install_hooks(args)
install_hooks(term, args)
elif args.command == 'check':
check_hooks()
check_hooks(term)


if __name__ == "__main__":
Expand Down
40 changes: 20 additions & 20 deletions autohooks/cli/activate.py
Expand Up @@ -20,39 +20,39 @@
from autohooks.config import (
load_config_from_pyproject_toml,
get_pyproject_toml_path,
AUTOHOOKS_SECTION,
)
from autohooks.hooks import PreCommitHook
from autohooks.settings import Mode
from autohooks.terminal import ok, warning, info
from autohooks.terminal import Terminal


def install_hooks(args: Namespace) -> None:
def install_hooks(term: Terminal, args: Namespace) -> None:
pre_commit_hook = PreCommitHook()
pyproject_toml = get_pyproject_toml_path()
config = load_config_from_pyproject_toml(pyproject_toml)

if pre_commit_hook.exists() and not args.force:
ok(
'pre-commit hook is already installed at {}.'.format(
term.ok(
'autohooks pre-commit hook is already installed at {}.'.format(
str(pre_commit_hook)
)
)
info(
"Run 'autohooks activate --force' to override the current "
"installed pre-commit hook."
)
info(
"Run 'autohooks check' to validate the current status of "
"the installed pre-commit hook."
)
with term.indent():
term.print()
term.info(
"Run 'autohooks activate --force' to override the current "
"installed pre-commit hook."
)
term.info(
"Run 'autohooks check' to validate the current status of "
"the installed pre-commit hook."
)
else:
if not config.is_autohooks_enabled():
warning(
'Warning: autohooks is not enabled in your {} file. Please add '
'a "{}" section. Run autohooks check for more details.'.format(
str(pyproject_toml), AUTOHOOKS_SECTION
)
term.warning(
'autohooks is not enabled in your {} file. '
'Run \'autohooks check\' for more '
'details.'.format(str(pyproject_toml))
)

if args.mode:
Expand All @@ -62,8 +62,8 @@ def install_hooks(args: Namespace) -> None:

pre_commit_hook.write(mode=mode)

ok(
'pre-commit hook installed at {} using {} mode'.format(
term.ok(
'autohooks pre-commit hook installed at {} using {} mode.'.format(
str(pre_commit_hook), str(mode.get_effective_mode())
)
)
86 changes: 63 additions & 23 deletions autohooks/cli/check.py
Expand Up @@ -34,74 +34,114 @@

from autohooks.settings import Mode

from autohooks.terminal import ok, error, warning
from autohooks.terminal import Terminal


def check_hooks() -> None:
def check_hooks(term: Terminal) -> None:
pre_commit_hook = PreCommitHook()
hook_mode = pre_commit_hook.read_mode()

check_pre_commit_hook(pre_commit_hook)
check_pre_commit_hook(term, pre_commit_hook, hook_mode)

pyproject_toml = get_pyproject_toml_path()

check_config(pyproject_toml, pre_commit_hook.read_mode())
check_config(term, pyproject_toml, pre_commit_hook, hook_mode)


def check_pre_commit_hook(pre_commit_hook: PreCommitHook) -> None:
def check_pre_commit_hook(
term: Terminal, pre_commit_hook: PreCommitHook, hook_mode: Mode,
) -> None:
if pre_commit_hook.exists():
if pre_commit_hook.is_autohooks_pre_commit_hook():
ok('autohooks pre-commit hook is active.')
term.ok('autohooks pre-commit hook is active.')

if pre_commit_hook.is_current_autohooks_pre_commit_hook():
ok('autohooks pre-commit hook is up-to-date.')
term.ok('autohooks pre-commit hook is up-to-date.')
else:
warning(
term.warning(
'autohooks pre-commit hook is outdated. Please run '
'\'autohooks activate --force\' to update your pre-commit '
'hook.'
)

hook_mode = pre_commit_hook.read_mode()
if hook_mode == Mode.UNKNOWN:
term.warning(
'Unknown autohooks mode in {}. Falling back to "{}" '
'mode.'.format(
str(pre_commit_hook),
str(hook_mode.get_effective_mode()),
)
)
else:
error(
term.error(
'autohooks pre-commit hook is not active. But a different '
'pre-commit hook has been found at {}.'.format(
str(pre_commit_hook)
)
)

else:
error(
term.error(
'autohooks pre-commit hook not active. Please run \'autohooks '
'activate\'.'
)


def check_config(pyproject_toml: Path, hook_mode: Mode) -> None:
def check_config(
term: Terminal,
pyproject_toml: Path,
pre_commit_hook: PreCommitHook,
hook_mode: Mode,
) -> None:
if not pyproject_toml.exists():
error(
term.error(
'Missing {} file. Please add a pyproject.toml file and include '
'a "{}" section.'.format(str(pyproject_toml), AUTOHOOKS_SECTION)
)
else:
config = load_config_from_pyproject_toml(pyproject_toml)
if not config.is_autohooks_enabled():
error(
term.error(
'autohooks is not enabled in your {} file. Please add '
'a "{}" section.'.format(str(pyproject_toml), AUTOHOOKS_SECTION)
)
else:
if config.get_mode() != hook_mode:
warning(
'autohooks mode in pre-commit hook ("{}") differs from '
'mode in {} file ("{}")'.format(
config_mode = config.get_mode()
if config_mode == Mode.UNDEFINED:
term.warning(
'autohooks mode is not defined in {}.'.format(
str(pyproject_toml)
)
)
elif config_mode == Mode.UNKNOWN:
term.warning(
'Unknown autohooks mode in {}.'.format(str(pyproject_toml))
)

if (
config_mode.get_effective_mode()
!= hook_mode.get_effective_mode()
):
term.warning(
'autohooks mode "{}" in pre-commit hook {} differs from '
'mode "{}" in {}.'.format(
str(hook_mode),
str(pre_commit_hook),
str(config_mode),
str(pyproject_toml),
str(config.get_mode()),
)
)

term.info(
'Using autohooks mode "{}".'.format(
str(hook_mode.get_effective_mode())
)
)

plugins = config.get_pre_commit_script_names()
if not plugins:
error(
term.error(
'No autohooks plugin is activated in {} for your pre '
'commit hook. Please add a '
'"pre-commit = [plugin1, plugin2]" '
Expand All @@ -113,27 +153,27 @@ def check_config(pyproject_toml: Path, hook_mode: Mode) -> None:
try:
plugin = load_plugin(name)
if not has_precommit_function(plugin):
error(
term.error(
'Plugin "{}" has no precommit function. '
'The function is required to run the '
'plugin as git pre commit hook.'.format(
name
)
)
elif not has_precommit_parameters(plugin):
warning(
term.warning(
'Plugin "{}" uses a deprecated signature '
'for its precommit function. It is missing '
'the **kwargs parameter.'.format(name)
)
else:
ok(
term.ok(
'Plugin "{}" active and loadable.'.format(
name
)
)
except ImportError as e:
error(
term.error(
'"{}" is not a valid autohooks '
'plugin. {}'.format(name, e)
)