Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
43 / 43
93.48% covered (success)
93.48%
43 / 46
25.00% covered (danger)
25.00%
14 / 56
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Opts
100.00% covered (success)
100.00%
43 / 43
93.48% covered (success)
93.48%
43 / 46
25.00% covered (danger)
25.00%
14 / 56
100.00% covered (success)
100.00%
6 / 6
207.05
100.00% covered (success)
100.00%
1 / 1
 __construct
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
 has
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
 get
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
4
 all
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
4
 getOpts
100.00% covered (success)
100.00%
19 / 19
86.96% covered (warning)
86.96%
20 / 23
0.00% covered (danger)
0.00%
0 / 42
100.00% covered (success)
100.00%
1 / 1
7
 validate
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace Celemas\Cli;
6
7use ValueError;
8
9/**
10 * PHP's native `getopt` stops after the first "non-option" argument
11 * which in our case is the command in `php run <command>`.
12 *
13 * `-arg`, `--arg` and even `---arg` are recognized but treated as different flags.
14 *
15 * @api
16 */
17final class Opts
18{
19    private readonly array $opts;
20
21    public function __construct()
22    {
23        $this->opts = $this->getOpts();
24    }
25
26    public function has(string $key, bool $default = false): bool
27    {
28        if (array_key_exists($key, $this->opts)) {
29            return true;
30        }
31
32        return $default;
33    }
34
35    public function get(string $key, string $default = ''): string
36    {
37        if (func_num_args() === 1) {
38            $this->validate($key);
39
40            return $this->opts[$key]->get();
41        }
42
43        if (!$this->has($key)) {
44            return $default;
45        }
46
47        if ($this->opts[$key]->isset()) {
48            return $this->opts[$key]->get();
49        }
50
51        return $default;
52    }
53
54    public function all(string $key, array $default = []): array
55    {
56        if (func_num_args() === 1) {
57            $this->validate($key);
58
59            return $this->opts[$key]->all();
60        }
61
62        if (!$this->has($key)) {
63            return $default;
64        }
65
66        if ($this->opts[$key]->isset()) {
67            return $this->opts[$key]->all();
68        }
69
70        return $default;
71    }
72
73    private static function getOpts(): array
74    {
75        $opts = [];
76        $key = null;
77
78        foreach ($_SERVER['argv'] ?? [] as $arg) {
79            if (!str_starts_with($arg, '-')) {
80                if ($key !== null) {
81                    $opts[$key]->set($arg);
82                }
83
84                continue;
85            }
86
87            $key = $arg;
88            $value = null;
89
90            if (str_contains($key, '=')) {
91                $parts = explode('=', $key);
92                $key = array_shift($parts);
93                $value = implode('=', $parts);
94            }
95
96            if (!array_key_exists($key, $opts)) {
97                $opts[$key] = new Opt($value);
98
99                continue;
100            }
101
102            if ($value !== null) {
103                $opts[$key]->set($value);
104            }
105        }
106
107        return $opts;
108    }
109
110    private function validate(string $key): void
111    {
112        if (!array_key_exists($key, $this->opts)) {
113            throw new ValueError("Unknown option: {$key}");
114        }
115
116        if (!$this->opts[$key]->isset()) {
117            throw new ValueError("No value given for {$key}");
118        }
119    }
120}

Branches

Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once. Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

Opts->__construct
23        $this->opts = $this->getOpts();
24    }
Opts->all
54    public function all(string $key, array $default = []): array
55    {
56        if (func_num_args() === 1) {
57            $this->validate($key);
58
59            return $this->opts[$key]->all();
62        if (!$this->has($key)) {
63            return $default;
66        if ($this->opts[$key]->isset()) {
67            return $this->opts[$key]->all();
70        return $default;
71    }
Opts->get
35    public function get(string $key, string $default = ''): string
36    {
37        if (func_num_args() === 1) {
38            $this->validate($key);
39
40            return $this->opts[$key]->get();
43        if (!$this->has($key)) {
44            return $default;
47        if ($this->opts[$key]->isset()) {
48            return $this->opts[$key]->get();
51        return $default;
52    }
Opts->getOpts
75        $opts = [];
76        $key = null;
77
78        foreach ($_SERVER['argv'] ?? [] as $arg) {
78        foreach ($_SERVER['argv'] ?? [] as $arg) {
79            if (!str_starts_with($arg, '-')) {
79            if (!str_starts_with($arg, '-')) {
79            if (!str_starts_with($arg, '-')) {
79            if (!str_starts_with($arg, '-')) {
80                if ($key !== null) {
81                    $opts[$key]->set($arg);
82                }
83
84                continue;
84                continue;
87            $key = $arg;
88            $value = null;
89
90            if (str_contains($key, '=')) {
90            if (str_contains($key, '=')) {
90            if (str_contains($key, '=')) {
90            if (str_contains($key, '=')) {
91                $parts = explode('=', $key);
92                $key = array_shift($parts);
93                $value = implode('=', $parts);
93                $value = implode('=', $parts);
93                $value = implode('=', $parts);
93                $value = implode('=', $parts);
94            }
95
96            if (!array_key_exists($key, $opts)) {
96            if (!array_key_exists($key, $opts)) {
97                $opts[$key] = new Opt($value);
98
99                continue;
102            if ($value !== null) {
78        foreach ($_SERVER['argv'] ?? [] as $arg) {
79            if (!str_starts_with($arg, '-')) {
80                if ($key !== null) {
81                    $opts[$key]->set($arg);
82                }
83
84                continue;
85            }
86
87            $key = $arg;
88            $value = null;
89
90            if (str_contains($key, '=')) {
91                $parts = explode('=', $key);
92                $key = array_shift($parts);
93                $value = implode('=', $parts);
94            }
95
96            if (!array_key_exists($key, $opts)) {
97                $opts[$key] = new Opt($value);
98
99                continue;
100            }
101
102            if ($value !== null) {
103                $opts[$key]->set($value);
78        foreach ($_SERVER['argv'] ?? [] as $arg) {
78        foreach ($_SERVER['argv'] ?? [] as $arg) {
79            if (!str_starts_with($arg, '-')) {
80                if ($key !== null) {
81                    $opts[$key]->set($arg);
82                }
83
84                continue;
85            }
86
87            $key = $arg;
88            $value = null;
89
90            if (str_contains($key, '=')) {
91                $parts = explode('=', $key);
92                $key = array_shift($parts);
93                $value = implode('=', $parts);
94            }
95
96            if (!array_key_exists($key, $opts)) {
97                $opts[$key] = new Opt($value);
98
99                continue;
100            }
101
102            if ($value !== null) {
103                $opts[$key]->set($value);
104            }
105        }
106
107        return $opts;
108    }
Opts->has
26    public function has(string $key, bool $default = false): bool
27    {
28        if (array_key_exists($key, $this->opts)) {
29            return true;
32        return $default;
33    }
Opts->validate
110    private function validate(string $key): void
111    {
112        if (!array_key_exists($key, $this->opts)) {
113            throw new ValueError("Unknown option: {$key}");
116        if (!$this->opts[$key]->isset()) {
117            throw new ValueError("No value given for {$key}");
119    }