Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade tools #13

Merged
merged 1 commit into from
Oct 21, 2024
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
3 changes: 2 additions & 1 deletion .github/workflows/analyzers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
php-versions: ['8.1', '8.2', '8.3', '8.4']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand All @@ -23,3 +23,4 @@ jobs:
run: composer update --prefer-dist --no-progress --no-suggest ${{ matrix.composer-options }}
- name: Run the tests
run: composer run psalm
continue-on-error: ${{ matrix.php-versions == '8.4'}}
2 changes: 1 addition & 1 deletion .github/workflows/code-style.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
php-versions: ['8.1', '8.2', '8.3', '8.4']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/functional.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
php-versions: ['8.1', '8.2', '8.3', '8.4']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
php-versions: ['8.1', '8.2', '8.3', '8.4']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand All @@ -24,4 +24,4 @@ jobs:
- name: Run the tests
run: composer run tests
- name: Check tests quality
run: composer parallel coverage infection || true
run: composer parallel coverage infection
8 changes: 4 additions & 4 deletions .phive/phars.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpunit" version="^9.5.26" installed="9.5.26" location="./tools/phpunit.phar" copy="true"/>
<phar name="psalm" version="^4.29.0" installed="4.29.0" location="./tools/psalm.phar" copy="true"/>
<phar name="infection" version="^0.26" installed="0.26.1" location="./tools/infection.phar" copy="true"/>
<phar name="php-cs-fixer" version="^3.13.0" installed="3.13.0" location="./tools/php-cs-fixer.phar" copy="true"/>
<phar name="phpunit" version="^9.5.26" installed="9.6.21" location="./tools/phpunit.phar" copy="true"/>
<phar name="psalm" version="^5.26.1" installed="5.26.1" location="./tools/psalm.phar" copy="true"/>
<phar name="infection" version="^0.26" installed="0.26.21" location="./tools/infection.phar" copy="true"/>
<phar name="php-cs-fixer" version="^3.13.0" installed="3.64.0" location="./tools/php-cs-fixer.phar" copy="true"/>
</phive>
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
}
],
"require": {
"php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
"composer-plugin-api": "~2.0"
},
"require-dev": {
Expand Down
7 changes: 6 additions & 1 deletion infection.json.dist
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
"text": "infection.log"
},
"mutators": {
"@default": true
"@default": true,
"CastInt": {
"ignore": [
"ComposerRunParallel\\Scripts\\ParallelScript::__invoke"
]
}
}
}
2 changes: 2 additions & 0 deletions src/Executor/AsyncTaskExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public function __invoke(string $task, array $args): PromiseInterface
* @param list<string> $args
*
* @throws ParallelException
*
* @psalm-suppress RiskyTruthyFalsyComparison
*/
private function buildProcess(string $task, array $args): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Finder/PhpExecutableFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static function default(): self
public function __invoke(): string
{
$phpPath = $this->finder->find(false);
if (!$phpPath) {
if (false === $phpPath) {
throw ParallelException::phpBinaryNotFound();
}

Expand Down
4 changes: 2 additions & 2 deletions src/Result/ResultMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function listFailedTasks(): array
}

/**
* @throws ParallelException
* @throws ParallelException
*
* @return list<string>
*/
Expand Down Expand Up @@ -96,7 +96,7 @@ public function getResultCode(): int
*/
public function conclude(
callable $onSuccess,
callable $onFailure
callable $onFailure,
) {
$resultCode = $this->getResultCode();

Expand Down
2 changes: 1 addition & 1 deletion src/Scripts/ParallelScript.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function __invoke(Event $event): int
static function (Process $process) use ($task, $io, $resultMap): void {
$resultMap->registerResult($task, (int) $process->getExitCode());

$io->write('<info>Finished task '.$task.'</info>');
$io->write(sprintf('<info>Finished task %s</info>', $task));
$io->writeError($process->getErrorOutput());
$io->write([$process->getOutput(), '']);
}
Expand Down
9 changes: 7 additions & 2 deletions tests/Unit/Exception/ParallelExceptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ final class ParallelExceptionTest extends TestCase
public function it_can_throw_exception_on_invalid_amount_of_tasks(): void
{
$this->expectException(ParallelException::class);
$this->expectExceptionMessage('Expected at least 1 task to run in parallel!');

throw ParallelException::atLeastOneTask();
}
Expand All @@ -24,7 +25,7 @@ public function it_can_throw_exception_on_invalid_amount_of_tasks(): void
public function it_can_throw_exception_on_unkown_task(): void
{
$this->expectException(ParallelException::class);
$this->expectExceptionMessage('taskName');
$this->expectExceptionMessage('Script "taskName" is not defined in this package');

throw ParallelException::invalidTask('taskName');
}
Expand All @@ -33,7 +34,7 @@ public function it_can_throw_exception_on_unkown_task(): void
public function it_can_throw_exception_on_no_result_yet_for_task(): void
{
$this->expectException(ParallelException::class);
$this->expectExceptionMessage('taskName');
$this->expectExceptionMessage('Received no result for task taskName yet.');

throw ParallelException::noResultForTaskYet('taskName');
}
Expand All @@ -42,6 +43,9 @@ public function it_can_throw_exception_on_no_result_yet_for_task(): void
public function it_can_throw_exception_if_composer_does_not_contain_executor(): void
{
$this->expectException(ParallelException::class);
$this->expectExceptionMessage(
'The composer Loop does not contain a ProcessExecutor. Please log an issue with detailed information on how to reproduce!'
);

throw ParallelException::noProcessExecutorDetected();
}
Expand All @@ -50,6 +54,7 @@ public function it_can_throw_exception_if_composer_does_not_contain_executor():
public function it_can_throw_exception_if_php_binary_cannot_be_found(): void
{
$this->expectException(ParallelException::class);
$this->expectExceptionMessage('Failed to locate PHP binary to execute.');

throw ParallelException::phpBinaryNotFound();
}
Expand Down
22 changes: 22 additions & 0 deletions tests/Unit/Finder/PhpExecutableFinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace ComposerRunParallel\Test\Unit\Executor;

use Composer\Util\ProcessExecutor;
use ComposerRunParallel\Exception\ParallelException;
use ComposerRunParallel\Finder\PhpExecutableFinder;
use PHPUnit\Framework\TestCase;
Expand All @@ -27,6 +28,27 @@ public function it_throws_exception_on_php_executable_not_found(): void
$phpExecutableFinder();
}

/** @test */
public function it_can_find_executable(): void
{
$finder = $this->createMock(SymfonyPhpExecutableFinder::class);
$finder->method('find')->with(false)->willReturn('php');

$phpExecutableFinder = new PhpExecutableFinder($finder);
$actual = $phpExecutableFinder();

$allowUrlFOpenFlag = '-d allow_url_fopen='.ProcessExecutor::escape(ini_get('allow_url_fopen'));
$disableFunctionsFlag = '-d disable_functions='.ProcessExecutor::escape(ini_get('disable_functions'));
$memoryLimitFlag = '-d memory_limit='.ProcessExecutor::escape(ini_get('memory_limit'));

self::assertSame(
<<<EOCLI
'php' {$allowUrlFOpenFlag} {$disableFunctionsFlag} {$memoryLimitFlag}
EOCLI,
$actual
);
}

/** @test */
public function it_can_create_a_default_finder(): void
{
Expand Down
30 changes: 24 additions & 6 deletions tests/Unit/Scripts/ParallelScriptTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,19 @@ protected function setUp(): void
$finder->method('find')->willReturn('php');
$finder->method('findArguments')->willReturn([]);

// Composer comes with symfony console 2.8, which has deprecated methods:
// Deprecated: Return type of Symfony\Component\Console\Helper\HelperSet::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable,
// Since it's a composer dependency, we can't change it, so we need to suppress the deprecation notice
// Let's mute it for now.
$previousErrorLevel = error_reporting(0);
$this->io = new BufferIO();
error_reporting($previousErrorLevel);

$dispatcher = $this->createMock(EventDispatcher::class);
$dispatcher
->method('hasEventListeners')
->will($this->returnCallback(
static fn (Event $event) => in_array($event->getName(), ['task1', 'task2'], true)
static fn (Event $event) => in_array($event->getName(), ['task1', 'task2', 'task3', 'task4'], true)
));

$this->composer = new Composer();
Expand Down Expand Up @@ -81,36 +87,48 @@ public function it_fails_if_a_task_is_not_known(): void
public function it_can_successfully_run_scripts_in_parallel(): void
{
$this->processExecutor->method('executeAsync')->willReturn(
$this->createProcessResult(true),
$this->createProcessResult(true)
);

$result = ($this->script)($this->createEvent(['task1']));
$result = ($this->script)($this->createEvent(['task1', 'task2']));

self::assertEquals(0, $result);

$output = $this->io->getOutput();
self::assertStringContainsString('Finished running: '.PHP_EOL.'task1', $output);
self::assertStringContainsString('Running tasks in parallel:'.PHP_EOL.'task1'.PHP_EOL.'task2'.PHP_EOL, $output);
self::assertStringContainsString('Finished task task1'.PHP_EOL.'stderr'.PHP_EOL.'stdout'.PHP_EOL, $output);
self::assertStringContainsString('Finished task task2'.PHP_EOL.'stderr'.PHP_EOL.'stdout'.PHP_EOL, $output);
self::assertStringContainsString('Finished running: '.PHP_EOL.'task1'.PHP_EOL.'task2', $output);
}

/** @test */
public function it_can_insuccessfully_run_scripts_in_parallel(): void
{
$this->processExecutor->method('executeAsync')->willReturn(
$this->createProcessResult(false),
$this->createProcessResult(true),
$this->createProcessResult(false),
$this->createProcessResult(true)
);
$exception = null;

try {
($this->script)($this->createEvent(['task1', 'task2']));
($this->script)($this->createEvent(['task1', 'task2', 'task3', 'task4']));
} catch (ScriptExecutionException $exception) {
}

self::assertInstanceOf(ScriptExecutionException::class, $exception);
self::assertSame(1, $exception->getCode());

$output = $this->io->getOutput();
self::assertStringContainsString('Succesfully ran: '.PHP_EOL.'task2', $output);
self::assertStringContainsString('Failed running: '.PHP_EOL.'task1', $output);
self::assertStringContainsString('Running tasks in parallel:'.PHP_EOL.'task1'.PHP_EOL.'task2'.PHP_EOL.'task3'.PHP_EOL.'task4'.PHP_EOL, $output);
self::assertStringContainsString('Finished task task1'.PHP_EOL.'stderr'.PHP_EOL.'stdout'.PHP_EOL, $output);
self::assertStringContainsString('Finished task task2'.PHP_EOL.'stderr'.PHP_EOL.'stdout'.PHP_EOL, $output);
self::assertStringContainsString('Finished task task3'.PHP_EOL.'stderr'.PHP_EOL.'stdout'.PHP_EOL, $output);
self::assertStringContainsString('Finished task task4'.PHP_EOL.'stderr'.PHP_EOL.'stdout'.PHP_EOL, $output);
self::assertStringContainsString('Succesfully ran: '.PHP_EOL.'task2'.PHP_EOL.'task4', $output);
self::assertStringContainsString('Failed running: '.PHP_EOL.'task1'.PHP_EOL.'task3', $output);
self::assertStringContainsString('Not all tasks could be executed successfully!', $output);
}

Expand Down
2 changes: 1 addition & 1 deletion tools/full-coverage-check.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
$checkedElements = (int) current($xml->xpath('/coverage/project/metrics/@coveredelements'));
$coverage = round(($checkedElements / $totalElements) * 100, 2);

if ($coverage !== 100) {
if ($coverage !== 100.0) {
echo('Expected coverage of 100%, only got '.$coverage.'%.'.PHP_EOL);
exit(1);
}
Expand Down
Binary file modified tools/infection.phar
Binary file not shown.
Binary file modified tools/php-cs-fixer.phar
Binary file not shown.
Loading
Loading