浏览代码

Implemented php version check in autoload.php (#8546)

Yanick Witschi 5 年之前
父节点
当前提交
e23710f92d

+ 12 - 162
composer.lock

@@ -60,35 +60,20 @@
                 "ssl",
                 "tls"
             ],
-            "support": {
-                "irc": "irc://irc.freenode.org/composer",
-                "issues": "https://github.com/composer/ca-bundle/issues",
-                "source": "https://github.com/composer/ca-bundle/tree/1.2.7"
-            },
-            "funding": [
-                {
-                    "url": "https://packagist.com",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-04-08T08:27:21+00:00"
         },
         {
             "name": "composer/semver",
-            "version": "2.0.x-dev",
+            "version": "dev-master",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/semver.git",
-                "reference": "4df5ff3249f01018504939d66040d8d2b783d820"
+                "reference": "2fbee6b82f09aeaa3905444eb6652c554411fe55"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/semver/zipball/4df5ff3249f01018504939d66040d8d2b783d820",
-                "reference": "4df5ff3249f01018504939d66040d8d2b783d820",
+                "url": "https://api.github.com/repos/composer/semver/zipball/2fbee6b82f09aeaa3905444eb6652c554411fe55",
+                "reference": "2fbee6b82f09aeaa3905444eb6652c554411fe55",
                 "shasum": ""
             },
             "require": {
@@ -136,22 +121,7 @@
                 "validation",
                 "versioning"
             ],
-            "support": {
-                "irc": "irc://irc.freenode.org/composer",
-                "issues": "https://github.com/composer/semver/issues",
-                "source": "https://github.com/composer/semver/tree/2.0"
-            },
-            "funding": [
-                {
-                    "url": "https://packagist.com",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2020-03-11T13:41:23+00:00"
+            "time": "2020-04-16T13:02:51+00:00"
         },
         {
             "name": "composer/spdx-licenses",
@@ -211,11 +181,6 @@
                 "spdx",
                 "validator"
             ],
-            "support": {
-                "irc": "irc://irc.freenode.org/composer",
-                "issues": "https://github.com/composer/spdx-licenses/issues",
-                "source": "https://github.com/composer/spdx-licenses/tree/1.5.3"
-            },
             "time": "2020-02-14T07:44:31+00:00"
         },
         {
@@ -260,17 +225,6 @@
                 "Xdebug",
                 "performance"
             ],
-            "support": {
-                "irc": "irc://irc.freenode.org/composer",
-                "issues": "https://github.com/composer/xdebug-handler/issues",
-                "source": "https://github.com/composer/xdebug-handler/tree/master"
-            },
-            "funding": [
-                {
-                    "url": "https://packagist.com",
-                    "type": "custom"
-                }
-            ],
             "time": "2020-03-01T12:26:26+00:00"
         },
         {
@@ -337,10 +291,6 @@
                 "json",
                 "schema"
             ],
-            "support": {
-                "issues": "https://github.com/justinrainbow/json-schema/issues",
-                "source": "https://github.com/justinrainbow/json-schema/tree/5.2.9"
-            },
             "time": "2019-09-25T14:49:45+00:00"
         },
         {
@@ -388,9 +338,6 @@
                 "psr",
                 "psr-3"
             ],
-            "support": {
-                "source": "https://github.com/php-fig/log/tree/1.1.3"
-            },
             "time": "2020-03-23T09:12:05+00:00"
         },
         {
@@ -428,6 +375,12 @@
             "license": [
                 "MIT"
             ],
+            "authors": [
+                {
+                    "name": "Jan Sorgalla",
+                    "email": "jsorgalla@gmail.com"
+                }
+            ],
             "description": "A lightweight implementation of CommonJS Promises/A for PHP",
             "time": "2016-03-07T13:46:50+00:00"
         },
@@ -478,10 +431,6 @@
                 "parser",
                 "validator"
             ],
-            "support": {
-                "issues": "https://github.com/Seldaek/jsonlint/issues",
-                "source": "https://github.com/Seldaek/jsonlint/tree/1.7.2"
-            },
             "time": "2019-10-24T14:27:39+00:00"
         },
         {
@@ -526,10 +475,6 @@
             "keywords": [
                 "phar"
             ],
-            "support": {
-                "issues": "https://github.com/Seldaek/phar-utils/issues",
-                "source": "https://github.com/Seldaek/phar-utils/tree/1.1.0"
-            },
             "time": "2020-02-14T15:25:33+00:00"
         },
         {
@@ -591,9 +536,6 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "https://symfony.com",
-            "support": {
-                "source": "https://github.com/symfony/console/tree/v2.8.52"
-            },
             "time": "2018-11-20T15:55:20+00:00"
         },
         {
@@ -651,9 +593,6 @@
             ],
             "description": "Symfony Debug Component",
             "homepage": "https://symfony.com",
