From 8c41c8fff15196e9125655351f7378f3b3089d66 Mon Sep 17 00:00:00 2001 From: C0DE-SLAYER Date: Mon, 14 Aug 2023 21:21:08 +0530 Subject: [PATCH 1/2] coloured text --- spcache/cli.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/spcache/cli.py b/spcache/cli.py index 0404c1c..cd66e21 100644 --- a/spcache/cli.py +++ b/spcache/cli.py @@ -30,10 +30,11 @@ def handle_file( file = detect.detect_prefs_file() if file is None: - click.echo( + click.secho( "The Spotify prefs file couldn't be auto-detected." "\nPlease specify a path to the prefs file using the --file option.", err=True, + fg="red", ) ctx.exit(2) @@ -47,9 +48,10 @@ def handle_file( filepath = pathlib.Path(file) if filepath.name != "prefs": - click.echo( + click.secho( f"The given file should be named 'prefs', not '{filepath.name}'. Is the path correct?", err=True, + fg="red", ) return file @@ -124,17 +126,20 @@ def set( import textwrap line_preview = textwrap.shorten(e.line_content.rstrip(), 80) - click.echo( + click.secho( f"Line {e.line_no} is invalid. ({line_preview})" "\nTo ignore this error, use the --force flag.", err=True, + fg="red", ) ctx.exit(3) if previous_value is not None: - click.echo(f"The cache size has been updated from {previous_value} MB to {size} MB.") + click.secho( + f"The cache size has been updated from {previous_value} MB to {size} MB.", fg="green" + ) else: - click.echo(f"The cache size has been set to {size} MB.") + click.secho(f"The cache size has been set to {size} MB.", fg="green") @spcache.command() @@ -160,17 +165,20 @@ def get( import textwrap line_preview = textwrap.shorten(e.line_content.rstrip(), 80) - click.echo( + click.secho( f"Line {e.line_no} is invalid. ({line_preview})" "\nTo ignore this error, use the --force flag.", err=True, + fg="red", ) ctx.exit(3) if limit is not None: - click.echo(f"The cache size is currently {limit} MB.") + click.secho(f"The cache size is currently {limit} MB.", fg="green") else: - click.echo("The cache size has not been set! Run 'spcache set' to set a limit.") + click.secho( + "The cache size has not been set! Run 'spcache set' to set a limit.", fg="yellow" + ) @spcache.command() @@ -181,10 +189,10 @@ def detect(ctx: click.Context) -> None: file = detect.detect_prefs_file() if file is None: - click.echo("The Spotify prefs file couldn't be auto-detected.", err=True) + click.secho("The Spotify prefs file couldn't be auto-detected.", err=True, fg="red") ctx.exit(2) - click.echo(file) + click.secho(file, fg="green") if __name__ == "__main__": From 190f38cf853311791908fe09b322ada60c1257ca Mon Sep 17 00:00:00 2001 From: C0DE-SLAYER Date: Wed, 16 Aug 2023 20:20:33 +0530 Subject: [PATCH 2/2] Integrate rick_click and handle Exception --- spcache/cli.py | 86 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/spcache/cli.py b/spcache/cli.py index cd66e21..ad6aad1 100644 --- a/spcache/cli.py +++ b/spcache/cli.py @@ -2,7 +2,7 @@ import typing as t -import click +import rich_click as click # TODO: Inspect the behaviour of the Spotify client when the cache size # is set to 0. @@ -14,6 +14,57 @@ import dotenv.main +class ExceptionBase(click.ClickException): + """ + Base class for exceptions raised by this CLI tool. + + Supports reading the message from a class variable. + """ + + exit_code: t.ClassVar[int] + message: t.ClassVar[str] + + def __init__(self) -> None: + super().__init__(self.message) + + +class FileDetectionErrorWithFileOption(ExceptionBase): + """ + Raised when the Spotify prefs file can't be auto-detected. + + can provide --file option to specify the path to prefs file. + """ + + exit_code = 2 + message = ( + "The Spotify prefs file couldn't be auto-detected." + "\nPlease specify a path to the prefs file using the --file option." + ) + + +class FileDetectionError(ExceptionBase): + """Raised when the Spotify prefs file can't be auto-detected.""" + + exit_code = 2 + message = "The Spotify prefs file couldn't be auto-detected." + + +class EnvInvalidLineError(ExceptionBase): + """Raised when a line in a .env file is invalid.""" + + exit_code = 3 + message = None + + def __init__(self, e: tuple) -> None: + import textwrap + + line_preview = textwrap.shorten(e.line_content.rstrip(), 80) + EnvInvalidLineError.message = ( + f"Line {e.line_no} is invalid. ({line_preview})" + "\nTo ignore this error, use the --force flag." + ) + + def handle_file( ctx: click.Context, file: t.Optional["dotenv.main.StrPath"], no_prompts: bool ) -> "dotenv.main.StrPath": @@ -30,13 +81,7 @@ def handle_file( file = detect.detect_prefs_file() if file is None: - click.secho( - "The Spotify prefs file couldn't be auto-detected." - "\nPlease specify a path to the prefs file using the --file option.", - err=True, - fg="red", - ) - ctx.exit(2) + raise FileDetectionErrorWithFileOption if not no_prompts: click.confirm( @@ -123,16 +168,7 @@ def set( file, CACHE_KEY, str(size), quote_mode="never", ignore_errors=force ) except env.InvalidLineError as e: - import textwrap - - line_preview = textwrap.shorten(e.line_content.rstrip(), 80) - click.secho( - f"Line {e.line_no} is invalid. ({line_preview})" - "\nTo ignore this error, use the --force flag.", - err=True, - fg="red", - ) - ctx.exit(3) + raise EnvInvalidLineError(e) from None if previous_value is not None: click.secho( @@ -162,16 +198,7 @@ def get( try: limit = env.get_key(file, CACHE_KEY, ignore_errors=force) except env.InvalidLineError as e: - import textwrap - - line_preview = textwrap.shorten(e.line_content.rstrip(), 80) - click.secho( - f"Line {e.line_no} is invalid. ({line_preview})" - "\nTo ignore this error, use the --force flag.", - err=True, - fg="red", - ) - ctx.exit(3) + raise EnvInvalidLineError(e) from None if limit is not None: click.secho(f"The cache size is currently {limit} MB.", fg="green") @@ -189,8 +216,7 @@ def detect(ctx: click.Context) -> None: file = detect.detect_prefs_file() if file is None: - click.secho("The Spotify prefs file couldn't be auto-detected.", err=True, fg="red") - ctx.exit(2) + raise FileDetectionError click.secho(file, fg="green")