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
108 changes: 108 additions & 0 deletions tests/AgentLoopReleaseSetVerifierTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

declare(strict_types=1);

namespace voku\tests;

use PHPUnit\Framework\TestCase;
use RuntimeException;

/** @internal */
final class AgentLoopReleaseSetVerifierTest extends TestCase
{
public function testRejectsPackageDeclaredInRequireAndRequireDev(): void
{
$directory = sys_get_temp_dir() . '/simple-php-parser-release-set-' . bin2hex(random_bytes(4));
if (!mkdir($directory, 0o775, true) && !is_dir($directory)) {
throw new RuntimeException('Unable to create test directory: ' . $directory);

Check warning on line 17 in tests/AgentLoopReleaseSetVerifierTest.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=voku_Simple-PHP-Code-Parser&issues=AaAOWkukp3kRdUaaoNqp&open=AaAOWkukp3kRdUaaoNqp&pullRequest=117
}

$issuePath = $directory . '/issue.json';
$composerPath = $directory . '/composer.json';

try {
self::writeJson($issuePath, [
'toolchain' => [
'agent_loop_release' => '0.16.5',
],
]);
self::writeJson($composerPath, [
'require' => [
'voku/agent-loop' => '0.16.5',
],
'require-dev' => [
'voku/agent-loop' => '0.16.4',
],
]);

[$exitCode, $stdout, $stderr] = $this->execute([
PHP_BINARY,
dirname(__DIR__) . '/tools/agent-loop/verify-release-set.php',
$issuePath,
$composerPath,
]);

self::assertSame(1, $exitCode, $stdout . $stderr);
self::assertSame('', $stdout);
self::assertStringContainsString(
'must not declare the same package in both require and require-dev: voku/agent-loop',
$stderr,
);
} finally {
foreach ([$issuePath, $composerPath] as $path) {
if (is_file($path) && !unlink($path)) {
throw new RuntimeException('Unable to remove test file: ' . $path);

Check warning on line 54 in tests/AgentLoopReleaseSetVerifierTest.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=voku_Simple-PHP-Code-Parser&issues=AaAOWwbuKbB-PIbWmfUU&open=AaAOWwbuKbB-PIbWmfUU&pullRequest=117
}
}
if (is_dir($directory) && !rmdir($directory)) {
throw new RuntimeException('Unable to remove test directory: ' . $directory);

Check warning on line 58 in tests/AgentLoopReleaseSetVerifierTest.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=voku_Simple-PHP-Code-Parser&issues=AaAOWwbuKbB-PIbWmfUV&open=AaAOWwbuKbB-PIbWmfUV&pullRequest=117
}
}
}

/**
* @param array<string, mixed> $data
*/
private static function writeJson(string $path, array $data): void
{
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
if (file_put_contents($path, $json . "\n") === false) {
throw new RuntimeException('Unable to write test file: ' . $path);

Check warning on line 70 in tests/AgentLoopReleaseSetVerifierTest.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=voku_Simple-PHP-Code-Parser&issues=AaAOWwbuKbB-PIbWmfUW&open=AaAOWwbuKbB-PIbWmfUW&pullRequest=117
}
}

/**
* @param list<string> $command
*
* @return array{0: int, 1: string, 2: string}
*/
private function execute(array $command): array
{
$pipes = [];
$process = proc_open(
$command,
[
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
],
$pipes,
);
if (!is_resource($process)) {
throw new RuntimeException('Unable to start verifier process.');

Check warning on line 92 in tests/AgentLoopReleaseSetVerifierTest.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=voku_Simple-PHP-Code-Parser&issues=AaAOWkukp3kRdUaaoNqq&open=AaAOWkukp3kRdUaaoNqq&pullRequest=117
}

fclose($pipes[0]);
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$exitCode = proc_close($process);

return [
$exitCode,
is_string($stdout) ? $stdout : '',
is_string($stderr) ? $stderr : '',
];
}
}
11 changes: 11 additions & 0 deletions tools/agent-loop/verify-release-set.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@
$toolchain = requireArray($issue, 'toolchain', $argv[1]);
$require = stringRequirements($composer['require'] ?? [], 'require', $argv[2]);
$requireDev = stringRequirements($composer['require-dev'] ?? [], 'require-dev', $argv[2]);

$duplicatePackages = array_keys(array_intersect_key($require, $requireDev));
if ($duplicatePackages !== []) {
sort($duplicatePackages, SORT_STRING);
throw new \RuntimeException(sprintf(
'%s must not declare the same package in both require and require-dev: %s.',
$argv[2],
implode(', ', $duplicatePackages),
));
}

$rootRequirements = $require + $requireDev;

$expectedAgentLoop = requireString($toolchain, 'agent_loop_release', $argv[1]);
Expand Down