diff --git a/src/Building/UnixBuild.php b/src/Building/UnixBuild.php index e067a3de..12eb6184 100644 --- a/src/Building/UnixBuild.php +++ b/src/Building/UnixBuild.php @@ -74,17 +74,7 @@ private function buildFromSource( array $configureOptions, IOInterface $io, ): BinaryFile { - $outputCallback = null; - if ($io->isVerbose()) { - $outputCallback = static function (string $type, string $outputMessage) use ($io): void { - $io->write(sprintf( - '%s%s%s', - $type === SymfonyProcess::ERR ? '' : '', - $outputMessage, - $type === SymfonyProcess::ERR ? '' : '', - )); - }; - } + $outputCallback = Process::outputCallbackForVerbosity($io, IOInterface::VERBOSE); $phpizePath = $targetPlatform->phpizePath ?? PhpizePath::guessFrom($targetPlatform->phpBinaryPath); diff --git a/src/DependencyResolver/DependencyInstaller/PrescanSystemDependencies.php b/src/DependencyResolver/DependencyInstaller/PrescanSystemDependencies.php index 4b3a303e..a2652855 100644 --- a/src/DependencyResolver/DependencyInstaller/PrescanSystemDependencies.php +++ b/src/DependencyResolver/DependencyInstaller/PrescanSystemDependencies.php @@ -107,7 +107,7 @@ static function (DependencyStatus $dependencyStatus): bool { } try { - $this->packageManager->install($packageManagerPackages); + $this->packageManager->install($this->io, $packageManagerPackages); $this->io->write('Missing system dependencies have been installed.'); } catch (Throwable $anything) { diff --git a/src/Platform/PackageManager.php b/src/Platform/PackageManager.php index 572391a0..8b1dfb3f 100644 --- a/src/Platform/PackageManager.php +++ b/src/Platform/PackageManager.php @@ -4,6 +4,7 @@ namespace Php\Pie\Platform; +use Composer\IO\IOInterface; use Php\Pie\File\Sudo; use Php\Pie\Platform; use Php\Pie\Util\Process; @@ -58,19 +59,21 @@ public function installCommand(array $packages): array } /** @param list $packages */ - public function install(array $packages): void + public function install(IOInterface $io, array $packages): void { + $outputCallback = Process::outputCallbackForVerbosity($io, IOInterface::VERY_VERBOSE); + $cmd = self::installCommand($packages); try { - Process::run($cmd); + Process::run($cmd, outputCallback: $outputCallback); return; } catch (ProcessFailedException $e) { if (Platform::isInteractive() && Process::processProbablyPermissionDenied($e)) { array_unshift($cmd, Sudo::find()); - Process::run($cmd); + Process::run($cmd, outputCallback: $outputCallback); return; } diff --git a/src/SelfManage/BuildTools/BinaryBuildToolFinder.php b/src/SelfManage/BuildTools/BinaryBuildToolFinder.php index d5a0f9aa..2f50965c 100644 --- a/src/SelfManage/BuildTools/BinaryBuildToolFinder.php +++ b/src/SelfManage/BuildTools/BinaryBuildToolFinder.php @@ -11,6 +11,7 @@ use function array_key_exists; use function implode; use function is_array; +use function preg_replace; use function str_replace; /** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */ @@ -51,6 +52,10 @@ public function packageNameFor(PackageManager $packageManager, TargetPlatform $t return null; } + if ($this->packageManagerPackages[$packageManager->value] === '{php-config-path}') { + return preg_replace('((.*)php)', '$1php-config', $targetPlatform->phpBinaryPath->phpBinaryPath); + } + // If we need to customise specific package names depending on OS // specific parameters, this is likely the place to do it return str_replace( diff --git a/src/SelfManage/BuildTools/CheckAllBuildTools.php b/src/SelfManage/BuildTools/CheckAllBuildTools.php index ac02c6ab..3059efe0 100644 --- a/src/SelfManage/BuildTools/CheckAllBuildTools.php +++ b/src/SelfManage/BuildTools/CheckAllBuildTools.php @@ -74,8 +74,8 @@ public static function buildToolsFactory(): self [ PackageManager::Apt->value => 'php-dev', PackageManager::Apk->value => 'php{major}{minor}-dev', - PackageManager::Dnf->value => 'php-devel', - PackageManager::Yum->value => 'php-devel', + PackageManager::Dnf->value => '{php-config-path}', + PackageManager::Yum->value => '{php-config-path}', PackageManager::Brew->value => 'php', ], ), @@ -160,7 +160,7 @@ public function check(IOInterface $io, PackageManager|null $packageManager, Targ } try { - $packageManager->install(array_values(array_unique($packagesToInstall))); + $packageManager->install($io, array_values(array_unique($packagesToInstall))); $io->write('Missing build tools have been installed.'); } catch (Throwable $throwable) { diff --git a/src/Util/Process.php b/src/Util/Process.php index 41abed8e..4ddfbc5a 100644 --- a/src/Util/Process.php +++ b/src/Util/Process.php @@ -4,9 +4,11 @@ namespace Php\Pie\Util; +use Composer\IO\IOInterface; use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Process as SymfonyProcess; +use function sprintf; use function str_contains; use function strtolower; use function trim; @@ -48,6 +50,31 @@ public static function run( ->getOutput()); } + /** + * @param IOInterface::* $minVerbosity + * + * @return callable(SymfonyProcess::ERR|SymfonyProcess::OUT, string): void|null + */ + public static function outputCallbackForVerbosity(IOInterface $io, int $minVerbosity): callable|null + { + if ( + ($minVerbosity === IOInterface::VERBOSE && ! $io->isVerbose() && ! $io->isVeryVerbose() && ! $io->isDebug()) + || ($minVerbosity === IOInterface::VERY_VERBOSE && ! $io->isVeryVerbose() && ! $io->isDebug()) + || ($minVerbosity === IOInterface::DEBUG && ! $io->isDebug()) + ) { + return null; + } + + return static function (string $type, string $outputMessage) use ($io): void { + $io->write(sprintf( + '%s%s%s', + $type === SymfonyProcess::ERR ? '' : '', + $outputMessage, + $type === SymfonyProcess::ERR ? '' : '', + )); + }; + } + public static function processProbablyPermissionDenied(ProcessFailedException $e): bool { $mergedProcessOutput = strtolower($e->getProcess()->getErrorOutput() . $e->getProcess()->getOutput()); diff --git a/test/end-to-end/Dockerfile b/test/end-to-end/Dockerfile index 375978f6..986db2af 100644 --- a/test/end-to-end/Dockerfile +++ b/test/end-to-end/Dockerfile @@ -1,38 +1,50 @@ -FROM boxproject/box:4.7.0 AS build_pie_phar +FROM boxproject/box:4.7.0 AS box_base +FROM alpine:3.24 AS alpine_base +FROM fedora:44 AS fedora_base +FROM ubuntu:26.04 AS ubuntu_base +FROM homebrew/brew:4.6.20 AS homebrew_base + +FROM box_base AS build_pie_phar RUN apk add git COPY . /app RUN cd /app && touch creating_this_means_phar_will_never_be_verified && /box.phar compile -FROM alpine AS test_pie_installs_build_tools_on_alpine +FROM alpine_base AS test_pie_installs_build_tools_on_alpine RUN apk add php php-phar php-mbstring php-iconv php-openssl bzip2-dev libbz2 COPY --from=build_pie_phar /app/pie.phar /usr/local/bin/pie -RUN pie install --auto-install-build-tools -v php/bz2 +RUN pie install --auto-install-build-tools -v asgrim/example-pie-extension:2.0.5 RUN apk del .php-pie-deps RUN pie show -FROM fedora AS test_pie_installs_build_tools_on_fedora +FROM fedora_base AS test_pie_installs_build_tools_on_fedora RUN dnf install -y php php-pecl-zip unzip bzip2-devel COPY --from=build_pie_phar /app/pie.phar /usr/local/bin/pie -RUN pie install --auto-install-build-tools -v php/bz2 +RUN pie install --auto-install-build-tools -v asgrim/example-pie-extension:2.0.5 +RUN pie show + +FROM quay.io/rockylinux/rockylinux:10 AS test_pie_installs_build_tools_on_rocky +RUN dnf install -y php8.4-cli epel-release unzip +COPY --from=build_pie_phar /app/pie.phar /usr/local/bin/pie +RUN pie install --auto-install-build-tools -vv asgrim/example-pie-extension:2.0.5 RUN pie show -FROM ubuntu AS test_pie_installs_build_tools_on_ubuntu +FROM ubuntu_base AS test_pie_installs_build_tools_on_ubuntu RUN apt-get update && apt-get install -y php unzip libbz2-dev COPY --from=build_pie_phar /app/pie.phar /usr/local/bin/pie -RUN pie install --auto-install-build-tools -v php/bz2 +RUN pie install --auto-install-build-tools -v asgrim/example-pie-extension:2.0.5 RUN pie show -FROM homebrew/brew AS test_pie_installs_build_tools_with_brew -RUN brew install php +FROM homebrew_base AS test_pie_installs_build_tools_with_brew +RUN brew update && brew install php COPY --from=build_pie_phar /app/pie.phar /usr/local/bin/pie USER root RUN apt-get update && apt-get install -y unzip RUN apt-get remove --allow-remove-essential -y apt USER linuxbrew -RUN pie install --auto-install-build-tools -v asgrim/example-pie-extension +RUN pie install --auto-install-build-tools -v asgrim/example-pie-extension:2.0.5 RUN pie show -FROM ubuntu AS test_pie_installs_system_deps_on_ubuntu +FROM ubuntu_base AS test_pie_installs_system_deps_on_ubuntu RUN apt-get update && apt install -y unzip curl wget gcc make autoconf libtool bison re2c pkg-config libzip-dev libssl-dev libonig-dev RUN mkdir -p /opt/php \ && mkdir -p /tmp/php \ @@ -47,14 +59,14 @@ RUN mkdir -p /opt/php \ && make install ENV PATH="$PATH:/opt/php/bin" COPY --from=build_pie_phar /app/pie.phar /usr/local/bin/pie -RUN pie install -v --auto-install-system-dependencies php/sodium +RUN pie install -v --auto-install-system-dependencies --force php/sodium -FROM alpine AS test_pie_installs_system_deps_on_alpine +FROM alpine_base AS test_pie_installs_system_deps_on_alpine RUN apk add php php-phar php-mbstring php-iconv php-openssl bzip2-dev libbz2 build-base autoconf bison re2c libtool php85-dev COPY --from=build_pie_phar /app/pie.phar /usr/local/bin/pie -RUN pie install -v --auto-install-system-dependencies php/sodium +RUN pie install -v --auto-install-system-dependencies --force php/sodium -FROM fedora AS test_pie_installs_system_deps_on_fedora +FROM fedora_base AS test_pie_installs_system_deps_on_fedora RUN dnf install -y php php-pecl-zip unzip gcc make autoconf bison re2c libtool php-devel COPY --from=build_pie_phar /app/pie.phar /usr/local/bin/pie -RUN pie install -v --auto-install-system-dependencies php/sodium +RUN pie install -v --auto-install-system-dependencies --force php/sodium