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