From 27c1154882197efb4c1bc0085caf48ebbb280c5b Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 12 Mar 2026 08:42:49 +0100 Subject: [PATCH 1/3] Update lint jobs --- .github/workflows/coverage.yml | 1 + .github/workflows/phan.yml | 4 +++- .github/workflows/phpcs.yml | 8 +++++--- .github/workflows/phpcsf.yml | 8 +++++--- .github/workflows/phpmd.yml | 4 +++- .github/workflows/psalm.yml | 5 ++--- .github/workflows/tests.yml | 1 + composer.json | 4 ++-- psalm.xml | 3 +++ src/Phug/Split/Command/CommandBase.php | 4 ++-- src/Phug/Split/Git/Commit.php | 2 +- src/Phug/Split/Git/EmptyLogList.php | 2 +- src/Phug/Split/Git/ImmutableLogException.php | 2 +- .../Git/InvalidGitLogStringException.php | 2 +- src/Phug/Split/Git/InvalidGitLogUnit.php | 2 +- src/Phug/Split/Git/Log.php | 4 ++-- src/Phug/Split/InvalidCli.php | 2 +- tests/use-fork.php | 19 ------------------- 18 files changed, 35 insertions(+), 42 deletions(-) delete mode 100644 tests/use-fork.php diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5b9b638..1a3d1cc 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -41,6 +41,7 @@ jobs: if: steps.composer-cache.outputs.cache-hit != 'true' run: | composer config version 1.9.0 + composer remove --no-update --dev phan/phan friendsofphp/php-cs-fixer nette/utils phpmd/phpmd phpstan/phpstan squizlabs/php_codesniffer vimeo/psalm composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress ${{ matrix.php >= 8.1 && '--ignore-platform-req=php' || '' }} - name: Prepare git config diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 7b8b165..2ad1c70 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -38,7 +38,9 @@ jobs: - name: Install dependencies if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress + run: | + composer remove --no-update --dev phpunit/phpunit friendsofphp/php-cs-fixer nette/utils phpmd/phpmd phpstan/phpstan squizlabs/php_codesniffer vimeo/psalm + composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress - name: Check style with Phan run: composer run-script phan diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml index 503f7b5..2770d61 100644 --- a/.github/workflows/phpcs.yml +++ b/.github/workflows/phpcs.yml @@ -32,13 +32,15 @@ jobs: uses: actions/cache@v4 with: path: vendor - key: style-${{ runner.os }}-${{ matrix.setup }}-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} + key: cs-${{ runner.os }}-${{ matrix.setup }}-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} restore-keys: | - style-${{ runner.os }}-${{ matrix.setup }}-${{ matrix.php }}- + cs-${{ runner.os }}-${{ matrix.setup }}-${{ matrix.php }}- - name: Install dependencies if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress + run: | + composer remove --no-update --dev phpunit/phpunit phan/phan friendsofphp/php-cs-fixer nette/utils phpmd/phpmd phpstan/phpstan vimeo/psalm + composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress - name: Check style with PHPCS run: composer run-script phpcs diff --git a/.github/workflows/phpcsf.yml b/.github/workflows/phpcsf.yml index 40cd1a7..0433c3c 100644 --- a/.github/workflows/phpcsf.yml +++ b/.github/workflows/phpcsf.yml @@ -32,13 +32,15 @@ jobs: uses: actions/cache@v4 with: path: vendor - key: style-${{ runner.os }}-${{ matrix.setup }}-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} + key: csf-${{ runner.os }}-${{ matrix.setup }}-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} restore-keys: | - style-${{ runner.os }}-${{ matrix.setup }}-${{ matrix.php }}- + csf-${{ runner.os }}-${{ matrix.setup }}-${{ matrix.php }}- - name: Install dependencies if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress + run: | + composer remove --no-update --dev phpunit/phpunit phan/phan nette/utils phpmd/phpmd phpstan/phpstan squizlabs/php_codesniffer vimeo/psalm + composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress - name: Check style with phpcsf run: composer run-script phpcsf diff --git a/.github/workflows/phpmd.yml b/.github/workflows/phpmd.yml index 0e72a1f..5b76e16 100644 --- a/.github/workflows/phpmd.yml +++ b/.github/workflows/phpmd.yml @@ -38,7 +38,9 @@ jobs: - name: Install dependencies if: steps.composer-cache.outputs.cache-hit != 'true' - run: composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress + run: | + composer remove --no-update --dev phpunit/phpunit phan/phan friendsofphp/php-cs-fixer nette/utils phpstan/phpstan squizlabs/php_codesniffer vimeo/psalm + composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress - name: Check style with phpmd run: composer run-script phpmd diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index 9ac9887..9a53b77 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - php: ['8.2'] + php: ['8.4'] setup: ['stable'] name: PHP ${{ matrix.php }} - ${{ matrix.setup }} @@ -38,9 +38,8 @@ jobs: - name: Install dependencies if: steps.composer-cache.outputs.cache-hit != 'true' - # tests/use-fork.php because of https://github.com/vimeo/psalm/issues/8957 run: | - php tests/use-fork.php vimeo/psalm 5.14.2 https://github.com/kylekatarnls/psalm.git fix/datetime-inheritance-5.x + composer remove --no-update --dev phan/phan phpunit/phpunit friendsofphp/php-cs-fixer nette/utils phpmd/phpmd phpstan/phpstan squizlabs/php_codesniffer composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress - name: Check style with psalm diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 22811be..483df81 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -45,6 +45,7 @@ jobs: if: steps.composer-cache.outputs.cache-hit != 'true' run: | composer config version 1.9.0 + composer remove --no-update --dev phan/phan friendsofphp/php-cs-fixer nette/utils phpmd/phpmd phpstan/phpstan squizlabs/php_codesniffer vimeo/psalm composer update --prefer-dist ${{ matrix.setup != 'next' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress ${{ matrix.php >= 8.1 && '--ignore-platform-req=php' || '' }} --no-interaction - name: Prepare git config diff --git a/composer.json b/composer.json index a96834b..c43ab8a 100644 --- a/composer.json +++ b/composer.json @@ -27,13 +27,13 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.15.0 || ^3.23.0", - "nette/utils": "^3.2.10", + "nette/utils": "^3.2.10 || ^4.1.3", "phan/phan": "^3.2.10 || ^5.4.2", "phpunit/phpunit": "^8.5.52 || ^9.6.34", "phpmd/phpmd": "^2.13.0", "phpstan/phpstan": "^0.11.15 || ^1.10.29", "squizlabs/php_codesniffer": "^3.7.2", - "vimeo/psalm": "^4.30.0 || ^5.14.1" + "vimeo/psalm": "^4.30.0 || ^5.14.1 || ^6.15.1" }, "autoload": { "psr-4": { diff --git a/psalm.xml b/psalm.xml index 84a90c8..43845c8 100644 --- a/psalm.xml +++ b/psalm.xml @@ -32,6 +32,9 @@ + + + diff --git a/src/Phug/Split/Command/CommandBase.php b/src/Phug/Split/Command/CommandBase.php index 37c6c67..c2f49c6 100644 --- a/src/Phug/Split/Command/CommandBase.php +++ b/src/Phug/Split/Command/CommandBase.php @@ -55,7 +55,7 @@ protected function gitEscape(string $value): string * * @psalm-suppress UndefinedThisPropertyFetch RiskyTruthyFalsyComparison */ - protected function getGitCommand(string $command, array $options = [], string $redirect = null): string + protected function getGitCommand(string $command, array $options = [], ?string $redirect = null): string { foreach ($options as $name => $value) { $command .= ' --'.$name.'='.$this->gitEscape($value); @@ -73,7 +73,7 @@ protected function getGitCommand(string $command, array $options = [], string $r * * @return string|null */ - protected function git(string $command, array $options = [], string $redirect = null): ?string + protected function git(string $command, array $options = [], ?string $redirect = null): ?string { $command = $this->getGitCommand($command, $options, $redirect); diff --git a/src/Phug/Split/Git/Commit.php b/src/Phug/Split/Git/Commit.php index 95b8cd8..69e843e 100644 --- a/src/Phug/Split/Git/Commit.php +++ b/src/Phug/Split/Git/Commit.php @@ -76,7 +76,7 @@ public static function fromGitLogString(string $log): self new Author(trim($matches['commitName']), trim($matches['commitEmail'])), new Date($matches['commitDate']), ), - preg_replace('/^ {4}/m', '', trim($matches['message'])), + (string) preg_replace('/^ {4}/m', '', trim($matches['message'])), ); } diff --git a/src/Phug/Split/Git/EmptyLogList.php b/src/Phug/Split/Git/EmptyLogList.php index 081f7e4..aad6d30 100644 --- a/src/Phug/Split/Git/EmptyLogList.php +++ b/src/Phug/Split/Git/EmptyLogList.php @@ -7,7 +7,7 @@ class EmptyLogList extends InvalidArgumentException { - public function __construct(int $code = 0, Throwable $previous = null) + public function __construct(int $code = 0, ?Throwable $previous = null) { parent::__construct('Log list should contain at least one commit.', $code, $previous); } diff --git a/src/Phug/Split/Git/ImmutableLogException.php b/src/Phug/Split/Git/ImmutableLogException.php index a1d0835..9a8174a 100644 --- a/src/Phug/Split/Git/ImmutableLogException.php +++ b/src/Phug/Split/Git/ImmutableLogException.php @@ -7,7 +7,7 @@ class ImmutableLogException extends InvalidArgumentException { - public function __construct(int $code = 0, Throwable $previous = null) + public function __construct(int $code = 0, ?Throwable $previous = null) { parent::__construct( 'Log instance is immutable, create a new instance new Log($commits) with a new list of commits', diff --git a/src/Phug/Split/Git/InvalidGitLogStringException.php b/src/Phug/Split/Git/InvalidGitLogStringException.php index 64027d2..8e1aa14 100644 --- a/src/Phug/Split/Git/InvalidGitLogStringException.php +++ b/src/Phug/Split/Git/InvalidGitLogStringException.php @@ -7,7 +7,7 @@ class InvalidGitLogStringException extends InvalidArgumentException { - public function __construct(string $log = '', int $code = 0, Throwable $previous = null) + public function __construct(string $log = '', int $code = 0, ?Throwable $previous = null) { parent::__construct("Invalid git log string: $log", $code, $previous); } diff --git a/src/Phug/Split/Git/InvalidGitLogUnit.php b/src/Phug/Split/Git/InvalidGitLogUnit.php index d306c86..f6602a8 100644 --- a/src/Phug/Split/Git/InvalidGitLogUnit.php +++ b/src/Phug/Split/Git/InvalidGitLogUnit.php @@ -7,7 +7,7 @@ class InvalidGitLogUnit extends InvalidArgumentException { - public function __construct(string $unit = '', int $code = 0, Throwable $previous = null) + public function __construct(string $unit = '', int $code = 0, ?Throwable $previous = null) { parent::__construct("Invalid git log unit: $unit, ".Commit::class.' expected', $code, $previous); } diff --git a/src/Phug/Split/Git/Log.php b/src/Phug/Split/Git/Log.php index f254b8c..44cf128 100644 --- a/src/Phug/Split/Git/Log.php +++ b/src/Phug/Split/Git/Log.php @@ -70,13 +70,13 @@ public static function fromGitLogString(string $log): self { $commitLogs = preg_split('/[\n\r](?=commit )/', $log); - return new self(array_map(static function (string $commitLog) { + return new self($commitLogs === false ? [] : array_map(static function (string $commitLog) { return Commit::fromGitLogString($commitLog); }, $commitLogs)); } /** - * Whether a offset exists. + * Whether an offset exists. * * @link https://php.net/manual/en/arrayaccess.offsetexists.php * diff --git a/src/Phug/Split/InvalidCli.php b/src/Phug/Split/InvalidCli.php index dcc284a..2365b2e 100644 --- a/src/Phug/Split/InvalidCli.php +++ b/src/Phug/Split/InvalidCli.php @@ -8,7 +8,7 @@ class InvalidCli extends InvalidArgumentException { - public function __construct(object $cli, int $code = 0, Throwable $previous = null) + public function __construct(object $cli, int $code = 0, ?Throwable $previous = null) { $class = get_class($cli); diff --git a/tests/use-fork.php b/tests/use-fork.php deleted file mode 100644 index a394c1b..0000000 --- a/tests/use-fork.php +++ /dev/null @@ -1,19 +0,0 @@ - 'vcs', - 'url' => $url, -]; -$composer['repositories'] = $repositories; -$dev = isset($composer['require-dev'][$package]) ? ' --dev' : ''; -file_put_contents('composer.json', json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); - -echo shell_exec( - 'composer require -n --no-update' . $dev . ' "' . $package . ':dev-' . $branch . ' as ' . $version . '"' -); From 89cef1cbc6069b79d58715627223e02b6c89b49e Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 12 Mar 2026 09:12:06 +0100 Subject: [PATCH 2/3] Fix few typing issues --- src/Phug/Split/Command/Analyze.php | 9 +++++---- src/Phug/Split/Command/CommandBase.php | 11 +++++++---- src/Phug/Split/Command/Copy.php | 5 ++++- src/Phug/Split/Command/Dist.php | 13 ++++++++----- src/Phug/Split/Command/Update.php | 8 ++++---- src/Phug/Split/Git/Commit.php | 4 ++++ 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/Phug/Split/Command/Analyze.php b/src/Phug/Split/Command/Analyze.php index 8cdf516..6d1d7c2 100644 --- a/src/Phug/Split/Command/Analyze.php +++ b/src/Phug/Split/Command/Analyze.php @@ -66,7 +66,7 @@ protected function calculatePackagesTree(Split $cli): bool return $cli->error('Root project directory should contains a '.$this->composerFile.' file.'); } - $data = (array) json_decode(file_get_contents($this->composerFile), true); + $data = (array) json_decode((string) file_get_contents($this->composerFile), true); $vendorDirectory = ($data['config'] ?? [])['vendor-dir'] ?? 'vendor'; $cli->writeLine((string) $data['name']); @@ -93,7 +93,7 @@ protected function getPackages(): iterable protected function dumpPackagesTree(Split $cli, iterable $packages, int $level = 0): bool { - $count = is_countable($packages) ? count($packages) : INF; + $count = is_countable($packages) ? count($packages) : 0; foreach ($packages as $index => $package) { $symbol = $index === $count - 1 ? '└' : '├'; @@ -106,7 +106,8 @@ protected function dumpPackagesTree(Split $cli, iterable $packages, int $level = protected function mapDirectories(string $directory, callable $callback): iterable { - foreach (scandir($directory) as $element) { + /** @psalm-suppress RiskyTruthyFalsyComparison */ + foreach ((scandir($directory) ?: []) as $element) { if (substr($element, 0, 1) === '.') { continue; } @@ -141,7 +142,7 @@ protected function scanDirectories(string $directory): iterable $composerPath = $directory.DIRECTORY_SEPARATOR.$this->composerFile; if (file_exists($composerPath)) { - $data = json_decode(file_get_contents($composerPath), true); + $data = json_decode((string) file_get_contents($composerPath), true); $mainPackage = $this->getPackage($directory, $data); } diff --git a/src/Phug/Split/Command/CommandBase.php b/src/Phug/Split/Command/CommandBase.php index c2f49c6..66fc630 100644 --- a/src/Phug/Split/Command/CommandBase.php +++ b/src/Phug/Split/Command/CommandBase.php @@ -53,7 +53,7 @@ protected function gitEscape(string $value): string * * @return string * - * @psalm-suppress UndefinedThisPropertyFetch RiskyTruthyFalsyComparison + * @psalm-suppress UndefinedThisPropertyFetch */ protected function getGitCommand(string $command, array $options = [], ?string $redirect = null): string { @@ -61,6 +61,7 @@ protected function getGitCommand(string $command, array $options = [], ?string $ $command .= ' --'.$name.'='.$this->gitEscape($value); } + /** @psalm-suppress RiskyTruthyFalsyComparison */ return $this->gitProgram.' '.$command.($redirect ? ' '.$redirect : ''); } @@ -71,13 +72,13 @@ protected function getGitCommand(string $command, array $options = [], ?string $ * @param array $options CLI git command options * @param string|null $redirect redirection suffix (like '2>&1') * - * @return string|null + * @return string */ - protected function git(string $command, array $options = [], ?string $redirect = null): ?string + protected function git(string $command, array $options = [], ?string $redirect = null): string { $command = $this->getGitCommand($command, $options, $redirect); - return shell_exec($command); + return (string) shell_exec($command); } /** @@ -118,6 +119,8 @@ protected function last(string $directory = ''): Commit * * @return string|null * + * @psalm-return truthy-string|null + * * @psalm-suppress UndefinedThisPropertyFetch */ protected function getCurrentLinkedCommitHash(): ?string diff --git a/src/Phug/Split/Command/Copy.php b/src/Phug/Split/Command/Copy.php index 8a9e817..4889cdb 100644 --- a/src/Phug/Split/Command/Copy.php +++ b/src/Phug/Split/Command/Copy.php @@ -50,6 +50,8 @@ class Copy extends CommandBase * @throws Exception * * @return bool + * + * @SuppressWarnings(PHPMD.ErrorControlOperator) */ public function run(SimpleCli $cli): bool { @@ -65,7 +67,8 @@ public function run(SimpleCli $cli): bool return $cli->error('Last commit must be linked to a mono-repository commit.'); } - $destination = realpath($this->destination); + /** @psalm-var truthy-string|false $destination */ + $destination = @realpath($this->destination); if (!$destination) { return $cli->error('Destination directory "'.$this->destination.'" does not seem to exist.'); diff --git a/src/Phug/Split/Command/Dist.php b/src/Phug/Split/Command/Dist.php index d0fbab7..566a2cf 100644 --- a/src/Phug/Split/Command/Dist.php +++ b/src/Phug/Split/Command/Dist.php @@ -72,20 +72,23 @@ protected function distribute(Split $cli): bool $this->remove($this->output); $cli->chdir($this->directory); @mkdir($this->output, 0777, true); - $this->output = @realpath($this->output); + /** @psalm-var truthy-string|false $output */ + $output = @realpath($this->output); - if (!$this->output) { + if (!$output) { return $cli->error('Unable to create output directory.'); } - if (!preg_match('/^\* (.+)$/m', (string) $this->git('branch', [], '2>&1') ?: '', $branch)) { + $this->output = $output; + + if (!preg_match('/^\* (.+)$/m', $this->git('branch', [], '2>&1') ?: '', $branch)) { return $cli->error('You must be on a branch in a git repository to run this command.'); } $branch = $branch[1]; if (substr($branch, 0, 18) === '(HEAD detached at ') { - $branch = trim(explode("\n", (string) $this->git('describe --contains --all HEAD', [], '2>&1') ?: '')[0]); + $branch = trim(explode("\n", $this->git('describe --contains --all HEAD', [], '2>&1') ?: '')[0]); } foreach ($this->getPackages() as $package) { @@ -103,7 +106,7 @@ protected function distributePackage(Split $cli, array $package, string $branch) $name = (string) $package['name']; - $data = (array) json_decode(file_get_contents(strtr($this->api, ['%s' => $name])), true); + $data = (array) json_decode((string) file_get_contents(strtr($this->api, ['%s' => $name])), true); $config = $data['packages'][$name] ?? []; $config = $config['dev-master'] ?? next($config); diff --git a/src/Phug/Split/Command/Update.php b/src/Phug/Split/Command/Update.php index 8a6f3e6..9dcd693 100644 --- a/src/Phug/Split/Command/Update.php +++ b/src/Phug/Split/Command/Update.php @@ -45,8 +45,8 @@ class Update extends Dist protected function getPackage(string $directory, array $data): array { return [ - 'name' => $data['name'], - 'directory' => realpath($directory), + 'name' => (string) $data['name'], + 'directory' => (string) realpath($directory), 'children' => [], ]; } @@ -184,7 +184,7 @@ protected function cherryPickCommit( if (!$this->noPush) { $name = $package['name']; - $push = (string) $this->git("push origin $branch", [], '2>&1'); + $push = $this->git("push origin $branch", [], '2>&1'); $cli->writeLine("Pushing $name\n".$push, strpos($push, 'error:') === false ? 'light_cyan' : 'red'); } @@ -215,7 +215,7 @@ protected function distributePackage(Split $cli, array $package, string $branch) } $hash = $this->getCurrentLinkedCommitHash(); - $distributionDirectory = getcwd(); + $distributionDirectory = (string) getcwd(); $sourceDirectory = $package['directory']; $cli->chdir($sourceDirectory); diff --git a/src/Phug/Split/Git/Commit.php b/src/Phug/Split/Git/Commit.php index 69e843e..bd4a738 100644 --- a/src/Phug/Split/Git/Commit.php +++ b/src/Phug/Split/Git/Commit.php @@ -126,6 +126,10 @@ public function getMessage(): string * @param non-empty-string $regExp * * @return string|null + * + * @psalm-return truthy-string|null + * + * @psalm-suppress LessSpecificReturnStatement, MoreSpecificReturnType */ public function findInMessage(string $regExp): ?string { From 7e814ca9137c84e2be5cb780801ead390a405c6d Mon Sep 17 00:00:00 2001 From: KyleKatarn Date: Thu, 12 Mar 2026 09:21:42 +0100 Subject: [PATCH 3/3] Add exception for scandir failures --- src/Phug/Split/Command/Analyze.php | 10 ++++++++-- src/Phug/Split/Command/CommandBase.php | 5 ++++- src/Phug/Split/UnableToListDirectoryItems.php | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/Phug/Split/UnableToListDirectoryItems.php diff --git a/src/Phug/Split/Command/Analyze.php b/src/Phug/Split/Command/Analyze.php index 6d1d7c2..bf30c3c 100644 --- a/src/Phug/Split/Command/Analyze.php +++ b/src/Phug/Split/Command/Analyze.php @@ -3,6 +3,7 @@ namespace Phug\Split\Command; use Phug\Split; +use Phug\Split\UnableToListDirectoryItems; use SimpleCli\SimpleCli; use Traversable; @@ -106,8 +107,13 @@ protected function dumpPackagesTree(Split $cli, iterable $packages, int $level = protected function mapDirectories(string $directory, callable $callback): iterable { - /** @psalm-suppress RiskyTruthyFalsyComparison */ - foreach ((scandir($directory) ?: []) as $element) { + $elements = scandir($directory); + + if ($elements === false) { + throw new UnableToListDirectoryItems($directory); + } + + foreach ($elements as $element) { if (substr($element, 0, 1) === '.') { continue; } diff --git a/src/Phug/Split/Command/CommandBase.php b/src/Phug/Split/Command/CommandBase.php index 66fc630..d23f823 100644 --- a/src/Phug/Split/Command/CommandBase.php +++ b/src/Phug/Split/Command/CommandBase.php @@ -51,6 +51,8 @@ protected function gitEscape(string $value): string * @param array $options CLI git command options * @param string|null $redirect redirection suffix (like '2>&1') * + * @psalm-param truthy-string|null $redirect + * * @return string * * @psalm-suppress UndefinedThisPropertyFetch @@ -61,7 +63,6 @@ protected function getGitCommand(string $command, array $options = [], ?string $ $command .= ' --'.$name.'='.$this->gitEscape($value); } - /** @psalm-suppress RiskyTruthyFalsyComparison */ return $this->gitProgram.' '.$command.($redirect ? ' '.$redirect : ''); } @@ -72,6 +73,8 @@ protected function getGitCommand(string $command, array $options = [], ?string $ * @param array $options CLI git command options * @param string|null $redirect redirection suffix (like '2>&1') * + * @psalm-param truthy-string|null $redirect + * * @return string */ protected function git(string $command, array $options = [], ?string $redirect = null): string diff --git a/src/Phug/Split/UnableToListDirectoryItems.php b/src/Phug/Split/UnableToListDirectoryItems.php new file mode 100644 index 0000000..09f2d70 --- /dev/null +++ b/src/Phug/Split/UnableToListDirectoryItems.php @@ -0,0 +1,14 @@ +