diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9c9392fa689789304797bead085a1ad02fc2570..d56b4bc1d9bb08f650c32d05a24f4408a3caefd8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,8 +31,8 @@ jobs: - name: Run PHP-CS-Fixer run: ./tools/php-cs-fixer fix --dry-run --show-progress=dots --using-cache=no --verbose - type-checker: - name: Type Checker + static-analysis: + name: Static Analysis runs-on: ubuntu-latest @@ -49,8 +49,8 @@ jobs: - name: Install dependencies with Composer run: ./tools/composer update --no-interaction --no-ansi --no-progress - - name: Run Psalm - run: ./tools/psalm --config=.psalm/config.xml --no-progress --shepherd --show-info=false --stats + - name: Run PHPStan + run: ./tools/phpstan analyse --no-progress --error-format=github tests: name: Tests diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000000000000000000000000000000000000..10c6ce0610676c13babf385135c5e3ebec4282ee --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,43 @@ +# https://docs.github.com/en/actions + +on: + push: + tags: + - "**" + +name: Release + +jobs: + release: + name: Release + + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: 8.3 + coverage: none + extensions: none + tools: none + + - name: Determine tag + run: echo "RELEASE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + + - name: Parse ChangeLog + run: build/scripts/extract-release-notes.php ${{ env.RELEASE_TAG }} > release-notes.md + + - name: Create release + uses: ncipollo/release-action@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + tag: ${{ env.RELEASE_TAG }} + name: phpunit/php-file-iterator ${{ env.RELEASE_TAG }} + bodyFile: release-notes.md diff --git a/.phive/phars.xml b/.phive/phars.xml index e9c9ac614ce23a493db0e191ef7f71bdc5974af7..4817da71b394359dd9a4e623de1ab849dab53d4c 100644 --- a/.phive/phars.xml +++ b/.phive/phars.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <phive xmlns="https://phar.io/phive"> - <phar name="php-cs-fixer" version="^3.0" installed="3.41.1" location="./tools/php-cs-fixer" copy="true"/> - <phar name="psalm" version="^5.0" installed="5.18.0" location="./tools/psalm" copy="true"/> - <phar name="composer" version="^2.0.3" installed="2.6.6" location="./tools/composer" copy="true"/> + <phar name="php-cs-fixer" version="^3.59" installed="3.59.3" location="./tools/php-cs-fixer" copy="true"/> + <phar name="composer" version="^2.7" installed="2.7.7" location="./tools/composer" copy="true"/> + <phar name="phpstan" version="^1.11" installed="1.11.5" location="./tools/phpstan" copy="true"/> </phive> diff --git a/.psalm/baseline.xml b/.psalm/baseline.xml deleted file mode 100644 index 09f04decaf4b9d0bd54237d72aa92d06d63ce3db..0000000000000000000000000000000000000000 --- a/.psalm/baseline.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<files psalm-version="5.6.0@e784128902dfe01d489c4123d69918a9f3c1eac5"> - <file src="src/ExcludeIterator.php"> - <MissingTemplateParam> - <code>ExcludeIterator</code> - </MissingTemplateParam> - </file> -</files> diff --git a/.psalm/config.xml b/.psalm/config.xml deleted file mode 100644 index 343cc8e3ed28b3bb8dcaaec70244b56f6daf71a5..0000000000000000000000000000000000000000 --- a/.psalm/config.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0"?> -<psalm - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="https://getpsalm.org/schema/config" - xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" - resolveFromConfigFile="false" - errorBaseline=".psalm/baseline.xml" - findUnusedBaselineEntry="true" - findUnusedCode="false" -> - <projectFiles> - <directory name="src" /> - <ignoreFiles> - <directory name="vendor" /> - </ignoreFiles> - </projectFiles> -</psalm> diff --git a/ChangeLog.md b/ChangeLog.md index 959ce0ba7228ea4627bc2b340e8ae8edcdab707a..970f762489ce21a793cc43d106a58cda79c077b4 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [5.0.1] - 2024-07-03 + +### Changed + +* This project now uses PHPStan instead of Psalm for static analysis + ## [5.0.0] - 2024-02-02 ### Removed @@ -156,6 +162,7 @@ No changes * [#23](https://github.com/sebastianbergmann/php-file-iterator/pull/23): Added support for wildcards (glob) in exclude +[5.0.1]: https://github.com/sebastianbergmann/php-file-iterator/compare/5.0.0...5.0.1 [5.0.0]: https://github.com/sebastianbergmann/php-file-iterator/compare/4.1...5.0.0 [4.1.0]: https://github.com/sebastianbergmann/php-file-iterator/compare/4.0.2...4.1.0 [4.0.2]: https://github.com/sebastianbergmann/php-file-iterator/compare/4.0.1...4.0.2 diff --git a/build/scripts/extract-release-notes.php b/build/scripts/extract-release-notes.php new file mode 100755 index 0000000000000000000000000000000000000000..553189267ddf74728028ea8f5992eb35ebf2d114 --- /dev/null +++ b/build/scripts/extract-release-notes.php @@ -0,0 +1,46 @@ +#!/usr/bin/env php +<?php declare(strict_types=1); +if ($argc !== 2) { + print $argv[0] . ' <tag>' . PHP_EOL; + + exit(1); +} + +$version = $argv[1]; + +$file = __DIR__ . '/../../ChangeLog.md'; + +if (!is_file($file) || !is_readable($file)) { + print $file . ' cannot be read' . PHP_EOL; + + exit(1); +} + +$buffer = ''; +$append = false; + +foreach (file($file) as $line) { + if (str_starts_with($line, '## [' . $version . ']')) { + $append = true; + + continue; + } + + if ($append && (str_starts_with($line, '## ') || str_starts_with($line, '['))) { + break; + } + + if ($append) { + $buffer .= $line; + } +} + +$buffer = trim($buffer); + +if ($buffer === '') { + print 'Unable to extract release notes' . PHP_EOL; + + exit(1); +} + +print $buffer . PHP_EOL; diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000000000000000000000000000000000000..08566d07a495531f34abd8522c67f0c39eb68d96 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 9 + paths: + - src + - tests diff --git a/phpunit.xml b/phpunit.xml index 9f8393da394b824f0fd92b7e216d45ab31695c16..931d837d11cacac17f662ce691c6c79f600aabc6 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,9 +16,7 @@ </testsuite> </testsuites> - <source restrictDeprecations="true" - restrictNotices="true" - restrictWarnings="true"> + <source ignoreIndirectDeprecations="true" restrictNotices="true" restrictWarnings="true"> <include> <directory>src</directory> </include> diff --git a/src/ExcludeIterator.php b/src/ExcludeIterator.php index 23c9335e2893dd9c2383e85a2c038a76b72beec2..209ec00f59ca505972acddbf37d462c1d77c853f 100644 --- a/src/ExcludeIterator.php +++ b/src/ExcludeIterator.php @@ -21,12 +21,12 @@ use SplFileInfo; final class ExcludeIterator extends RecursiveFilterIterator { /** - * @psalm-var list<string> + * @var list<string> */ private array $exclude; /** - * @psalm-param list<string> $exclude + * @param list<string> $exclude */ public function __construct(RecursiveDirectoryIterator $iterator, array $exclude) { diff --git a/src/Facade.php b/src/Facade.php index b782bf96a3daa24d3748e98630719b08ccef268e..a0410e842ef6f3adc23c0572462c464514e395bb 100644 --- a/src/Facade.php +++ b/src/Facade.php @@ -20,12 +20,12 @@ use SplFileInfo; final class Facade { /** - * @psalm-param list<non-empty-string>|non-empty-string $paths - * @psalm-param list<non-empty-string>|string $suffixes - * @psalm-param list<non-empty-string>|string $prefixes - * @psalm-param list<non-empty-string> $exclude + * @param list<non-empty-string>|non-empty-string $paths + * @param list<non-empty-string>|string $suffixes + * @param list<non-empty-string>|string $prefixes + * @param list<non-empty-string> $exclude * - * @psalm-return list<non-empty-string> + * @return list<non-empty-string> */ public function getFilesAsArray(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []): array { diff --git a/src/Factory.php b/src/Factory.php index 7a0f0b1263649879745bd3c80e67a233fd100c4f..a2ebce6c184f7f4c2aa9e5e3c614f95ab18f68f3 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -29,10 +29,10 @@ use RecursiveIteratorIterator; final class Factory { /** - * @psalm-param list<non-empty-string>|non-empty-string $paths - * @psalm-param list<non-empty-string>|string $suffixes - * @psalm-param list<non-empty-string>|string $prefixes - * @psalm-param list<non-empty-string> $exclude + * @param list<non-empty-string>|non-empty-string $paths + * @param list<non-empty-string>|string $suffixes + * @param list<non-empty-string>|string $prefixes + * @param list<non-empty-string> $exclude */ public function getFileIterator(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []): AppendIterator { @@ -83,9 +83,9 @@ final class Factory } /** - * @psalm-param list<non-empty-string> $paths + * @param list<non-empty-string> $paths * - * @psalm-return list<non-empty-string> + * @return list<non-empty-string> */ private function resolveWildcards(array $paths): array { diff --git a/src/Iterator.php b/src/Iterator.php index 52dd22d7794da69dac2f4efa627eec252ee3b4ec..405f25de2005fcaaab1dca79f55ee19a6ddd3c4c 100644 --- a/src/Iterator.php +++ b/src/Iterator.php @@ -15,12 +15,11 @@ use function realpath; use function str_ends_with; use function str_replace; use function str_starts_with; -use AppendIterator; use FilterIterator; use SplFileInfo; /** - * @template-extends FilterIterator<int, string, AppendIterator> + * @template-extends FilterIterator<int, SplFileInfo, \Iterator> * * @internal This class is not covered by the backward compatibility promise for phpunit/php-file-iterator */ @@ -31,18 +30,18 @@ final class Iterator extends FilterIterator private false|string $basePath; /** - * @psalm-var list<string> + * @var list<string> */ private array $suffixes; /** - * @psalm-var list<string> + * @var list<string> */ private array $prefixes; /** - * @psalm-param list<string> $suffixes - * @psalm-param list<string> $prefixes + * @param list<string> $suffixes + * @param list<string> $prefixes */ public function __construct(string $basePath, \Iterator $iterator, array $suffixes = [], array $prefixes = []) { @@ -94,7 +93,7 @@ final class Iterator extends FilterIterator } /** - * @psalm-param list<string> $subStrings + * @param list<string> $subStrings */ private function acceptSubString(string $filename, array $subStrings, int $type): bool { diff --git a/tests/unit/FacadeTest.php b/tests/unit/FacadeTest.php index 8d85e5ea71764599c4ab10fb6175e6c2f224c71d..3200790702ef77a884fcde09daa994fd456b51ea 100644 --- a/tests/unit/FacadeTest.php +++ b/tests/unit/FacadeTest.php @@ -24,6 +24,9 @@ use PHPUnit\Framework\TestCase; #[Small] final class FacadeTest extends TestCase { + /** + * @return non-empty-array<non-empty-string, array{0: list<non-empty-string>, 1: list<non-empty-string>|non-empty-string, 2: list<non-empty-string>|string, 3: list<non-empty-string>|string, 4: list<non-empty-string>}> + */ public static function provider(): array { $fixtureDirectoryRealpath = self::fixtureDirectoryRealpath(); @@ -136,6 +139,13 @@ final class FacadeTest extends TestCase unlink(self::fixtureDirectoryRealpath() . '/a/DoesNotExist.php'); } + /** + * @param list<non-empty-string> $expected + * @param list<non-empty-string>|non-empty-string $paths + * @param list<non-empty-string>|string $suffixes + * @param list<non-empty-string>|string $prefixes + * @param list<non-empty-string> $exclude + */ #[DataProvider('provider')] public function testSomething(array $expected, array|string $paths, array|string $suffixes, array|string $prefixes, array $exclude): void {