Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bin/run-task.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
return;
}

$exitCode = (new Runner($output))->run(taskCommands($task));
$failFast = !in_array($task, ['tests', 'tests:details'], true);
$exitCode = (new Runner($output, $failFast))->run(taskCommands($task));

if ($exitCode !== 0) {
throw new RuntimeException(sprintf('Task "%s" failed with exit code %d.', $task, $exitCode));
Expand All @@ -53,6 +54,7 @@ function taskCommands(string $task): array
'test:static' => TaskCatalog::staticAnalysis(),
'test:syntax' => TaskCatalog::syntax(),
'tests' => TaskCatalog::testAll(),
'tests:details' => TaskCatalog::testDetails(),
default => throw new InvalidArgumentException(sprintf('Unknown task "%s".', $task)),
};
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
"ic:test:syntax": "@php bin/run-task.php test:syntax",
"ic:tests": "@php bin/run-task.php tests",
"ic:tests:all": "@ic:tests",
"ic:tests:details": "@php bin/run-task.php tests:details",
"ic:tests:parallel": "@php bin/run-task.php tests:parallel"
}
}
2 changes: 1 addition & 1 deletion src/Composer/CiCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ protected function configure(): void
protected function execute(InputInterface $input, OutputInterface $output): int
{
if ((bool) $input->getOption('prefer-lowest')) {
return (new Runner($output))->run(TaskCatalog::ci(true));
return (new Runner($output, false))->run(TaskCatalog::ci(true));
}

return (new ParallelRunner($output))->run(TaskCatalog::syntax(), TaskCatalog::testParallel());
Expand Down
3 changes: 2 additions & 1 deletion src/Composer/CommandProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ private function commandRows(): array
private function infocyphCommands(string $group): array
{
$commands = [];
$failFast = $group !== 'quality';

foreach ($this->commandRows() as [$rowGroup, $name, $description, $taskMethod]) {
if ($rowGroup === $group) {
$commands[] = new InfocyphCommand($name, $description, $this->tasks($taskMethod));
$commands[] = new InfocyphCommand($name, $description, $this->tasks($taskMethod), false, [], $failFast);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Composer/InfocyphCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function __construct(
private readonly array $tasks,
private readonly bool $parallel = false,
private readonly array $preflightTasks = [],
private readonly bool $failFast = true,
) {
parent::__construct($commandName);
}
Expand All @@ -40,6 +41,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return (new ParallelRunner($output))->run($this->preflightTasks, $this->tasks);
}

return (new Runner($output))->run($this->tasks);
return (new Runner($output, $this->failFast))->run($this->tasks);
}
}
2 changes: 1 addition & 1 deletion src/Support/Cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private function ci(array $args): int
return (new ParallelRunner($output))->run(TaskCatalog::syntax(), TaskCatalog::testParallel());
}

return (new Runner($output))->run(TaskCatalog::ci(true));
return (new Runner($output, false))->run(TaskCatalog::ci(true));
}

private function help(): int
Expand Down
14 changes: 11 additions & 3 deletions src/Support/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ final class Runner

public function __construct(
private readonly OutputInterface $output,
private readonly bool $failFast = true,
) {}

/**
Expand All @@ -24,22 +25,29 @@ public function run(array $tasks): int

$isFirstTask = true;
$results = [];
$failureExitCode = 0;

foreach ($tasks as $task) {
$result = $this->runTask($task, $isFirstTask);
$isFirstTask = false;
$results[] = $result;

if ($result['status'] === 'FAIL') {
QualitySummary::write($results);
if ($failureExitCode === 0) {
$failureExitCode = $result['exit_code'];
}

return $result['exit_code'];
if ($this->failFast) {
QualitySummary::write($results);

return $result['exit_code'];
}
}
}

QualitySummary::write($results);

return 0;
return $failureExitCode;
}

private function detectComposerVersion(): string
Expand Down
47 changes: 47 additions & 0 deletions tests/Support/RunnerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

use Infocyph\PHPForge\Support\Runner;
use Symfony\Component\Console\Output\BufferedOutput;

function runnerTempPath(string $suffix): string
{
return sys_get_temp_dir().DIRECTORY_SEPARATOR.'phpforge-runner-'.uniqid('', true).'-'.$suffix;
}

it('returns failure exit code after running all tasks when fail-fast is disabled', function (): void {
$marker = runnerTempPath('continued.txt');
$output = new BufferedOutput();
$runner = new Runner($output, false);

$exitCode = $runner->run([
[PHP_BINARY, '-r', 'fwrite(STDERR, "first failed\n"); exit(3);'],
[PHP_BINARY, '-r', 'file_put_contents('.var_export($marker, true).', "ran");'],
]);

expect($exitCode)->toBe(3)
->and(is_file($marker))->toBeTrue();

if (is_file($marker)) {
unlink($marker);
}
});

it('stops at first failure when fail-fast is enabled', function (): void {
$marker = runnerTempPath('stopped.txt');
$output = new BufferedOutput();
$runner = new Runner($output, true);

$exitCode = $runner->run([
[PHP_BINARY, '-r', 'fwrite(STDERR, "first failed\n"); exit(4);'],
[PHP_BINARY, '-r', 'file_put_contents('.var_export($marker, true).', "ran");'],
]);

expect($exitCode)->toBe(4)
->and(is_file($marker))->toBeFalse();

if (is_file($marker)) {
unlink($marker);
}
});