Skip to content

Commit f81fe0d

Browse files
Add config info reader
1 parent 6e2f548 commit f81fe0d

File tree

3 files changed

+418
-4
lines changed

3 files changed

+418
-4
lines changed

src/Runner/Config/Reader.php

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
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/captainhookphp/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+
public function setHook(string $hook): self
63+
{
64+
$arg = new Arg(
65+
$hook,
66+
static function (string $hook): bool {
67+
return !HookUtil::isValid($hook);
68+
}
69+
);
70+
$this->hooks = $arg->hooks();
71+
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+
public function display(string $name, bool $value): Reader
82+
{
83+
if ($value) {
84+
$this->options[$name] = true;
85+
}
86+
return $this;
87+
}
88+
89+
/**
90+
* Show more detailed information
91+
*
92+
* @param bool $value
93+
* @return $this
94+
*/
95+
public function extensive(bool $value): Reader
96+
{
97+
$this->extensive = $value;
98+
return $this;
99+
}
100+
101+
/**
102+
* Executes the Runner
103+
*
104+
* @return void
105+
* @throws \RuntimeException
106+
*/
107+
public function run(): void
108+
{
109+
if (!$this->config->isLoadedFromFile()) {
110+
throw new RuntimeException('No configuration to read');
111+
}
112+
foreach ($this->config->getHookConfigs() as $hookConfig) {
113+
$this->displayHook($hookConfig);
114+
}
115+
}
116+
117+
/**
118+
* Display a hook configuration
119+
* @param \CaptainHook\App\Config\Hook $config
120+
* @return void
121+
*/
122+
private function displayHook(Config\Hook $config): void
123+
{
124+
if ($this->shouldHookBeDisplayed($config->getName())) {
125+
$this->io->write('<info>' . $config->getName() . '</info>', !$this->extensive);
126+
$this->displayExtended($config);
127+
$this->displayActions($config);
128+
}
129+
}
130+
131+
/**
132+
* Display detailed information
133+
*
134+
* @param \CaptainHook\App\Config\Hook $config
135+
* @return void
136+
*/
137+
private function displayExtended(Config\Hook $config): void
138+
{
139+
if ($this->extensive) {
140+
$this->io->write(
141+
' ' . str_repeat('-', 18 - strlen($config->getName())) .
142+
'--[enabled: ' . $this->yesOrNo($config->isEnabled()) .
143+
', installed: ' . $this->yesOrNo($this->repository->hookExists($config->getName())) . ']'
144+
);
145+
}
146+
}
147+
148+
/**
149+
* Display all actions
150+
*
151+
* @param \CaptainHook\App\Config\Hook $config
152+
* @return void
153+
*/
154+
private function displayActions(Config\Hook $config): void
155+
{
156+
foreach ($config->getActions() as $action) {
157+
$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+
private function displayAction(Config\Action $action): void
168+
{
169+
$this->io->write(' - <fg=cyan>' . $action->getAction() . '</>');
170+
$this->displayOptions($action->getOptions());
171+
$this->displayConditions($action->getConditions());
172+
}
173+
174+
/**
175+
* Display all options
176+
*
177+
* @param \CaptainHook\App\Config\Options $options
178+
* @return void
179+
*/
180+
private function displayOptions(Config\Options $options): void
181+
{
182+
if (empty($options->getAll())) {
183+
return;
184+
}
185+
if ($this->show(self::OPT_OPTIONS)) {
186+
$this->io->write(' <comment>Options:</comment>');
187+
foreach ($options->getAll() as $key => $value) {
188+
$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+
private function displayOption(mixed $key, mixed $value, string $prefix = ''): void
202+
{
203+
if (is_array($value)) {
204+
$value = implode(', ', $value);
205+
}
206+
$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+
private function displayConditions(array $conditions, string $prefix = ''): void
217+
{
218+
if (empty($conditions)) {
219+
return;
220+
}
221+
if ($this->show(self::OPT_CONDITIONS)) {
222+
if (empty($prefix)) {
223+
$this->io->write($prefix . ' <comment>Conditions:</comment>');
224+
}
225+
foreach ($conditions as $condition) {
226+
$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+
private function displayCondition(Config\Condition $condition, string $prefix = ''): void
239+
{
240+
$this->io->write($prefix . ' - ' . $condition->getExec());
241+
242+
if (in_array(strtoupper($condition->getExec()), ['OR', 'AND'])) {
243+
$conditions = [];
244+
foreach ($condition->getArgs() as $conf) {
245+
$conditions[] = new Config\Condition($conf['exec'], $conf['args'] ?? []);
246+
}
247+
$this->displayConditions($conditions, $prefix . ' ');
248+
return;
249+
}
250+
if ($this->show(self::OPT_OPTIONS)) {
251+
if (empty($condition->getArgs())) {
252+
return;
253+
}
254+
$this->io->write($prefix . ' <comment>Args:</comment>');
255+
foreach ($condition->getArgs() as $key => $value) {
256+
$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+
private function show(string $option): bool
268+
{
269+
if (empty($this->options)) {
270+
return true;
271+
}
272+
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+
private function shouldHookBeDisplayed(string $name): bool
282+
{
283+
if (empty($this->hooks)) {
284+
return true;
285+
}
286+
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+
private function yesOrNo(bool $bool): string
296+
{
297+
return $bool ? '' : '';
298+
}
299+
}

tests/files/config/valid-with-nested-and-conditions.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"actions": [
1313
{
1414
"action": "phpunit --configuration=build/phpunit-hook.xml",
15-
"options": [],
15+
"options": {
16+
"foo": "bar"
17+
},
1618
"conditions": [
1719
{
1820
"exec": "and",
@@ -23,9 +25,7 @@
2325
]
2426
},{
2527
"exec": "\\CaptainHook\\App\\Hook\\Condition\\AnyFileChanged",
26-
"args": [
27-
["foo.php", "bar.php"]
28-
]
28+
"args": []
2929
}]
3030
}
3131
]

0 commit comments

Comments
 (0)