From 46ee540537b7ff7f8cd8f19c0ece56bcf0fa8e85 Mon Sep 17 00:00:00 2001 From: Dariusz Duda Date: Tue, 10 Dec 2024 17:03:51 -0500 Subject: [PATCH] feat: add ordered to the add_command_group API (#574) Signed-off-by: Dariusz Duda --- craft_application/application.py | 8 +++-- docs/reference/changelog.rst | 5 +++ tests/integration/test_application.py | 45 +++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/craft_application/application.py b/craft_application/application.py index bfb43310..e2842018 100644 --- a/craft_application/application.py +++ b/craft_application/application.py @@ -268,10 +268,14 @@ def add_global_argument(self, argument: craft_cli.GlobalArgument) -> None: self._global_arguments.append(argument) def add_command_group( - self, name: str, commands: Sequence[type[craft_cli.BaseCommand]] + self, + name: str, + commands: Sequence[type[craft_cli.BaseCommand]], + *, + ordered: bool = False, ) -> None: """Add a CommandGroup to the Application.""" - self._command_groups.append(craft_cli.CommandGroup(name, commands)) + self._command_groups.append(craft_cli.CommandGroup(name, commands, ordered)) @cached_property def cache_dir(self) -> pathlib.Path: diff --git a/docs/reference/changelog.rst b/docs/reference/changelog.rst index 2227f2ba..d607022b 100644 --- a/docs/reference/changelog.rst +++ b/docs/reference/changelog.rst @@ -31,6 +31,11 @@ Git - Use ``craft.git`` for Git-related operations run with ``subprocess`` in ``GitRepo``. +Application +=========== + +- Add support for keeping order in help for commands provided to + ``add_command_group()``. .. For a complete list of commits, check out the `4.6.0`_ release on GitHub. diff --git a/tests/integration/test_application.py b/tests/integration/test_application.py index f5eedfb9..d712ce4f 100644 --- a/tests/integration/test_application.py +++ b/tests/integration/test_application.py @@ -12,12 +12,14 @@ # You should have received a copy of the GNU Lesser General Public License along # with this program. If not, see . """Integration tests for the Application.""" + import argparse import pathlib import shutil import textwrap import craft_application +import craft_application.commands import craft_cli import pytest import pytest_check @@ -127,6 +129,49 @@ def test_special_inputs(capsys, monkeypatch, app, argv, stdout, stderr, exit_cod pytest_check.equal(captured.err, stderr, "stderr does not match") +def _create_command(command_name): + class _FakeCommand(craft_application.commands.AppCommand): + name = command_name + + return _FakeCommand + + +@pytest.mark.parametrize( + "ordered", + [True, False], + ids=lambda ordered: f"keep_order={ordered}", +) +def test_registering_new_commands( + app: TestableApplication, + monkeypatch: pytest.MonkeyPatch, + capsys: pytest.CaptureFixture[str], + *, + ordered: bool, +) -> None: + command_names = ["second", "first"] + app.add_command_group( + "TestingApplicationGroup", + [_create_command(name) for name in command_names], + ordered=ordered, + ) + + monkeypatch.setattr("sys.argv", ["testcraft", "help"]) + + with pytest.raises(SystemExit) as exc_info: + app.run() + assert exc_info.value.code == 0, "App should finish without any problems" + + captured_help = capsys.readouterr() + # if ordered is set to True, craft_cli should respect command ordering + expected_command_order_in_help = ", ".join( + command_names if ordered else sorted(command_names) + ) + assert ( + f"TestingApplicationGroup: {expected_command_order_in_help}" + in captured_help.err + ), "Commands are positioned in the wrong order" + + @pytest.mark.usefixtures("pretend_jammy") @pytest.mark.parametrize("project", (d.name for d in VALID_PROJECTS_DIR.iterdir())) def test_project_managed(capsys, monkeypatch, tmp_path, project, create_app):