Passed
Push — master ( 3d076e...fba7a8 )
by Timm
02:10
created

Cmd::createRootCmd()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
eloc 3
nc 1
nop 1
ccs 4
cts 4
cp 1
crap 1
1
<?php
2
3
namespace Stefaminator\Cli;
4
5
use Exception;
6
use GetOptionKit\OptionCollection;
7
use GetOptionKit\OptionResult;
8
9
10
class Cmd {
11
12
    /**
13
     * @var Cmd
14
     */
15
    public $parent;
16
17
    /**
18
     * @var string
19
     */
20
    public $cmd;
21
22
    /**
23
     * @var string
24
     */
25
    public $descr;
26
27
    /**
28
     * @var array
29
     */
30
    public $optionSpecs = [];
31
32
    /**
33
     * @var OptionCollection
34
     */
35
    private $optionCollection;
36
37
    /**
38
     * @var OptionResult|null
39
     */
40
    public $optionResult;
41
42
    /**
43
     * @var Exception
44
     */
45
    public $optionParseException;
46
47
    /**
48
     * @var array
49
     */
50
    public $argumentSpecs = [];
51
52
    /**
53
     * @var string[]
54
     */
55
    public $arguments = [];
56
57
    /**
58
     * @var Cmd[]
59
     */
60
    public $subcommands = [];
61
62
    /**
63
     * @var CmdRunner|null
64
     */
65
    private $runner;
66
67
68 21
    public function __construct(string $cmd) {
69 21
        $this->cmd = $cmd;
70 21
    }
71
72 21
    public function addOption(string $specString, array $config): self {
73
74 21
        $this->optionSpecs[$specString] = $config;
75
76 21
        return $this;
77
    }
78
79 16
    public function addArgument(string $specString, array $config): self {
80
81 16
        foreach ($this->argumentSpecs as $k => $v) {
82 16
            if (array_key_exists('multiple', $v)) {
83
                unset($this->argumentSpecs[$k]['multiple']);
84
            }
85
        }
86
87 16
        $config['index'] = count($this->argumentSpecs);
88
89 16
        $this->argumentSpecs[$specString] = $config;
90
91 16
        return $this;
92
    }
93
94 16
    public function addSubCmd(Cmd $cmd): self {
95
96 16
        $cmd->parent = $this;
97 16
        $this->subcommands[$cmd->cmd] = $cmd;
98
99 16
        return $this;
100
    }
101
102 16
    public function setDescription(string $descr): self {
103
104 16
        $this->descr = $descr;
105
106 16
        return $this;
107
    }
108
109 21
    public function setRunner(CmdRunner $runner): self {
110
111 21
        if ($this->runner === null) {
112
113 21
            $runner->init($this);
114
115 21
            $this->runner = $runner;
116
        }
117
118 21
        return $this;
119
    }
120
121 17
    public function hasSubCmd(string $cmd): bool {
122 17
        return array_key_exists($cmd, $this->subcommands);
123
    }
124
125 4
    public function hasProvidedOption(string $key): bool {
126 4
        return $this->optionResult !== null && $this->optionResult->has($key);
127
    }
128
129 2
    public function getProvidedOption(string $key) {
130 2
        if ($this->optionResult !== null) {
131 2
            return $this->optionResult->get($key);
132
        }
133
        return null;
134
    }
135
136 1
    public function getAllProvidedOptions(): array {
137 1
        $r = [];
138 1
        if ($this->optionResult !== null) {
139 1
            $keys = array_keys($this->optionResult->keys);
140 1
            foreach ($keys as $key) {
141 1
                $r[$key] = $this->getProvidedOption($key);
142
            }
143
        }
144 1
        return $r;
145
    }
146
147 1
    public function getAllProvidedArguments(): array {
148 1
        return $this->arguments;
149
    }
150
151 11
    public function getSubCmd(string $cmd): ?Cmd {
152 11
        if ($this->hasSubCmd($cmd)) {
153 11
            return $this->subcommands[$cmd];
154
        }
155
        return null;
156
    }
157
158 6
    public function getRunner(): ?CmdRunner {
159 6
        return $this->runner;
160
    }
161
162 21
    public function getOptionCollection(): OptionCollection {
163
164 21
        if ($this->optionCollection !== null) {
165 4
            return $this->optionCollection;
166
        }
167
168 21
        $specs = (array)$this->optionSpecs;
169
170 21
        $collection = new OptionCollection();
171
172 21
        foreach ($specs as $k => $v) {
173 21
            $opt = $collection->add($k, $v['description']);
174 21
            if (array_key_exists('isa', $v)) {
175 11
                $opt->isa($v['isa']);
176
            }
177 21
            if (array_key_exists('default', $v)) {
178 9
                $opt->defaultValue($v['default']);
179
            }
180
        }
181
182 21
        $this->optionCollection = $collection;
183 21
        return $this->optionCollection;
184
    }
185
186 6
    public function handleOptionParseException(): bool {
187
188 6
        if ($this->optionParseException === null) {
189 5
            return false;
190
        }
191
192 1
        CmdRunner::eol();
193 1
        CmdRunner::echo('Uups, something went wrong!', Color::FOREGROUND_COLOR_RED);
194 1
        CmdRunner::eol();
195 1
        CmdRunner::echo($this->optionParseException->getMessage(), Color::FOREGROUND_COLOR_RED);
196 1
        CmdRunner::eol();
197
198 1
        $this->help();
199
200 1
        return true;
201
    }
202
203 4
    public function help(): void {
204 4
        (new HelpRunner($this))->run();
205 4
    }
206
207 21
    public static function createRootCmd(CmdRunner $runner): Cmd {
208 21
        $_cmd = new Cmd('__root');
209 21
        $_cmd->setRunner($runner);
210 21
        return $_cmd;
211
    }
212
213 16
    public static function createSubCmd(string $cmd, CmdRunner $runner): Cmd {
214 16
        $_cmd = new Cmd($cmd);
215 16
        $_cmd->setRunner($runner);
216 16
        return $_cmd;
217
    }
218
219
}