diff --git a/src/serious_scaffold/cli.py b/src/serious_scaffold/cli.py index 5a4957d9..bb0aa6d5 100644 --- a/src/serious_scaffold/cli.py +++ b/src/serious_scaffold/cli.py @@ -9,6 +9,19 @@ def run() -> None: """Run command.""" +# NOTE(huxuan): callback is required for single command as a subcommand in typer. +# And it is a convenient way to document the cli here. +# Reference: https://typer.tiangolo.com/tutorial/commands/one-or-multiple/#one-command-and-one-callback +# BTW, `no_args_is_help` is set to `True` to avoid error when invoking the cli with no +# subcommands. The default behavior is strange and might change in the future. +# Reference: https://github.com/tiangolo/typer/issues/328 +@app.callback(no_args_is_help=True) +def main() -> None: + """CLI for Serious Scaffold Python.""" + + +# NOTE(huxuan): click object is used for document generation. +# Reference: https://github.com/tiangolo/typer/issues/200#issuecomment-796485787 typer_click_object = typer.main.get_command(app) diff --git a/src/{{ module_name }}/cli.py b/src/{{ module_name }}/cli.py deleted file mode 100644 index 5a4957d9..00000000 --- a/src/{{ module_name }}/cli.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Command Line Interface.""" -import typer - -app = typer.Typer() - - -@app.command() -def run() -> None: - """Run command.""" - - -typer_click_object = typer.main.get_command(app) - - -if __name__ == "__main__": - app() # pragma: no cover diff --git a/src/{{ module_name }}/cli.py.jinja b/src/{{ module_name }}/cli.py.jinja new file mode 100644 index 00000000..2f7b3a19 --- /dev/null +++ b/src/{{ module_name }}/cli.py.jinja @@ -0,0 +1,29 @@ +"""Command Line Interface.""" +import typer + +app = typer.Typer() + + +@app.command() +def run() -> None: + """Run command.""" + + +# NOTE(huxuan): callback is required for single command as a subcommand in typer. +# And it is a convenient way to document the cli here. +# Reference: https://typer.tiangolo.com/tutorial/commands/one-or-multiple/#one-command-and-one-callback +# BTW, `no_args_is_help` is set to `True` to avoid error when invoking the cli with no +# subcommands. The default behavior is strange and might change in the future. +# Reference: https://github.com/tiangolo/typer/issues/328 +@app.callback(no_args_is_help=True) +def main() -> None: + """CLI for {{ project_name }}.""" + + +# NOTE(huxuan): click object is used for document generation. +# Reference: https://github.com/tiangolo/typer/issues/200#issuecomment-796485787 +typer_click_object = typer.main.get_command(app) + + +if __name__ == "__main__": + app() # pragma: no cover diff --git a/tests/cli_test.py b/tests/cli_test.py index c140e4c8..8f7268e3 100644 --- a/tests/cli_test.py +++ b/tests/cli_test.py @@ -6,8 +6,15 @@ runner = CliRunner() -def test_app() -> None: +def test_cli() -> None: """Tests for cli.""" result = runner.invoke(app) assert result.exit_code == 0 + assert "Usage" in result.output + + +def test_cli_run() -> None: + """Tests for run subcommand of the cli.""" + result = runner.invoke(app, "run") + assert result.exit_code == 0 assert not result.output diff --git a/tests/cli_test.py.jinja b/tests/cli_test.py.jinja index 3569f115..09139c1b 100644 --- a/tests/cli_test.py.jinja +++ b/tests/cli_test.py.jinja @@ -6,8 +6,15 @@ from {{ module_name }}.cli import app runner = CliRunner() -def test_app() -> None: +def test_cli() -> None: """Tests for cli.""" result = runner.invoke(app) assert result.exit_code == 0 + assert "Usage" in result.output + + +def test_cli_run() -> None: + """Tests for run subcommand of the cli.""" + result = runner.invoke(app, "run") + assert result.exit_code == 0 assert not result.output