From 6e5991426bda3e3477e3fff05eabc4ea2bb4c11f Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Thu, 18 Sep 2025 21:08:25 +0100 Subject: [PATCH 1/2] Improve output of pie info to include dependencies met/unmet --- src/Command/InfoCommand.php | 41 +++++++++++++++++-- .../ResolveDependencyWithComposer.php | 8 ++-- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/Command/InfoCommand.php b/src/Command/InfoCommand.php index d31c9a36..86efc218 100644 --- a/src/Command/InfoCommand.php +++ b/src/Command/InfoCommand.php @@ -4,6 +4,8 @@ namespace Php\Pie\Command; +use Composer\Semver\Constraint\Constraint; +use Php\Pie\ComposerIntegration\PhpBinaryPathBasedPlatformRepository; use Php\Pie\ComposerIntegration\PieComposerFactory; use Php\Pie\ComposerIntegration\PieComposerRequest; use Php\Pie\ComposerIntegration\PieOperation; @@ -12,12 +14,15 @@ use Php\Pie\DependencyResolver\InvalidPackageName; use Php\Pie\DependencyResolver\UnableToResolveRequirement; use Php\Pie\Installing\InstallForPhpProject\FindMatchingPackages; +use Php\Pie\Platform\InstalledPiePackages; +use Php\Pie\Util\Emoji; use Psr\Container\ContainerInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use function array_key_exists; use function count; use function sprintf; @@ -78,7 +83,7 @@ public function execute(InputInterface $input, OutputInterface $output): int $composer, $targetPlatform, $requestedNameAndVersion, - CommandHelper::determineForceInstallingPackageVersion($input), + true, ); } catch (UnableToResolveRequirement $unableToResolveRequirement) { return CommandHelper::handlePackageNotFound( @@ -103,13 +108,43 @@ public function execute(InputInterface $input, OutputInterface $output): int $output->writeln(sprintf('Version: %s', $package->version())); $output->writeln(sprintf('Download URL: %s', $package->downloadUrl() ?? '(not specified)')); + $output->writeln("\nDependencies:"); + $requires = $package->composerPackage()->getRequires(); + + if (count($requires) > 0) { + /** @var array> $platformConstraints */ + $platformConstraints = []; + $composerPlatform = new PhpBinaryPathBasedPlatformRepository($targetPlatform->phpBinaryPath, $composer, new InstalledPiePackages(), null); + foreach ($composerPlatform->getPackages() as $platformPackage) { + $platformConstraints[$platformPackage->getName()][] = new Constraint('==', $platformPackage->getPrettyVersion()); + } + + foreach ($requires as $requireName => $requireLink) { + $packageStatus = sprintf(' %s: %s %%s', $requireName, $requireLink->getConstraint()->getPrettyString()); + if (! array_key_exists($requireName, $platformConstraints)) { + $output->writeln(sprintf($packageStatus, Emoji::PROHIBITED . ' (not installed)')); + continue; + } + + foreach ($platformConstraints[$requireName] as $constraint) { + if ($requireLink->getConstraint()->matches($constraint)) { + $output->writeln(sprintf($packageStatus, Emoji::GREEN_CHECKMARK)); + } else { + $output->writeln(sprintf($packageStatus, Emoji::PROHIBITED . ' (your version is ' . $constraint->getVersion() . ')')); + } + } + } + } else { + $output->writeln(' No dependencies.'); + } + + $output->writeln("\nConfigure options:"); if (count($package->configureOptions())) { - $output->writeln('Configure options:'); foreach ($package->configureOptions() as $configureOption) { $output->writeln(sprintf(' --%s%s (%s)', $configureOption->name, $configureOption->needsValue ? '=?' : '', $configureOption->description)); } } else { - $output->writeln('No configure options are specified.'); + $output->writeln(' No configure options are specified.'); } return Command::SUCCESS; diff --git a/src/DependencyResolver/ResolveDependencyWithComposer.php b/src/DependencyResolver/ResolveDependencyWithComposer.php index 2eb46309..03a733f4 100644 --- a/src/DependencyResolver/ResolveDependencyWithComposer.php +++ b/src/DependencyResolver/ResolveDependencyWithComposer.php @@ -65,9 +65,11 @@ public function __invoke( $piePackage = Package::fromComposerCompletePackage($package); - $this->assertBuildProviderProvidersBundledExtensions($targetPlatform, $piePackage, $forceInstallPackageVersion); - $this->assertCompatibleOsFamily($targetPlatform, $piePackage); - $this->assertCompatibleThreadSafetyMode($targetPlatform->threadSafety, $piePackage); + if (! $forceInstallPackageVersion) { + $this->assertBuildProviderProvidersBundledExtensions($targetPlatform, $piePackage, $forceInstallPackageVersion); + $this->assertCompatibleOsFamily($targetPlatform, $piePackage); + $this->assertCompatibleThreadSafetyMode($targetPlatform->threadSafety, $piePackage); + } return $piePackage; } From d6f02be274deb388965caf2273ced6512feabc8c Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Thu, 18 Sep 2025 21:50:18 +0100 Subject: [PATCH 2/2] Display TS/NTS and OS compatibility --- src/Command/InfoCommand.php | 15 +++++++++++++++ .../ResolveDependencyWithComposer.php | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Command/InfoCommand.php b/src/Command/InfoCommand.php index 86efc218..95d382ce 100644 --- a/src/Command/InfoCommand.php +++ b/src/Command/InfoCommand.php @@ -15,6 +15,7 @@ use Php\Pie\DependencyResolver\UnableToResolveRequirement; use Php\Pie\Installing\InstallForPhpProject\FindMatchingPackages; use Php\Pie\Platform\InstalledPiePackages; +use Php\Pie\Platform\ThreadSafetyMode; use Php\Pie\Util\Emoji; use Psr\Container\ContainerInterface; use Symfony\Component\Console\Attribute\AsCommand; @@ -24,6 +25,7 @@ use function array_key_exists; use function count; +use function in_array; use function sprintf; #[AsCommand( @@ -107,6 +109,19 @@ public function execute(InputInterface $input, OutputInterface $output): int $output->writeln(sprintf('Composer package name: %s', $package->name())); $output->writeln(sprintf('Version: %s', $package->version())); $output->writeln(sprintf('Download URL: %s', $package->downloadUrl() ?? '(not specified)')); + $output->writeln(sprintf( + 'TS/NTS: %s', + ($targetPlatform->threadSafety === ThreadSafetyMode::NonThreadSafe && ! $package->supportNts()) + || ($targetPlatform->threadSafety === ThreadSafetyMode::ThreadSafe && ! $package->supportZts()) ? sprintf('%s (not supported on %s)', Emoji::PROHIBITED, $targetPlatform->threadSafety->asShort()) : Emoji::GREEN_CHECKMARK, + )); + + $output->writeln(sprintf( + 'OS: %s', + ($package->compatibleOsFamilies() === null || in_array($targetPlatform->operatingSystemFamily, $package->compatibleOsFamilies(), true)) + && ($package->incompatibleOsFamilies() === null || ! in_array($targetPlatform->operatingSystemFamily, $package->incompatibleOsFamilies(), true)) + ? Emoji::GREEN_CHECKMARK + : sprintf('%s (not supported on %s)', Emoji::PROHIBITED, $targetPlatform->operatingSystemFamily->value), + )); $output->writeln("\nDependencies:"); $requires = $package->composerPackage()->getRequires(); diff --git a/src/DependencyResolver/ResolveDependencyWithComposer.php b/src/DependencyResolver/ResolveDependencyWithComposer.php index 03a733f4..7546d32d 100644 --- a/src/DependencyResolver/ResolveDependencyWithComposer.php +++ b/src/DependencyResolver/ResolveDependencyWithComposer.php @@ -65,8 +65,9 @@ public function __invoke( $piePackage = Package::fromComposerCompletePackage($package); + $this->assertBuildProviderProvidersBundledExtensions($targetPlatform, $piePackage, $forceInstallPackageVersion); + if (! $forceInstallPackageVersion) { - $this->assertBuildProviderProvidersBundledExtensions($targetPlatform, $piePackage, $forceInstallPackageVersion); $this->assertCompatibleOsFamily($targetPlatform, $piePackage); $this->assertCompatibleThreadSafetyMode($targetPlatform->threadSafety, $piePackage); }