-            "support": {
-                "source": "https://github.com/symfony/debug/tree/v2.8.50"
-            },
             "time": "2018-11-11T11:18:13+00:00"
         },
         {
@@ -704,9 +643,6 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com",
-            "support": {
-                "source": "https://github.com/symfony/filesystem/tree/v2.8.52"
-            },
             "time": "2018-11-11T11:18:13+00:00"
         },
         {
@@ -756,9 +692,6 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "support": {
-                "source": "https://github.com/symfony/finder/tree/v2.8.50"
-            },
             "time": "2018-11-11T11:18:13+00:00"
         },
         {
@@ -817,23 +750,6 @@
                 "polyfill",
                 "portable"
             ],
-            "support": {
-                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.15.0"
-            },
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-02-27T09:26:54+00:00"
         },
         {
@@ -893,23 +809,6 @@
                 "portable",
                 "shim"
             ],
-            "support": {
-                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.15.0"
-            },
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-03-09T19:04:49+00:00"
         },
         {
@@ -959,9 +858,6 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "support": {
-                "source": "https://github.com/symfony/process/tree/v2.8.50"
-            },
             "time": "2018-11-11T11:18:13+00:00"
         }
     ],
@@ -1018,10 +914,6 @@
                 "constructor",
                 "instantiate"
             ],
-            "support": {
-                "issues": "https://github.com/doctrine/instantiator/issues",
-                "source": "https://github.com/doctrine/instantiator/tree/master"
-            },
             "time": "2015-06-14T21:17:01+00:00"
         },
         {
@@ -1071,10 +963,6 @@
                     "email": "mike.vanriel@naenius.com"
                 }
             ],
-            "support": {
-                "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
-                "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/2.x"
-            },
             "time": "2016-01-25T08:17:30+00:00"
         },
         {
@@ -1138,10 +1026,6 @@
                 "spy",
                 "stub"
             ],
-            "support": {
-                "issues": "https://github.com/phpspec/prophecy/issues",
-                "source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
-            },
             "time": "2020-03-05T15:02:03+00:00"
         },
         {
@@ -1206,10 +1090,6 @@
                 "compare",
                 "equality"
             ],
-            "support": {
-                "issues": "https://github.com/sebastianbergmann/comparator/issues",
-                "source": "https://github.com/sebastianbergmann/comparator/tree/1.2"
-            },
             "time": "2017-01-29T09:50:25+00:00"
         },
         {
@@ -1262,10 +1142,6 @@
             "keywords": [
                 "diff"
             ],
-            "support": {
-                "issues": "https://github.com/sebastianbergmann/diff/issues",
-                "source": "https://github.com/sebastianbergmann/diff/tree/1.4"
-            },
             "time": "2017-05-22T07:24:03+00:00"
         },
         {
@@ -1333,10 +1209,6 @@
                 "export",
                 "exporter"
             ],
-            "support": {
-                "issues": "https://github.com/sebastianbergmann/exporter/issues",
-                "source": "https://github.com/sebastianbergmann/exporter/tree/master"
-            },
             "time": "2016-11-19T08:54:04+00:00"
         },
         {
@@ -1390,10 +1262,6 @@
             ],
             "description": "Provides functionality to recursively process PHP variables",
             "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
-            "support": {
-                "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
-                "source": "https://github.com/sebastianbergmann/recursion-context/tree/master"
-            },
             "time": "2016-11-19T07:33:16+00:00"
         },
         {
@@ -1459,23 +1327,6 @@
             ],
             "description": "Symfony PHPUnit Bridge",
             "homepage": "https://symfony.com",
-            "support": {
-                "source": "https://github.com/symfony/phpunit-bridge/tree/v3.4.38"
-            },
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
             "time": "2020-02-21T08:01:47+00:00"
         }
     ],
@@ -1492,6 +1343,5 @@
     "platform-dev": [],
     "platform-overrides": {
         "php": "5.3.9"
-    },
-    "plugin-api-version": "2.0.0"
+    }
 }

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

