Skip to content

Commit 7835ea0

Browse files
committed
build: improve transpile script
build: improve v3.5 transpile command
1 parent 7e9f003 commit 7835ea0

File tree

6 files changed

+413
-2
lines changed

6 files changed

+413
-2
lines changed

bin/build-35-to-dir.sh

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,35 @@ cp config/composer-35.json composer.json
2929
rm -rf config
3030
cd -
3131

32+
# Run PHP 7.1 compatibility checks using Docker
33+
echo "Running PHP 7.1 compatibility checks..."
34+
35+
# Run Docker container with PHP 7.1 for compatibility checks
36+
docker run --rm \
37+
-v "$(pwd)/.build/35:/app" \
38+
-w /app \
39+
php:7.1-cli \
40+
bash -c '
41+
set -e
42+
echo "==> Running PHP syntax check on all PHP files..."
43+
find . -name "*.php" -not -path "./vendor/*" -print0 | xargs -0 -n1 php -l > /dev/null
44+
echo "✓ All PHP 7.1 compatibility checks passed!"
45+
' || {
46+
echo "✗ PHP 7.1 compatibility check failed!"
47+
exit 1
48+
}
49+
50+
vendor/bin/phpcs --standard=config/version-35-compatibility.xml \
51+
--runtime-set ignore_warnings_on_exit 1 \
52+
-s \
53+
./.build/35/src/**/*.php ./.build/35/includes/**/*.php
54+
55+
# Clean up temporary config
56+
rm -f ./.build/35/phpcs-compat.xml
57+
3258
rsync -av ./.build/35/includes/ "$destination_dir/includes"
3359
rsync -av ./.build/35/src/ "$destination_dir/src"
3460
rsync -av ./.build/35/tests/ "$destination_dir/tests"
35-
vendor/bin/phpcbf --standard=config/phpcs.xml "$destination_dir/src"
61+
vendor/bin/phpcbf --standard=config/phpcs.xml "$destination_dir/src" || true
62+
63+
rm -rf .build

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
"phpstan/phpstan-symfony": "^1.3",
5050
"squizlabs/php_codesniffer": "^3.7",
5151
"rector/rector": "0.19.8",
52-
"automattic/vipwpcs": "^3.0"
52+
"automattic/vipwpcs": "^3.0",
53+
"phpcompatibility/php-compatibility": "^10.0.0@dev"
5354
},
5455
"autoload": {
5556
"psr-4": {

config/rector-35.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
declare(strict_types=1);
44

5+
use lucatume\Rector\DowngradePhpOsFamily;
56
use lucatume\Rector\RemoveTypeHinting;
7+
use lucatume\Rector\SerializableThrowableCompatibilityRector;
68
use Rector\Config\RectorConfig;
79
use Rector\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector;
810
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
@@ -46,6 +48,12 @@
4648
$rectorConfig->sets([DowngradeLevelSetList::DOWN_TO_PHP_71]);
4749
$rectorConfig->skip([DowngradeParameterTypeWideningRector::class]);
4850

51+
// Downgrade PHP_OS_FAMILY (PHP 7.2+) to PHP_OS for PHP 7.1 compatibility
52+
$rectorConfig->rule(DowngradePhpOsFamily::class);
53+
54+
// Make SerializableThrowable compatible with PHP <7.3 and downgrade str_contains()
55+
$rectorConfig->rule(SerializableThrowableCompatibilityRector::class);
56+
4957
$rectorConfig->ruleWithConfiguration(RemoveTypeHinting::class, [
5058
'lucatume\WPBrowser\Module\WPDb' => [
5159
'_cleanup' => [
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
namespace lucatume\Rector;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Expr\BinaryOp\Identical;
7+
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
8+
use PhpParser\Node\Expr\ConstFetch;
9+
use PhpParser\Node\Expr\FuncCall;
10+
use PhpParser\Node\Name;
11+
use PhpParser\Node\Scalar\String_;
12+
use Rector\Rector\AbstractRector;
13+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
14+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
15+
16+
/**
17+
* Rector rule to downgrade PHP_OS_FAMILY (PHP 7.2+) to PHP_OS (PHP 7.1).
18+
*
19+
* This rule:
20+
* 1. Replaces `PHP_OS_FAMILY === 'Windows'` with `strtolower(substr(PHP_OS, 0, 3)) === 'win'`
21+
* 2. Replaces `PHP_OS_FAMILY !== 'Windows'` with `strtolower(substr(PHP_OS, 0, 3)) !== 'win'`
22+
* 3. Replaces other uses of `PHP_OS_FAMILY` with `PHP_OS`
23+
*/
24+
class DowngradePhpOsFamily extends AbstractRector
25+
{
26+
public function getRuleDefinition(): RuleDefinition
27+
{
28+
return new RuleDefinition(
29+
'Downgrade PHP_OS_FAMILY to PHP_OS for PHP 7.1 compatibility',
30+
[
31+
new CodeSample(
32+
'if (PHP_OS_FAMILY === \'Windows\') {}',
33+
'if (strtolower(substr(PHP_OS, 0, 3)) === \'win\') {}'
34+
),
35+
new CodeSample(
36+
'if (PHP_OS_FAMILY !== \'Windows\') {}',
37+
'if (strtolower(substr(PHP_OS, 0, 3)) !== \'win\') {}'
38+
),
39+
new CodeSample(
40+
'substr(PHP_OS_FAMILY, 0, 3)',
41+
'substr(PHP_OS, 0, 3)'
42+
)
43+
]
44+
);
45+
}
46+
47+
public function getNodeTypes(): array
48+
{
49+
return [Identical::class, NotIdentical::class, ConstFetch::class];
50+
}
51+
52+
/**
53+
* @param Identical|NotIdentical|ConstFetch $node
54+
*/
55+
public function refactor(Node $node): ?Node
56+
{
57+
if ($node instanceof Identical || $node instanceof NotIdentical) {
58+
return $this->refactorComparison($node);
59+
}
60+
61+
if ($node instanceof ConstFetch) {
62+
return $this->refactorConstFetch($node);
63+
}
64+
65+
return null;
66+
}
67+
68+
/**
69+
* Refactor comparison operations (=== or !==) involving PHP_OS_FAMILY and 'Windows'
70+
*/
71+
private function refactorComparison(Identical|NotIdentical $node): ?Node
72+
{
73+
// Check if one side is PHP_OS_FAMILY constant and the other is 'Windows'
74+
$isPhpOsFamily = false;
75+
$isWindowsString = false;
76+
77+
if ($node->left instanceof ConstFetch && $this->isName($node->left, 'PHP_OS_FAMILY')) {
78+
$isPhpOsFamily = true;
79+
if ($node->right instanceof String_ && $node->right->value === 'Windows') {
80+
$isWindowsString = true;
81+
}
82+
} elseif ($node->right instanceof ConstFetch && $this->isName($node->right, 'PHP_OS_FAMILY')) {
83+
$isPhpOsFamily = true;
84+
if ($node->left instanceof String_ && $node->left->value === 'Windows') {
85+
$isWindowsString = true;
86+
}
87+
}
88+
89+
if (!$isPhpOsFamily || !$isWindowsString) {
90+
return null;
91+
}
92+
93+
// Build: strtolower(substr(PHP_OS, 0, 3))
94+
$phpOsConst = new ConstFetch(new Name('PHP_OS'));
95+
$substrCall = new FuncCall(
96+
new Name('substr'),
97+
[
98+
new Node\Arg($phpOsConst),
99+
new Node\Arg(new Node\Scalar\LNumber(0)),
100+
new Node\Arg(new Node\Scalar\LNumber(3))
101+
]
102+
);
103+
$strtolowerCall = new FuncCall(
104+
new Name('strtolower'),
105+
[new Node\Arg($substrCall)]
106+
);
107+
108+
// Create the 'win' string
109+
$winString = new String_('win');
110+
111+
// Create the comparison
112+
if ($node instanceof Identical) {
113+
return new Identical($strtolowerCall, $winString);
114+
} else {
115+
return new NotIdentical($strtolowerCall, $winString);
116+
}
117+
}
118+
119+
/**
120+
* Refactor direct PHP_OS_FAMILY constant fetch to PHP_OS
121+
*/
122+
private function refactorConstFetch(ConstFetch $node): ?Node
123+
{
124+
if (!$this->isName($node, 'PHP_OS_FAMILY')) {
125+
return null;
126+
}
127+
128+
// Don't replace if this is part of a comparison we already handled
129+
$parent = $node->getAttribute('parent');
130+
if ($parent instanceof Identical || $parent instanceof NotIdentical) {
131+
// Check if the comparison is with 'Windows'
132+
if ($parent->left instanceof String_ && $parent->left->value === 'Windows') {
133+
return null; // Already handled by refactorComparison
134+
}
135+
if ($parent->right instanceof String_ && $parent->right->value === 'Windows') {
136+
return null; // Already handled by refactorComparison
137+
}
138+
}
139+
140+
// Replace PHP_OS_FAMILY with PHP_OS
141+
return new ConstFetch(new Name('PHP_OS'));
142+
}
143+
}

0 commit comments

Comments
 (0)