Skip to content

Commit dc299c3

Browse files
authored
Merge pull request #155 from asgrim/20-detect-setup-php-ini
Automatically setup php.ini entries
2 parents e213e44 + 8887791 commit dc299c3

File tree

59 files changed

+3142
-22
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+3142
-22
lines changed

src/Command/BuildCommand.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
5454
PieOperation::Resolve,
5555
[], // Configure options are not needed for resolve only
5656
null,
57+
false, // setting up INI not needed for build
5758
),
5859
);
5960

@@ -74,6 +75,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
7475
PieOperation::Build,
7576
$configureOptionsValues,
7677
CommandHelper::determinePhpizePathFromInputs($input),
78+
false, // setting up INI not needed for build
7779
),
7880
);
7981

src/Command/CommandHelper.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ final class CommandHelper
3838
private const OPTION_WITH_PHP_PATH = 'with-php-path';
3939
private const OPTION_WITH_PHPIZE_PATH = 'with-phpize-path';
4040
private const OPTION_MAKE_PARALLEL_JOBS = 'make-parallel-jobs';
41+
private const OPTION_SKIP_ENABLE_EXTENSION = 'skip-enable-extension';
4142

4243
/** @psalm-suppress UnusedConstructor */
4344
private function __construct()
@@ -79,6 +80,12 @@ public static function configureDownloadBuildInstallOptions(Command $command): v
7980
InputOption::VALUE_REQUIRED,
8081
'The path to the `phpize` binary to use as the target PHP platform, e.g. --' . self::OPTION_WITH_PHPIZE_PATH . '=/usr/bin/phpize7.4',
8182
);
83+
$command->addOption(
84+
self::OPTION_SKIP_ENABLE_EXTENSION,
85+
null,
86+
InputOption::VALUE_NONE,
87+
'Specify this to skip attempting to enable the extension in php.ini',
88+
);
8289

8390
self::configurePhpConfigOptions($command);
8491

@@ -154,6 +161,11 @@ public static function determineTargetPlatformFromInputs(InputInterface $input,
154161
return $targetPlatform;
155162
}
156163

164+
public static function determineAttemptToSetupIniFile(InputInterface $input): bool
165+
{
166+
return ! $input->hasOption(self::OPTION_SKIP_ENABLE_EXTENSION) || ! $input->getOption(self::OPTION_SKIP_ENABLE_EXTENSION);
167+
}
168+
157169
public static function determinePhpizePathFromInputs(InputInterface $input): PhpizePath|null
158170
{
159171
if ($input->hasOption(self::OPTION_WITH_PHPIZE_PATH)) {

src/Command/DownloadCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
5656
PieOperation::Download,
5757
[], // Configure options are not needed for download only
5858
null,
59+
false, // setting up INI not needed for download
5960
),
6061
);
6162

src/Command/InfoCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
5454
PieOperation::Resolve,
5555
[], // Configure options are not needed for resolve only
5656
null,
57+
false, // setting up INI not needed for info
5758
),
5859
);
5960

src/Command/InstallCommand.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
5959
PieOperation::Resolve,
6060
[], // Configure options are not needed for resolve only
6161
null,
62+
false, // setting up INI not needed for resolve step
6263
),
6364
);
6465

@@ -79,6 +80,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
7980
PieOperation::Install,
8081
$configureOptionsValues,
8182
CommandHelper::determinePhpizePathFromInputs($input),
83+
CommandHelper::determineAttemptToSetupIniFile($input),
8284
),
8385
);
8486

src/ComposerIntegration/InstallAndBuildProcess.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public function __invoke(
7777
$downloadedPackage,
7878
$composerRequest->targetPlatform,
7979
$output,
80+
$composerRequest->attemptToSetupIniFile,
8081
),
8182
);
8283
}

src/ComposerIntegration/PieComposerRequest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public function __construct(
2424
public readonly PieOperation $operation,
2525
public readonly array $configureOptions,
2626
public readonly PhpizePath|null $phpizePath,
27+
public readonly bool $attemptToSetupIniFile,
2728
) {
2829
}
2930
}

src/Container.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Php\Pie\DependencyResolver\ResolveDependencyWithComposer;
2020
use Php\Pie\Downloading\GithubPackageReleaseAssets;
2121
use Php\Pie\Downloading\PackageReleaseAssets;
22+
use Php\Pie\Installing\Ini;
2223
use Php\Pie\Installing\Install;
2324
use Php\Pie\Installing\UnixInstall;
2425
use Php\Pie\Installing\WindowsInstall;
@@ -71,6 +72,19 @@ static function (ContainerInterface $container): Build {
7172
},
7273
);
7374

