mirror of
https://github.com/php/pie.git
synced 2026-03-23 23:12:17 +01:00
Added docker-php-ext-enable INI method
This commit is contained in:
@@ -77,6 +77,7 @@ final class Container
|
||||
static function (ContainerInterface $container): Ini\SetupIniApproach {
|
||||
return new Ini\PickBestSetupIniApproach([
|
||||
$container->get(Ini\PreCheckExtensionAlreadyLoaded::class),
|
||||
$container->get(Ini\DockerPhpExtEnable::class),
|
||||
$container->get(Ini\StandardAdditionalPhpIniDirectory::class),
|
||||
$container->get(Ini\StandardSinglePhpIni::class),
|
||||
]);
|
||||
|
||||
89
src/Installing/Ini/DockerPhpExtEnable.php
Normal file
89
src/Installing/Ini/DockerPhpExtEnable.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
4
test/assets/docker-php-ext-enable/bad
Executable file
4
test/assets/docker-php-ext-enable/bad
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "something bad happened"
|
||||
exit 1
|
||||
4
test/assets/docker-php-ext-enable/good
Executable file
4
test/assets/docker-php-ext-enable/good
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "hi"
|
||||
exit 0
|
||||
176
test/unit/Installing/Ini/DockerPhpExtEnableTest.php
Normal file
176
test/unit/Installing/Ini/DockerPhpExtEnableTest.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?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\Attributes\RequiresOperatingSystemFamily;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
|
||||
#[RequiresOperatingSystemFamily('Linux')]
|
||||
#[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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user