diff options
Diffstat (limited to 'prometheus_borgmatic_exporter/cli.py')
| -rw-r--r-- | prometheus_borgmatic_exporter/cli.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/prometheus_borgmatic_exporter/cli.py b/prometheus_borgmatic_exporter/cli.py new file mode 100644 index 0000000..cc6f374 --- /dev/null +++ b/prometheus_borgmatic_exporter/cli.py @@ -0,0 +1,116 @@ +# SPDX-FileCopyrightText: 2026 Dennis Fink <me+coding@dennisfink.me> +# +# SPDX-License-Identifier: BSD-3-Clause + +import click_extra as click + + +class FlexibleColorOption(click.ColorOption): + """Allow the color option value to be passed with or without ``=``.""" + + _gnu_optional_value = False + + +def emit(prefix: str, color: str, *message: str, enabled: bool = True) -> None: + """Render a styled prefix and message to stdout. + + Internal helper used by error(), msg(), warn(), verbose(), and debug() + to avoid duplicating the Click styling and echo logic. The first message + argument is rendered in bold, subsequent arguments are appended unstyled. + + Args: + prefix: The prefix string shown before the message (e.g. "==>", "==> ERROR:"). + color: A Click-compatible color name (e.g. "red", "green") applied to the prefix. + *message: One or more message parts to display. At least one is required. + enabled: If False, the function returns immediately without printing. + Defaults to True. + + Raises: + TypeError: If no message arguments are provided. + """ + if not message: + raise TypeError("emit() missing 1 required positional argument: 'message'") + + if not enabled: + return + + click.echo( + " ".join( + [ + click.style(prefix, fg=color, bold=True), + click.style(message[0], bold=True), + *message[1:], + ] + ) + ) + + +def error(*message: str) -> None: + """Print a formatted error message to stdout in red. + + The first argument is rendered in bold, subsequent arguments are appended + unstyled. Always prints regardless of quiet or verbose flags. + + Args: + *message: One or more message parts to display. + """ + emit("==> ERROR:", "red", *message) + + +@click.pass_obj +def msg(obj: dict[str, bool], *message: str) -> None: + """Print a formatted informational message to stdout in green. + + Suppressed when the quiet flag is set. The first argument is rendered + in bold, subsequent arguments are appended unstyled. + + Args: + *message: One or more message parts to display. + """ + emit("==>", "green", *message, enabled=not obj.get("quiet", False)) + + +@click.pass_obj +def warn(obj: dict[str, bool], *message: str) -> None: + """Print a formatted warning message to stdout in yellow. + + Suppressed when the quiet flag is set. The first argument is rendered + in bold, subsequent arguments are appended unstyled. + + Args: + *message: One or more message parts to display. + """ + emit("==>", "yellow", *message, enabled=not obj.get("quiet", False)) + + +@click.pass_obj +def verbose(obj: dict[str, bool], *message: str) -> None: + """Print a formatted verbose message to stdout in blue. + + Only prints when the verbose flag is set and the quiet flag is not. + The first argument is rendered in bold, subsequent arguments are + appended unstyled. + + Args: + *message: One or more message parts to display. + """ + emit( + "==>", + "blue", + *message, + enabled=obj.get("verbose", False) and not obj.get("quiet", False), + ) + + +@click.pass_obj +def debug(obj: dict[str, bool], *message: str) -> None: + """Print a formatted debug message to stdout in magenta. + + Only prints when the DEBUG environment variable is set to a truthy + value (1, true, yes). The first argument is rendered in bold, + subsequent arguments are appended unstyled. + + Args: + *message: One or more message parts to display. + """ + emit("==>", "magenta", *message, enabled=obj.get("debug", False)) |
