Skip to content

Commit 6e0bafd

Browse files
authored
Merge pull request #509 from asgrim/install-root-env-var
Prefix INSTALL_ROOT env var for UnixInstall
2 parents 682a10b + 62361e1 commit 6e0bafd

5 files changed

Lines changed: 69 additions & 7 deletions

File tree

src/Installing/UnixInstall.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Php\Pie\Installing;
66

77
use Composer\IO\IOInterface;
8+
use Composer\Util\Platform as ComposerPlatform;
89
use Php\Pie\Downloading\DownloadedPackage;
910
use Php\Pie\Downloading\DownloadUrlMethod;
1011
use Php\Pie\File\BinaryFile;
@@ -37,7 +38,14 @@ public function __invoke(
3738
IOInterface $io,
3839
bool $attemptToSetupIniFile,
3940
): BinaryFile {
40-
$targetExtensionPath = $targetPlatform->phpBinaryPath->extensionPath();
41+
$env = [];
42+
$installRoot = (string) ComposerPlatform::getEnv('INSTALL_ROOT');
43+
if ($installRoot !== '') {
44+
$io->write(sprintf('<info>Using INSTALL_ROOT=%s</info>', $installRoot));
45+
$env['INSTALL_ROOT'] = $installRoot;
46+
}
47+
48+
$targetExtensionPath = $targetPlatform->phpBinaryPath->extensionPath($installRoot);
4149

4250
$sharedObjectName = $downloadedPackage->package->extensionName()->name() . '.so';
4351
$expectedSharedObjectLocation = sprintf(
@@ -93,6 +101,7 @@ public function __invoke(
93101
$installCommand,
94102
$downloadedPackage->extractedSourcePath,
95103
self::MAKE_INSTALL_TIMEOUT_SECS,
104+
env: $env,
96105
);
97106

98107
$io->write($makeInstallOutput, verbosity: IOInterface::VERY_VERBOSE);

src/Platform/TargetPhp/PhpBinaryPath.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
use function in_array;
3131
use function is_dir;
3232
use function is_executable;
33+
use function ltrim;
3334
use function mkdir;
3435
use function preg_match;
3536
use function preg_replace;
37+
use function rtrim;
3638
use function sprintf;
3739
use function strtolower;
3840
use function trim;
@@ -103,7 +105,7 @@ public function debugMode(): DebugBuild
103105
}
104106

105107
/** @return non-empty-string */
106-
public function extensionPath(): string
108+
public function extensionPath(string|null $prefixInstallRoot = null): string
107109
{
108110
$phpinfo = $this->phpinfo();
109111

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

121+
if (self::operatingSystem() !== OperatingSystem::Windows && $prefixInstallRoot !== null && $prefixInstallRoot !== '') {
122+
$extensionPath = rtrim($prefixInstallRoot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ltrim($extensionPath, DIRECTORY_SEPARATOR);
123+
}
124+
119125
if (file_exists($extensionPath) && is_dir($extensionPath)) {
120126
return $extensionPath;
121127
}

src/Util/Process.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ private function __construct()
3030
*
3131
* @param list<string> $command
3232
* @param callable(SymfonyProcess::ERR|SymfonyProcess::OUT, string): void|null $outputCallback
33+
* @param array<string, scalar>|null $env
3334
*
3435
* @throws ProcessFailedException
3536
*/
@@ -38,8 +39,9 @@ public static function run(
3839
string|null $workingDirectory = null,
3940
int|null $timeout = self::NO_TIMEOUT,
4041
callable|null $outputCallback = null,
42+
array|null $env = null,
4143
): string {
42-
return trim((new SymfonyProcess($command, $workingDirectory, timeout: $timeout))
44+
return trim((new SymfonyProcess($command, $workingDirectory, $env, timeout: $timeout))
4345
->mustRun($outputCallback)
4446
->getOutput());
4547
}

test/integration/Installing/UnixInstallTest.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Composer\IO\BufferIO;
88
use Composer\Package\CompletePackageInterface;
9+
use Composer\Util\Filesystem;
910
use Composer\Util\Platform;
1011
use Php\Pie\Building\UnixBuild;
1112
use Php\Pie\DependencyResolver\Package;
@@ -30,11 +31,13 @@
3031
use function array_unshift;
3132
use function assert;
3233
use function file_exists;
34+
use function getenv;
3335
use function is_executable;
3436
use function is_writable;
3537
use function mkdir;
38+
use function putenv;
3639
use function rename;
37-
use function unlink;
40+
use function uniqid;
3841

3942
use const DIRECTORY_SEPARATOR;
4043

@@ -79,14 +82,18 @@ public static function phpPathProvider(): array
7982
#[DataProvider('phpPathProvider')]
8083
public function testUnixInstallCanInstallExtensionBuiltFromSource(string $phpConfig): void
8184
{
85+
$installRoot = '/tmp/' . uniqid('pie-test-install-root-', true);
86+
$oldInstallRoot = getenv('INSTALL_ROOT');
87+
putenv('INSTALL_ROOT=' . $installRoot);
88+
8289
assert($phpConfig !== '');
8390
if (Platform::isWindows()) {
8491
self::markTestSkipped('Unix build test cannot be run on Windows');
8592
}
8693

8794
$output = new BufferIO();
8895
$targetPlatform = TargetPlatform::fromPhpBinaryPath(PhpBinaryPath::fromPhpConfigExecutable($phpConfig), null, null);
89-
$extensionPath = $targetPlatform->phpBinaryPath->extensionPath();
96+
$extensionPath = $targetPlatform->phpBinaryPath->extensionPath($installRoot);
9097

9198
$composerPackage = $this->createMock(CompletePackageInterface::class);
9299
$composerPackage
@@ -135,19 +142,26 @@ public function testUnixInstallCanInstallExtensionBuiltFromSource(string $phpCon
135142
(new Process($rmCommand))->mustRun();
136143
(new Process(['make', 'clean'], $downloadedPackage->extractedSourcePath))->mustRun();
137144
(new Process(['phpize', '--clean'], $downloadedPackage->extractedSourcePath))->mustRun();
145+
(new Filesystem())->remove($installRoot);
146+
putenv('INSTALL_ROOT=' . $oldInstallRoot);
138147
}
139148

140149
#[DataProvider('phpPathProvider')]
141150
public function testUnixInstallCanInstallPrePackagedBinary(string $phpConfig): void
142151
{
152+
$installRoot = '/tmp/' . uniqid('pie-test-install-root-', true);
153+
$oldInstallRoot = getenv('INSTALL_ROOT');
154+
putenv('INSTALL_ROOT=' . $installRoot);
155+
143156
assert($phpConfig !== '');
144157
if (Platform::isWindows()) {
145158
self::markTestSkipped('Unix build test cannot be run on Windows');
146159
}
147160

148161
$output = new BufferIO();
149162
$targetPlatform = TargetPlatform::fromPhpBinaryPath(PhpBinaryPath::fromPhpConfigExecutable($phpConfig), null, null);
150-
$extensionPath = $targetPlatform->phpBinaryPath->extensionPath();
163+
$extensionPath = $installRoot . $targetPlatform->phpBinaryPath->extensionPath();
164+
mkdir($extensionPath, 0777, true);
151165

152166
// First build it (otherwise the test assets would need to have a binary for every test platform...)
153167
$composerPackage = $this->createMock(CompletePackageInterface::class);
@@ -218,6 +232,8 @@ public function testUnixInstallCanInstallPrePackagedBinary(string $phpConfig): v
218232
}
219233

220234
(new Process($rmCommand))->mustRun();
221-
unlink($prebuiltBinaryFile->filePath);
235+
(new Filesystem())->remove($prebuiltBinaryFile->filePath);
236+
(new Filesystem())->remove($installRoot);
237+
putenv('INSTALL_ROOT=' . $oldInstallRoot);
222238
}
223239
}

test/unit/Platform/TargetPhp/PhpBinaryPathTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,22 @@ public function testExtensionPathOnLinuxThatAlreadyExists(): void
276276
);
277277
}
278278

279+
#[RequiresOperatingSystemFamily('Linux')]
280+
public function testExtensionPathWithInstallRootPrefixOnLinuxThatAlreadyExists(): void
281+
{
282+
$installRoot = '/tmp/' . uniqid('pie-test-install-root-existing-', true);
283+
$phpBinary = PhpBinaryPath::fromCurrentProcess();
284+
285+
$expectedExtensionDir = $installRoot . ini_get('extension_dir');
286+
mkdir($expectedExtensionDir, 0777, true);
287+
self::assertDirectoryExists($expectedExtensionDir);
288+
289+
self::assertSame(
290+
$expectedExtensionDir,
291+
$phpBinary->extensionPath($installRoot),
292+
);
293+
}
294+
279295
#[RequiresOperatingSystemFamily('Windows')]
280296
public function testExtensionPathOnWindows(): void
281297
{
@@ -336,6 +352,19 @@ public function testExtensionPathIsImplicitlyCreated(): void
336352
self::assertDirectoryExists($configuredExtensionPath);
337353
}
338354

355+
#[RequiresOperatingSystemFamily('Linux')]
356+
public function testExtensionPathWithInstallRootPrefixIsImplicitlyCreated(): void
357+
{
358+
$installRoot = '/tmp/' . uniqid('pie-test-install-root-not-existing-', true);
359+
$phpBinary = PhpBinaryPath::fromCurrentProcess();
360+
361+
$expectedExtensionDir = $installRoot . ini_get('extension_dir');
362+
self::assertDirectoryDoesNotExist($expectedExtensionDir);
363+
364+
self::assertSame($expectedExtensionDir, $phpBinary->extensionPath($installRoot));
365+
self::assertDirectoryExists($expectedExtensionDir);
366+
}
367+
339368
/** @return array<string, array{0: string}> */
340369
public static function phpPathProvider(): array
341370
{

0 commit comments

Comments
 (0)