diff --git a/dbt_meshify/cli.py b/dbt_meshify/cli.py index 91e5dff..2e024b2 100644 --- a/dbt_meshify/cli.py +++ b/dbt_meshify/cli.py @@ -116,7 +116,7 @@ def owner(func): @functools.wraps(func) def wrapper_decorator(*args, **kwargs): - if kwargs.get('owner_name') is None and kwargs.get('owner_email') is None: + if kwargs.get("owner_name") is None and kwargs.get("owner_email") is None: raise click.UsageError( "Groups require an Owner to be defined using --owner-name and/or --owner-email." ) @@ -136,3 +136,10 @@ def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: pieces = self.collect_usage_pieces(ctx) pieces = pieces[1:] + [pieces[0]] formatter.write_usage(ctx.command_path, " ".join(pieces)) + + +def get_version() -> str: + """Get the current package version number.""" + import importlib.metadata + + return importlib.metadata.version("dbt-meshify") diff --git a/dbt_meshify/main.py b/dbt_meshify/main.py index 45d27a7..a9d79f9 100644 --- a/dbt_meshify/main.py +++ b/dbt_meshify/main.py @@ -25,6 +25,7 @@ create_path, exclude, exclude_projects, + get_version, group_yml_path, latest, owner, @@ -72,15 +73,27 @@ def logger_operation_level_filter(record): # define cli group -@click.group() +@click.group(invoke_without_command=True) @click.option("--dry-run", is_flag=True) @click.option("--debug", is_flag=True) -def cli(dry_run: bool, debug: bool): +@click.option("--version", is_flag=True, help="Show version information and exit") +@click.pass_context +def cli(ctx, dry_run: bool, debug: bool, version: bool): log_level = "DEBUG" if debug else "INFO" logger.add(sys.stdout, format=log_format, filter=logger_log_level_filter, level=log_level) logger.add(sys.stdout, format=operation_format, filter=logger_operation_level_filter) + # If the --version flag has been provided, print the version number and exit. + if version: + print(get_version()) + exit(0) + + # If a command has not been provided, print the help text and exit. + if ctx.invoked_subcommand is None: + print(ctx.get_help()) + exit(0) + @cli.result_callback() def handle_change_sets(change_sets=List[ChangeSet], dry_run=False, **kwargs): diff --git a/tests/integration/test_cli_group.py b/tests/integration/test_cli_group.py new file mode 100644 index 0000000..fec527f --- /dev/null +++ b/tests/integration/test_cli_group.py @@ -0,0 +1,31 @@ +from click.testing import CliRunner + +from dbt_meshify.cli import get_version +from dbt_meshify.main import cli + + +def test_version_option(): + """When the --version option is passed, meshify returns the version and exits.""" + + runner = CliRunner() + result = runner.invoke( + cli, + [ + "--version", + ], + ) + + assert result.exit_code == 0 + assert result.stdout.rstrip() == get_version() + + +def test_no_command_prints_help(): + """When an invoked subcommand is not provided, print the help and exit.""" + + runner = CliRunner() + result = runner.invoke(cli) + + assert result.exit_code == 0 + + help_result = runner.invoke(cli, ["--help"]) + assert result.stdout == help_result.stdout