diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index f5fc336eb..81901f401 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -44,8 +44,8 @@ jobs: - name: "Check cs" run: make php-cs-check - static-code-analysis: - name: "Static Code Analysis" + static-code-analysis-phpstan: + name: "Static Code Analysis by PHPStan" runs-on: ubuntu-latest @@ -88,6 +88,50 @@ jobs: - name: PHPStan run: make phpstan + static-code-analysis-psalm: + name: "Static Code Analysis by Psalm" + + runs-on: ubuntu-latest + + steps: + - name: "Checkout" + uses: actions/checkout@v2 + + - name: "Cache tools installed with phive" + uses: actions/cache@v2 + with: + path: | + ~~/.phive + ./tools + key: ${{ runner.os }}-phive-cache-${{ hashFiles('**/.phive/phars.xml') }} + restore-keys: | + phive-cache- + + - name: "Cache dependencies installed with composer" + uses: actions/cache@v2 + with: + path: ~/.composer/cache + key: composer-cache-${{ hashFiles('**/composer.lock') }} + restore-keys: | + composer-cache- + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.2' + extensions: mbstring, xml, ctype, iconv + coverage: none + tools: phive + + - name: "Install tools with phive" + run: make tools-install + + - name: "Install dependencies with composer" + run: composer install --no-interaction --no-progress --no-suggest --optimize-autoloader + + - name: Psalm + run: make psalm + tests: name: "PHP ${{ matrix.php-versions }} Test" diff --git a/.phive/phars.xml b/.phive/phars.xml index 1afae8985..ac1d1c830 100644 --- a/.phive/phars.xml +++ b/.phive/phars.xml @@ -3,5 +3,6 @@ + diff --git a/Makefile b/Makefile index e402c30c4..d51c0f18f 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ PHP_BIN := php PHIVE_BIN := phive PHP_CS_FIXER_BIN := ./tools/php-cs-fixer PHPSTAN_BIN := ./tools/phpstan +PSALM_BIN := ./tools/psalm PHPUNIT_BIN := ./tools/phpunit .PHONY: build tools-install composer-install tests tests-coverage gpg php-cs-check php-cs-fix phpstan @@ -34,6 +35,9 @@ php-cs-fix: ## run cs fixer phpstan: $(PHPSTAN_BIN) analyse +psalm: + $(PSALM_BIN) analyse + gpg: gpg --detach-sign --armor --output deptrac.phar.asc deptrac.phar gpg --verify deptrac.phar.asc deptrac.phar diff --git a/baseline.xml b/baseline.xml new file mode 100644 index 000000000..e8894fde0 --- /dev/null +++ b/baseline.xml @@ -0,0 +1,9 @@ + + + + + $layer + $layerDependOn + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 000000000..8f098e3ec --- /dev/null +++ b/psalm.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php index 736374f52..d2238cac8 100644 --- a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php +++ b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php @@ -91,7 +91,9 @@ public function getAstForClassReference(AstClassReference $classReference): ?Nod return self::$classAstMap[$classLikeName]; } - if (null === $classReference->getFileReference()) { + $astFileReference = $classReference->getFileReference(); + + if (null === $astFileReference) { return null; } @@ -102,9 +104,7 @@ static function (Node $node): bool { ); $this->traverser->addVisitor($findingVisitor); - $this->traverser->traverse( - $this->fileParser->parse(new \SplFileInfo($classReference->getFileReference()->getFilepath())) - ); + $this->traverser->traverse($this->fileParser->parse(new \SplFileInfo($astFileReference->getFilepath()))); $this->traverser->removeVisitor($findingVisitor); /** @var Node\Stmt\ClassLike[] $classLikeNodes */ diff --git a/src/FileResolver.php b/src/FileResolver.php index 58df2b546..60387d89d 100644 --- a/src/FileResolver.php +++ b/src/FileResolver.php @@ -4,6 +4,7 @@ namespace SensioLabs\Deptrac; +use Iterator; use SensioLabs\Deptrac\Configuration\Configuration; use SplFileInfo; use Symfony\Component\Finder\Finder; @@ -24,11 +25,13 @@ public function resolve(Configuration $configuration): array ->ignoreVCS(true) ->notPath($configuration->getExcludeFiles()); - $finder = new PathNameFilterIterator( - $finder->getIterator(), - [], - $configuration->getExcludeFiles() - ); + $customFilterIterator = $finder->getIterator(); + + if (!$customFilterIterator instanceof Iterator) { + throw new \RuntimeException('unable to create an interator for the configured paths'); + } + + $finder = new PathNameFilterIterator($customFilterIterator, [], $configuration->getExcludeFiles()); return iterator_to_array($finder); }