[Scoper] Using different scoper.php for php 7.0 (#6295)

* [Scoper] Using different scoper.php for php 7.0

* revert

* revert

* eol
This commit is contained in:
Abdul Malik Ikhsan 2021-05-03 01:19:33 +07:00 committed by GitHub
parent 10705059a3
commit e1c87b5900
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 260 additions and 26 deletions

View File

@ -5,7 +5,7 @@ name: Build Scoped Rector PHP 7.0
on:
push:
branches:
- main
- never
tags:
- '*'
@ -44,7 +44,7 @@ jobs:
- run: sh build/downgrade-rector-php70.sh rector-build-php70
# 3. prefix classes
- run: sh build/build-rector-scoped.sh rector-build-php70 rector-prefixed-downgraded-php70
- run: sh build/build-rector-scoped-php70.sh rector-build-php70 rector-prefixed-downgraded-php70
# 4. lint the code for PHP 7.0 - this must happen here, as setup-php allows only one PHP version switch: https://github.com/shivammathur/setup-php/issues/434
-

View File

@ -0,0 +1,59 @@
#!/usr/bin/env bash
# see https://stackoverflow.com/questions/66644233/how-to-propagate-colors-from-bash-script-to-github-action?noredirect=1#comment117811853_66644233
export TERM=xterm-color
# show errors
set -e
# script fails if trying to access to an undefined variable
set -u
# functions
note()
{
MESSAGE=$1;
printf "\n";
echo "[NOTE] $MESSAGE";
printf "\n";
}
# configure here
BUILD_DIRECTORY=$1
RESULT_DIRECTORY=$2
# ---------------------------
note "Starts"
# this will remove dependency on dev packages that are imported in phpstan.neon
rm -f "$BUILD_DIRECTORY/phpstan-for-rector.neon"
# 2. scope it
note "Running scoper to $RESULT_DIRECTORY"
wget https://github.com/humbug/php-scoper/releases/download/0.14.0/php-scoper.phar -N --no-verbose
# Work around possible PHP memory limits
php -d memory_limit=-1 php-scoper.phar add-prefix preload.php bin config src packages rules vendor composer.json --output-dir "../$RESULT_DIRECTORY" --config scoper-php70.php --force --ansi --working-dir "$BUILD_DIRECTORY"
# note "Dumping Composer Autoload"
composer dump-autoload --working-dir "$RESULT_DIRECTORY" --ansi --classmap-authoritative --no-dev
php "$BUILD_DIRECTORY/build/build-preload.php" $RESULT_DIRECTORY
rm -rf "$BUILD_DIRECTORY"
# copy metafiles needed for release
note "Copy metafiles like composer.json, .github etc to repository"
rm -f "$RESULT_DIRECTORY/composer.json"
# make bin/rector runnable without "php"
chmod 777 "$RESULT_DIRECTORY/bin/rector"
chmod 777 "$RESULT_DIRECTORY/bin/rector.php"
note "Finished"

199
scoper-php70.php Normal file
View File

@ -0,0 +1,199 @@
<?php
declare(strict_types=1);
use Nette\Utils\DateTime;
use Nette\Utils\Strings;
use Rector\Compiler\PhpScoper\StaticEasyPrefixer;
use Rector\Compiler\Unprefixer;
use Rector\Compiler\ValueObject\ScoperOption;
require_once __DIR__ . '/vendor/autoload.php';
// [BEWARE] this path is relative to the root and location of this file
$filePathsToRemoveNamespace = [
// @see https://github.com/rectorphp/rector/issues/2852#issuecomment-586315588
'vendor/symfony/deprecation-contracts/function.php',
// it would make polyfill function work only with namespace = brokes
'vendor/symfony/polyfill-ctype/bootstrap.php',
'vendor/symfony/polyfill-intl-normalizer/bootstrap.php',
'vendor/symfony/polyfill-intl-grapheme/bootstrap.php',
'vendor/symfony/polyfill-mbstring/bootstrap.php',
'vendor/symfony/polyfill-php80/bootstrap.php',
'vendor/symfony/polyfill-php74/bootstrap.php',
'vendor/symfony/polyfill-php73/bootstrap.php',
'vendor/symfony/polyfill-php72/bootstrap.php',
'vendor/symfony/polyfill-uuid/bootstrap.php',
];
// remove phpstan, because it is already prefixed in its own scope
$dateTime = DateTime::from('now');
$timestamp = $dateTime->format('Ymd');
// see https://github.com/humbug/php-scoper
return [
ScoperOption::PREFIX => 'RectorPrefix' . $timestamp,
ScoperOption::WHITELIST => StaticEasyPrefixer::getExcludedNamespacesAndClasses(),
// ScoperOption::FILES_WHITELIST => [
// // composer versions
// '../../vendor/composer/InstalledVersions.php'
// ],
ScoperOption::PATCHERS => [
// [BEWARE] $filePath is absolute!
// fixes https://github.com/rectorphp/rector-prefixed/runs/2143717534
function (string $filePath, string $prefix, string $content) use ($filePathsToRemoveNamespace): string {
// @see https://regex101.com/r/0jaVB1/1
$prefixedNamespacePattern = '#^namespace (.*?);$#m';
foreach ($filePathsToRemoveNamespace as $filePathToRemoveNamespace) {
if (Strings::endsWith($filePath, $filePathToRemoveNamespace)) {
return Strings::replace($content, $prefixedNamespacePattern, '');
}
}
return $content;
},
function (string $filePath, string $prefix, string $content): string {
if (! Strings::endsWith($filePath, 'vendor/composer/package-versions-deprecated/src/PackageVersions/Versions.php')) {
return $content;
}
// see https://regex101.com/r/v8zRMm/1
return Strings::replace(
$content, '
#' . $prefix . '\\\\Composer\\\\InstalledVersions#',
'Composer\InstalledVersions'
);
},
function (string $filePath, string $prefix, string $content): string {
if (! Strings::contains($content, $prefix . '\Composer\Plugin')) {
return $content;
}
return Strings::replace(
$content, '
#' . $prefix . '\\\\Composer\\\\Plugin#',
'Composer\Plugin'
);
},
function (string $filePath, string $prefix, string $content): string {
if (! Strings::contains($content, $prefix . '\Composer\EventDispatcher')) {
return $content;
}
return Strings::replace(
$content, '
#' . $prefix . '\\\\Composer\\\\EventDispatcher#',
'Composer\EventDispatcher'
);
},
// get version for prefixed version
function (string $filePath, string $prefix, string $content): string {
if (! Strings::endsWith($filePath, 'src/Configuration/Configuration.php')) {
return $content;
}
// @see https://regex101.com/r/gLefQk/1
return Strings::replace(
$content, '#\(\'rector\/rector\'\)#',
"('rector/rector-prefixed')"
);
},
// un-prefix composer plugin
function (string $filePath, string $prefix, string $content): string {
if (! Strings::endsWith($filePath, 'vendor/rector/rector-installer/src/Plugin.php')) {
return $content;
}
// see https://regex101.com/r/v8zRMm/1
return Strings::replace($content, '#' . $prefix . '\\\\Composer\\\\#', 'Composer\\');
},
// fixes https://github.com/rectorphp/rector/issues/6007
function (string $filePath, string $prefix, string $content): string {
if (! Strings::contains($filePath, 'vendor/')) {
return $content;
}
// @see https://regex101.com/r/lBV8IO/2
$fqcnReservedPattern = sprintf('#(\\\\)?%s\\\\(parent|self|static)#m', $prefix);
$matches = Strings::matchAll($content, $fqcnReservedPattern);
if (! $matches) {
return $content;
}
foreach ($matches as $match) {
$content = str_replace($match[0], $match[2], $content);
}
return $content;
},
function (string $filePath, string $prefix, string $content): string {
if (
! Strings::endsWith($filePath, 'packages/Testing/PHPUnit/AbstractTestCase.php')
&& ! Strings::endsWith($filePath, 'packages/Testing/PHPUnit/AbstractRectorTestCase.php')
) {
return $content;
}
// un-prefix
return Strings::replace(
$content,
'#' . $prefix . '\\\\PHPUnit\\\\Framework\\\\TestCase#',
'PHPUnit\Framework\TestCase'
);
},
// fixes https://github.com/rectorphp/rector/issues/6010 + test case prefix
function (string $filePath, string $prefix, string $content): string {
// @see https://regex101.com/r/bA1nQa/1
if (! Strings::match($filePath, '#vendor/symfony/polyfill-php\d{2}/Resources/stubs#')) {
return $content;
}
// @see https://regex101.com/r/x5Ukrx/1
$namespace = sprintf('#namespace %s;#m', $prefix);
return Strings::replace($content, $namespace);
},
// unprefix string classes, as they're string on purpose - they have to be checked in original form, not prefixed
function (string $filePath, string $prefix, string $content): string {
// skip vendor, expect rector packages
if (Strings::contains($filePath, 'vendor/') && ! Strings::contains($filePath, 'vendor/rector')) {
return $content;
}
// skip bin/rector.php for composer autoload class
if (Strings::endsWith($filePath, 'bin/rector.php')) {
return $content;
}
return Unprefixer::unprefixQuoted($content, $prefix);
},
// scoper missed PSR-4 autodiscovery in Symfony
function (string $filePath, string $prefix, string $content): string {
// scoper missed PSR-4 autodiscovery in Symfony
if (! Strings::endsWith($filePath, 'config.php') && ! Strings::endsWith($filePath, 'services.php')) {
return $content;
}
// skip "Rector\\" namespace
if (Strings::contains($content, '$services->load(\'Rector')) {
return $content;
}
return Strings::replace($content, '#services\->load\(\'#', 'services->load(\'' . $prefix . '\\');
},
],
];

View File

@ -69,30 +69,6 @@ return [
);
},
function (string $filePath, string $prefix, string $content): string {
if (! Strings::contains($content, $prefix . '\Composer\Plugin')) {
return $content;
}
return Strings::replace(
$content, '
#' . $prefix . '\\\\Composer\\\\Plugin#',
'Composer\Plugin'
);
},
function (string $filePath, string $prefix, string $content): string {
if (! Strings::contains($content, $prefix . '\Composer\EventDispatcher')) {
return $content;
}
return Strings::replace(
$content, '
#' . $prefix . '\\\\Composer\\\\EventDispatcher#',
'Composer\EventDispatcher'
);
},
// get version for prefixed version
function (string $filePath, string $prefix, string $content): string {
if (! Strings::endsWith($filePath, 'src/Configuration/Configuration.php')) {