-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added docker-php-ext-enable INI method
- Loading branch information
Showing
5 changed files
with
272 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Php\Pie\Installing\Ini; | ||
|
||
use Php\Pie\BinaryFile; | ||
use Php\Pie\Downloading\DownloadedPackage; | ||
use Php\Pie\Platform\TargetPhp\Exception\ExtensionIsNotLoaded; | ||
use Php\Pie\Platform\TargetPlatform; | ||
use Php\Pie\Util\Process; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\Process\Exception\ProcessFailedException; | ||
|
||
use function sprintf; | ||
|
||
/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */ | ||
final class DockerPhpExtEnable implements SetupIniApproach | ||
{ | ||
private const DOCKER_PHP_EXT_ENABLE = 'docker-php-ext-enable'; | ||
|
||
public function __construct(private readonly string $dockerPhpExtEnableName = self::DOCKER_PHP_EXT_ENABLE) | ||
{ | ||
} | ||
|
||
public function canBeUsed(TargetPlatform $targetPlatform): bool | ||
{ | ||
return $this->dockerPhpExtEnablePath() !== null; | ||
} | ||
|
||
public function setup( | ||
TargetPlatform $targetPlatform, | ||
DownloadedPackage $downloadedPackage, | ||
BinaryFile $binaryFile, | ||
OutputInterface $output, | ||
): bool { | ||
$dockerPhpExtEnable = $this->dockerPhpExtEnablePath(); | ||
|
||
if ($dockerPhpExtEnable === null) { | ||
return false; | ||
} | ||
|
||
try { | ||
$enableOutput = Process::run([$dockerPhpExtEnable, $downloadedPackage->package->extensionName->name()]); | ||
} catch (ProcessFailedException $processFailed) { | ||
$output->writeln( | ||
sprintf( | ||
'Could not enable extension %s using %s. Exception was: %s', | ||
$downloadedPackage->package->extensionName->name(), | ||
$this->dockerPhpExtEnableName, | ||
$processFailed->getMessage(), | ||
), | ||
OutputInterface::VERBOSITY_VERBOSE, | ||
); | ||
|
||
return false; | ||
} | ||
|
||
try { | ||
$targetPlatform->phpBinaryPath->assertExtensionIsLoadedInRuntime( | ||
$downloadedPackage->package->extensionName, | ||
$output, | ||
); | ||
|
||
return true; | ||
} catch (ExtensionIsNotLoaded) { | ||
$output->writeln( | ||
sprintf( | ||
'Asserting that extension %s was enabled using %s failed. Output was: %s', | ||
$downloadedPackage->package->extensionName->name(), | ||
$this->dockerPhpExtEnableName, | ||
$enableOutput !== '' ? $enableOutput : '(empty)', | ||
), | ||
OutputInterface::VERBOSITY_VERBOSE, | ||
); | ||
|
||
return false; | ||
} | ||
} | ||
|
||
private function dockerPhpExtEnablePath(): string|null | ||
{ | ||
try { | ||
return Process::run(['which', $this->dockerPhpExtEnableName]); | ||
} catch (ProcessFailedException) { | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/usr/bin/env bash | ||
|
||
echo "something bad happened" | ||
exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/usr/bin/env bash | ||
|
||
echo "hi" | ||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Php\PieUnitTest\Installing\Ini; | ||
|
||
use Composer\Package\CompletePackageInterface; | ||
use Php\Pie\BinaryFile; | ||
use Php\Pie\DependencyResolver\Package; | ||
use Php\Pie\Downloading\DownloadedPackage; | ||
use Php\Pie\ExtensionName; | ||
use Php\Pie\ExtensionType; | ||
use Php\Pie\Installing\Ini\DockerPhpExtEnable; | ||
use Php\Pie\Platform\Architecture; | ||
use Php\Pie\Platform\OperatingSystem; | ||
use Php\Pie\Platform\OperatingSystemFamily; | ||
use Php\Pie\Platform\TargetPhp\Exception\ExtensionIsNotLoaded; | ||
use Php\Pie\Platform\TargetPhp\PhpBinaryPath; | ||
use Php\Pie\Platform\TargetPlatform; | ||
use Php\Pie\Platform\ThreadSafetyMode; | ||
use PHPUnit\Framework\Attributes\CoversClass; | ||
use PHPUnit\Framework\MockObject\MockObject; | ||
use PHPUnit\Framework\TestCase; | ||
use Symfony\Component\Console\Output\BufferedOutput; | ||
|
||
#[CoversClass(DockerPhpExtEnable::class)] | ||
final class DockerPhpExtEnableTest extends TestCase | ||
{ | ||
private const NON_EXISTENT_DOCKER_PHP_EXT_ENABLE = 'something-that-should-not-be-in-path'; | ||
private const GOOD_DOCKER_PHP_EXT_ENABLE = __DIR__ . '/../../../assets/docker-php-ext-enable/good'; | ||
private const BAD_DOCKER_PHP_EXT_ENABLE = __DIR__ . '/../../../assets/docker-php-ext-enable/bad'; | ||
|
||
private BufferedOutput $output; | ||
private PhpBinaryPath&MockObject $mockPhpBinary; | ||
private TargetPlatform $targetPlatform; | ||
private DownloadedPackage $downloadedPackage; | ||
private BinaryFile $binaryFile; | ||
|
||
public function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
$this->output = new BufferedOutput(BufferedOutput::VERBOSITY_VERBOSE); | ||
|
||
$this->mockPhpBinary = $this->createMock(PhpBinaryPath::class); | ||
/** | ||
* @psalm-suppress PossiblyNullFunctionCall | ||
* @psalm-suppress UndefinedThisPropertyAssignment | ||
*/ | ||
(fn () => $this->phpBinaryPath = '/path/to/php') | ||
->bindTo($this->mockPhpBinary, PhpBinaryPath::class)(); | ||
|
||
$this->targetPlatform = new TargetPlatform( | ||
OperatingSystem::NonWindows, | ||
OperatingSystemFamily::Linux, | ||
$this->mockPhpBinary, | ||
Architecture::x86_64, | ||
ThreadSafetyMode::ThreadSafe, | ||
1, | ||
null, | ||
); | ||
|
||
$this->downloadedPackage = DownloadedPackage::fromPackageAndExtractedPath( | ||
new Package( | ||
$this->createMock(CompletePackageInterface::class), | ||
ExtensionType::PhpModule, | ||
ExtensionName::normaliseFromString('foobar'), | ||
'foo/bar', | ||
'1.2.3', | ||
null, | ||
[], | ||
true, | ||
true, | ||
null, | ||
null, | ||
null, | ||
99, | ||
), | ||
'/path/to/extracted/source', | ||
); | ||
|
||
$this->binaryFile = new BinaryFile('/path/to/compiled/extension.so', 'fake checksum'); | ||
} | ||
|
||
public function testCannotBeUsedWhenDockerPhpExtEnableIsNotInPath(): void | ||
{ | ||
self::assertFalse( | ||
(new DockerPhpExtEnable(self::NON_EXISTENT_DOCKER_PHP_EXT_ENABLE)) | ||
->canBeUsed($this->targetPlatform), | ||
); | ||
} | ||
|
||
public function testCanBeUsedWhenDockerPhpExtEnableIsInPath(): void | ||
{ | ||
self::assertTrue( | ||
(new DockerPhpExtEnable(self::GOOD_DOCKER_PHP_EXT_ENABLE)) | ||
->canBeUsed($this->targetPlatform), | ||
); | ||
} | ||
|
||
public function testSetupReturnsFalseWhenWhenDockerPhpExtEnableIsNotInPath(): void | ||
{ | ||
$this->mockPhpBinary | ||
->expects(self::never()) | ||
->method('assertExtensionIsLoadedInRuntime'); | ||
|
||
self::assertFalse( | ||
(new DockerPhpExtEnable(self::NON_EXISTENT_DOCKER_PHP_EXT_ENABLE)) | ||
->setup( | ||
$this->targetPlatform, | ||
$this->downloadedPackage, | ||
$this->binaryFile, | ||
$this->output, | ||
), | ||
); | ||
} | ||
|
||
public function testReturnsTrueWhenDockerPhpExtEnableSuccessfullyEnablesExtension(): void | ||
{ | ||
$this->mockPhpBinary | ||
->expects(self::once()) | ||
->method('assertExtensionIsLoadedInRuntime') | ||
->with($this->downloadedPackage->package->extensionName, $this->output); | ||
|
||
self::assertTrue( | ||
(new DockerPhpExtEnable(self::GOOD_DOCKER_PHP_EXT_ENABLE)) | ||
->setup( | ||
$this->targetPlatform, | ||
$this->downloadedPackage, | ||
$this->binaryFile, | ||
$this->output, | ||
), | ||
); | ||
} | ||
|
||
public function testReturnsFalseWhenDockerPhpExtEnableFailsToBeRun(): void | ||
{ | ||
$this->mockPhpBinary | ||
->expects(self::never()) | ||
->method('assertExtensionIsLoadedInRuntime'); | ||
|
||
self::assertFalse( | ||
(new DockerPhpExtEnable(self::BAD_DOCKER_PHP_EXT_ENABLE)) | ||
->setup( | ||
$this->targetPlatform, | ||
$this->downloadedPackage, | ||
$this->binaryFile, | ||
$this->output, | ||
), | ||
); | ||
} | ||
|
||
public function testReturnsFalseWhenDockerPhpExtEnableFailsToAssertExtensionWasEnabled(): void | ||
{ | ||
$this->mockPhpBinary | ||
->expects(self::once()) | ||
->method('assertExtensionIsLoadedInRuntime') | ||
->with($this->downloadedPackage->package->extensionName, $this->output) | ||
->willThrowException(ExtensionIsNotLoaded::fromExpectedExtension( | ||
$this->mockPhpBinary, | ||
$this->downloadedPackage->package->extensionName, | ||
)); | ||
|
||
self::assertFalse( | ||
(new DockerPhpExtEnable(self::GOOD_DOCKER_PHP_EXT_ENABLE)) | ||
->setup( | ||
$this->targetPlatform, | ||
$this->downloadedPackage, | ||
$this->binaryFile, | ||
$this->output, | ||
), | ||
); | ||
} | ||
} |