diff --git a/ChangeLog-10.5.md b/ChangeLog-10.5.md index a71f09acdbc..441bc9c8d04 100644 --- a/ChangeLog-10.5.md +++ b/ChangeLog-10.5.md @@ -2,6 +2,12 @@ All notable changes of the PHPUnit 10.5 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. +## [10.5.10] - 2024-MM-DD + +### Fixed + +* [#5692](https://github.com/sebastianbergmann/phpunit/issues/5692): `--log-events-text` and `--log-events-verbose-text` require the destination file to exit + ## [10.5.9] - 2024-01-22 ### Fixed @@ -97,6 +103,7 @@ All notable changes of the PHPUnit 10.5 release series are documented in this fi * [#5563](https://github.com/sebastianbergmann/phpunit/issues/5563): `createMockForIntersectionOfInterfaces()` does not automatically register mock object for expectation verification +[10.5.10]: https://github.com/sebastianbergmann/phpunit/compare/10.5.9...10.5 [10.5.9]: https://github.com/sebastianbergmann/phpunit/compare/10.5.8...10.5.9 [10.5.8]: https://github.com/sebastianbergmann/phpunit/compare/10.5.7...10.5.8 [10.5.7]: https://github.com/sebastianbergmann/phpunit/compare/10.5.6...10.5.7 diff --git a/src/TextUI/Configuration/Cli/Builder.php b/src/TextUI/Configuration/Cli/Builder.php index 2e5b57ee046..0f6cb18a52b 100644 --- a/src/TextUI/Configuration/Cli/Builder.php +++ b/src/TextUI/Configuration/Cli/Builder.php @@ -17,6 +17,7 @@ use function is_numeric; use function sprintf; use PHPUnit\Runner\TestSuiteSorter; +use PHPUnit\Util\Filesystem; use SebastianBergmann\CliParser\Exception as CliParserException; use SebastianBergmann\CliParser\Parser as CliParser; @@ -805,12 +806,30 @@ public function fromParameters(array $parameters): Configuration break; case '--log-events-text': - $logEventsText = $option[1]; + $logEventsText = Filesystem::resolveStreamOrFile($option[1]); + + if ($logEventsText === false) { + throw new Exception( + sprintf( + 'The path "%s" specified for the --log-events-text option could not be resolved', + $option[1], + ), + ); + } break; case '--log-events-verbose-text': - $logEventsVerboseText = $option[1]; + $logEventsVerboseText = Filesystem::resolveStreamOrFile($option[1]); + + if ($logEventsVerboseText === false) { + throw new Exception( + sprintf( + 'The path "%s" specified for the --log-events-verbose-text option could not be resolved', + $option[1], + ), + ); + } break; diff --git a/src/Util/Filesystem.php b/src/Util/Filesystem.php index 9789fe29a74..d683696a2ea 100644 --- a/src/Util/Filesystem.php +++ b/src/Util/Filesystem.php @@ -9,8 +9,12 @@ */ namespace PHPUnit\Util; +use function basename; +use function dirname; use function is_dir; use function mkdir; +use function realpath; +use function str_starts_with; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit @@ -21,4 +25,24 @@ public static function createDirectory(string $directory): bool { return !(!is_dir($directory) && !@mkdir($directory, 0o777, true) && !is_dir($directory)); } + + /** + * @psalm-param non-empty-string $path + * + * @return false|non-empty-string + */ + public static function resolveStreamOrFile(string $path): false|string + { + if (str_starts_with($path, 'php://') || str_starts_with($path, 'socket://')) { + return $path; + } + + $directory = dirname($path); + + if (is_dir($directory)) { + return realpath($directory) . DIRECTORY_SEPARATOR . basename($path); + } + + return false; + } } diff --git a/tests/end-to-end/cli/log-events-text-invalid-argument.phpt b/tests/end-to-end/cli/log-events-text-invalid-argument.phpt new file mode 100644 index 00000000000..f3c3c5bd28b --- /dev/null +++ b/tests/end-to-end/cli/log-events-text-invalid-argument.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test fails with invalid path +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +The path "%s" specified for the --log-events-text option could not be resolved diff --git a/tests/end-to-end/cli/log-events-verbose-text-invalid-argument.phpt b/tests/end-to-end/cli/log-events-verbose-text-invalid-argument.phpt new file mode 100644 index 00000000000..1e22d7c6a09 --- /dev/null +++ b/tests/end-to-end/cli/log-events-verbose-text-invalid-argument.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test fails with invalid path +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +The path "%s" specified for the --log-events-verbose-text option could not be resolved diff --git a/tests/unit/Util/FilesystemTest.php b/tests/unit/Util/FilesystemTest.php new file mode 100644 index 00000000000..666fab7d8bc --- /dev/null +++ b/tests/unit/Util/FilesystemTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Small; +use PHPUnit\Framework\TestCase; + +#[CoversClass(Filesystem::class)] +#[Small] +final class FilesystemTest extends TestCase +{ + public function testCanResolveStreamOrFile(): void + { + $this->assertSame('php://stdout', Filesystem::resolveStreamOrFile('php://stdout')); + $this->assertSame('socket://hostname:port', Filesystem::resolveStreamOrFile('socket://hostname:port')); + $this->assertSame(__FILE__, Filesystem::resolveStreamOrFile(__FILE__)); + $this->assertSame(__DIR__ . '/does-not-exist', Filesystem::resolveStreamOrFile(__DIR__ . '/does-not-exist')); + $this->assertFalse(Filesystem::resolveStreamOrFile(__DIR__ . '/does-not-exist/does-not-exist')); + } +}