1 | <?php namespace Tarsana\Command; |
||
2 | |||
3 | use Tarsana\Command\Commands\HelpCommand; |
||
4 | use Tarsana\Command\Commands\InteractiveCommand; |
||
5 | use Tarsana\Command\Commands\VersionCommand; |
||
6 | use Tarsana\Command\Config\ConfigLoader; |
||
7 | use Tarsana\Command\Console\Console; |
||
8 | use Tarsana\Command\Console\ExceptionPrinter; |
||
9 | use Tarsana\Command\Interfaces\Console\ConsoleInterface; |
||
10 | use Tarsana\Command\Interfaces\Template\TemplateLoaderInterface; |
||
11 | use Tarsana\Command\SubCommand; |
||
12 | use Tarsana\Command\Template\TemplateLoader; |
||
13 | use Tarsana\IO\Filesystem; |
||
14 | use Tarsana\IO\FilesystemInterface; |
||
15 | use Tarsana\Syntax\Exceptions\ParseException; |
||
16 | use Tarsana\Syntax\Factory as S; |
||
17 | use Tarsana\Syntax\Text as T; |
||
18 | |||
19 | class Command { |
||
20 | |||
21 | protected $name; |
||
22 | protected $version; |
||
23 | protected $description; |
||
24 | |||
25 | protected $syntax; |
||
26 | protected $descriptions; |
||
27 | |||
28 | protected $options; |
||
29 | protected $args; |
||
30 | |||
31 | protected $action; |
||
32 | protected $commands; |
||
33 | |||
34 | protected $console; |
||
35 | protected $fs; |
||
36 | protected $templatesLoader; |
||
37 | protected $config; |
||
38 | |||
39 | public static function create(callable $action = null) { |
||
40 | $command = new Command; |
||
41 | if (null !== $action) |
||
42 | $command->action($action); |
||
43 | return $command; |
||
44 | } |
||
45 | |||
46 | public function __construct() |
||
47 | { |
||
48 | $this->commands([]) |
||
49 | ->name('Unknown') |
||
50 | ->version('1.0.0') |
||
51 | ->description('...') |
||
52 | ->descriptions([]) |
||
53 | ->options([]) |
||
54 | ->console(new Console) |
||
55 | ->fs(new Filesystem('.')) |
||
56 | ->configPaths([]) |
||
57 | ->setupSubCommands() |
||
58 | ->init(); |
||
59 | } |
||
60 | |||
61 | /** |
||
62 | * name getter and setter. |
||
63 | * |
||
64 | * @param string |
||
65 | * @return mixed |
||
66 | */ |
||
67 | public function name(string $value = null) |
||
68 | { |
||
69 | if (null === $value) { |
||
70 | return $this->name; |
||
71 | } |
||
72 | $this->name = $value; |
||
73 | return $this; |
||
74 | } |
||
75 | |||
76 | /** |
||
77 | * version getter and setter. |
||
78 | * |
||
79 | * @param string |
||
80 | * @return mixed |
||
81 | */ |
||
82 | public function version(string $value = null) |
||
83 | { |
||
84 | if (null === $value) { |
||
85 | return $this->version; |
||
86 | } |
||
87 | $this->version = $value; |
||
88 | return $this; |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * description getter and setter. |
||
93 | * |
||
94 | * @param string |
||
95 | * @return mixed |
||
96 | */ |
||
97 | public function description(string $value = null) |
||
98 | { |
||
99 | if (null === $value) { |
||
100 | return $this->description; |
||
101 | } |
||
102 | $this->description = $value; |
||
103 | return $this; |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * descriptions getter and setter. |
||
108 | * |
||
109 | * @param string |
||
110 | * @return mixed |
||
111 | */ |
||
112 | public function descriptions(array $value = null) |
||
113 | { |
||
114 | if (null === $value) { |
||
115 | return $this->descriptions; |
||
116 | } |
||
117 | $this->descriptions = $value; |
||
118 | return $this; |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * syntax getter and setter. |
||
123 | * |
||
124 | * @param string|null $syntax |
||
125 | * @return Syntax|self |
||
126 | */ |
||
127 | public function syntax(string $syntax = null) |
||
128 | { |
||
129 | if (null === $syntax) |
||
130 | return $this->syntax; |
||
131 | |||
132 | $this->syntax = S::syntax()->parse("{{$syntax}| }"); |
||
133 | return $this; |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * options getter and setter. |
||
138 | * |
||
139 | * @param array |
||
140 | * @return mixed |
||
141 | */ |
||
142 | public function options(array $options = null) |
||
143 | { |
||
144 | if (null === $options) { |
||
145 | return $this->options; |
||
146 | } |
||
147 | |||
148 | $this->options = []; |
||
149 | foreach($options as $option) |
||
150 | $this->options[$option] = false; |
||
151 | |||
152 | return $this; |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * option getter. |
||
157 | * |
||
158 | * @param string |
||
159 | * @return mixed |
||
160 | */ |
||
161 | public function option(string $name) |
||
162 | { |
||
163 | if (!array_key_exists($name, $this->options)) |
||
164 | throw new \InvalidArgumentException("Unknown option '{$name}'"); |
||
165 | return $this->options[$name]; |
||
166 | } |
||
167 | |||
168 | /** |
||
169 | * args getter and setter. |
||
170 | * |
||
171 | * @param stdClass |
||
172 | * @return mixed |
||
173 | */ |
||
174 | public function args(\stdClass $value = null) |
||
175 | { |
||
176 | if (null === $value) { |
||
177 | return $this->args; |
||
178 | } |
||
179 | $this->args = $value; |
||
180 | return $this; |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * console getter and setter. |
||
185 | * |
||
186 | * @param ConsoleInterface |
||
187 | * @return mixed |
||
188 | */ |
||
189 | public function console(ConsoleInterface $value = null) |
||
190 | { |
||
191 | if (null === $value) { |
||
192 | return $this->console; |
||
193 | } |
||
194 | $this->console = $value; |
||
195 | foreach ($this->commands as $name => $command) { |
||
196 | $command->console = $value; |
||
197 | } |
||
198 | return $this; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * fs getter and setter. |
||
203 | * |
||
204 | * @param Tarsana\IO\Filesystem|string |
||
205 | * @return mixed |
||
206 | */ |
||
207 | public function fs($value = null) |
||
208 | { |
||
209 | if (null === $value) { |
||
210 | return $this->fs; |
||
211 | } |
||
212 | if (is_string($value)) |
||
213 | $value = new Filesystem($value); |
||
214 | $this->fs = $value; |
||
215 | foreach ($this->commands as $name => $command) { |
||
216 | $command->fs = $value; |
||
217 | } |
||
218 | return $this; |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * templatesLoader getter and setter. |
||
223 | * |
||
224 | * @param Tarsana\Command\Interfaces\Template\TemplateLoaderInterface |
||
225 | * @return mixed |
||
226 | */ |
||
227 | public function templatesLoader(TemplateLoaderInterface $value = null) |
||
228 | { |
||
229 | if (null === $value) { |
||
230 | return $this->templatesLoader; |
||
231 | } |
||
232 | $this->templatesLoader = $value; |
||
233 | foreach ($this->commands as $name => $command) { |
||
234 | $command->templatesLoader = $value; |
||
235 | } |
||
236 | return $this; |
||
237 | } |
||
238 | |||
239 | public function templatesPath(string $path, string $cachePath = null) |
||
240 | { |
||
241 | $this->templatesLoader = new TemplateLoader($path, $cachePath); |
||
242 | foreach ($this->commands as $name => $command) { |
||
243 | $command->templatesLoader = $this->templatesLoader(); |
||
244 | } |
||
245 | return $this; |
||
246 | } |
||
247 | |||
248 | public function template(string $name) |
||
249 | { |
||
250 | if (null === $this->templatesLoader) |
||
251 | throw new \Exception("Please initialize the templates loader before trying to load templates!"); |
||
252 | return $this->templatesLoader->load($name); |
||
253 | } |
||
254 | |||
255 | public function configPaths(array $paths) |
||
256 | { |
||
257 | $configLoader = new ConfigLoader($this->fs); |
||
258 | $this->config = $configLoader->load($paths); |
||
259 | foreach ($this->commands as $name => $command) { |
||
260 | $command->config = $this->config; |
||
261 | } |
||
262 | return $this; |
||
263 | } |
||
264 | |||
265 | public function config(string $path = null) |
||
266 | { |
||
267 | return $this->config->get($path); |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * action getter and setter. |
||
272 | * |
||
273 | * @param callable |
||
274 | * @return mixed |
||
275 | */ |
||
276 | public function action(callable $value = null) |
||
277 | { |
||
278 | if (null === $value) { |
||
279 | return $this->action; |
||
280 | } |
||
281 | $this->action = $value; |
||
282 | return $this; |
||
283 | } |
||
284 | |||
285 | /** |
||
286 | * commands getter and setter. |
||
287 | * |
||
288 | * @param array |
||
289 | * @return mixed |
||
290 | */ |
||
291 | public function commands(array $value = null) |
||
292 | { |
||
293 | if (null === $value) { |
||
294 | return $this->commands; |
||
295 | } |
||
296 | $this->commands = []; |
||
297 | foreach ($value as $name => $command) { |
||
298 | $this->command($name, $command); |
||
299 | } |
||
300 | return $this; |
||
301 | } |
||
302 | |||
303 | public function command(string $name, Command $command = null) |
||
304 | { |
||
305 | if (null === $command) { |
||
306 | if (!array_key_exists($name, $this->commands)) |
||
307 | throw new \InvalidArgumentException("subcommand '{$name}' not found!"); |
||
308 | return $this->commands[$name]; |
||
309 | } |
||
310 | $this->commands[$name] = $command; |
||
311 | return $this; |
||
312 | } |
||
313 | |||
314 | public function hasCommand(string $name) : bool |
||
315 | { |
||
316 | return array_key_exists($name, $this->commands); |
||
317 | } |
||
318 | |||
319 | protected function setupSubCommands() |
||
320 | { |
||
321 | return $this->command('--help', new HelpCommand($this)) |
||
322 | ->command('--version', new VersionCommand($this)) |
||
323 | ->command('-i', new InteractiveCommand($this)); |
||
324 | } |
||
325 | |||
326 | public function describe(string $name, string $description = null) |
||
327 | { |
||
328 | if (null === $description) |
||
329 | return array_key_exists($name, $this->descriptions) |
||
330 | ? $this->descriptions[$name] : ''; |
||
331 | if (substr($name, 0, 2) == '--' && array_key_exists($name, $this->options())) { |
||
332 | $this->descriptions[$name] = $description; |
||
333 | return $this; |
||
334 | } |
||
335 | try { |
||
336 | $this->syntax->field($name); |
||
337 | // throws exception if field is missing |
||
338 | $this->descriptions[$name] = $description; |
||
339 | return $this; |
||
340 | } catch (\Exception $e) { |
||
341 | throw new \InvalidArgumentException("Unknown field '{$name}'"); |
||
342 | } |
||
343 | } |
||
344 | |||
345 | public function run(array $args = null, array $options = [], bool $rawArgs = true) |
||
346 | { |
||
347 | try { |
||
348 | $this->clear(); |
||
349 | |||
350 | if ($rawArgs) { |
||
351 | if (null === $args) { |
||
352 | $args = $GLOBALS['argv']; |
||
353 | array_shift($args); |
||
354 | } |
||
355 | |||
356 | if (!empty($args) && array_key_exists($args[0], $this->commands)) { |
||
357 | $name = $args[0]; |
||
358 | array_shift($args); |
||
359 | return $this->command($name)->run($args); |
||
360 | } |
||
361 | |||
362 | $this->parseArguments($args); |
||
363 | } else { |
||
364 | $this->args = (object) $args; |
||
365 | foreach ($options as $name) { |
||
366 | if (!array_key_exists($name, $this->options)) |
||
367 | throw new \Exception("Unknown option '{$name}'"); |
||
368 | $this->options[$name] = true; |
||
369 | } |
||
370 | } |
||
371 | |||
372 | return $this->fire(); |
||
373 | } catch (\Exception $e) { |
||
374 | $this->handleError($e); |
||
375 | } |
||
376 | } |
||
377 | |||
378 | protected function fire() |
||
379 | { |
||
380 | return (null === $this->action) |
||
381 | ? $this->execute() |
||
0 ignored issues
–
show
|
|||
382 | : ($this->action)($this); |
||
383 | } |
||
384 | |||
385 | protected function clear() |
||
386 | { |
||
387 | $this->args = null; |
||
388 | foreach($this->options as $name => $value) { |
||
389 | $this->options[$name] = false; |
||
390 | } |
||
391 | } |
||
392 | |||
393 | protected function parseArguments(array $args) |
||
394 | { |
||
395 | $arguments = []; |
||
396 | foreach ($args as &$arg) { |
||
397 | if (array_key_exists($arg, $this->options)) |
||
398 | $this->options[$arg] = true; |
||
399 | else |
||
400 | $arguments[] = $arg; |
||
401 | } |
||
402 | if (null === $this->syntax) { |
||
403 | $this->args = null; |
||
404 | } else { |
||
405 | $arguments = T::join($arguments, ' '); |
||
406 | $this->args = $this->syntax->parse($arguments); |
||
407 | } |
||
408 | } |
||
409 | |||
410 | protected function handleError(\Exception $e) { |
||
411 | $output = (new ExceptionPrinter)->print($e); |
||
412 | $this->console()->error($output); |
||
413 | } |
||
414 | |||
415 | protected function init() {} |
||
416 | protected function execute() {} |
||
417 | |||
418 | } |
||
419 |
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.