Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
25 / 25
90.91% covered (success)
90.91%
20 / 22
100.00% covered (success)
100.00%
18 / 18
CRAP
100.00% covered (success)
100.00%
1 / 1
Command
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
25 / 25
90.91% covered (success)
90.91%
20 / 22
100.00% covered (success)
100.00%
18 / 18
21.33
100.00% covered (success)
100.00%
1 / 1
 run
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
0
 name
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 group
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 prefix
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 description
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 script
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 output
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 echo
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 echoln
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 info
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 success
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 warn
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 error
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 color
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 indent
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 out
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 help
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 helpHeader
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
5 / 5
50.00% covered (danger)
50.00%
2 / 4
100.00% covered (success)
100.00%
1 / 1
4.12
 helpOption
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Celemas\Cli;
6
7use RuntimeException;
8
9/**
10 * @api
11 */
12abstract class Command
13{
14    public const int SUCCESS = 0;
15    public const int FAILURE = 1;
16
17    protected string $name = '';
18    protected string $group = '';
19    protected string $prefix = '';
20    protected string $description = '';
21    protected ?Output $output = null;
22
23    abstract public function run(Args $args): int;
24
25    public function name(): string
26    {
27        return $this->name;
28    }
29
30    public function group(): string
31    {
32        return $this->group;
33    }
34
35    public function prefix(): string
36    {
37        return $this->prefix === '' ? strtolower($this->group) : $this->prefix;
38    }
39
40    public function description(): string
41    {
42        return $this->description;
43    }
44
45    public function script(): string
46    {
47        return $_SERVER['argv'][0] ?? '';
48    }
49
50    public function output(Output $output): static
51    {
52        $this->output = $output;
53
54        return $this;
55    }
56
57    public function echo(string $message, string $color = '', string $background = ''): void
58    {
59        $this->out()->echo($message, $color, $background);
60    }
61
62    public function echoln(string $message, string $color = '', string $background = ''): void
63    {
64        $this->out()->echoln($message, $color, $background);
65    }
66
67    public function info(string $message): void
68    {
69        $this->echoln($message);
70    }
71
72    public function success(string $message): void
73    {
74        $this->echoln($message, 'green');
75    }
76
77    public function warn(string $message): void
78    {
79        $this->out()->echolnErr($message, 'yellow');
80    }
81
82    public function error(string $message): void
83    {
84        $this->out()->echolnErr($message, 'red');
85    }
86
87    public function color(string $text, string $color, string $background = ''): string
88    {
89        return $this->out()->color($text, $color, $background);
90    }
91
92    public function indent(
93        string $text,
94        int $indent,
95        ?int $max = null,
96    ): string {
97        return $this->out()->indent($text, $indent, $max);
98    }
99
100    private function out(): Output
101    {
102        return $this->output ?? throw new RuntimeException('Output missing');
103    }
104
105    public function help(): void
106    {
107        $this->helpHeader(withOptions: false);
108    }
109
110    protected function helpHeader(bool $withOptions = false): void
111    {
112        $script = $this->script();
113        $name = $this->name;
114        $prefix = $this->prefix();
115        $desc = $this->description;
116
117        if ($desc !== '') {
118            $label = $this->color('Description:', 'brown') . "\n";
119            $this->echo("{$label}  {$desc}\n\n");
120        }
121
122        $usage = $this->color('Usage:', 'brown') . "\n  php {$script} {$prefix}:{$name}";
123
124        if ($withOptions) {
125            $this->echo("{$usage} [options]\n\n");
126            $this->echoln($this->color('Options:', 'brown'));
127
128            return;
129        }
130
131        $this->echo("{$usage}\n");
132    }
133
134    protected function helpOption(string $option, string $description): void
135    {
136        $this->echo('    ' . $this->color($option, 'green') . "\n");
137        $this->echo($this->indent($description, 8, 80) . "\n");
138    }
139}