diff --git a/obsws_cli/__about__.py b/obsws_cli/__about__.py index 1d2fc1a..08e8f89 100644 --- a/obsws_cli/__about__.py +++ b/obsws_cli/__about__.py @@ -1,4 +1,4 @@ # SPDX-FileCopyrightText: 2025-present onyx-and-iris # # SPDX-License-Identifier: MIT -__version__ = "0.18.3" +__version__ = "0.18.4" diff --git a/obsws_cli/app.py b/obsws_cli/app.py index 9a1776c..8adfc99 100644 --- a/obsws_cli/app.py +++ b/obsws_cli/app.py @@ -50,6 +50,15 @@ def setup_logging(debug: bool): ) +def validate_style(value: str): + """Validate and return the style.""" + if value not in styles.registry: + raise typer.BadParameter( + f'Invalid style: {value}. Available styles: {", ".join(styles.registry.keys())}' + ) + return value + + @app.callback() def main( ctx: typer.Context, @@ -112,6 +121,7 @@ def main( envvar='OBS_STYLE', help='Set the style for the CLI output', show_default='disabled', + callback=validate_style, ), ] = settings.get('style'), no_border: Annotated[ diff --git a/obsws_cli/styles.py b/obsws_cli/styles.py index 4c7aa05..d128b27 100644 --- a/obsws_cli/styles.py +++ b/obsws_cli/styles.py @@ -3,15 +3,15 @@ import os from dataclasses import dataclass -_registry = {} +registry = {} def register_style(cls): """Register a style class.""" key = cls.__name__.lower() - if key in _registry: + if key in registry: raise ValueError(f'Style {key} is already registered.') - _registry[key] = cls + registry[key] = cls return cls @@ -19,11 +19,10 @@ def register_style(cls): class Style: """Base class for styles.""" - name: str = 'no_colour' - description: str = 'Style disabled' - border: str = 'none' - column: str = 'none' - highlight: str = 'none' + name: str + border: str + column: str + highlight: str no_border: bool = False def __post_init__(self): @@ -32,9 +31,21 @@ class Style: if self.no_border: self.border = None - def __str__(self): - """Return a string representation of the style.""" - return f'{self.name} - {self.description}' + +@register_style +@dataclass +class Disabled(Style): + """Disabled style.""" + + name: str = 'disabled' + border: str = 'none' + column: str = 'none' + highlight: str = 'none' + + def __post_init__(self): + """Post-initialization to set default values.""" + super().__post_init__() + os.environ['NO_COLOR'] = '1' @register_style @@ -43,10 +54,9 @@ class Red(Style): """Red style.""" name: str = 'red' - description: str = 'Red text color' border: str = 'red3' - highlight: str = 'red1' column: str = 'red1' + highlight: str = 'red1' @register_style @@ -55,10 +65,9 @@ class Magenta(Style): """Magenta style.""" name: str = 'magenta' - description: str = 'Magenta text color' border: str = 'magenta3' - highlight: str = 'orchid1' column: str = 'orchid1' + highlight: str = 'orchid1' @register_style @@ -67,10 +76,9 @@ class Purple(Style): """Purple style.""" name: str = 'purple' - description: str = 'Purple text color' border: str = 'medium_purple4' - highlight: str = 'medium_purple' column: str = 'medium_purple' + highlight: str = 'medium_purple' @register_style @@ -79,10 +87,9 @@ class Blue(Style): """Blue style.""" name: str = 'blue' - description: str = 'Blue text color' border: str = 'cornflower_blue' - highlight: str = 'sky_blue2' column: str = 'sky_blue2' + highlight: str = 'sky_blue2' @register_style @@ -91,10 +98,9 @@ class Cyan(Style): """Cyan style.""" name: str = 'cyan' - description: str = 'Cyan text color' border: str = 'dark_cyan' - highlight: str = 'cyan' column: str = 'cyan' + highlight: str = 'cyan' @register_style @@ -103,10 +109,9 @@ class Green(Style): """Green style.""" name: str = 'green' - description: str = 'Green text color' border: str = 'green4' - highlight: str = 'spring_green3' column: str = 'spring_green3' + highlight: str = 'spring_green3' @register_style @@ -115,10 +120,9 @@ class Yellow(Style): """Yellow style.""" name: str = 'yellow' - description: str = 'Yellow text color' border: str = 'yellow3' - highlight: str = 'wheat1' column: str = 'wheat1' + highlight: str = 'wheat1' @register_style @@ -127,10 +131,9 @@ class Orange(Style): """Orange style.""" name: str = 'orange' - description: str = 'Orange text color' border: str = 'dark_orange' - highlight: str = 'orange1' column: str = 'orange1' + highlight: str = 'orange1' @register_style @@ -139,10 +142,9 @@ class White(Style): """White style.""" name: str = 'white' - description: str = 'White text color' border: str = 'grey82' - highlight: str = 'grey100' column: str = 'grey100' + highlight: str = 'grey100' @register_style @@ -151,10 +153,9 @@ class Grey(Style): """Grey style.""" name: str = 'grey' - description: str = 'Grey text color' border: str = 'grey50' - highlight: str = 'grey70' column: str = 'grey70' + highlight: str = 'grey70' @register_style @@ -163,10 +164,9 @@ class Navy(Style): """Navy Blue style.""" name: str = 'navyblue' - description: str = 'Navy Blue text color' border: str = 'deep_sky_blue4' - highlight: str = 'light_sky_blue3' column: str = 'light_sky_blue3' + highlight: str = 'light_sky_blue3' @register_style @@ -175,17 +175,11 @@ class Black(Style): """Black style.""" name: str = 'black' - description: str = 'Black text color' border: str = 'grey19' column: str = 'grey11' + highlight: str = 'grey11' def request_style_obj(style_name: str, no_border: bool) -> Style: """Entry point for style objects. Returns a Style object based on the style name.""" - style_name = str(style_name).lower() # coerce the type to string and lowercase it - - if style_name not in _registry: - os.environ['NO_COLOR'] = '1' # Disable colour output - return Style() - - return _registry[style_name](no_border=no_border) + return registry[style_name.lower()](no_border=no_border)