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
parent
7a3d2b8157
commit
ace8a1776c
|
@ -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.
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue