Passed
Push — master ( fba7a8...13fed3 )
by Timm
06:38
created

Cmd::hasChild()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
namespace Stefaminator\Cli;
5
6
7
use Exception;
8
use GetOptionKit\OptionCollection;
9
use GetOptionKit\OptionResult;
10
11
abstract class Cmd {
12
13
    /**
14
     * @var Cmd
15
     */
16
    public $parent;
17
18
    /**
19
     * @var Cmd[]
20
     */
21
    public $children = [];
22
23
    /**
24
     * @var string
25
     */
26
    public $cmd;
27
28
    /**
29
     * @var string
30
     */
31
    private $description = '';
32
33
    /**
34
     * @var array
35
     */
36
    private $argSpecs = [];
37
38
    /**
39
     * @var string[]
40
     */
41
    public $arguments = [];
42
43
    /**
44
     * @var array
45
     */
46
    public $optSpecs = [];
47
48
    /**
49
     * @var OptionCollection
50
     */
51
    private $optionCollection;
52
53
    /**
54
     * @var OptionResult|null
55
     */
56
    public $optionResult;
57
58
    /**
59
     * @var Exception
60
     */
61
    public $optionParseException;
62
63
64
    /**
65
     * The constructor.
66
     * @param string|null $cmd
67
     */
68 21
    public function __construct(string $cmd = null) {
69 21
        $this->cmd = $cmd;
70 21
        $this->init();
71 21
    }
72
73
74 4
    public function runHelp(): void {
75 4
        (new Help($this))->run();
76 4
    }
77
78
    /**
79
     * Run the cmd
80
     */
81
    abstract public function init(): void;
82
83
    /**
84
     * Run the cmd
85
     */
86
    abstract public function run(): void;
87
88
    /**
89
     * Overwrite this method for extended help
90
     */
91 3
    public function help(): void {
92
93 3
    }
94
95 2
    public function description(): string {
96 2
        return $this->description;
97
    }
98
99 1
    public function arguments(): array {
100 1
        return $this->arguments;
101
    }
102
103 4
    public function argSpecs(): array {
104 4
        return $this->argSpecs;
105
    }
106
107 21
    public function optionCollection(): OptionCollection {
108
109 21
        if ($this->optionCollection !== null) {
110 4
            return $this->optionCollection;
111
        }
112
113 21
        $specs = (array)$this->optSpecs;
114
115 21
        $collection = new OptionCollection();
116
117 21
        foreach ($specs as $k => $v) {
118 21
            $opt = $collection->add($k, $v['description']);
119
120 21
            if (array_key_exists('isa', $v)) {
121 11
                if(array_key_exists('regex', $v) && strtolower($v['isa']) === 'regex') {
122
                    $opt->isa('regex', $v['regex']);
123
                } else {
124 11
                    $opt->isa($v['isa']);
125
                }
126
            }
127
128 21
            if (array_key_exists('default', $v)) {
129 9
                $opt->defaultValue($v['default']);
130 9
                continue;
131
            }
132
133 21
            if (array_key_exists('incremental', $v) && $v['incremental'] === true) {
134
                $opt->incremental();
135
                continue;
136
            }
137
        }
138
139 21
        $this->optionCollection = $collection;
140 21
        return $this->optionCollection;
141
    }
142
143 2
    public function getProvidedOption(string $key) {
144 2
        if ($this->optionResult !== null) {
145 2
            return $this->optionResult->get($key);
146
        }
147
        return null;
148
    }
149
150 1
    public function getAllProvidedOptions(): array {
151 1
        $r = [];
152 1
        if ($this->optionResult !== null) {
153 1
            $keys = array_keys($this->optionResult->keys);
154 1
            foreach ($keys as $key) {
155 1
                $r[$key] = $this->getProvidedOption($key);
156
            }
157
        }
158 1
        return $r;
159
    }
160
161
    /**
162
     * @param string $key
163
     * @return bool
164
     */
165 4
    public function hasProvidedOption(string $key): bool {
166 4
        return $this->optionResult !== null && $this->optionResult->has($key);
167
    }
168
169 17
    public function hasChild(string $cmd): bool {
170 17
        return array_key_exists($cmd, $this->children);
171
    }
172
173 17
    public function getChild(string $cmd): ?self {
174 17
        if ($this->hasChild($cmd)) {
175 11
            return $this->children[$cmd];
176
        }
177 8
        return null;
178
    }
179
180 16
    public function addChild(Cmd $runner): self {
181
182 16
        $runner->parent = $this;
183 16
        $this->children[$runner->cmd] = $runner;
184
185 16
        return $this;
186
    }
187
188 16
    protected function setDescription(string $description): self {
189 16
        $this->description = $description;
190 16
        return $this;
191
    }
192
193 21
    protected function addOption(string $specString, array $config): self {
194
195 21
        $this->optSpecs[$specString] = $config;
196
197 21
        return $this;
198
    }
199
200 16
    protected function addArgument(string $specString, array $config): self {
201
202 16
        foreach ($this->argSpecs as $k => $v) {
203 16
            if (array_key_exists('multiple', $v)) {
204
                unset($this->argSpecs[$k]['multiple']);
205
            }
206
        }
207
208 16
        $config['index'] = count($this->argSpecs);
209
210 16
        $this->argSpecs[$specString] = $config;
211
212 16
        return $this;
213
    }
214
215
216 6
    public function handleOptionParseException(): bool {
217
218 6
        if ($this->optionParseException === null) {
219 5
            return false;
220
        }
221
222 1
        self::eol();
223 1
        self::echo('Uups, something went wrong!', Color::FOREGROUND_COLOR_RED);
224 1
        self::eol();
225 1
        self::echo($this->optionParseException->getMessage(), Color::FOREGROUND_COLOR_RED);
226 1
        self::eol();
227
228 1
        $this->runHelp();
229
230 1
        return true;
231
    }
232
233
234
    public const EOL = "\n";
235
236
237 6
    public static function eol(): void {
238 6
        echo self::EOL;
239 6
    }
240
241 6
    public static function echo(string $str, ?string $foreground_color = null): void {
242
243 6
        $lines = preg_split("/\r\n|\n|\r/", $str);
244
245 6
        $output = [];
246 6
        foreach ($lines as $line) {
247 6
            if ($foreground_color !== null) {
248 6
                $line = Color::getColoredString($line, $foreground_color);
249
            }
250 6
            $output[] = $line;
251
        }
252
253 6
        echo implode(self::EOL, $output);
254 6
    }
255
256
}