@@ -19,6 +19,7 @@ use Composer\IO\IOInterface;
 use Composer\Package\AliasPackage;
 use Composer\Package\PackageInterface;
 use Composer\Repository\InstalledRepositoryInterface;
+use Composer\Semver\Constraint\Bound;
 use Composer\Util\Filesystem;
 use Composer\Script\ScriptEvents;
 use Composer\Util\PackageSorter;
@@ -311,6 +312,7 @@ EOF;
             unlink($includeFilesFilePath);
         }
         $this->filePutContentsIfModified($targetDir.'/autoload_static.php', $this->getStaticFile($suffix, $targetDir, $vendorPath, $basePath, $staticPhpVersion));
+        $this->filePutContentsIfModified($targetDir.'/platform_check.php', $this->getPlatformCheck($packageMap));
         $this->filePutContentsIfModified($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
         $this->filePutContentsIfModified($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFileContents, $targetDirLoader, (bool) $includeFilesFileContents, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion));
 
@@ -570,6 +572,94 @@ EOF;
         return $baseDir . (($path !== false) ? var_export($path, true) : "");
     }
 
+    protected function getPlatformCheck($packageMap)
+    {
+        $lowestPhpVersion = Bound::zero();
+        $highestPhpVersion = Bound::positiveInfinity();
+        $requiredExtensions = array();
+
+        foreach ($packageMap as $item) {
+            list($package, $installPath) = $item;
+            foreach ($package->getRequires() as $link) {
+                if ('php' === $link->getTarget() && ($constraint = $link->getConstraint())) {
+                    if ($constraint->getLowerBound()->compareTo($lowestPhpVersion, '>')) {
+                        $lowestPhpVersion = $constraint->getLowerBound();
+                    }
+                    if ($constraint->getUpperBound()->compareTo($highestPhpVersion, '<')) {
+                        $highestPhpVersion = $constraint->getUpperBound();
+                    }
+                }
+
+                if (preg_match('{^ext-(.+)$}iD', $link->getTarget(), $match)) {
+                    $requiredExtensions[] = $match[1];
+                }
+            }
+        }
+
+        $requiredExtensions = array_values(array_unique($requiredExtensions));
+        sort($requiredExtensions);
+
+        $formatToPhpVersionId = function (Bound $bound) {
+            if ($bound->isZero()) {
+                return 0;
+            }
+
+            if ($bound->isPositiveInfinity()) {
+                return 99999;
+            }
+
+            $version = str_replace('-', '.', $bound->getVersion());
+            $chunks = array_map('intval', explode('.', $version));
+            return $chunks[0] * 10000 + $chunks[1] * 100 + $chunks[2];
+        };
+
+        $formatToHumanReadable = function (Bound $bound) {
+            if ($bound->isZero()) {
+                return 0;
+            }
+
+            if ($bound->isPositiveInfinity()) {
+                return 99999;
+            }
+
+            $version = str_replace('-', '.', $bound->getVersion());
+            $chunks = explode('.', $version);
+            $chunks = array_slice($chunks, 0, 3);
+            return implode('.', $chunks);
+        };
+
+        $lowestOperator = $lowestPhpVersion->isInclusive() ? '>=' : '>';
+        $highestOperator = $highestPhpVersion->isInclusive() ? '<=' : '<';
+        $lowestPhpVersionId = $formatToPhpVersionId($lowestPhpVersion);
+        $highestPhpVersionId = $formatToPhpVersionId($highestPhpVersion);
+        $lowestPhpVersion = $formatToHumanReadable($lowestPhpVersion);
+        $highestPhpVersion = $formatToHumanReadable($highestPhpVersion);
+        $requiredExtensions = var_export($requiredExtensions, true);
+
+        return <<<PLATFORM_CHECK
+<?php
+
+// platform_check.php @generated by Composer
+
+\$issues = array();
+
+if (!(PHP_VERSION_ID $lowestOperator $lowestPhpVersionId && PHP_VERSION_ID $highestOperator $highestPhpVersionId)) {
+    \$issues[] = 'Your Composer dependencies require a PHP version "$lowestOperator $lowestPhpVersion" and "$highestOperator $highestPhpVersion". You are running ' . PHP_VERSION  .  '.';
+}
+
+\$missingExtensions = array_diff($requiredExtensions, array_map('strtolower', get_loaded_extensions()));
+
+if (0 !== count(\$missingExtensions)) {
+    \$issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', \$missingExtensions);
+}
+
+if (0 !== count(\$issues)) {
+    die('Composer detected issues in your platform:' . "\\n\\n" . implode("\\n", \$issues));
+}
+
+PLATFORM_CHECK;
+    }
+
     protected function getAutoloadFile($vendorPathToTargetDirCode, $suffix)
     {
         $lastChar = $vendorPathToTargetDirCode[strlen($vendorPathToTargetDirCode) - 1];
@@ -618,6 +708,8 @@ class ComposerAutoloaderInit$suffix
             return self::\$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'), true, $prependAutoloader);
         self::\$loader = \$loader = new \\Composer\\Autoload\\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'));

+ 65 - 0
tests/Composer/Test/Autoload/AutoloadGeneratorTest.php

@@ -14,6 +14,7 @@ namespace Composer\Test\Autoload;
 
 use Composer\Autoload\AutoloadGenerator;
 use Composer\Package\Link;
+use Composer\Package\Version\VersionParser;
 use Composer\Semver\Constraint\Constraint;
 use Composer\Util\Filesystem;
 use Composer\Package\AliasPackage;
@@ -1625,6 +1626,70 @@ EOF;
         $this->assertAutoloadFiles('classmap', $this->vendorDir.'/composer', 'classmap');
     }
 