75+
$container->singleton(
76+
Ini\SetupIniApproach::class,
77+
static function (ContainerInterface $container): Ini\SetupIniApproach {
78+
return new Ini\PickBestSetupIniApproach([
79+
$container->get(Ini\PreCheckExtensionAlreadyLoaded::class),
80+
$container->get(Ini\OndrejPhpenmod::class),
81+
$container->get(Ini\DockerPhpExtEnable::class),
82+
$container->get(Ini\StandardAdditionalPhpIniDirectory::class),
83+
$container->get(Ini\StandardSinglePhpIni::class),
84+
]);
85+
},
86+
);
87+
7488
$container->singleton(
7589
Install::class,
7690
static function (ContainerInterface $container): Install {

src/DependencyResolver/Package.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public function __construct(
4747
public readonly string|null $buildPath,
4848
public readonly array|null $compatibleOsFamilies,
4949
public readonly array|null $incompatibleOsFamilies,
50+
public readonly int $priority,
5051
) {
5152
}
5253

@@ -93,6 +94,7 @@ public static function fromComposerCompletePackage(CompletePackageInterface $com
9394
$buildPath,
9495
self::convertInputStringsToOperatingSystemFamilies($compatibleOsFamilies),
9596
self::convertInputStringsToOperatingSystemFamilies($incompatibleOsFamilies),
97+
$phpExtOptions['priority'] ?? 80,
9698
);
9799
}
98100

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Php\Pie\Installing\Ini;
6+
7+
use Php\Pie\DependencyResolver\Package;
8+
use Php\Pie\ExtensionType;
9+
use Php\Pie\Platform\TargetPhp\PhpBinaryPath;
10+
use Symfony\Component\Console\Output\OutputInterface;
11+
use Throwable;
12+
13+
use function file_get_contents;
14+
use function file_put_contents;
15+
use function is_string;
16+
use function is_writable;
17+
use function sprintf;
18+
19+
use const PHP_EOL;
20+
21+
/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
22+
class AddExtensionToTheIniFile
23+
{
24+
/** @param callable():bool|null $additionalEnableStep */
25+
public function __invoke(
26+
string $ini,
27+
Package $package,
28+
PhpBinaryPath $phpBinaryPath,
29+
OutputInterface $output,
30+
callable|null $additionalEnableStep,
31+
): bool {
32+
if (! is_writable($ini)) {
33+
$output->writeln(
34+
sprintf(
35+
'PHP is configured to use %s, but it is not writable by PIE.',
36+
$ini,
37+
),
38+
OutputInterface::VERBOSITY_VERBOSE,
39+
);
40+
41+
return false;
42+
}
43+
44+
$originalIniContent = file_get_contents($ini);
45+
46+
if (! is_string($originalIniContent)) {
47+
$output->writeln(
48+
sprintf(
49+
'Tried making a backup of %s but could not read it, aborting enablement of extension',
50+
$ini,
51+
),
52+
OutputInterface::VERBOSITY_VERBOSE,
53+
);
54+
55+
return false;
56+
}
57+
58+
try {
59+
file_put_contents(
60+
$ini,
61+
$originalIniContent . $this->iniFileContent($package),
62+
);
63+
$output->writeln(
64+
sprintf(
65+
'Enabled extension %s in the INI file %s',
66+
$package->extensionName->name(),
67+
$ini,
68+
),
69+
OutputInterface::VERBOSITY_VERBOSE,
70+
);
71+
72+
if ($additionalEnableStep !== null && ! $additionalEnableStep()) {
73+
return false;
74+
}
75+
76+
$phpBinaryPath->assertExtensionIsLoadedInRuntime($package->extensionName, $output);
77+
78+
return true;
79+
} catch (Throwable $anything) {
80+
file_put_contents($ini, $originalIniContent);
81+
82+
$output->writeln(sprintf(
83+
'<error>Something went wrong enabling the %s extension: %s</error>',
84+
$package->extensionName->name(),
85+
$anything->getMessage(),
86+
));
87+
88+
return false;
89+
}
90+
}
91+
92+
/** @return non-empty-string */
93+
private function iniFileContent(Package $package): string
94+
{
95+
return PHP_EOL
96+
. '; PIE automatically added this to enable the ' . $package->name . ' extension' . PHP_EOL
97+
. '; priority=' . $package->priority . PHP_EOL
98+
. ($package->extensionType === ExtensionType::PhpModule ? 'extension' : 'zend_extension')
99+
. '='
100+
. $package->extensionName->name() . PHP_EOL;
101+
}
102+
}

0 commit comments

Comments
 (0)