Skip to content

Commit 9aa315e

Browse files
committed
Moved to traits for runners and commands.
1 parent 1c27974 commit 9aa315e

18 files changed

+692
-439
lines changed

.vortex/installer/phpunit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.4/phpunit.xsd"
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/12.4/phpunit.xsd"
33
bootstrap="vendor/autoload.php"
44
cacheDirectory=".phpunit.cache"
55
executionOrder="depends,defects"

.vortex/installer/src/Command/BuildCommand.php

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
namespace DrevOps\VortexInstaller\Command;
66

7-
use DrevOps\VortexInstaller\Runner\CommandRunner;
8-
use DrevOps\VortexInstaller\Runner\ProcessRunner;
7+
use DrevOps\VortexInstaller\Runner\CommandRunnerAwareInterface;
8+
use DrevOps\VortexInstaller\Runner\CommandRunnerAwareTrait;
9+
use DrevOps\VortexInstaller\Runner\ProcessRunnerAwareInterface;
10+
use DrevOps\VortexInstaller\Runner\ProcessRunnerAwareTrait;
911
use DrevOps\VortexInstaller\Runner\RunnerInterface;
1012
use DrevOps\VortexInstaller\Task\Task;
1113
use DrevOps\VortexInstaller\Utils\Tui;
@@ -17,7 +19,10 @@
1719
/**
1820
* Build command.
1921
*/
20-
class BuildCommand extends Command {
22+
class BuildCommand extends Command implements ProcessRunnerAwareInterface, CommandRunnerAwareInterface {
23+
24+
use ProcessRunnerAwareTrait;
25+
use CommandRunnerAwareTrait;
2126

2227
const string OPTION_PROFILE = 'profile';
2328

@@ -32,11 +37,6 @@ class BuildCommand extends Command {
3237
*/
3338
public static $defaultName = 'build';
3439

35-
/**
36-
* The process runner.
37-
*/
38-
protected ?ProcessRunner $runner = NULL;
39-
4040
/**
4141
* Whether to build from profile.
4242
*/
@@ -66,10 +66,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6666
$requirements_ok = Task::action(
6767
label: 'Checking requirements',
6868
action: function (): bool {
69-
$runner = (new CommandRunner($this->getApplication()))->disableLog();
70-
$runner->run('check-requirements', [], ['--no-summary' => '1']);
69+
$command_runner = $this->getCommandRunner()->disableLog();
70+
$command_runner->run('check-requirements', [], ['--no-summary' => '1']);
7171

72-
return $runner->getExitCode() === RunnerInterface::EXIT_SUCCESS;
72+
return $command_runner->getExitCode() === RunnerInterface::EXIT_SUCCESS;
7373
},
7474
failure: 'Missing requirements. Run: ./installer.php check-requirements',
7575
streaming: TRUE,
@@ -92,10 +92,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9292
$env['VORTEX_PROVISION_TYPE'] = 'profile';
9393
}
9494

95-
$this->runner = $this->getRunner()->setCwd($cwd);
96-
$this->runner->run('ahoy build', env: $env);
95+
$this->processRunner = $this->getProcessRunner()->setCwd($cwd);
96+
$this->processRunner->run('ahoy build', env: $env);
9797

98-
return $this->runner->getExitCode() === RunnerInterface::EXIT_SUCCESS;
98+
return $this->processRunner->getExitCode() === RunnerInterface::EXIT_SUCCESS;
9999
},
100100
success: fn(bool $result): string => $result ? 'Build completed' : 'Build failed',
101101
failure: 'Build failed',
@@ -139,7 +139,7 @@ protected function showSuccessSummary(): void {
139139
$output .= 'Login: ahoy login' . PHP_EOL;
140140
$output .= PHP_EOL;
141141

142-
$log_path = $this->runner->getLogger()->getPath();
142+
$log_path = $this->processRunner->getLogger()->getPath();
143143
if ($log_path) {
144144
$output .= 'Log file: ' . $log_path . PHP_EOL;
145145
$output .= PHP_EOL;
@@ -160,23 +160,23 @@ protected function showSuccessSummary(): void {
160160
protected function showFailureSummary(): void {
161161
Tui::line('');
162162

163-
$command = $this->runner->getCommand();
163+
$command = $this->processRunner->getCommand();
164164
if ($command) {
165165
Tui::line('Failed at: ' . $command);
166166
}
167167

168-
$exit_code = $this->runner->getExitCode();
168+
$exit_code = $this->processRunner->getExitCode();
169169
Tui::line('Exit code: ' . $exit_code);
170170

171-
$log_path = $this->runner->getLogger()->getPath();
171+
$log_path = $this->processRunner->getLogger()->getPath();
172172
if ($log_path) {
173173
Tui::line('Log file: ' . $log_path);
174174
}
175175

176176
Tui::line('');
177177

178178
// Show last 10 lines of output for context.
179-
$runner_output = $this->runner->getOutput(as_array: TRUE);
179+
$runner_output = $this->processRunner->getOutput(as_array: TRUE);
180180

181181
if (!is_array($runner_output)) {
182182
throw new \RuntimeException('Runner output is not an array.');
@@ -191,23 +191,4 @@ protected function showFailureSummary(): void {
191191
}
192192
}
193193

194-
/**
195-
* Get the process runner.
196-
*
197-
* Factory method that returns existing runner or creates new one.
198-
*/
199-
protected function getRunner(): ProcessRunner {
200-
// Return already-set runner if available (for testing).
201-
return $this->runner ?? (new ProcessRunner());
202-
}
203-
204-
/**
205-
* Set the process runner.
206-
*
207-
* Allows dependency injection for testing.
208-
*/
209-
public function setRunner(ProcessRunner $runner): void {
210-
$this->runner = $runner;
211-
}
212-
213194
}

.vortex/installer/src/Command/CheckRequirementsCommand.php

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44

55
namespace DrevOps\VortexInstaller\Command;
66

7+
use DrevOps\VortexInstaller\Runner\ExecutableFinderAwareInterface;
8+
use DrevOps\VortexInstaller\Runner\ExecutableFinderAwareTrait;
79
use DrevOps\VortexInstaller\Runner\ProcessRunner;
10+
use DrevOps\VortexInstaller\Runner\ProcessRunnerAwareInterface;
11+
use DrevOps\VortexInstaller\Runner\ProcessRunnerAwareTrait;
812
use DrevOps\VortexInstaller\Runner\RunnerInterface;
913
use DrevOps\VortexInstaller\Task\Task;
1014
use DrevOps\VortexInstaller\Utils\Tui;
@@ -16,7 +20,10 @@
1620
/**
1721
* Check requirements command.
1822
*/
19-
class CheckRequirementsCommand extends Command {
23+
class CheckRequirementsCommand extends Command implements ProcessRunnerAwareInterface, ExecutableFinderAwareInterface {
24+
25+
use ProcessRunnerAwareTrait;
26+
use ExecutableFinderAwareTrait;
2027

2128
const string OPTION_ONLY = 'only';
2229

@@ -44,11 +51,6 @@ class CheckRequirementsCommand extends Command {
4451
*/
4552
public static $defaultName = 'check-requirements';
4653

47-
/**
48-
* The process runner.
49-
*/
50-
protected ProcessRunner $runner;
51-
5254
/**
5355
* Present tools.
5456
*
@@ -83,7 +85,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8385
$only = $input->getOption(static::OPTION_ONLY);
8486
$requirements = $this->validateRequirements($only ? array_map(trim(...), explode(',', (string) $only)) : NULL);
8587

86-
$this->runner = $this->getRunner();
88+
$this->processRunner ??= $this->getProcessRunner();
8789
$this->present = [];
8890
$this->missing = [];
8991

@@ -146,7 +148,7 @@ protected function validateRequirements(?array $only): array {
146148
if ($only !== NULL) {
147149
$unknown = array_diff($only, static::REQUIREMENTS);
148150
if (!empty($unknown)) {
149-
throw new \InvalidArgumentException(sprintf('Unknown requirements: %s. Available: %s.', implode(', ', $unknown), implode(', ', static::REQUIREMENTS)));
151+
throw new \InvalidArgumentException(sprintf("Unknown requirements: %s.\nAvailable: %s.", implode(', ', $unknown), implode(', ', static::REQUIREMENTS)));
150152
}
151153
}
152154

@@ -274,37 +276,37 @@ protected function checkPygmy(): bool {
274276

275277
$version = $this->getCommandVersion('pygmy version');
276278

277-
$this->runner->run('pygmy status');
278-
if ($this->runner->getExitCode() === RunnerInterface::EXIT_SUCCESS) {
279+
$this->processRunner->run('pygmy status');
280+
if ($this->processRunner->getExitCode() === RunnerInterface::EXIT_SUCCESS) {
279281
$this->present['Pygmy'] = $version;
280282
return TRUE;
281283
}
282284

283-
$this->runner->run('docker ps --format "{{.Names}}" | grep -q amazeeio');
285+
$this->processRunner->run('docker ps --format "{{.Names}}" | grep -q amazeeio');
284286
// @phpstan-ignore-next-line notIdentical.alwaysFalse
285-
if ($this->runner->getExitCode() === RunnerInterface::EXIT_SUCCESS) {
287+
if ($this->processRunner->getExitCode() === RunnerInterface::EXIT_SUCCESS) {
286288
$this->present['Pygmy'] = $version;
287289
return TRUE;
288290
}
289291

290292
$this->missing['Pygmy'] = 'Run: pygmy up';
293+
291294
return FALSE;
292295
}
293296

294297
/**
295298
* Check if a command exists.
296299
*/
297300
protected function commandExists(string $command): bool {
298-
$this->runner->run(sprintf('command -v %s', escapeshellarg($command)));
299-
return $this->runner->getExitCode() === RunnerInterface::EXIT_SUCCESS;
301+
return $this->getExecutableFinder()->find($command) !== NULL;
300302
}
301303

302304
/**
303305
* Check if Docker Compose exists.
304306
*/
305307
protected function dockerComposeExists(): bool {
306-
$this->runner->run('docker compose version');
307-
if ($this->runner->getExitCode() === RunnerInterface::EXIT_SUCCESS) {
308+
$this->processRunner->run('docker compose version');
309+
if ($this->processRunner->getExitCode() === RunnerInterface::EXIT_SUCCESS) {
308310
return TRUE;
309311
}
310312

@@ -320,36 +322,17 @@ protected function dockerComposeExists(): bool {
320322
* Number of lines to retrieve from the output. Defaults to 1.
321323
*/
322324
protected function getCommandVersion(string $command, int $lines = 1): string {
323-
$this->runner->run($command);
324-
$raw_output = $this->runner->getOutput(FALSE, $lines);
325+
$this->processRunner->run($command);
326+
$raw_output = $this->processRunner->getOutput(FALSE, $lines);
325327
$output = trim(is_string($raw_output) ? $raw_output : implode(PHP_EOL, $raw_output));
326328
return empty($output) ? 'Available' : $output;
327329
}
328330

329331
/**
330-
* Get the process runner instance.
331-
*
332-
* Factory method to create the runner, allowing tests to override this
333-
* to inject mocks via setRunner().
334-
*
335-
* @return \DrevOps\VortexInstaller\Runner\ProcessRunner
336-
* The process runner instance.
337-
*/
338-
protected function getRunner(): ProcessRunner {
339-
// Return already-set runner if available (for testing).
340-
return $this->runner ?? (new ProcessRunner())->disableLog()->disableStreaming();
341-
}
342-
343-
/**
344-
* Set the process runner instance.
345-
*
346-
* Allows dependency injection for testing.
347-
*
348-
* @param \DrevOps\VortexInstaller\Runner\ProcessRunner $runner
349-
* The process runner instance.
332+
* {@inheritdoc}
350333
*/
351-
public function setRunner(ProcessRunner $runner): void {
352-
$this->runner = $runner;
334+
public function getProcessRunner(): ProcessRunner {
335+
return $this->processRunner ?? (new ProcessRunner())->disableLog()->disableStreaming();
353336
}
354337

355338
}

0 commit comments

Comments
 (0)