|
5 | 5 | namespace Php\Pie\Command; |
6 | 6 |
|
7 | 7 | use Composer\Package\Link; |
| 8 | +use Composer\Package\Version\VersionParser; |
8 | 9 | use OutOfRangeException; |
9 | 10 | use Php\Pie\ComposerIntegration\PieComposerFactory; |
10 | 11 | use Php\Pie\ComposerIntegration\PieComposerRequest; |
|
16 | 17 | use Php\Pie\Installing\InstallForPhpProject\FindMatchingPackages; |
17 | 18 | use Php\Pie\Installing\InstallForPhpProject\InstallPiePackageFromPath; |
18 | 19 | use Php\Pie\Installing\InstallForPhpProject\InstallSelectedPackage; |
| 20 | +use Php\Pie\Platform\InstalledPiePackages; |
| 21 | +use Php\Pie\Util\Emoji; |
19 | 22 | use Psr\Container\ContainerInterface; |
20 | 23 | use Symfony\Component\Console\Attribute\AsCommand; |
21 | 24 | use Symfony\Component\Console\Command\Command; |
@@ -53,6 +56,7 @@ final class InstallExtensionsForProjectCommand extends Command |
53 | 56 | public function __construct( |
54 | 57 | private readonly ComposerFactoryForProject $composerFactoryForProject, |
55 | 58 | private readonly DetermineExtensionsRequired $determineExtensionsRequired, |
| 59 | + private readonly InstalledPiePackages $installedPiePackages, |
56 | 60 | private readonly FindMatchingPackages $findMatchingPackages, |
57 | 61 | private readonly InstallSelectedPackage $installSelectedPackage, |
58 | 62 | private readonly InstallPiePackageFromPath $installPiePackageFromPath, |
@@ -138,28 +142,62 @@ public function execute(InputInterface $input, OutputInterface $output): int |
138 | 142 | ); |
139 | 143 |
|
140 | 144 | $phpEnabledExtensions = array_keys($targetPlatform->phpBinaryPath->extensions()); |
| 145 | + $installedPiePackages = $this->installedPiePackages->allPiePackages($pieComposer); |
141 | 146 |
|
142 | 147 | $anyErrorsHappened = false; |
143 | 148 |
|
144 | 149 | array_walk( |
145 | 150 | $extensionsRequired, |
146 | | - function (Link $link) use ($pieComposer, $phpEnabledExtensions, $input, $output, $helper, &$anyErrorsHappened): void { |
147 | | - $extension = ExtensionName::normaliseFromString($link->getTarget()); |
| 151 | + function (Link $link) use ($pieComposer, $phpEnabledExtensions, $installedPiePackages, $input, $output, $helper, &$anyErrorsHappened): void { |
| 152 | + $extension = ExtensionName::normaliseFromString($link->getTarget()); |
| 153 | + $linkRequiresConstraint = $link->getPrettyConstraint(); |
| 154 | + |
| 155 | + $piePackageVersion = null; |
| 156 | + if (in_array($extension->name(), array_keys($installedPiePackages))) { |
| 157 | + $piePackageVersion = $installedPiePackages[$extension->name()]->version(); |
| 158 | + } |
| 159 | + |
| 160 | + $piePackageVersionMatchesLinkConstraint = null; |
| 161 | + if ($piePackageVersion !== null) { |
| 162 | + $piePackageVersionMatchesLinkConstraint = $link |
| 163 | + ->getConstraint() |
| 164 | + ->matches( |
| 165 | + (new VersionParser())->parseConstraints($piePackageVersion), |
| 166 | + ); |
| 167 | + } |
148 | 168 |
|
149 | 169 | if (in_array($extension->name(), $phpEnabledExtensions)) { |
| 170 | + if ($piePackageVersion !== null && $piePackageVersionMatchesLinkConstraint === false) { |
| 171 | + $output->writeln(sprintf( |
| 172 | + '%s: <comment>%s:%s</comment> %s Version %s is installed, but does not meet the version requirement %s', |
| 173 | + $link->getDescription(), |
| 174 | + $link->getTarget(), |
| 175 | + $linkRequiresConstraint, |
| 176 | + Emoji::WARNING, |
| 177 | + $piePackageVersion, |
| 178 | + $link->getConstraint()->getPrettyString(), |
| 179 | + )); |
| 180 | + |
| 181 | + return; |
| 182 | + } |
| 183 | + |
150 | 184 | $output->writeln(sprintf( |
151 | | - '%s: <info>%s</info> ✅ Already installed', |
| 185 | + '%s: <info>%s:%s</info> %s Already installed', |
152 | 186 | $link->getDescription(), |
153 | | - $link, |
| 187 | + $link->getTarget(), |
| 188 | + $linkRequiresConstraint, |
| 189 | + Emoji::GREEN_CHECKMARK, |
154 | 190 | )); |
155 | 191 |
|
156 | 192 | return; |
157 | 193 | } |
158 | 194 |
|
159 | 195 | $output->writeln(sprintf( |
160 | | - '%s: <comment>%s</comment> ⚠️ Missing', |
| 196 | + '%s: <comment>%s:%s</comment> %s Missing', |
161 | 197 | $link->getDescription(), |
162 | | - $link, |
| 198 | + $link->getTarget(), |
| 199 | + $linkRequiresConstraint, |
| 200 | + Emoji::PROHIBITED, |
163 | 201 | )); |
164 | 202 |
|
165 | 203 | try { |
@@ -205,9 +243,14 @@ static function (array $match): string { |
205 | 243 | return; |
206 | 244 | } |
207 | 245 |
|
| 246 | + $requestInstallConstraint = ''; |
| 247 | + if ($linkRequiresConstraint !== '*') { |
| 248 | + $requestInstallConstraint = ':' . $linkRequiresConstraint; |
| 249 | + } |
| 250 | + |
208 | 251 | try { |
209 | 252 | $this->installSelectedPackage->withPieCli( |
210 | | - substr($selectedPackageAnswer, 0, (int) strpos($selectedPackageAnswer, ':')), |
| 253 | + substr($selectedPackageAnswer, 0, (int) strpos($selectedPackageAnswer, ':')) . $requestInstallConstraint, |
211 | 254 | $input, |
212 | 255 | $output, |
213 | 256 | ); |
|
0 commit comments