1from typing import Optional
2
3from clikit.api.args import Args
4from clikit.api.command import Command as CliKitCommand
5from clikit.api.config.command_config import CommandConfig
6
7from cleo.io import ConsoleIO
8
9
10class CommandError(Exception):
11    pass
12
13
14class BaseCommand(object):
15
16    name = None
17
18    description = None
19
20    help = None
21
22    arguments = []
23    options = []
24
25    aliases = []
26
27    enabled = True
28    hidden = False
29
30    commands = []
31
32    def __init__(self):
33        self._application = None
34
35        self._config = CommandConfig(self.name)
36        self._config.set_description(self.description)
37        self._config.set_help(self.help)
38        for argument in self.arguments:
39            self._config._format_builder.add_argument(argument)
40
41        for option in self.options:
42            self._config._format_builder.add_option(option)
43
44        for alias in self.aliases:
45            self._config.add_alias(alias)
46
47        if not self.enabled:
48            self._config.disable()
49
50        if self.hidden:
51            self._config.hide()
52
53        if self.commands:
54            for command in self.commands:
55                self.add_sub_command(command)
56
57        self._config.set_handler(self)
58
59    @property
60    def config(self):  # type: () -> CommandConfig
61        return self._config
62
63    @property
64    def application(self):
65        return self._application
66
67    def handle(
68        self, args, io, command
69    ):  # type: (Args, ConsoleIO, CliKitCommand) -> Optional[int]
70        raise NotImplementedError()
71
72    def set_application(self, application):
73        self._application = application
74
75        for command in self.commands:
76            command.set_application(application)
77
78    def add_sub_command(self, command):  # type: (BaseCommand) -> None
79        self._config.add_sub_command_config(command.config)
80
81        command.set_application(self.application)
82
83    def default(self, default=True):  # type: (bool) -> BaseCommand
84        self._config.default(default)
85
86        return self
87
88    def anonymous(self):  # type: () -> BaseCommand
89        self._config.anonymous()
90
91        return self
92