Skip to content
Open
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
11 changes: 10 additions & 1 deletion src/Installing/UnixInstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Php\Pie\Installing;

use Composer\IO\IOInterface;
use Composer\Util\Platform as ComposerPlatform;
use Php\Pie\Downloading\DownloadedPackage;
use Php\Pie\Downloading\DownloadUrlMethod;
use Php\Pie\File\BinaryFile;
Expand Down Expand Up @@ -37,7 +38,14 @@ public function __invoke(
IOInterface $io,
bool $attemptToSetupIniFile,
): BinaryFile {
$targetExtensionPath = $targetPlatform->phpBinaryPath->extensionPath();
$env = [];
$installRoot = (string) ComposerPlatform::getEnv('INSTALL_ROOT');
if ($installRoot !== '') {
$io->write(sprintf('<info>Using INSTALL_ROOT=%s</info>', $installRoot));
$env['INSTALL_ROOT'] = $installRoot;
}

$targetExtensionPath = $targetPlatform->phpBinaryPath->extensionPath($installRoot);

$sharedObjectName = $downloadedPackage->package->extensionName()->name() . '.so';
$expectedSharedObjectLocation = sprintf(
Expand Down Expand Up @@ -93,6 +101,7 @@ public function __invoke(
$installCommand,
$downloadedPackage->extractedSourcePath,
self::MAKE_INSTALL_TIMEOUT_SECS,
env: $env,
);

$io->write($makeInstallOutput, verbosity: IOInterface::VERY_VERBOSE);
Expand Down
8 changes: 7 additions & 1 deletion src/Platform/TargetPhp/PhpBinaryPath.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
use function in_array;
use function is_dir;
use function is_executable;
use function ltrim;
use function mkdir;
use function preg_match;
use function preg_replace;
use function rtrim;
use function sprintf;
use function strtolower;
use function trim;
Expand Down Expand Up @@ -103,7 +105,7 @@ public function debugMode(): DebugBuild
}

/** @return non-empty-string */
public function extensionPath(): string
public function extensionPath(string|null $prefixInstallRoot = null): string
{
$phpinfo = $this->phpinfo();

Expand All @@ -116,6 +118,10 @@ public function extensionPath(): string
$extensionPath = trim($matches[1]);
assert($extensionPath !== '');

if (self::operatingSystem() !== OperatingSystem::Windows && $prefixInstallRoot !== null && $prefixInstallRoot !== '') {
$extensionPath = rtrim($prefixInstallRoot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ltrim($extensionPath, DIRECTORY_SEPARATOR);
}

if (file_exists($extensionPath) && is_dir($extensionPath)) {
return $extensionPath;
}
Expand Down
4 changes: 3 additions & 1 deletion src/Util/Process.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private function __construct()
*
* @param list<string> $command
* @param callable(SymfonyProcess::ERR|SymfonyProcess::OUT, string): void|null $outputCallback
* @param array<string, scalar>|null $env
*
* @throws ProcessFailedException
*/
Expand All @@ -38,8 +39,9 @@ public static function run(
string|null $workingDirectory = null,
int|null $timeout = self::NO_TIMEOUT,
callable|null $outputCallback = null,
array|null $env = null,
): string {
return trim((new SymfonyProcess($command, $workingDirectory, timeout: $timeout))
return trim((new SymfonyProcess($command, $workingDirectory, $env, timeout: $timeout))
->mustRun($outputCallback)
->getOutput());
}
Expand Down
24 changes: 20 additions & 4 deletions test/integration/Installing/UnixInstallTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Composer\IO\BufferIO;
use Composer\Package\CompletePackageInterface;
use Composer\Util\Filesystem;
use Composer\Util\Platform;
use Php\Pie\Building\UnixBuild;
use Php\Pie\DependencyResolver\Package;
Expand All @@ -30,11 +31,13 @@
use function array_unshift;
use function assert;
use function file_exists;
use function getenv;
use function is_executable;
use function is_writable;
use function mkdir;
use function putenv;
use function rename;
use function unlink;
use function uniqid;

use const DIRECTORY_SEPARATOR;

Expand Down Expand Up @@ -79,14 +82,18 @@ public static function phpPathProvider(): array
#[DataProvider('phpPathProvider')]
public function testUnixInstallCanInstallExtensionBuiltFromSource(string $phpConfig): void
{
$installRoot = '/tmp/' . uniqid('pie-test-install-root-', true);
$oldInstallRoot = getenv('INSTALL_ROOT');
putenv('INSTALL_ROOT=' . $installRoot);

assert($phpConfig !== '');
if (Platform::isWindows()) {
self::markTestSkipped('Unix build test cannot be run on Windows');
}

$output = new BufferIO();
$targetPlatform = TargetPlatform::fromPhpBinaryPath(PhpBinaryPath::fromPhpConfigExecutable($phpConfig), null);
$extensionPath = $targetPlatform->phpBinaryPath->extensionPath();
$extensionPath = $targetPlatform->phpBinaryPath->extensionPath($installRoot);

$composerPackage = $this->createMock(CompletePackageInterface::class);
$composerPackage
Expand Down Expand Up @@ -136,19 +143,26 @@ public function testUnixInstallCanInstallExtensionBuiltFromSource(string $phpCon
(new Process($rmCommand))->mustRun();
(new Process(['make', 'clean'], $downloadedPackage->extractedSourcePath))->mustRun();
(new Process(['phpize', '--clean'], $downloadedPackage->extractedSourcePath))->mustRun();
(new Filesystem())->remove($installRoot);
putenv('INSTALL_ROOT=' . $oldInstallRoot);
}

#[DataProvider('phpPathProvider')]
public function testUnixInstallCanInstallPrePackagedBinary(string $phpConfig): void
{
$installRoot = '/tmp/' . uniqid('pie-test-install-root-', true);
$oldInstallRoot = getenv('INSTALL_ROOT');
putenv('INSTALL_ROOT=' . $installRoot);

assert($phpConfig !== '');
if (Platform::isWindows()) {
self::markTestSkipped('Unix build test cannot be run on Windows');
}

$output = new BufferIO();
$targetPlatform = TargetPlatform::fromPhpBinaryPath(PhpBinaryPath::fromPhpConfigExecutable($phpConfig), null);
$extensionPath = $targetPlatform->phpBinaryPath->extensionPath();
$extensionPath = $installRoot . $targetPlatform->phpBinaryPath->extensionPath();
mkdir($extensionPath, 0777, true);

// First build it (otherwise the test assets would need to have a binary for every test platform...)
$composerPackage = $this->createMock(CompletePackageInterface::class);
Expand Down Expand Up @@ -220,6 +234,8 @@ public function testUnixInstallCanInstallPrePackagedBinary(string $phpConfig): v
}

(new Process($rmCommand))->mustRun();
unlink($prebuiltBinaryFile->filePath);
(new Filesystem())->remove($prebuiltBinaryFile->filePath);
(new Filesystem())->remove($installRoot);
putenv('INSTALL_ROOT=' . $oldInstallRoot);
}
}
29 changes: 29 additions & 0 deletions test/unit/Platform/TargetPhp/PhpBinaryPathTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,22 @@ public function testExtensionPathOnLinuxThatAlreadyExists(): void
);
}

#[RequiresOperatingSystemFamily('Linux')]
public function testExtensionPathWithInstallRootPrefixOnLinuxThatAlreadyExists(): void
{
$installRoot = '/tmp/' . uniqid('pie-test-install-root-existing-', true);
$phpBinary = PhpBinaryPath::fromCurrentProcess();

$expectedExtensionDir = $installRoot . ini_get('extension_dir');
mkdir($expectedExtensionDir, 0777, true);
self::assertDirectoryExists($expectedExtensionDir);

self::assertSame(
$expectedExtensionDir,
$phpBinary->extensionPath($installRoot),
);
}

#[RequiresOperatingSystemFamily('Windows')]
public function testExtensionPathOnWindows(): void
{
Expand Down Expand Up @@ -336,6 +352,19 @@ public function testExtensionPathIsImplicitlyCreated(): void
self::assertDirectoryExists($configuredExtensionPath);
}

#[RequiresOperatingSystemFamily('Linux')]
public function testExtensionPathWithInstallRootPrefixIsImplicitlyCreated(): void
{
$installRoot = '/tmp/' . uniqid('pie-test-install-root-not-existing-', true);
$phpBinary = PhpBinaryPath::fromCurrentProcess();

$expectedExtensionDir = $installRoot . ini_get('extension_dir');
self::assertDirectoryDoesNotExist($expectedExtensionDir);

self::assertSame($expectedExtensionDir, $phpBinary->extensionPath($installRoot));
self::assertDirectoryExists($expectedExtensionDir);
}

/** @return array<string, array{0: string}> */
public static function phpPathProvider(): array
{
Expand Down