Browse Source

Handle provider/replacer packages and avoid checking extensions which are provided by packages, refs #8546

Jordi Boggiano 4 years ago
parent
commit
6a6ea6057f

+ 20 - 0
src/Composer/Autoload/AutoloadGenerator.php

@@ -20,6 +20,7 @@ use Composer\Package\AliasPackage;
 use Composer\Package\PackageInterface;
 use Composer\Repository\InstalledRepositoryInterface;
 use Composer\Semver\Constraint\Bound;
+use Composer\Semver\Constraint\EmptyConstraint;
 use Composer\Util\Filesystem;
 use Composer\Script\ScriptEvents;
 use Composer\Util\PackageSorter;
@@ -573,6 +574,16 @@ EOF;
         $lowestPhpVersion = Bound::zero();
         $highestPhpVersion = Bound::positiveInfinity();
         $requiredExtensions = array();
+        $extensionProviders = array();
+
+        foreach ($packageMap as $item) {
+            list($package, $installPath) = $item;
+            foreach (array_merge($package->getReplaces(), $package->getProvides()) as $link) {
+                if (preg_match('{^ext-(.+)$}iD', $link->getTarget(), $match)) {
+                    $extensionProviders[$match[1]][] = $link->getConstraint() ?: new EmptyConstraint();
+                }
+            }
+        }
 
         foreach ($packageMap as $item) {
             list($package, $installPath) = $item;
@@ -587,6 +598,15 @@ EOF;
                 }
 
                 if (preg_match('{^ext-(.+)$}iD', $link->getTarget(), $match)) {
+                    // skip extension checks if they have a valid provider/replacer
+                    if (isset($extensionProviders[$match[1]])) {
+                        foreach ($extensionProviders[$match[1]] as $provided) {
+                            if (!$link->getConstraint() || $provided->matches($link->getConstraint())) {
+                                continue 2;
+                            }
+                        }
+                    }
+
                     $extension = var_export($match[1], true);
                     if ($match[1] === 'pcntl') {
                         $requiredExtensions[$extension] = "PHP_SAPI !== 'cli' || extension_loaded($extension) || \$missingExtensions[] = $extension;\n";

+ 28 - 2
tests/Composer/Test/Autoload/AutoloadGeneratorTest.php

@@ -1648,11 +1648,19 @@ EOF;
     /**
      * @dataProvider platformCheckProvider
      */
-    public function testGeneratesPlatformCheck(array $requires, $expectedFixture)
+    public function testGeneratesPlatformCheck(array $requires, $expectedFixture, array $provides = array(), array $replaces = array())
     {
         $package = new Package('a', '1.0', '1.0');
         $package->setRequires($requires);
 
+        if ($provides) {
+            $package->setProvides($provides);
+        }
+
+        if ($replaces) {
+            $package->setReplaces($replaces);
+        }
+
         $this->repository->expects($this->once())
             ->method('getCanonicalPackages')
             ->will($this->returnValue(array()));
@@ -1705,7 +1713,25 @@ EOF;
                     new Link('a', 'php', $versionParser->parseConstraints('^7.2')),
                 ),
                 'no_extensions_required'
-            )
+            ),
+            'Replaced/provided extensions are not checked for + checking case insensitivity' => array(
+                array(
+                    new Link('a', 'ext-xml', $versionParser->parseConstraints('^7.2')),
+                    new Link('a', 'ext-Pdo', $versionParser->parseConstraints('^7.2')),
+                    new Link('a', 'ext-bcMath', $versionParser->parseConstraints('^7.2')),
+                ),
+                'replaced_provided_exts',
+                array(
+                    // constraint does not satisfy all the ^7.2 requirement so we do not accept it as being replaced
+                    new Link('a', 'ext-PDO', $versionParser->parseConstraints('7.1.*')),
+                    // valid replace of bcmath so no need to check for it
+                    new Link('a', 'ext-BCMath', $versionParser->parseConstraints('^7.1')),
+                ),
+                array(
+                    // valid provide of ext-xml so no need to check for it
+                    new Link('a', 'ext-XML', $versionParser->parseConstraints('*')),
+                ),
+            ),
         );
     }
 

+ 21 - 0
tests/Composer/Test/Autoload/Fixtures/platform/replaced_provided_exts.php

@@ -0,0 +1,21 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 0 && PHP_VERSION_ID < 99999)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 0" and "< 99999". You are running ' . PHP_VERSION  .  '.';
+}
+
+$missingExtensions = array();
+extension_loaded('pdo') || $missingExtensions[] = 'pdo';
+
+if ($missingExtensions) {
+    $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions);
+}
+
+if ($issues) {
+    echo 'Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues);
+    exit(104);
+}