1
0
Fork 0

Add composer platform package with exact Composer version (#10313)

Co-authored-by: Lars Strojny <lars.strojny@internations.org>
Co-authored-by: Nils Adermann <naderman@naderman.de>
pull/9619/head
Helmut Hummel 2021-11-27 14:26:57 +01:00 committed by GitHub
parent 7a3d2b8157
commit ace8a1776c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 143 additions and 1 deletions

View File

@ -0,0 +1,77 @@
<!--
tagline: Making your package depend on specific Composer versions
-->
# Composer platform dependencies
## What are platform dependencies
Composer makes information about the environment Composer runs in available as virtual packages. This allows other
packages to define dependencies ([require](../04-schema.md#require), [conflict](../04-schema.md#conflict),
[provide](../04-schema.md#provide), [replace](../04-schema.md#replace)) on different aspects of the platform, like PHP,
extensions or system libraries, including version constraints.
When you require one of the platform packages no code is installed. The version numbers of platform packages are
derived from the environment Composer is executed in and they cannot be updated or removed. They can however be
overwritten for the purposes of dependency resolution with a [platform configuration](../06-config.md#platform).
**For example:** If you are executing `composer update` with a PHP interpreter in version
`7.4.42`, then Composer automatically adds a package to the pool of available packages
called `php` and assigns version `7.4.42` to it.
That's how packages can add a dependency on the used PHP version:
```json
{
"require" : {
"php" : ">=7.4"
}
}
```
Composer will check this requirement against the currently used PHP version when running the composer command.
### Different types of platform packages
The following types of platform packages exist and can be depended on:
1. PHP (`php` and the subtypes: `php-64bit`, `php-ipv6`, `php-zts` `php-debug`)
2. PHP Extensions (`ext-*`, e.g. `ext-mbstring`)
3. PHP Libraries (`lib-*`, e.g. `lib-curl`)
4. Composer (`composer`, `composer-plugin-api`, `composer-runtime-api`)
To see the complete list of platform packages available in your environment
you can run `php composer.phar show --platform` (or `show -p` for short).
The differences between the various Composer platform packages are explained further in this document.
## Plugin package `composer-plugin-api`
You can modify Composer's behavior with [plugin](plugins.md) packages. Composer provides a set of versioned APIs for
plugins. Because internal Composer changes may **not** change the plugin APIs, the API version may not increase every
time the Composer version increases. E.g. In Composer version `2.3.12`, the `composer-plugin-api` version could still
be `2.2.0`.
## Runtime package `composer-runtime-api`
When applications which were installed with Composer are run (either on CLI or through a web request), they require the
`vendor/autoload.php` file, typically as one of the first lines of executed code. Invocations of the Composer
autoloader are considered the application "runtime".
Starting with version 2.0, Composer makes [additional features](../07-runtime.md) (besides registering the class autoloader) available to the application runtime environment.
Similar to `composer-plugin-api`, not every Composer release adds new runtime features,
thus the version of `composer-runtimeapi` is also increased independently from Composer's version.
## Composer package `composer`
Starting with Composer 2.2.0, a new platform package called `composer` is available, which represents the exact
Composer version that is executed. Packages depending on this platform package can therefore depend on (or conflict
with) individual Composer versions to cover edge cases where neither the `composer-runtime-api` version nor the
`composer-plugin-api` was changed.
Because this option was introduced with Composer 2.2.0, it is recommended to add a `composer-plugin-api` dependency on
at least `>=2.2.0` to provide a more meaningful error message for users running older Composer versions.
In general, depending on `composer-plugin-api` or `composer-runtime-api` is always recommended
over depending on concrete Composer versions with the `composer` platform package.

View File

@ -31,7 +31,7 @@ use Composer\XdebugHandler\XdebugHandler;
*/
class PlatformRepository extends ArrayRepository
{
const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer-(?:plugin|runtime)-api)$}iD';
const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer(?:-(?:plugin|runtime)-api)?)$}iD';
/**
* @var ?string
@ -124,6 +124,12 @@ class PlatformRepository extends ArrayRepository
}
}
$prettyVersion = Composer::getVersion();
$version = $this->versionParser->normalize($prettyVersion);
$composer = new CompletePackage('composer', $version, $prettyVersion);
$composer->setDescription('Composer package');
$this->addPackage($composer);
$prettyVersion = PluginInterface::PLUGIN_API_VERSION;
$version = $this->versionParser->normalize($prettyVersion);
$composerPluginApi = new CompletePackage('composer-plugin-api', $version, $prettyVersion);

View File

@ -12,6 +12,7 @@
namespace Composer\Test\Repository;
use Composer\Composer;
use Composer\Package\Link;
use Composer\Package\PackageInterface;
use Composer\Repository\PlatformRepository;
@ -1213,6 +1214,64 @@ Linked Version => 1.2.11',
self::assertTrue($link->getConstraint()->matches($this->getVersionConstraint('=', $sourcePackage->getVersion())));
}
}
public function testComposerPlatformVersion()
{
$runtime = $this->getMockBuilder('Composer\Platform\Runtime')->getMock();
$runtime
->method('getExtensions')
->willReturn(array());
$runtime
->method('getConstant')
->willReturnMap(
array(
array('PHP_VERSION', null, '7.0.0'),
array('PHP_DEBUG', null, false),
)
);
$platformRepository = new PlatformRepository(array(), array(), $runtime);
$package = $platformRepository->findPackage('composer', '='.Composer::getVersion());
self::assertNotNull($package, 'Composer package exists');
}
public static function providePlatformPackages()
{
return array(
array('php', true),
array('php-debug', true),
array('php-ipv6', true),
array('php-64bit', true),
array('php-zts', true),
array('hhvm', true),
array('hhvm-foo', false),
array('ext-foo', true),
array('ext-123', true),
array('extfoo', false),
array('ext', false),
array('lib-foo', true),
array('lib-123', true),
array('libfoo', false),
array('lib', false),
array('composer', true),
array('composer-foo', false),
array('composer-plugin-api', true),
array('composer-plugin', false),
array('composer-runtime-api', true),
array('composer-runtime', false),
);
}
/**
* @param string $packageName
* @param bool $expectation
* @dataProvider providePlatformPackages
*/
public function testValidPlatformPackages($packageName, $expectation)
{
self::assertSame($expectation, PlatformRepository::isPlatformPackage($packageName));
}
}
class ResourceBundleStub