diff --git a/CHANGELOG.md b/CHANGELOG.md index 2977e26..471b254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.2.7 - 2026-07-22 + +### CLI + +- Allow options after the project directory (`uvx create-awesome-python-app my-api --template …`). Typer was registering `cache` as a nested command group, so Click treated `--template` as a COMMAND name. + ## 0.2.6 - 2026-07-18 ### Docs diff --git a/packages/create-awesome-python-app/pyproject.toml b/packages/create-awesome-python-app/pyproject.toml index 084868c..b0f9ac3 100644 --- a/packages/create-awesome-python-app/pyproject.toml +++ b/packages/create-awesome-python-app/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "create-awesome-python-app" -version = "0.2.6" +version = "0.2.7" description = "Composable scaffolding CLI for production-ready Python apps" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/create-awesome-python-app/src/create_awesome_python_app/__init__.py b/packages/create-awesome-python-app/src/create_awesome_python_app/__init__.py index b7a0d9b..f8e94da 100644 --- a/packages/create-awesome-python-app/src/create_awesome_python_app/__init__.py +++ b/packages/create-awesome-python-app/src/create_awesome_python_app/__init__.py @@ -1,3 +1,3 @@ """Create Awesome Python App CLI.""" -__version__ = "0.2.6" +__version__ = "0.2.7" diff --git a/packages/create-awesome-python-app/src/create_awesome_python_app/cli.py b/packages/create-awesome-python-app/src/create_awesome_python_app/cli.py index 537d56c..ae8d795 100644 --- a/packages/create-awesome-python-app/src/create_awesome_python_app/cli.py +++ b/packages/create-awesome-python-app/src/create_awesome_python_app/cli.py @@ -34,9 +34,12 @@ help="Composable scaffolding CLI for production-ready Python apps.", no_args_is_help=False, add_completion=True, + # Keep cache out of this Typer app (routed in main()). A nested command + # group turns the CLI into Click Group form `[ARGS] COMMAND`, so + # `cpa my-api --template …` fails with "No such command '--template'". + epilog="Cache: create-awesome-python-app cache [list|dir|clean|verify|…]", ) cache_app = typer.Typer(help="Inspect and manage the local template cache") -app.add_typer(cache_app, name="cache") console = Console(stderr=True) @@ -209,9 +212,8 @@ def main() -> None: app() -@app.callback(invoke_without_command=True) +@app.command(name="create-awesome-python-app") def scaffold( - ctx: typer.Context, project_directory: str | None = typer.Argument("my-project"), version: bool = typer.Option(False, "--version"), info: bool = typer.Option(False, "--info", "-i"), @@ -247,8 +249,6 @@ def scaffold( raise typer.Exit(0) if info: print_env_info() - if ctx.invoked_subcommand is not None: - return # Translate --fixture into env vars before catalog loads # (--list-templates / interactive / scaffold). diff --git a/packages/create-awesome-python-app/tests/test_cli.py b/packages/create-awesome-python-app/tests/test_cli.py index f1f53de..bdb85a2 100644 --- a/packages/create-awesome-python-app/tests/test_cli.py +++ b/packages/create-awesome-python-app/tests/test_cli.py @@ -223,6 +223,54 @@ def test_help_mentions_fixture() -> None: assert "fixture" in text.lower() +def test_options_after_project_directory(tmp_path: Path, monkeypatch) -> None: + """Regression: README-style `cpa my-api --template …` must work. + + Registering a Typer subcommand group made Click treat ``--template`` as a + COMMAND after the positional project directory. + """ + tpl = tmp_path / "tpl" + tpl.mkdir() + captured: dict[str, object] = {} + + async def fake_check_for_latest_version(_package_name): + return None + + async def fake_create_python_app(project_directory, options, *_args, **_kwargs): + captured["project_directory"] = project_directory + captured["options"] = options + + monkeypatch.setattr( + "create_awesome_python_app.cli.check_for_latest_version", + fake_check_for_latest_version, + ) + monkeypatch.setattr( + "create_awesome_python_app.cli.create_python_app", + fake_create_python_app, + ) + + result = runner.invoke( + app, + [ + "my-api", + "--template", + f"file://{tpl}", + "--addons", + "github-setup", + "--no-install", + "--no-interactive", + ], + ) + + text = (result.stdout or "") + (result.stderr or "") + assert result.exit_code == 0, text + assert "No such command" not in text + assert captured["project_directory"] == "my-api" + options = captured["options"] + assert isinstance(options, dict) + assert options["template"] == f"file://{tpl}" + + def test_preprocess_fixture_argv_bare_and_with_dir() -> None: from create_awesome_python_app.cli import _FIXTURE_AUTO, _preprocess_fixture_argv diff --git a/uv.lock b/uv.lock index 9d01460..835150d 100644 --- a/uv.lock +++ b/uv.lock @@ -138,7 +138,7 @@ wheels = [ [[package]] name = "create-awesome-python-app" -version = "0.2.5" +version = "0.2.7" source = { editable = "packages/create-awesome-python-app" } dependencies = [ { name = "create-python-app-core" }, @@ -157,7 +157,7 @@ requires-dist = [ [[package]] name = "create-python-app-core" -version = "0.2.5" +version = "0.2.6" source = { editable = "packages/create-python-app-core" } dependencies = [ { name = "httpx" },