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
|
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
|
* @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;
|
$prettyVersion = PluginInterface::PLUGIN_API_VERSION;
|
||||||
$version = $this->versionParser->normalize($prettyVersion);
|
$version = $this->versionParser->normalize($prettyVersion);
|
||||||
$composerPluginApi = new CompletePackage('composer-plugin-api', $version, $prettyVersion);
|
$composerPluginApi = new CompletePackage('composer-plugin-api', $version, $prettyVersion);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
namespace Composer\Test\Repository;
|
namespace Composer\Test\Repository;
|
||||||
|
|
||||||
|
use Composer\Composer;
|
||||||
use Composer\Package\Link;
|
use Composer\Package\Link;
|
||||||
use Composer\Package\PackageInterface;
|
use Composer\Package\PackageInterface;
|
||||||
use Composer\Repository\PlatformRepository;
|
use Composer\Repository\PlatformRepository;
|
||||||
|
@ -1213,6 +1214,64 @@ Linked Version => 1.2.11',
|
||||||
self::assertTrue($link->getConstraint()->matches($this->getVersionConstraint('=', $sourcePackage->getVersion())));
|
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
|
class ResourceBundleStub
|
||||||
|
|
Loading…
Reference in New Issue