From 70ad5cc84490c67de7f1ea74d0aeea602ff6b6c7 Mon Sep 17 00:00:00 2001 From: Paul Mitchum Date: Mon, 22 Jan 2024 10:14:34 -0800 Subject: [PATCH] Add support for PHP 8.2 (#31) --- .circleci/config.yml | 2 +- .gitattributes | 15 +++++++++++++++ composer.json | 9 +++++---- phpunit.xml | 35 ++++++++++++++++++++--------------- rector.php | 28 ++++++++++++++++++++++++++-- src/FileFetcher.php | 8 ++++---- test/FileFetcherTest.php | 28 ++++++++++++++-------------- test/Mock/FakeProcessor.php | 3 +++ test/Mock/FakeRemote.php | 5 ++--- test/Processor/LocalTest.php | 4 ++-- test/Processor/RemoteTest.php | 6 +++--- 11 files changed, 95 insertions(+), 48 deletions(-) create mode 100644 .gitattributes diff --git a/.circleci/config.yml b/.circleci/config.yml index 63cd55f..37a9d8e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -176,5 +176,5 @@ workflows: - matrix-conditions: matrix: parameters: - version: ["7.4", "8.0", "8.1"] + version: ["7.4", "8.0", "8.1", "8.2"] install-flags: ["", "--prefer-lowest"] diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7c33d67 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +# Exclude build/test files from archive +/.circleci export-ignore +/test export-ignore +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/Doxyfile export-ignore +/doxygen.tag.xml export-ignore +/phpcs.xml export-ignore +/phpunit.xml export-ignore +/procrastinator.tag.xml export-ignore +/rector.php export-ignore + +# Configure diff output for .php and .phar files. +*.php diff=php diff --git a/composer.json b/composer.json index 220af16..7ef3b2d 100644 --- a/composer.json +++ b/composer.json @@ -9,17 +9,18 @@ } ], "require": { - "php": ">=7.4 <8.2", + "php": ">=7.4 <8.3", "ext-curl": "*", "getdkan/procrastinator": "^5.0.0", "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5" }, "require-dev": { - "getdkan/mock-chain": "^1.3.5", - "mikey179/vfsstream": "^1.6.10", + "getdkan/mock-chain": "^1.3.6", + "mikey179/vfsstream": "^1.6.11", "phpunit/phpunit": "^9.6", "rector/rector": "^0.15.18", - "squizlabs/php_codesniffer": "^3.7" + "squizlabs/php_codesniffer": "^3.7", + "symfony/phpunit-bridge": "^7.0" }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/phpunit.xml b/phpunit.xml index 6af318b..1e1245d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,17 +1,22 @@ - - - - src - - - - - test - - + + + + src + + + + + + + + + + + + test + + diff --git a/rector.php b/rector.php index dc1c6df..70c366b 100644 --- a/rector.php +++ b/rector.php @@ -3,8 +3,14 @@ declare(strict_types=1); use Rector\Config\RectorConfig; -use Rector\Set\ValueObject\LevelSetList; +use Rector\Core\ValueObject\PhpVersion; +use Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveUselessReturnTagRector; +use Rector\DeadCode\Rector\Property\RemoveUselessVarTagRector; use Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector; +use Rector\Set\ValueObject\SetList; +use Rector\TypeDeclaration\Rector\ClassMethod\ArrayShapeFromConstantArrayReturnRector; +use Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector; return static function (RectorConfig $rectorConfig): void { $rectorConfig->paths([ @@ -12,11 +18,29 @@ __DIR__ . '/test', ]); + // Our base version of PHP. + $rectorConfig->phpVersion(PhpVersion::PHP_74); + $rectorConfig->sets([ - LevelSetList::UP_TO_PHP_74, + SetList::PHP_82, + // Please no dead code or unneeded variables. + SetList::DEAD_CODE, + // Try to figure out type hints. + SetList::TYPE_DECLARATION, ]); $rectorConfig->skip([ + // Don't throw errors on JSON parse problems. Yet. + // @todo Throw errors and deal with them appropriately. JsonThrowOnErrorRector::class, + // We like our tags. Please don't remove them. + RemoveUselessParamTagRector::class, + RemoveUselessReturnTagRector::class, + RemoveUselessVarTagRector::class, + ArrayShapeFromConstantArrayReturnRector::class, + AddMethodCallBasedStrictParamTypeRector::class, ]); + + $rectorConfig->importNames(); + $rectorConfig->importShortClasses(false); }; diff --git a/src/FileFetcher.php b/src/FileFetcher.php index 6a18b77..be38602 100644 --- a/src/FileFetcher.php +++ b/src/FileFetcher.php @@ -29,7 +29,7 @@ class FileFetcher extends AbstractPersistentJob * * Stored here so that we don't have to recompute it. * - * @var \FileFetcher\Processor\ProcessorInterface|null + * @var ProcessorInterface|null */ private ?ProcessorInterface $processor = null; @@ -130,7 +130,7 @@ protected function getProcessors(): array return $processors; } - private static function getDefaultProcessors() + private static function getDefaultProcessors(): array { return [ Local::class => new Local(), @@ -141,7 +141,7 @@ private static function getDefaultProcessors() /** * Get the processor used by this file fetcher object. * - * @return \FileFetcher\Processor\ProcessorInterface|null + * @return ProcessorInterface|null * A processor object, determined by configuration, or NULL if none is * suitable. */ @@ -248,7 +248,7 @@ private function unsetDuplicateCustomProcessorClasses(array $processors):void * @param $processorClass * Processor class name. * - * @return \FileFetcher\Processor\ProcessorInterface|null + * @return ProcessorInterface|null * An instance of the processor class. If the given class name does not * exist, or does not implement ProcessorInterface, then null is * returned. diff --git a/test/FileFetcherTest.php b/test/FileFetcherTest.php index 2e3a0cf..5d645df 100644 --- a/test/FileFetcherTest.php +++ b/test/FileFetcherTest.php @@ -17,7 +17,7 @@ class FileFetcherTest extends TestCase { - public function testCopyALocalFile() + public function testCopyALocalFile(): void { $config = ["filePath" => __DIR__ . '/files/tiny.csv']; $fetcher = FileFetcher::get("1", new Memory(), $config); @@ -34,7 +34,7 @@ public function testCopyALocalFile() ); } - public function testKeepOriginalFilename() + public function testKeepOriginalFilename(): void { $fetcher = FileFetcher::get( "2", @@ -50,12 +50,12 @@ public function testKeepOriginalFilename() $state = $fetcher->getState(); $this->assertEquals( - basename($state['source']), - basename($state['destination']) + basename((string) $state['source']), + basename((string) $state['destination']) ); } - public function testConfigValidationErrorConfigurationMissing() + public function testConfigValidationErrorConfigurationMissing(): void { $this->expectExceptionMessage('Constructor missing expected config filePath.'); FileFetcher::get( @@ -64,7 +64,7 @@ public function testConfigValidationErrorConfigurationMissing() ); } - public function testConfigValidationErrorMissingFilePath() + public function testConfigValidationErrorMissingFilePath(): void { $this->expectExceptionMessage('Constructor missing expected config filePath.'); FileFetcher::get( @@ -74,9 +74,9 @@ public function testConfigValidationErrorMissingFilePath() ); } - public function testCustomProcessorsValidationIsNotAnArray() + public function testCustomProcessorsValidationIsNotAnArray(): void { - $fetcher = FileFetcher::get( + FileFetcher::get( "2", new Memory(), [ @@ -88,9 +88,9 @@ public function testCustomProcessorsValidationIsNotAnArray() $this->assertTrue(true); } - public function testCustomProcessorsValidationNotAClass() + public function testCustomProcessorsValidationNotAClass(): void { - $fetcher = FileFetcher::get( + FileFetcher::get( "2", new Memory(), [ @@ -102,9 +102,9 @@ public function testCustomProcessorsValidationNotAClass() $this->assertTrue(true); } - public function testCustomProcessorsValidationImproperClass() + public function testCustomProcessorsValidationImproperClass(): void { - $fetcher = FileFetcher::get( + FileFetcher::get( "2", new Memory(), [ @@ -116,7 +116,7 @@ public function testCustomProcessorsValidationImproperClass() $this->assertTrue(true); } - public function testSwitchProcessor() + public function testSwitchProcessor(): void { $file_path = __DIR__ . '/files/tiny.csv'; $temporary_directory = '/temp/foo'; @@ -191,7 +191,7 @@ public function testSwitchProcessor() /** * @covers ::addProcessors */ - public function testAddProcessors() + public function testAddProcessors(): void { $file_path = __DIR__ . '/files/tiny.csv'; $temporary_directory = '/temp/foo'; diff --git a/test/Mock/FakeProcessor.php b/test/Mock/FakeProcessor.php index 25b95d5..b9ad1b0 100644 --- a/test/Mock/FakeProcessor.php +++ b/test/Mock/FakeProcessor.php @@ -18,6 +18,9 @@ public function setupState(array $state): array return $state; } + /** + * @return array{state: mixed[], result: Result} + */ public function copy(array $state, Result $result, int $timeLimit = PHP_INT_MAX): array { return ['state' => $state, 'result' => $result]; diff --git a/test/Mock/FakeRemote.php b/test/Mock/FakeRemote.php index ce1b1cb..c9f1e12 100644 --- a/test/Mock/FakeRemote.php +++ b/test/Mock/FakeRemote.php @@ -16,12 +16,11 @@ protected function getClient(): Client return new Client(['handler' => $handlerStack]); } - private function getMockHandler() + private function getMockHandler(): MockHandler { - $mock = new MockHandler([ + return new MockHandler([ new Response(200, ['X-Foo' => 'Bar'], 'Hello, World'), ]); - return $mock; } protected function getFileSize($path): int diff --git a/test/Processor/LocalTest.php b/test/Processor/LocalTest.php index 45f0afa..2593307 100644 --- a/test/Processor/LocalTest.php +++ b/test/Processor/LocalTest.php @@ -12,7 +12,7 @@ class LocalTest extends TestCase { - public function provideSource() + public function provideSource(): array { return [ 'any-normal-file' => ['blah'], @@ -24,7 +24,7 @@ public function provideSource() * @covers ::isServerCompatible * @dataProvider provideSource */ - public function test($source) + public function test(string $source): void { $processor = new Local(); $state = ['source' => $source]; diff --git a/test/Processor/RemoteTest.php b/test/Processor/RemoteTest.php index 5d96b89..1de0067 100644 --- a/test/Processor/RemoteTest.php +++ b/test/Processor/RemoteTest.php @@ -16,7 +16,7 @@ class RemoteTest extends TestCase { - public function testCopyAFileWithRemoteProcessor() + public function testCopyAFileWithRemoteProcessor(): void { $config = [ "filePath" => 'http://notreal.blah/notacsv.csv', @@ -51,13 +51,13 @@ public function provideIsServerCompatible(): array * * @dataProvider provideIsServerCompatible */ - public function testIsServerCompatible($expected, $source) + public function testIsServerCompatible(bool $expected, string $source): void { $processor = new Remote(); $this->assertSame($expected, $processor->isServerCompatible(['source' => $source])); } - public function testCopyException() + public function testCopyException(): void { // Ensure the status object contains the message from an exception. // We'll use vfsstream to mock a file system with no permissions to