Reader::displayOption()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 10
1
<?php
2
3
/**
4
 * This file is part of CaptainHook
5
 *
6
 * (c) Sebastian Feldmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace CaptainHook\App\Runner\Config;
13
14
use CaptainHook\App\Config;
15
use CaptainHook\App\Hook\Util as HookUtil;
16
use CaptainHook\App\Runner;
17
use CaptainHook\App\Runner\Hook\Arg;
18
use RuntimeException;
19
20
/**
21
 * Class Info
22
 *
23
 * @package CaptainHook
24
 * @author  Sebastian Feldmann <[email protected]>
25
 * @link    https://github.com/captainhook-git/captainhook
26
 * @since   Class available since Release 5.24.0
27
 */
28
class Reader extends Runner\RepositoryAware
29
{
30
    /**
31
     * Option values
32
     */
33
    public const OPT_ACTIONS    = 'actions';
34
    public const OPT_CONDITIONS = 'conditions';
35
    public const OPT_OPTIONS    = 'options';
36
37
    /**
38
     * The hook to display
39
     *
40
     * @var array<int, string>
41
     */
42
    private array $hooks = [];
43
44
    /**
45
     * @var array<string, bool>
46
     */
47
    private array $options = [];
48
49
    /**
50
     * Show more detailed information
51
     * @var bool
52
     */
53
    private bool $extensive = false;
54
55
    /**
56
     * Limit uninstall to s specific hook
57
     *
58
     * @param  string $hook
59
     * @return static
60
     * @throws \CaptainHook\App\Exception\InvalidHookName
61
     */
62 6
    public function setHook(string $hook): self
63
    {
64 6
        $arg = new Arg(
65 6
            $hook,
66 6
            static function (string $hook): bool {
67 6
                return !HookUtil::isValid($hook);
68 6
            }
69 6
        );
70 5
        $this->hooks = $arg->hooks();
71 5
        return $this;
72
    }
73
74
    /**
75
     * Set the display setting for a config section (actions, conditions, options)
76
     *
77
     * @param  string $name
78
     * @param  bool   $value
79
     * @return $this
80
     */
81 4
    public function display(string $name, bool $value): Reader
82
    {
83 4
        if ($value) {
84 3
            $this->options[$name] = true;
85
        }
86 4
        return $this;
87
    }
88
89
    /**
90
     * Show more detailed information
91
     *
92
     * @param bool $value
93
     * @return $this
94
     */
95 2
    public function extensive(bool $value): Reader
96
    {
97 2
        $this->extensive = $value;
98 2
        return $this;
99
    }
100
101
    /**
102
     * Executes the Runner
103
     *
104
     * @return void
105
     * @throws \RuntimeException
106
     */
107 6
    public function run(): void
108
    {
109 6
        if (!$this->config->isLoadedFromFile()) {
110 1
            throw new RuntimeException('No configuration to read');
111
        }
112 5
        foreach ($this->config->getHookConfigs() as $hookConfig) {
113 5
            $this->displayHook($hookConfig);
114
        }
115
    }
116
117
    /**
118
     * Display a hook configuration
119
     * @param  \CaptainHook\App\Config\Hook $config
120
     * @return void
121
     */
122 5
    private function displayHook(Config\Hook $config): void
123
    {
124 5
        if ($this->shouldHookBeDisplayed($config->getName())) {
125 5
            $this->io->write('<info>' . $config->getName() . '</info>', !$this->extensive);
126 5
            $this->displayExtended($config);
127 5
            $this->displayActions($config);
128
        }
129
    }
130
131
    /**
132
     * Display detailed information
133
     *
134
     * @param \CaptainHook\App\Config\Hook $config
135
     * @return void
136
     */
137 5
    private function displayExtended(Config\Hook $config): void
138
    {
139 5
        if ($this->extensive) {
140 1
            $this->io->write(
141 1
                ' ' . str_repeat('-', 52 - strlen($config->getName())) .
142 1
                '--[enabled: ' . $this->yesOrNo($config->isEnabled()) .
143 1
                ', installed: ' . $this->yesOrNo($this->repository->hookExists($config->getName())) . ']'
144 1
            );
145
        }
146
    }
147
148
    /**
149
     * Display all actions
150
     *
151
     * @param \CaptainHook\App\Config\Hook $config
152
     * @return void
153
     */
154 5
    private function displayActions(Config\Hook $config): void
155
    {
156 5
        foreach ($config->getActions() as $action) {
157 5
            $this->displayAction($action);
158
        }
159
    }
160
161
    /**
162
     * Display a single Action
163
     *
164
     * @param \CaptainHook\App\Config\Action $action
165
     * @return void
166
     */
167 5
    private function displayAction(Config\Action $action): void
168
    {
169 5
        $this->io->write(' - <fg=cyan>' . $action->getAction() . '</>');
170 5
        $this->displayOptions($action->getOptions());
171 5
        $this->displayConditions($action->getConditions());
172
    }
173
174
    /**
175
     * Display all options
176
     *
177
     * @param \CaptainHook\App\Config\Options $options
178
     * @return void
179
     */
180 5
    private function displayOptions(Config\Options $options): void
181
    {
182 5
        if (empty($options->getAll())) {
183 4
            return;
184
        }
185 1
        if ($this->show(self::OPT_OPTIONS)) {
186 1
            $this->io->write('   <comment>Options:</comment>');
187 1
            foreach ($options->getAll() as $key => $value) {
188 1
                $this->displayOption($key, $value);
189
            }
190
        }
191
    }
192
193
    /**
194
     * Display a singe option
195
     *
196
     * @param  mixed  $key
197
     * @param  mixed  $value
198
     * @param  string $prefix
199
     * @return void
200
     */
201 1
    private function displayOption(mixed $key, mixed $value, string $prefix = ''): void
202
    {
203 1
        if (is_array($value)) {
204 1
            $value = implode(', ', $value);
205
        }
206 1
        $this->io->write($prefix . '    - ' . $key . ': ' . $value);
207
    }
208
209
    /**
210
     * Display all conditions
211
     *
212
     * @param array<\CaptainHook\App\Config\Condition> $conditions
213
     * @param string                                   $prefix
214
     * @return void
215
     */
216 5
    private function displayConditions(array $conditions, string $prefix = ''): void
217
    {
218 5
        if (empty($conditions)) {
219 3
            return;
220
        }
221 2
        if ($this->show(self::OPT_CONDITIONS)) {
222 2
            if (empty($prefix)) {
223 2
                $this->io->write($prefix . '   <comment>Conditions:</comment>');
224
            }
225 2
            foreach ($conditions as $condition) {
226 2
                $this->displayCondition($condition, $prefix);
227
            }
228
        }
229
    }
230
231
    /**
232
     * Display a single Condition
233
     *
234
     * @param \CaptainHook\App\Config\Condition $condition
235
     * @param string                            $prefix
236
     * @return void
237
     */
238 2
    private function displayCondition(Config\Condition $condition, string $prefix = ''): void
239
    {
240 2
        $this->io->write($prefix . '    - ' . $condition->getExec());
241
242 2
        if (in_array(strtoupper($condition->getExec()), ['OR', 'AND'])) {
243 1
            $conditions = [];
244 1
            foreach ($condition->getArgs() as $conf) {
245 1
                $conditions[] = new Config\Condition($conf['exec'], $conf['args'] ?? []);
246
            }
247 1
            $this->displayConditions($conditions, $prefix . '  ');
248 1
            return;
249
        }
250 2
        if ($this->show(self::OPT_OPTIONS)) {
251 1
            if (empty($condition->getArgs())) {
252 1
                return;
253
            }
254 1
            $this->io->write($prefix . '      <comment>Args:</comment>');
255 1
            foreach ($condition->getArgs() as $key => $value) {
256 1
                $this->displayOption($key, $value, $prefix . '   ');
257
            }
258
        }
259
    }
260
261
    /**
262
     * Check if a specific config part should be shown
263
     *
264
     * @param string $option
265
     * @return bool
266
     */
267 2
    private function show(string $option): bool
268
    {
269 2
        if (empty($this->options)) {
270 1
            return true;
271
        }
272 1
        return $this->options[$option] ?? false;
273
    }
274
275
    /**
276
     * Check if a hook should be displayed
277
     *
278
     * @param string $name
279
     * @return bool
280
     */
281 5
    private function shouldHookBeDisplayed(string $name): bool
282
    {
283 5
        if (empty($this->hooks)) {
284 1
            return true;
285
        }
286 4
        return in_array($name, $this->hooks);
287
    }
288
289
    /**
290
     * Return yes or no emoji
291
     *
292
     * @param bool $bool
293
     * @return string
294
     */
295 1
    private function yesOrNo(bool $bool): string
296
    {
297 1
        return $bool ? '✅ ' : '❌ ';
298
    }
299
}
300