-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathUnixInstall.php
More file actions
129 lines (107 loc) · 4.31 KB
/
Copy pathUnixInstall.php
File metadata and controls
129 lines (107 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
declare(strict_types=1);
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;
use Php\Pie\File\Sudo;
use Php\Pie\Platform\MakePath;
use Php\Pie\Platform\TargetPlatform;
use Php\Pie\Util\Process;
use RuntimeException;
use Webmozart\Assert\Assert;
use function array_map;
use function array_merge;
use function file_exists;
use function implode;
use function is_writable;
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 UnixInstall implements Install
{
private const MAKE_INSTALL_TIMEOUT_SECS = 300; // 5 minutes
public function __construct(private readonly SetupIniFile $setupIniFile)
{
}
public function __invoke(
DownloadedPackage $downloadedPackage,
TargetPlatform $targetPlatform,
BinaryFile|null $builtBinaryFile,
IOInterface $io,
bool $attemptToSetupIniFile,
): BinaryFile {
$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(
'%s/%s',
$targetExtensionPath,
$sharedObjectName,
);
$installCommands = [];
switch (DownloadUrlMethod::fromDownloadedPackage($downloadedPackage)) {
case DownloadUrlMethod::PrePackagedBinary:
Assert::notNull($builtBinaryFile);
if (file_exists($expectedSharedObjectLocation)) {
$installCommands[] = [
'rm',
'-v',
$expectedSharedObjectLocation,
];
}
$installCommands[] = [
'cp',
'-v',
$builtBinaryFile->filePath,
$targetExtensionPath,
];
break;
default:
$installCommands[] = [MakePath::guess(), 'install'];
}
// If the target directory isn't writable, or a .so file already exists and isn't writable, try to use sudo
if (
(
! is_writable($targetExtensionPath)
|| (file_exists($expectedSharedObjectLocation) && ! is_writable($expectedSharedObjectLocation))
)
&& Sudo::exists()
) {
$io->write(sprintf(
'<comment>Cannot write to %s, so using sudo to elevate privileges.</comment>',
$targetExtensionPath,
));
$installCommands = array_map(static fn (array $command) => array_merge(['sudo'], $command), $installCommands);
}
$io->write(sprintf('<info>Install commands are: %s</info>', implode(', ', array_map(static fn (array $command) => implode(' ', $command), $installCommands))), verbosity: IOInterface::VERY_VERBOSE);
foreach ($installCommands as $installCommand) {
$makeInstallOutput = Process::run(
$installCommand,
$downloadedPackage->extractedSourcePath,
self::MAKE_INSTALL_TIMEOUT_SECS,
env: $env,
);
$io->write($makeInstallOutput, verbosity: IOInterface::VERY_VERBOSE);
}
if (! file_exists($expectedSharedObjectLocation)) {
throw new RuntimeException('Install failed, ' . $expectedSharedObjectLocation . ' was not installed.');
}
$io->write('<info>Install complete:</info> ' . $expectedSharedObjectLocation);
$binaryFile = BinaryFile::fromFileWithSha256Checksum($expectedSharedObjectLocation);
($this->setupIniFile)(
$targetPlatform,
$downloadedPackage,
$binaryFile,
$io,
$attemptToSetupIniFile,
);
return $binaryFile;
}
}