From 6caeffe26a8881c6e9a69863fd37e048b73d7a3e Mon Sep 17 00:00:00 2001 From: Giuseppe Mazzapica Date: Wed, 30 Mar 2022 18:39:45 +0200 Subject: [PATCH] Add compatibility with Composer v2.3 - rewrite production autoload for compat with Composer v2.3 - refresh QA --- .github/workflows/qa.yml | 127 +++++++++++++----------- composer.json | 18 ++-- phpcs.xml.dist | 2 +- psalm.xml | 4 - src/Command.php | 10 +- src/Git/EnsureGitIgnore.php | 1 - src/Git/GitProcess.php | 1 - src/Git/MirrorCopier.php | 3 + src/Git/VipGit.php | 10 +- src/Task/EnsureGitKeep.php | 3 +- src/Task/GenerateMuPluginsLoader.php | 1 - src/Task/GenerateProductionAutoload.php | 65 +++++++++--- src/Utils/ArchiveDownloader.php | 3 +- src/Utils/HttpClient.php | 2 - src/Utils/InstalledPackages.php | 2 +- src/Utils/WpPluginFileFinder.php | 1 - 16 files changed, 150 insertions(+), 103 deletions(-) diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 09c6980..4206cdc 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -1,72 +1,83 @@ name: Quality Assurance -on: [push, pull_request] -jobs: - - cross_version: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - strategy: - matrix: - php: [ '7.3', '7.4' ] - tools: [ 'composer:v2', 'composer:v1' ] - prefer: [ 'lowest', 'highest' ] - ignore-platform: [ '' ] - experimental: [ false ] - include: - - php: "8.0" - prefer: "highest" - ignore-platform: "--ignore-platform-reqs" - experimental: true - tools: "composer:v2" - - php: "8.0" - prefer: "highest" - ignore-platform: "--ignore-platform-reqs" - experimental: true - tools: "composer:v1" +on: + push: + pull_request: + workflow_dispatch: + inputs: + skip-jobs: + required: true + type: choice + default: 'Run all' + description: 'Choose jobs to run' + options: + - 'Run all' + - 'Run static QA only' + - 'Run static unit tests only' - continue-on-error: ${{ matrix.experimental }} +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true - steps: - - name: Checkout - uses: actions/checkout@v2 +jobs: + static-qa: + runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, 'skip qa') || github.event.inputs.skip-jobs == 'Run static unit tests only' }} + steps: + - name: Checkout + uses: actions/checkout@v3 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - tools: ${{ matrix.tools }} + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + coverage: none + tools: cs2pr - - name: Check syntax error in sources - run: find ./src/ -type f -name '*.php' -print0 | xargs -0 -L 1 -P 4 -- php -l + - name: Install dependencies + uses: ramsey/composer-install@v2 - - name: Install dependencies - uses: "ramsey/composer-install@v1" - with: - dependency-versions: ${{ matrix.prefer }} - composer-options: ${{ matrix.ignore-platform }} + - name: Check code styles + run: ./vendor/bin/phpcs -q --report=checkstyle | cs2pr - qa: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" + - name: Check Psalm + run: ./vendor/bin/psalm --output-format=github --no-cache - steps: - - name: Checkout - uses: actions/checkout@v2 + unit-tests: + runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, 'skip tests') || github.event.inputs.skip-jobs == 'Run static QA only' }} + strategy: + fail-fast: false + matrix: + php-ver: [ '7.3', '7.4', '8.0' ] + composer: [ 'composer:2.0', 'composer:2.1', 'composer:2.2', 'composer:2.3', 'composer:v1' ] + dependency-versions: [ 'lowest', 'highest' ] + steps: + - name: Checkout + uses: actions/checkout@v3 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-ver }} + ini-values: zend.assertions=1, error_reporting=-1, display_errors=On + coverage: none + tools: cs2pr, ${{ matrix.composer }} - - name: Install dependencies - uses: "ramsey/composer-install@v1" + - name: Install parallel-lint + if: ${{ matrix.dependency-versions == 'highest' }} + run: composer require php-parallel-lint/php-parallel-lint:^1.3.1 --dev --no-update - - name: Check cross-version PHP compatibility - run: composer phpcompat + - name: Install dependencies + uses: ramsey/composer-install@v2 + with: + dependency-versions: ${{ matrix.dependency-versions }} + composer-options: ${{ matrix.composer-options }} - - name: Check code style - run: composer cs + - name: Lint PHP sources + if: ${{ matrix.dependency-versions == 'highest' }} + run: ./vendor/bin/parallel-lint ./src/ --checkstyle | cs2pr - - name: Check Psalm - run: composer psalm + # TODO: Write tests... + #- name: Run unit tests + # run: ./vendor/bin/phpunit --no-coverage diff --git a/composer.json b/composer.json index ef1d785..f58766f 100644 --- a/composer.json +++ b/composer.json @@ -24,9 +24,8 @@ }, "require-dev": { "composer/composer": "^2", - "inpsyde/php-coding-standards": "^1@dev", - "phpcompatibility/php-compatibility": "^9.3.0", - "vimeo/psalm": "^4.1.1" + "inpsyde/php-coding-standards": "^1", + "vimeo/psalm": "^4.22" }, "autoload": { "psr-4": { @@ -37,13 +36,16 @@ "class": "Inpsyde\\VipComposer\\Plugin" }, "scripts": { - "cs": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs", - "psalm": "@php ./vendor/vimeo/psalm/psalm --no-cache --show-info=false --output-format=compact --no-progress", - "phpcompat": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs -p . --standard=PHPCompatibility --ignore=*/vendor/* --extensions=php --basepath=./ --runtime-set testVersion 7.3-", + "phpcs": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs", + "psalm": "@php ./vendor/vimeo/psalm/psalm --no-cache --show-info=false --no-progress", "qa": [ - "@cs", - "@phpcompat", + "@phpcs", "@psalm" ] + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 311e3e8..c183224 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -4,7 +4,7 @@ - + diff --git a/psalm.xml b/psalm.xml index 600183b..a7590fc 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,11 +1,8 @@ - diff --git a/src/Command.php b/src/Command.php index 6e8455f..b72fd21 100644 --- a/src/Command.php +++ b/src/Command.php @@ -153,8 +153,14 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { $this->resetComposer(); - /** @var Composer $composer */ - $composer = $this->getComposer(true); + /** + * @psalm-suppress DeprecatedMethod + * @var Composer $composer + */ + $composer = is_callable([$this, 'requireComposer']) + ? $this->requireComposer() + : $this->getComposer(true); + $factory = new Factory($composer, $this->getIO()); $config = $factory->config(); diff --git a/src/Git/EnsureGitIgnore.php b/src/Git/EnsureGitIgnore.php index 929c39b..22f6fae 100644 --- a/src/Git/EnsureGitIgnore.php +++ b/src/Git/EnsureGitIgnore.php @@ -6,7 +6,6 @@ final class EnsureGitIgnore { - /** * @param string $dir * @return bool diff --git a/src/Git/GitProcess.php b/src/Git/GitProcess.php index f6895c3..3bc47fc 100644 --- a/src/Git/GitProcess.php +++ b/src/Git/GitProcess.php @@ -19,7 +19,6 @@ class GitProcess { - /** * @var string */ diff --git a/src/Git/MirrorCopier.php b/src/Git/MirrorCopier.php index e2471d1..7357c17 100644 --- a/src/Git/MirrorCopier.php +++ b/src/Git/MirrorCopier.php @@ -232,6 +232,9 @@ private function copyLinks(array $linksPaths): bool $copied = 0; foreach ($linksPaths as $link => $target) { $real = realpath($link); + if (!$real) { + continue; + } $targetParent = dirname($target); $saveIn = "{$targetParent}/" . pathinfo($real, PATHINFO_FILENAME) . '.zip'; $git->cd($real)->exec("archive --format zip --output {$saveIn} master"); diff --git a/src/Git/VipGit.php b/src/Git/VipGit.php index f21e93d..5c973fc 100644 --- a/src/Git/VipGit.php +++ b/src/Git/VipGit.php @@ -305,9 +305,7 @@ private function mergeAndPush( $branches = explode($output, "\n") ?: []; $currentBranch = ''; foreach ($branches as $branch) { - if (strpos(trim($branch), '* ')) { - $currentBranch = ltrim($branch, '* '); - } + strpos(trim($branch), '* ') and $currentBranch = ltrim($branch, '* '); } $commands = []; @@ -481,8 +479,8 @@ private function fillMirrorVendor(MirrorCopier $copier, string $mirrorDir): bool $vendorDir = $this->config->composerConfigValue('vendor-dir'); $vendorSource = $this->filesystem->normalizePath($vendorDir); $targetPath = $this->directories->targetPath(); - $subdir = $this->filesystem->findShortestPath($targetPath, $vendorSource, true); - $vendorTarget = "{$mirrorDir}/{$subdir}"; + $subDir = $this->filesystem->findShortestPath($targetPath, $vendorSource, true); + $vendorTarget = "{$mirrorDir}/{$subDir}"; $this->filesystem->ensureDirectoryExists($vendorTarget); $toCopy = $this->packages->noDevPackages(); @@ -552,7 +550,7 @@ static function (string $file) use (&$counts): void { } ); - if ($total < 1) { + if (!$files) { $this->nothingToDoMessage($push); return 0; diff --git a/src/Task/EnsureGitKeep.php b/src/Task/EnsureGitKeep.php index 5ca68fd..019e929 100644 --- a/src/Task/EnsureGitKeep.php +++ b/src/Task/EnsureGitKeep.php @@ -12,7 +12,6 @@ final class EnsureGitKeep implements Task { - /** * @var VipDirectories */ @@ -76,7 +75,7 @@ private function ensureGitKeepFor(string $dir): void } $hasFiles = $this->haveFiles(0, $dir); - $hasGitKeep = file_exists(realpath($dir) . '/.gitkeep'); + $hasGitKeep = file_exists((string)realpath($dir) . '/.gitkeep'); if (!$hasFiles && !$hasGitKeep) { file_put_contents("{$dir}/.gitkeep", "\n"); diff --git a/src/Task/GenerateMuPluginsLoader.php b/src/Task/GenerateMuPluginsLoader.php index c22a8e3..cdbc265 100644 --- a/src/Task/GenerateMuPluginsLoader.php +++ b/src/Task/GenerateMuPluginsLoader.php @@ -22,7 +22,6 @@ final class GenerateMuPluginsLoader implements Task { - /** * @var VipDirectories */ diff --git a/src/Task/GenerateProductionAutoload.php b/src/Task/GenerateProductionAutoload.php index efed922..e1b610e 100644 --- a/src/Task/GenerateProductionAutoload.php +++ b/src/Task/GenerateProductionAutoload.php @@ -94,13 +94,6 @@ public function run(Io $io, TaskConfig $taskConfig): void $autoloader->setClassMapAuthoritative(true); $autoloader->setRunScripts(false); - $suffix = ''; - $lockFile = $this->config->composerLockPath(); - if (is_readable($lockFile)) { - $data = (array)(json_decode(file_get_contents($lockFile) ?: '', true) ?: []); - $suffix = $data['content-hash'] ?? ''; - } - $prodAutoloadDirname = $this->config->prodAutoloadDir(); $autoloader->dump( @@ -110,16 +103,19 @@ public function run(Io $io, TaskConfig $taskConfig): void $this->composer->getInstallationManager(), $prodAutoloadDirname, true, - $suffix ?: md5(uniqid('', true)) + '' ); - $autoloadEntrypoint = "replaceVipPaths($path); + $this->writeVipLoader($path); $io->infoLine('Done!'); } @@ -131,7 +127,6 @@ private function replaceVipPaths(string $path): void { $vendorDir = '$vendorDir = WPCOM_VIP_CLIENT_MU_PLUGIN_DIR . \'/vendor\';'; $baseDir = '$baseDir = ABSPATH;'; - $staticLoader = '$useStaticLoader = false;'; $vipDirBase = basename($this->directories->targetPath()); $toReplace = [ @@ -157,9 +152,51 @@ private function replaceVipPaths(string $path): void ); file_put_contents("{$path}/{$file}", (string)$content); } + } + + /** + * @param string $path + * @return void + */ + private function writeVipLoader(string $path): void + { + $vipComposerAutoloader = <<<'PHP' +addClassMap($classMap); + $loader->setClassMapAuthoritative(true); + $loader->register(true); + + $includeFiles = require __DIR__ . '/autoload_files.php'; + foreach ($includeFiles as $fileIdentifier => $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + } + } +} - $real = file_get_contents("{$path}/autoload_real.php") ?: ''; - $real = preg_replace('~\$useStaticLoader(?:\s*=\s*)[^;]+;~', $staticLoader, $real, 1); - file_put_contents("{$path}/autoload_real.php", $real); +PHP; + file_put_contents("{$path}/VipComposerAutoloader.php", $vipComposerAutoloader); } } diff --git a/src/Utils/ArchiveDownloader.php b/src/Utils/ArchiveDownloader.php index 3227f30..932a3f2 100644 --- a/src/Utils/ArchiveDownloader.php +++ b/src/Utils/ArchiveDownloader.php @@ -82,6 +82,7 @@ public static function forV1( /** * @noinspection PhpParamsInspection * @psalm-suppress PossiblyFalseArgument + * @psalm-suppress InvalidArgument */ ($downloader instanceof FileDownloader) ? $downloader->download($package, $path, false) @@ -115,7 +116,7 @@ private function __construct( public function download(PackageInterface $package, string $path): bool { try { - $tempDir = dirname($path) . '/.tmp' . substr(md5(uniqid($path, true)), 0, 8); + $tempDir = dirname($path) . '/.tmp' . (string)substr(md5(uniqid($path, true)), 0, 8); $this->filesystem->ensureDirectoryExists($tempDir); ($this->downloadCallback)($package, $tempDir); $this->filesystem->ensureDirectoryExists($path); diff --git a/src/Utils/HttpClient.php b/src/Utils/HttpClient.php index 4bd9c25..29ff15d 100644 --- a/src/Utils/HttpClient.php +++ b/src/Utils/HttpClient.php @@ -5,14 +5,12 @@ namespace Inpsyde\VipComposer\Utils; use Composer\Composer; -use Composer\Util\Http\Response; use Composer\Util\HttpDownloader; use Composer\Util\RemoteFilesystem; use Inpsyde\VipComposer\Io; class HttpClient { - /** * @var Io */ diff --git a/src/Utils/InstalledPackages.php b/src/Utils/InstalledPackages.php index 2d31c4f..46b7d3d 100644 --- a/src/Utils/InstalledPackages.php +++ b/src/Utils/InstalledPackages.php @@ -120,7 +120,7 @@ private function parse(): array return $cache; } - $lock = (array)($locker->getLockData() ?: []); + $lock = $locker->getLockData(); $loader = new ArrayLoader(null, true); $cache = []; diff --git a/src/Utils/WpPluginFileFinder.php b/src/Utils/WpPluginFileFinder.php index ffca4ee..a60b6a8 100644 --- a/src/Utils/WpPluginFileFinder.php +++ b/src/Utils/WpPluginFileFinder.php @@ -18,7 +18,6 @@ class WpPluginFileFinder { - /** * @var Installer */