diff --git a/news/258.bugfix.md b/news/258.bugfix.md new file mode 100644 index 00000000..c59e0b79 --- /dev/null +++ b/news/258.bugfix.md @@ -0,0 +1 @@ +Fix built-in help command requiring quotes for nested subcommands diff --git a/src/cleo/commands/help_command.py b/src/cleo/commands/help_command.py index a52713eb..c949f4b5 100644 --- a/src/cleo/commands/help_command.py +++ b/src/cleo/commands/help_command.py @@ -16,7 +16,8 @@ class HelpCommand(Command): "command_name", required=False, description="The command name", - default="help", + default=["help"], + is_list=True, ) ] @@ -43,7 +44,12 @@ def handle(self) -> int: if self._command is None: assert self._application is not None - self._command = self._application.find(self.argument("command_name")) + command_name = self.argument("command_name") + if isinstance(command_name, list): + command_name = " ".join(command_name) + if not command_name: + command_name = "help" + self._command = self._application.find(command_name) self.line("") TextDescriptor().describe(self._io, self._command) diff --git a/tests/fixtures/application_run5.txt b/tests/fixtures/application_run5.txt index a322d59f..22244549 100644 --- a/tests/fixtures/application_run5.txt +++ b/tests/fixtures/application_run5.txt @@ -3,10 +3,10 @@ Description: Displays help for a command. Usage: - help [options] [--] [] + help [options] [--] [...] Arguments: - command_name The command name [default: "help"] + command_name The command name [default: ["help"]] Options: -h, --help Display help for the given command. When no command is given display help for the list command. diff --git a/tests/test_application.py b/tests/test_application.py index f08286a4..ca4b4fe6 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -346,6 +346,30 @@ def test_run_with_help(tester: ApplicationTester) -> None: ).read_text(encoding="utf-8") +def test_run_help_with_nested_subcommand() -> None: + app = Application() + app.add(FooSubNamespaced1Command()) + + tester1 = ApplicationTester(app) + exit1 = tester1.execute("help foo bar baz") + output1 = tester1.io.fetch_output() + + tester2 = ApplicationTester(app) + exit2 = tester2.execute('help "foo bar baz"') + output2 = tester2.io.fetch_output() + + tester3 = ApplicationTester(app) + exit3 = tester3.execute("--help foo bar baz") + output3 = tester3.io.fetch_output() + + assert exit1 == 0 + assert exit2 == 0 + assert exit3 == 0 + assert "The foo bar baz command" in output1 + assert output1 == output2 + assert output1 == output3 + + def test_run_with_input() -> None: app = Application() command = Foo3Command()