diff --git a/src/cleo/application.py b/src/cleo/application.py index 33749998..287870ee 100644 --- a/src/cleo/application.py +++ b/src/cleo/application.py @@ -428,6 +428,32 @@ def _run(self, io: IO) -> int: io.input.set_stream(stream) io.input.interactive(interactive) + if name == "help" and isinstance(io.input, ArgvInput): + # If the command is `help` we suppose + # that all without `-` is a command (possible namespaced) + argv = io.input._tokens[:] + + if io.input.script_name is not None: + argv.insert(0, io.input.script_name) + else: + # Needs because `ApplicationTester` doesn't add script name + argv.insert(0, self.name) + + # filter all words after `help` without `-` + start = argv.index(name) + words = list(filter(lambda arg: "-" not in arg, argv[start + 1 :])) + + if words: + index = argv.index(words[0]) + argv[index] = " ".join(argv[index:]) + del argv[index + 1 :] + + stream = io.input.stream + interactive = io.input.is_interactive() + io.set_input(ArgvInput(argv)) + io.input.set_stream(stream) + io.input.interactive(interactive) + exit_code = self._run_command(command, io) self._running_command = None diff --git a/tests/fixtures/application_help_multiple_word.txt b/tests/fixtures/application_help_multiple_word.txt new file mode 100644 index 00000000..1affd18a --- /dev/null +++ b/tests/fixtures/application_help_multiple_word.txt @@ -0,0 +1,16 @@ + +Description: + The foo bar command + +Usage: + foo bar [options] + afoobar + +Options: + -h, --help Display help for the given command. When no command is given display help for the list command. + -q, --quiet Do not output any message. + -V, --version Display this application version. + --ansi Force ANSI output. + --no-ansi Disable ANSI output. + -n, --no-interaction Do not ask any interactive question. + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug. diff --git a/tests/test_application.py b/tests/test_application.py index 6bb6bb65..0971709e 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -118,6 +118,21 @@ def test_silent_help(app: Application) -> None: assert tester.io.fetch_output() == "" +def test_help_multiple_word_command(app: Application) -> None: + app.catch_exceptions(False) + + foo = FooCommand() + app.add(foo) + + tester = ApplicationTester(app) + tester.execute("help foo bar") + + assert ( + tester.io.fetch_output() + == FIXTURES_PATH.joinpath("application_help_multiple_word.txt").read_text() + ) + + def test_get_namespaces(app: Application) -> None: app.add(FooCommand()) app.add(Foo1Command())