From 133f47d5f18161fd22a8fbaddef2318f363a6661 Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Sat, 31 Oct 2020 19:00:15 +0000 Subject: [PATCH] Adds ability to produce html report This enables molecule to produce HTML reports which contain all the console output. This feature is useful for CI usage. --- .pre-commit-config.yaml | 4 ++-- docs/configuration.rst | 1 + lib/molecule/command/base.py | 8 ++++++++ lib/molecule/console.py | 6 ++++-- lib/molecule/util.py | 6 ++++++ setup.cfg | 2 +- 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bc949c9b2d..e132846f95 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -52,7 +52,7 @@ repos: additional_dependencies: - packaging - rich - - subprocess-tee>=0.1.4 + - subprocess-tee>=0.1.5 - repo: https://github.com/pre-commit/mirrors-pylint rev: v2.6.0 hooks: @@ -60,5 +60,5 @@ repos: additional_dependencies: - ansible-base - rich - - subprocess-tee>=0.1.4 + - subprocess-tee>=0.1.5 - testinfra diff --git a/docs/configuration.rst b/docs/configuration.rst index af62097d1c..00da2a92c2 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -30,6 +30,7 @@ MOLECULE_INSTANCE_CONFIG ? MOLECULE_DEPENDENCY_NAME Dependency type name, usually 'galaxy' MOLECULE_DRIVER_NAME Name of the molecule scenario driver MOLECULE_PROVISIONER_NAME Name of the provisioner tool (usually 'ansible') +MOLECULE_REPORT Name of HTML file where to dump execution report. MOLECULE_SCENARIO_NAME Name of the scenario MOLECULE_VERBOSITY Determine Ansible verbosity level. MOLECULE_VERIFIER_NAME Name of the verifier tool (usually 'ansible') diff --git a/lib/molecule/command/base.py b/lib/molecule/command/base.py index e6ffb25efa..0891899401 100644 --- a/lib/molecule/command/base.py +++ b/lib/molecule/command/base.py @@ -238,6 +238,7 @@ def click_group_ex(): "reset": "blue", "test": "bright_yellow", }, + result_callback=result_callback, ) @@ -246,3 +247,10 @@ def click_command_ex() -> Callable[[Callable[..., Any]], click.Command]: return click.command( # type: ignore cls=HelpColorsCommand, help_headers_color="yellow", help_options_color="green" ) + + +def result_callback(*args, **kwargs): + """Click natural exit callback.""" + # We want to be used we run out custom exit code, regardless if run was + # a success or failure. + util.sysexit(0) diff --git a/lib/molecule/console.py b/lib/molecule/console.py index 5a582b2af0..5d0ae57b10 100644 --- a/lib/molecule/console.py +++ b/lib/molecule/console.py @@ -3,9 +3,9 @@ import sys from typing import Any -from rich.console import Console from rich.style import Style from rich.theme import Theme +from subprocess_tee.rich import ConsoleEx theme = Theme( { @@ -60,4 +60,6 @@ def should_do_markup() -> bool: return sys.stdout.isatty() and os.environ.get("TERM") != "dumb" -console = Console(force_terminal=should_do_markup(), theme=theme) +console = ConsoleEx( + force_terminal=should_do_markup(), theme=theme, record=True, redirect=True +) diff --git a/lib/molecule/util.py b/lib/molecule/util.py index 22c734f1ec..1ff2dd8991 100644 --- a/lib/molecule/util.py +++ b/lib/molecule/util.py @@ -83,6 +83,12 @@ def print_environment_vars(env: Optional[Dict[str, str]]) -> None: def sysexit(code: int = 1) -> NoReturn: """Perform a system exit with given code, default 1.""" + if "MOLECULE_REPORT" in os.environ: + report_file = os.environ["MOLECULE_REPORT"] + LOG.info("Writing %s report.", report_file) + with open(report_file, "w") as f: + f.write(console.export_html()) + sys.exit(code) diff --git a/setup.cfg b/setup.cfg index 5a22db7098..152fed51e1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -77,7 +77,7 @@ install_requires = pluggy >= 0.7.1, < 1.0 PyYAML >= 5.1, < 6 rich >= 6.0 - subprocess-tee >= 0.1.4 + subprocess-tee >= 0.1.5 setuptools >= 42 # for pkg_resources yamllint >= 1.15.0, < 2 # selinux python module is needed as least by ansible-docker/podman modules