Passed
Push — master ( 244bf6...cc00b6 )
by Timm
01:59
created

Cmd::getSubCmd()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 5
ccs 3
cts 4
cp 0.75
crap 2.0625
rs 10
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
        $runner->setCmd($this);
112
113 21
        $this->runner = $runner;
114
115 21
        return $this;
116
    }
117
118 17
    public function hasSubCmd(string $cmd): bool {
119 17
        return array_key_exists($cmd, $this->subcommands);
120
    }
121
122 4
    public function hasProvidedOption(string $key): bool {
123 4
        return $this->optionResult !== null && $this->optionResult->has($key);
124
    }
125
126 2
    public function getProvidedOption(string $key) {
127 2
        if ($this->optionResult !== null) {
128 2
            return $this->optionResult->get($key);
129
        }
130
        return null;
131
    }
132
133 1
    public function getAllProvidedOptions(): array {
134 1
        $r = [];
135 1
        if ($this->optionResult !== null) {
136 1
            $keys = array_keys($this->optionResult->keys);
137 1
            foreach($keys as $key) {
138 1
                $r[$key] = $this->getProvidedOption($key);
139
            }
140
        }
141 1
        return $r;
142
    }
143
144 1
    public function getAllProvidedArguments(): array {
145 1
        return $this->arguments;
146
    }
147
148 11
    public function getSubCmd(string $cmd): ?Cmd {
149 11
        if ($this->hasSubCmd($cmd)) {
150 11
            return $this->subcommands[$cmd];
151
        }
152
        return null;
153
    }
154
155 6
    public function getRunner(): ?CmdRunner {
156 6
        return $this->runner;
157
    }
158
159 21
    public function getOptionCollection(): OptionCollection {
160
161 21
        if ($this->optionCollection !== null) {
162 4
            return $this->optionCollection;
163
        }
164
165 21
        $specs = (array)$this->optionSpecs;
166
167 21
        $collection = new OptionCollection();
168
169 21
        foreach ($specs as $k => $v) {
170 21
            $opt = $collection->add($k, $v['description']);
171 21
            if (array_key_exists('isa', $v)) {
172 11
                $opt->isa($v['isa']);
173
            }
174 21
            if (array_key_exists('default', $v)) {
175 9
                $opt->defaultValue($v['default']);
176
            }
177
        }
178
179 21
        $this->optionCollection = $collection;
180 21
        return $this->optionCollection;
181
    }
182
183 6
    public function handleOptionParseException(): bool {
184
185 6
        if ($this->optionParseException === null) {
186 5
            return false;
187
        }
188
189 1
        CmdRunner::eol();
190 1
        CmdRunner::echo('Uups, something went wrong!', Color::FOREGROUND_COLOR_RED);
191 1
        CmdRunner::eol();
192 1
        CmdRunner::echo($this->optionParseException->getMessage(), Color::FOREGROUND_COLOR_RED);
193 1
        CmdRunner::eol();
194
195 1
        $this->help();
196
197 1
        return true;
198
    }
199
200 4
    public function help(): void {
201 4
        (new HelpRunner($this))->run();
202 4
    }
203
204
    public static function extend(string $cmd): Cmd {
205
        return new class($cmd) extends Cmd {
206
        };
207
    }
208
209 21
    public static function root(): Cmd {
210 21
        return self::extend('__root');
211
    }
212
}