cleo icon indicating copy to clipboard operation
cleo copied to clipboard

Default command feature does not work

Open esciara opened this issue 6 years ago • 8 comments

I came across the same problem as described in https://github.com/sdispater/cleo/issues/66#issuecomment-466410466 : the steps described to create a single command application does not work.

Example provided in the comment.

Also does not work with cleo 0.7.5 and python 3.6.9 .

esciara avatar Oct 02 '19 12:10 esciara

The same on cleo 0.7.6

b0g3r avatar Nov 02 '19 20:11 b0g3r

Commit 132ad3e (2018-12-06) removed set_default_command().


In versions <=0.6.8

Use set_default_command().

from cleo import Application

from .commands import GreetCommand

app = Application()
app.add(GreetCommand())
app.set_default_command("greet", is_single_command=True)

app.run()

In versions >0.6.8

Problem

  • When no command is given the application runs the first command that is set as .default().
  • The help() command is added first (as part of the default config) and is thus always run as the default command.

Solution Create a custom config where the help command is not set as default and pass it to your application, example:

foo/
  config.py
  main.py

config.py

from clikit.api.args.format.argument import Argument
from clikit.api.args.format.option import Option
from clikit.api.event import PRE_HANDLE
from clikit.api.event import PRE_RESOLVE
from clikit.config.default_application_config import DefaultApplicationConfig
from clikit.handler.help import HelpTextHandler
from clikit.resolver.help_resolver import HelpResolver


class ApplicationConfig(DefaultApplicationConfig):
    """
    The default application configuration.
    """

    def configure(self):
        self.set_io_factory(self.create_io)
        self.add_event_listener(PRE_RESOLVE, self.resolve_help_command)
        self.add_event_listener(PRE_HANDLE, self.print_version)

        self.add_option("help", "h", Option.NO_VALUE, "Display this help message")
        self.add_option("quiet", "q", Option.NO_VALUE, "Do not output any message")
        self.add_option(
            "verbose",
            "v",
            Option.OPTIONAL_VALUE,
            "Increase the verbosity of messages: "
            '"-v" for normal output, '
            '"-vv" for more verbose output '
            'and "-vvv" for debug',
        )
        self.add_option(
            "version", "V", Option.NO_VALUE, "Display this application version"
        )
        self.add_option("ansi", None, Option.NO_VALUE, "Force ANSI output")
        self.add_option("no-ansi", None, Option.NO_VALUE, "Disable ANSI output")
        self.add_option(
            "no-interaction",
            "n",
            Option.NO_VALUE,
            "Do not ask any interactive question",
        )

        with self.command("help") as c:
            # c.default()
            c.set_description("Display the manual of a command")
            c.add_argument(
                "command", Argument.OPTIONAL | Argument.MULTI_VALUED, "The command name"
            )
            c.set_handler(HelpTextHandler(HelpResolver()))

main.py

from cleo import Application
from cleo import Command

from .commands import GreetCommand
from .config import ApplicationConfig

config = ApplicationConfig("greet", "0.1.0")

app = Application(config=config)
app.add(GreetCommand().default())
app.run()

This is what I could think of until there is a public method available that allows you to define the default command.

vikpe avatar Nov 16 '19 15:11 vikpe