Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PHP8 support #321

Merged
merged 18 commits into from
Oct 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,23 @@ php:
- 7.2
- 7.3
- 7.4
- nightly

env:
matrix:
- SYMFONY_VERSION="^v3.4.5" PHPUNIT_BRIDGE_VERSION="^v3.4.31" DEPENDENCIES="high"
- SYMFONY_VERSION="^v3.4.5" PHPUNIT_BRIDGE_VERSION="^v3.4.31" DEPENDENCIES="low"
- SYMFONY_VERSION="^v3.4.5" PHPUNIT_BRIDGE_VERSION="^v3.4.40" DEPENDENCIES="high"
- SYMFONY_VERSION="^v3.4.5" PHPUNIT_BRIDGE_VERSION="^v3.4.40" DEPENDENCIES="low"
- SYMFONY_VERSION="~v4.3.0" DEPENDENCIES="high"
- SYMFONY_VERSION="~v4.3.0" DEPENDENCIES="low"
- SYMFONY_VERSION="~v4.4.0" DEPENDENCIES="high"
- SYMFONY_VERSION="~v4.4.0" DEPENDENCIES="low"
- SYMFONY_VERSION="~v5.0.0" PHPUNIT_BRIDGE_VERSION="~v5.0.0" DEPENDENCIES="high"
- SYMFONY_VERSION="~v5.0.0" PHPUNIT_BRIDGE_VERSION="~v5.0.0" DEPENDENCIES="low"
- SYMFONY_VERSION="~v5.0.0" PHPUNIT_BRIDGE_VERSION="~v5.0.8" DEPENDENCIES="high"
- SYMFONY_VERSION="~v5.0.0" PHPUNIT_BRIDGE_VERSION="~v5.0.8" DEPENDENCIES="low"
- SYMFONY_VERSION="~v5.1.0" DEPENDENCIES="high"
- SYMFONY_VERSION="~v5.1.0" DEPENDENCIES="low"
global:
- DEFAULT_COMPOSER_FLAGS="--no-interaction --no-progress --prefer-dist"
- PHPUNIT_BRIDGE_VERSION="~v4.4.0"
- PHPUNIT_BRIDGE_VERSION="~v4.4.8"

jobs:
fast_finish: true
Expand All @@ -44,6 +45,9 @@ before_install:
- composer self-update --2 --preview

install:
- if [[ "$TRAVIS_PHP_VERSION" = 'nightly' ]]; then
composer config platform.php 7.4.99;
fi
- php ./composer-install.php "$SYMFONY_VERSION" "$DEPENDENCIES" "$DEFAULT_COMPOSER_FLAGS" "$PHPUNIT_BRIDGE_VERSION"
- composer show
- if [[ "$STATIC_CHECKS" = '1' ]]; then
Expand All @@ -53,7 +57,6 @@ install:

script:
- if [[ "$STATIC_CHECKS" = '1' ]]; then
composer crunz:analyze;
composer phpstan:check;
composer crunz:analyze && composer phpstan:check;
fi
- vendor/bin/phpunit
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,27 @@ To install it:
```bash
composer require lavary/crunz
```
If the installation is successful, a command-line utility named **crunz** is symlinked to the `vendor/bin` directory of your project.
If the installation is successful, a command-line utility named **crunz** is symlinked to the `vendor/bin` directory of your project.

## PHP 8 issues/limitations

### Trick Composer to allow installation

While Crunz itself is compatible with PHP 8, not all dependencies are, so Composer must be tricked to allow installation

```shell script
composer config platform.php 7.4.99
```

### Do not use primitive return types for Closures

Package https://github.com/opis/closure do not support
PHP 8 on `v3` branch and closures with primitive return types
resolves to root namespace which throws exception on deserialization.

### Still doesn't work

Please add new bug at https://github.com/lavary/crunz/issues/new/choose

## How It Works?

Expand Down
26 changes: 14 additions & 12 deletions composer-install.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
$defaultComposerFlags = $_SERVER['argv'][3] ?? '';
$phpunitBridgeVersion = $_SERVER['argv'][4] ?? $version;
$composerFilePath = __DIR__ . DIRECTORY_SEPARATOR . 'composer.json';
$ignoredPackages = [
'symfony/error-handler',
'symfony/phpunit-bridge',
];
$ignoredPackages = ['symfony/error-handler'];
$changeVersion = static function (
array $packages
) use (
Expand All @@ -32,6 +29,12 @@
continue;
}

if (PHP_MAJOR_VERSION >= 8 && 'phpunit/phpunit' === $packageName) {
$packageVersion = '^9.4.0';

continue;
}