+    /**
+     * @dataProvider platformCheckProvider
+     */
+    public function testGeneratesPlatformCheck(array $requires, $expectedFixture)
+    {
+        $package = new Package('a', '1.0', '1.0');
+        $package->setRequires($requires);
+
+        $this->repository->expects($this->once())
+            ->method('getCanonicalPackages')
+            ->will($this->returnValue(array()));
+
+        $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_1');
+
+        $this->assertFileContentEquals(__DIR__ . '/Fixtures/platform/' . $expectedFixture . '.php', $this->vendorDir . '/composer/platform_check.php');
+    }
+
+    public function platformCheckProvider()
+    {
+        $versionParser = new VersionParser();
+
+        return array(
+            'Typical project requirements' => array(
+                array(
+                    new Link('a', 'php', $versionParser->parseConstraints('^7.2')),
+                    new Link('a', 'ext-xml', $versionParser->parseConstraints('*')),
+                    new Link('a', 'ext-json', $versionParser->parseConstraints('*'))
+                ),
+                'typical'
+            ),
+            'No PHP lower bound' => array(
+                array(
+                    new Link('a', 'php', $versionParser->parseConstraints('< 8')),
+                ),
+                'no_php_lower_bound'
+            ),
+            'No PHP upper bound' => array(
+                array(
+                    new Link('a', 'php', $versionParser->parseConstraints('>= 7.2')),
+                ),
+                'no_php_upper_bound'
+            ),
+            'Specific PHP release version' => array(
+                array(
+                    new Link('a', 'php', $versionParser->parseConstraints('^7.2.8')),
+                ),
+                'specific_php_release'
+            ),
+            'No PHP required' => array(
+                array(
+                    new Link('a', 'ext-xml', $versionParser->parseConstraints('*')),
+                    new Link('a', 'ext-json', $versionParser->parseConstraints('*'))
+                ),
+                'no_php_required'
+            ),
+            'No extensions required' => array(
+                array(
+                    new Link('a', 'php', $versionParser->parseConstraints('^7.2')),
+                ),
+                'no_extensions_required'
+            )
+        );
+    }
+
     private function assertAutoloadFiles($name, $dir, $type = 'namespaces')
     {
         $a = __DIR__.'/Fixtures/autoload_'.$name.'.php';

+ 2 - 0
tests/Composer/Test/Autoload/Fixtures/autoload_real_files_by_dependency.php

@@ -22,6 +22,8 @@ class ComposerAutoloaderInitFilesAutoloadOrder
             return self::$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInitFilesAutoloadOrder', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitFilesAutoloadOrder', 'loadClassLoader'));

+ 2 - 0
tests/Composer/Test/Autoload/Fixtures/autoload_real_functions.php

@@ -22,6 +22,8 @@ class ComposerAutoloaderInitFilesAutoload
             return self::$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInitFilesAutoload', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitFilesAutoload', 'loadClassLoader'));

+ 2 - 0
tests/Composer/Test/Autoload/Fixtures/autoload_real_functions_with_include_paths.php

