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

Display each command as a collapsable section under CI #2976

Merged
merged 4 commits into from
Nov 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/molecule/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"danger": "bold red",
"scenario": "green",
"action": "green",
"section_title": "bold cyan",
"logging.level.notset": Style(dim=True),
"logging.level.debug": Style(color="white", dim=True),
"logging.level.info": Style(color="blue"),
Expand Down
114 changes: 111 additions & 3 deletions src/molecule/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@
"""Logging Module."""

import logging
import os
import sys
from functools import lru_cache
import time
from functools import lru_cache, wraps
from typing import Callable, Iterable

from enrich.console import Console
from enrich.logging import RichHandler

from molecule.console import should_do_markup, theme
from molecule.console import console, should_do_markup, theme
from molecule.text import underscore

SUCCESS = 100
Expand Down Expand Up @@ -76,9 +78,104 @@ def get_logger(name=None) -> logging.Logger:
return logger


def github_actions_groups(func: Callable) -> Callable:
"""Print group indicators before/after execution of a method."""

@wraps(func)
def wrapper(*args, **kwargs):
self = args[0]
scenario = self._config.scenario.name
subcommand = underscore(self.__class__.__name__)
console.print(
"::group::",
f"[ci_info]Molecule[/] [scenario]{scenario}[/] > [action]{subcommand}[/]",
sep="",
markup=True,
emoji=False,
highlight=False,
)
try:
return func(*args, **kwargs)
finally:
console.print("::endgroup::", markup=True, emoji=False, highlight=False)

return wrapper


def gitlab_ci_sections(func: Callable) -> Callable:
"""Print group indicators before/after execution of a method."""
# GitLab requres:
# - \r (carriage return)
# - \e[0K (clear line ANSI escape code. We use \033 for the \e escape char)
clear_line = "\r\033[0K"

@wraps(func)
def wrapper(*args, **kwargs):
self = args[0]
scenario = self._config.scenario.name
subcommand = underscore(self.__class__.__name__)
console.print(
f"section_start:{int(time.time())}:{scenario}.{subcommand}",
end=clear_line,
markup=False,
emoji=False,
highlight=False,
)
console.print(
# must be one color for the whole line or gitlab sets odd widths to each word.
f"[ci_info]Molecule {scenario} > {subcommand}[/]",
end="\n",
markup=True,
emoji=False,
highlight=False,
)
try:
return func(*args, **kwargs)
finally:
console.print(
f"section_end:{int(time.time())}:{scenario}.{subcommand}",
end=f"{clear_line}\n",
markup=False,
emoji=False,
highlight=False,
)

return wrapper


def travis_ci_folds(func: Callable) -> Callable:
"""Print group indicators before/after execution of a method."""

@wraps(func)
def wrapper(*args, **kwargs):
self = args[0]
scenario = self._config.scenario.name
subcommand = underscore(self.__class__.__name__)
console.print(
f"travis_fold:start:{scenario}.{subcommand}",
f"[ci_info]Molecule[/] [scenario]{scenario}[/] > [action]{subcommand}[/]",
sep="",
markup=True,
emoji=False,
highlight=False,
)
try:
return func(*args, **kwargs)
finally:
console.print(
f"travis_fold:end:{scenario}.{subcommand}",
markup=False,
emoji=False,
highlight=False,
)

return wrapper


def section_logger(func: Callable) -> Callable:
"""Wrap effective execution of a method."""

@wraps(func)
def wrapper(*args, **kwargs):
self = args[0]
get_logger().info(
Expand All @@ -94,9 +191,20 @@ def wrapper(*args, **kwargs):
return wrapper


@lru_cache()
def get_section_loggers() -> Iterable[Callable]:
"""Return a list of section wrappers to be added."""
return [section_logger]
default_section_loggers = [section_logger]
if not os.getenv("CI"):
return default_section_loggers
elif os.getenv("GITHUB_ACTIONS"):
return [github_actions_groups] + default_section_loggers
elif os.getenv("GITLAB_CI"):
return [gitlab_ci_sections] + default_section_loggers
elif os.getenv("TRAVIS"):
return [travis_ci_folds] + default_section_loggers
# CI is set but no extra section_loggers apply.
return default_section_loggers


LOGGING_CONSOLE = Console(
Expand Down