if (false === \mb_strpos($packageName, 'symfony/')) {
continue;
}
Expand Down Expand Up @@ -59,15 +62,14 @@

\file_put_contents(
$composerFilePath,
\json_encode($composerJson)
\json_encode($composerJson, JSON_PRETTY_PRINT)
);

$command = "composer install -o {$defaultComposerFlags}";
echo $command, PHP_EOL;
echo \shell_exec($command);

$preferLowest = '';
if ('high' !== $dependenciesEnv) {
$updateCommand = "composer update -o --prefer-lowest {$defaultComposerFlags}";
echo $updateCommand, PHP_EOL;
echo \shell_exec($updateCommand);
$preferLowest = '--prefer-lowest';
}

$command = \trim("composer update -o {$defaultComposerFlags} {$preferLowest}");
echo $command, PHP_EOL;
echo \shell_exec($command);
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"issues": "http://github.com/lavary/crunz/issues"
},
"require": {
"php": "^7.2",
"php": ">=7.2",
"dragonmantank/cron-expression": "^2.0",
"opis/closure": "^3.5",
"swiftmailer/swiftmailer": "^6.0",
Expand All @@ -43,7 +43,7 @@
"bamarni/composer-bin-plugin": "^1.2",
"phpunit/phpunit": "^8.5.1",
"symfony/error-handler": "^4.4 || ^5.0",
"symfony/phpunit-bridge": "^3.4.31 || ^4.3 || ^5.0"
"symfony/phpunit-bridge": "^3.4.40 || ^4.4.8 || ^5.0.8"
},
"autoload": {
"psr-4": {
Expand Down
17 changes: 17 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,20 @@ services:
volumes:
- .:/var/www/html
- ./docker/php72/php.ini:/usr/local/etc/php/php.ini:ro

php80:
build:
context: ./docker/php80
working_dir: /var/www/html
environment:
CRUNZ_CONTAINER_DEBUG: 1
command: >
sh -c "
chown -R www-data:www-data /var/www/.composer \
&& echo 'Logs from /var/log/php/error.log:' \
&& touch /var/log/php/error.log \
&& tail -f /var/log/php/error.log
"
volumes:
- .:/var/www/html
- ./docker/php80/php.ini:/usr/local/etc/php/php.ini:ro
22 changes: 22 additions & 0 deletions docker/php80/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM php:8.0.0rc1-cli-alpine

RUN apk add --no-cache \
shadow \
su-exec && \
usermod --non-unique --uid 1000 www-data && \
apk del \
shadow && \
docker-php-ext-install -j$(nproc) \
opcache \
sysvsem

RUN mkdir -p \
/var/log/php \
/var/www/.composer \
&& touch /var/log/php/error.log \
&& chown www-data:www-data \
/var/log/php/error.log \
/var/www/.composer

COPY --from=composer:2.0.0-RC1 /usr/bin/composer /usr/bin/composer
ENV COMPOSER_HOME /var/www/.composer
27 changes: 27 additions & 0 deletions docker/php80/php.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
realpath_cache_size = 8192k
realpath_cache_ttl = 6000

expose_php = On
error_log = /var/log/php/error.log
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
report_memleaks = On

memory_limit = 80M

date.timezone = "UTC"

zend.assertions = 1

opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=80
opcache.interned_strings_buffer=5
opcache.max_accelerated_files=3000
opcache.validate_timestamps=1
opcache.revalidate_freq=0
opcache.save_comments=1
opcache.fast_shutdown=1
opcache.huge_code_pages=1
5 changes: 4 additions & 1 deletion tests/EndToEnd/DebugTaskTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ public function test_task_debug(): void
for ($i = 1; $i <= 5; ++$i) {
$key = "_{$i}";
$this->assertArrayHasKey($key, $contentLines);
$this->assertRegExp('/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:00 UTC$/', $contentLines[$key]);
$this->assertMatchesRegularExpression(
'/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:00 UTC$/',
$contentLines[$key]
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/EndToEnd/LoggerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private function assertLogRecord(
): void {
$levelFormatted = \mb_strtoupper($level);

$this->assertRegExp(
$this->assertMatchesRegularExpression(
"/^\[[0-9]{4}(-[0-9]{2}){2} [0-9]{2}(:[0-9]{2}){2}\] crunz\.{$levelFormatted}:.+?({$message})/",
$logRecord
);
Expand Down
2 changes: 1 addition & 1 deletion tests/EndToEnd/WrongTaskTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function everyTaskMustReturnCrunzScheduleInstance(string $crunzCommand):
$normalizedOutput = $this->normalizeProcessErrorOutput($process);

$this->assertFalse($process->isSuccessful());
$this->assertRegExp(
$this->assertMatchesRegularExpression(
"@Task at path '.*WrongTasks\\.php' returned 'array', but 'C( ?)runz\\\\Schedule' instance is required\.@",
$normalizedOutput
);
Expand Down
35 changes: 19 additions & 16 deletions tests/TestCase/EndToEnd/Environment/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,30 +188,33 @@ private function dumpComposerJson(): void

$projectDir = $this->filesystem
->projectRootDirectory();
$content = \json_encode(
[
'repositories' => [
[
'type' => 'path',
'url' => $projectDir,
'options' => [
'symlink' => false,
],
$content = [
'repositories' => [
[
'type' => 'path',
'url' => $projectDir,
'options' => [
'symlink' => false,
],
],
'require' => [
'lavary/crunz' => '*@dev',
],
],
JSON_PRETTY_PRINT
);
'require' => [
'lavary/crunz' => '*@dev',
],
];

if (PHP_MAJOR_VERSION >= 8) {
$content['config']['platform']['php'] = '7.4.99';
}

if (false === $content) {
$contentJson = \json_encode($content, JSON_PRETTY_PRINT);
if (false === $contentJson) {
throw new \RuntimeException("Unable to encode 'composer.json' content.");
}

$this->filesystem
->dumpFile($composerJson->toString(), $content);
->dumpFile($composerJson->toString(), $contentJson)
;
}

private function composerInstall(): void
Expand Down
2 changes: 2 additions & 0 deletions tests/TestCase/EndToEndTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

abstract class EndToEndTestCase extends TestCase
{
use PolyfillAssertTrait;

/** @var FilesystemInterface */
private $filesystem;

Expand Down
25 changes: 25 additions & 0 deletions tests/TestCase/PolyfillAssertTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Crunz\Tests\TestCase;

use PHPUnit\Framework\Constraint\DirectoryExists;
use PHPUnit\Framework\Constraint\LogicalNot;
use PHPUnit\Framework\Constraint\RegularExpression;

trait PolyfillAssertTrait
{
public static function assertMatchesRegularExpression(
string $pattern,
string $string,
string $message = ''
): void {
static::assertThat($string, new RegularExpression($pattern), $message);
}

public static function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
{
static::assertThat($directory, new LogicalNot(new DirectoryExists()), $message);
}
}
2 changes: 2 additions & 0 deletions tests/TestCase/UnitTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

abstract class UnitTestCase extends TestCase
{
use PolyfillAssertTrait;

/** @var ClosureSerializerInterface|null */
private $closureSerializer = null;

Expand Down
6 changes: 3 additions & 3 deletions tests/Unit/Filesystem/FilesystemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
use Crunz\Filesystem\Filesystem;
use Crunz\Path\Path;
use Crunz\Tests\TestCase\TemporaryFile;
use PHPUnit\Framework\TestCase;
use Crunz\Tests\TestCase\UnitTestCase;

final class FilesystemTest extends TestCase
final class FilesystemTest extends UnitTestCase
{
/** @test */
public function cwdIsCorrect(): void
Expand Down Expand Up @@ -57,7 +57,7 @@ public function removeDirectoryRemovesDirectoriesRecursively(): void

$filesystem->removeDirectory($rootPath->toString());

$this->assertDirectoryNotExists($rootPath->toString());
$this->assertDirectoryDoesNotExist($rootPath->toString());
}

/** @test */
Expand Down
13 changes: 10 additions & 3 deletions tests/Unit/HttpClient/StreamHttpClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,17 @@ final class StreamHttpClientTest extends TestCase
/** @test */
public function pingFailWithInvalidAddress(): void
{
$expectedExceptionMessage = 'Ping failed with message: "fopen(http://www.wrong-address.tld): failed to open stream: php_network_getaddresses: getaddrinfo failed:';
if (PHP_MAJOR_VERSION >= 8) {
$expectedExceptionMessage = \str_replace(
'failed to open',
'Failed to open',
$expectedExceptionMessage
);
}

$this->expectException(HttpClientException::class);
$this->expectExceptionMessage(
'Ping failed with message: "fopen(http://www.wrong-address.tld): failed to open stream: php_network_getaddresses: getaddrinfo failed:'
);
$this->expectExceptionMessage($expectedExceptionMessage);

$client = new StreamHttpClient();
$client->ping('http://www.wrong-address.tld');
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/UserInterface/Cli/ClosureRunCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ final class ClosureRunCommandTest extends UnitTestCase
/** @dataProvider closureValueProvider */
public function testReturnValueOfClosureIsOmitted(int $returnValue): void
{
$closure = static function () use ($returnValue): int {
$closure = static function () use ($returnValue) {
return $returnValue;
};
$command = $this->createCommand();
Expand Down
Loading