@@ -22,6 +22,8 @@ class ComposerAutoloaderInitFilesAutoload
             return self::$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInitFilesAutoload', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitFilesAutoload', 'loadClassLoader'));

+ 2 - 0
tests/Composer/Test/Autoload/Fixtures/autoload_real_functions_with_removed_include_paths_and_autolad_files.php

@@ -22,6 +22,8 @@ class ComposerAutoloaderInitFilesAutoload
             return self::$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInitFilesAutoload', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitFilesAutoload', 'loadClassLoader'));

+ 2 - 0
tests/Composer/Test/Autoload/Fixtures/autoload_real_include_path.php

@@ -22,6 +22,8 @@ class ComposerAutoloaderInitIncludePath
             return self::$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInitIncludePath', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitIncludePath', 'loadClassLoader'));

+ 2 - 0
tests/Composer/Test/Autoload/Fixtures/autoload_real_target_dir.php

@@ -22,6 +22,8 @@ class ComposerAutoloaderInitTargetDir
             return self::$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInitTargetDir', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
         spl_autoload_unregister(array('ComposerAutoloaderInitTargetDir', 'loadClassLoader'));

+ 20 - 0
tests/Composer/Test/Autoload/Fixtures/platform/no_extensions_required.php

@@ -0,0 +1,20 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 70200 && PHP_VERSION_ID < 80000)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0" and "< 8.0.0". You are running ' . PHP_VERSION  .  '.';
+}
+
+$missingExtensions = array_diff(array (
+), array_map('strtolower', get_loaded_extensions()));
+
+if (0 !== count($missingExtensions)) {
+    $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions);
+}
+
+if (0 !== count($issues)) {
+    die('Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues));
+}

+ 20 - 0
tests/Composer/Test/Autoload/Fixtures/platform/no_php_lower_bound.php

@@ -0,0 +1,20 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 0 && PHP_VERSION_ID < 80000)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 0" and "< 8.0.0". You are running ' . PHP_VERSION  .  '.';
+}
+
+$missingExtensions = array_diff(array (
+), array_map('strtolower', get_loaded_extensions()));
+
+if (0 !== count($missingExtensions)) {
+    $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions);
+}
+
+if (0 !== count($issues)) {
+    die('Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues));
+}

+ 22 - 0
tests/Composer/Test/Autoload/Fixtures/platform/no_php_required.php

@@ -0,0 +1,22 @@
+<?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_diff(array (
+  0 => 'json',
+  1 => 'xml',
+), array_map('strtolower', get_loaded_extensions()));
+
+if (0 !== count($missingExtensions)) {
+    $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions);
+}
+
+if (0 !== count($issues)) {
+    die('Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues));
+}

+ 20 - 0
tests/Composer/Test/Autoload/Fixtures/platform/no_php_upper_bound.php

@@ -0,0 +1,20 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 70200 && PHP_VERSION_ID < 99999)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0" and "< 99999". You are running ' . PHP_VERSION  .  '.';
+}
+
+$missingExtensions = array_diff(array (
+), array_map('strtolower', get_loaded_extensions()));
+
+if (0 !== count($missingExtensions)) {
+    $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions);
+}
+
+if (0 !== count($issues)) {
+    die('Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues));
+}

+ 20 - 0
tests/Composer/Test/Autoload/Fixtures/platform/specific_php_release.php

@@ -0,0 +1,20 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 70208 && PHP_VERSION_ID < 80000)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.8" and "< 8.0.0". You are running ' . PHP_VERSION  .  '.';
+}
+
+$missingExtensions = array_diff(array (
+), array_map('strtolower', get_loaded_extensions()));
+
+if (0 !== count($missingExtensions)) {
+    $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions);
+}
+
+if (0 !== count($issues)) {
+    die('Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues));
+}

+ 22 - 0
tests/Composer/Test/Autoload/Fixtures/platform/typical.php

@@ -0,0 +1,22 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 70200 && PHP_VERSION_ID < 80000)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0" and "< 8.0.0". You are running ' . PHP_VERSION  .  '.';
+}
+
+$missingExtensions = array_diff(array (
+  0 => 'json',
+  1 => 'xml',
+), array_map('strtolower', get_loaded_extensions()));
+
+if (0 !== count($missingExtensions)) {
+    $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions);
+}
+
+if (0 !== count($issues)) {
+    die('Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues));
+}