From 999220e835ace284390ee77b39831437eee1e521 Mon Sep 17 00:00:00 2001 From: David Pugh Date: Fri, 14 Aug 2026 13:15:01 +0100 Subject: [PATCH] adding json flag --- src/nskit/cli/app.py | 10 +++++++- tests/unit/test_cli/test_app.py | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/nskit/cli/app.py b/src/nskit/cli/app.py index 29ccb04..06c6e2b 100644 --- a/src/nskit/cli/app.py +++ b/src/nskit/cli/app.py @@ -150,8 +150,12 @@ def create_cli( backend = None @app.command(name="list", help="List available recipes.") - def list_recipes(): + def list_recipes( + json_output: Annotated[bool, typer.Option("--json", help="Output as JSON array of recipe names.")] = False, + ): """List available recipes from backend or installed entry points.""" + import json as json_mod + if client: recipes = client.list_recipes() else: @@ -161,6 +165,10 @@ def list_recipes(): names = get_extension_names(recipe_entrypoint) recipes = [RecipeInfo(name=n, versions=["local"]) for n in names] + if json_output: + print(json_mod.dumps(sorted(r.name for r in recipes))) + return + if not recipes: rich_print("[yellow]No recipes found[/yellow]") return diff --git a/tests/unit/test_cli/test_app.py b/tests/unit/test_cli/test_app.py index edf2ac4..8a8f50d 100644 --- a/tests/unit/test_cli/test_app.py +++ b/tests/unit/test_cli/test_app.py @@ -229,3 +229,46 @@ def test_no_push_when_declined(self, tmp_path): _commit_and_maybe_push(project, "proj", "", False, mock_vcs, console) mock_vcs.create.assert_not_called() + + +class TestListJsonFlag: + """``list --json`` outputs a machine-readable JSON array.""" + + def test_list_json_exits_zero(self, runner): + app = create_cli(recipe_entrypoint="nskit.recipes") + result = runner.invoke(app, ["list", "--json"]) + assert result.exit_code == 0, result.output + + def test_list_json_outputs_valid_json(self, runner): + import json + + app = create_cli(recipe_entrypoint="nskit.recipes") + result = runner.invoke(app, ["list", "--json"]) + data = json.loads(result.output) + assert isinstance(data, list) + + def test_list_json_contains_registered_recipes(self, runner): + import json + + app = create_cli(recipe_entrypoint="nskit.recipes") + result = runner.invoke(app, ["list", "--json"]) + data = json.loads(result.output) + assert "python_package" in data + + def test_list_json_is_sorted(self, runner): + import json + + app = create_cli(recipe_entrypoint="nskit.recipes") + result = runner.invoke(app, ["list", "--json"]) + data = json.loads(result.output) + assert data == sorted(data) + + def test_list_without_json_shows_table(self, runner): + """Without --json, output is a rich table (not JSON).""" + import json + + app = create_cli(recipe_entrypoint="nskit.recipes") + result = runner.invoke(app, ["list"]) + assert result.exit_code == 0 + with pytest.raises(json.JSONDecodeError): + json.loads(result.output)