Merge branch '2.2' into main

main
Jordi Boggiano 2 years ago
commit 40de07569d
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC

@ -46,7 +46,9 @@ Composer fires the following named events during its execution process:
### Installer Events
- **pre-operations-exec**: occurs before the install/upgrade/.. operations
are executed when installing a lock file.
are executed when installing a lock file. Plugins that need to hook into
this event will need to be installed globally to be usable, as otherwise
they would not be loaded yet when a fresh install of a project happens.
### Package Events

@ -3,7 +3,9 @@
Certain Composer commands, including `exec`, `install`, and `update` allow third party code to
execute on your system. This is from its "plugins" and "scripts" features. Plugins and scripts have
full access to the user account which runs Composer. For this reason, it is strongly advised to
**avoid running Composer as super-user/root**.
**avoid running Composer as super-user/root**. All commands also dispatch events which can be
caught by plugins so unless explicitly disabled installed plugins will be loaded/executed by **every**
Composer command.
You can disable plugins and scripts during package installation or updates with the following
syntax so only Composer's code, and no third party code, will execute:
@ -13,10 +15,11 @@ php composer.phar install --no-plugins --no-scripts ...
php composer.phar update --no-plugins --no-scripts ...
```
The `exec` command will always run third party code as the user which runs `composer`.
Depending on the operating system we have seen cases where it is possible to trigger execution
of files in the repository using specially crafted `composer.json`. So in general if you do want
to install untrusted dependencies you should sandbox them completely in a container or equivalent.
In some cases, like in CI systems or such where you want to install untrusted dependencies, the
safest way to do it is to run the above command.
Also note that the `exec` command will always run third party code as the user which runs `composer`.
See [Environment variable - COMPOSER_ALLOW_SUPERUSER](../03-cli.md#composer-allow-superuser)
See [Environment variable - COMPOSER_ALLOW_SUPERUSER](../03-cli.md#composer-allow-superuser)
for more info on how to disable warning

@ -95,12 +95,6 @@ trait PackageDiscoveryTrait
$requirement['version'],
$requirement['name']
));
} else {
// check that the specified version/constraint exists before we proceed
list($name) = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $platformRepo, $preferredStability, $checkProvidedVersions ? $requirement['version'] : null, 'dev', $fixed);
// replace package name from packagist.org
$requirement['name'] = $name;
}
$result[] = $requirement['name'] . ' ' . $requirement['version'];
@ -139,20 +133,8 @@ trait PackageDiscoveryTrait
$matches = array_values($matches);
$exactMatch = false;
$choices = array();
foreach ($matches as $position => $foundPackage) {
$abandoned = '';
if (isset($foundPackage['abandoned'])) {
if (is_string($foundPackage['abandoned'])) {
$replacement = sprintf('Use %s instead', $foundPackage['abandoned']);
} else {
$replacement = 'No replacement was suggested';
}
$abandoned = sprintf('<warning>Abandoned. %s.</warning>', $replacement);
}
$choices[] = sprintf(' <info>%5s</info> %s %s', "[$position]", $foundPackage['name'], $abandoned);
if ($foundPackage['name'] === $package) {
foreach ($matches as $match) {
if ($match['name'] === $package) {
$exactMatch = true;
break;
}
@ -160,6 +142,26 @@ trait PackageDiscoveryTrait
// no match, prompt which to pick
if (!$exactMatch) {
$providers = $this->getRepos()->getProviders($package);
if (count($providers) > 0) {
array_unshift($matches, array('name' => $package, 'description' => ''));
}
$choices = array();
foreach ($matches as $position => $foundPackage) {
$abandoned = '';
if (isset($foundPackage['abandoned'])) {
if (is_string($foundPackage['abandoned'])) {
$replacement = sprintf('Use %s instead', $foundPackage['abandoned']);
} else {
$replacement = 'No replacement was suggested';
}
$abandoned = sprintf('<warning>Abandoned. %s.</warning>', $replacement);
}
$choices[] = sprintf(' <info>%5s</info> %s %s', "[$position]", $foundPackage['name'], $abandoned);
}
$io->writeError(array(
'',
sprintf('Found <info>%s</info> packages matching <info>%s</info>', count($matches), $package),
@ -257,7 +259,8 @@ trait PackageDiscoveryTrait
$platformRequirementFilter = $this->getPlatformRequirementFilter($input);
// find the latest version allowed in this repo set
$versionSelector = new VersionSelector($this->getRepositorySet($input, $minimumStability), $platformRepo);
$repoSet = $this->getRepositorySet($input, $minimumStability);
$versionSelector = new VersionSelector($repoSet, $platformRepo);
$effectiveMinimumStability = $minimumStability ?? $this->getMinimumStability($input);
$package = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, $platformRequirementFilter);
@ -269,6 +272,22 @@ trait PackageDiscoveryTrait
return array($name, $requiredVersion ?: '*');
}
// Check if it is a virtual package provided by others
$providers = $repoSet->getProviders($name);
if (count($providers) > 0) {
$constraint = '*';
if ($input->isInteractive()) {
$constraint = $this->getIO()->askAndValidate('Package "<info>'.$name.'</info>" does not exist but is provided by '.count($providers).' packages. Which version constraint would you like to use? [<info>*</info>] ', function ($value) {
$parser = new VersionParser();
$parser->parseConstraints($value);
return $value;
}, 3, '*');
}
return array($name, $constraint);
}
// Check whether the package requirements were the problem
if (!($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter) && false !== ($candidate = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, PlatformRequirementFilterFactory::ignoreAll()))) {
throw new \InvalidArgumentException(sprintf(

@ -20,6 +20,9 @@ use Composer\Util\ComposerMirror;
* Core package definitions that are needed to resolve dependencies and install packages
*
* @author Nils Adermann <naderman@naderman.de>
*
* @phpstan-import-type AutoloadRules from PackageInterface
* @phpstan-import-type DevAutoloadRules from PackageInterface
*/
class Package extends BasePackage
{
@ -79,9 +82,15 @@ class Package extends BasePackage
protected $devRequires = array();
/** @var array<string, string> */
protected $suggests = array();
/** @var array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>} */
/**
* @var array
* @phpstan-var AutoloadRules
*/
protected $autoload = array();
/** @var array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>} */
/**
* @var array
* @phpstan-var DevAutoloadRules
*/
protected $devAutoload = array();
/** @var string[] */
protected $includePaths = array();
@ -598,7 +607,7 @@ class Package extends BasePackage
*
* @return void
*
* @phpstan-param array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>} $autoload
* @phpstan-param AutoloadRules $autoload
*/
public function setAutoload(array $autoload)
{
@ -620,7 +629,7 @@ class Package extends BasePackage
*
* @return void
*
* @phpstan-param array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>} $devAutoload
* @phpstan-param DevAutoloadRules $devAutoload
*/
public function setDevAutoload(array $devAutoload)
{

@ -18,6 +18,9 @@ use Composer\Repository\RepositoryInterface;
* Defines the essential information a package has that is used during solving/installation
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*
* @phpstan-type AutoloadRules array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>, exclude-from-classmap?: list<string>}
* @phpstan-type DevAutoloadRules array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>}
*/
interface PackageInterface
{
@ -303,7 +306,7 @@ interface PackageInterface
* directories for autoloading using the type specified.
*
* @return array Mapping of autoloading rules
* @phpstan-return array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>}
* @phpstan-return AutoloadRules
*/
public function getAutoload();
@ -316,7 +319,7 @@ interface PackageInterface
* directories for autoloading using the type specified.
*
* @return array Mapping of dev autoloading rules
* @phpstan-return array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>}
* @phpstan-return DevAutoloadRules
*/
public function getDevAutoload();

@ -16,6 +16,9 @@ namespace Composer\Package;
* Defines additional fields that are only needed for the root package
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*
* @phpstan-import-type AutoloadRules from PackageInterface
* @phpstan-import-type DevAutoloadRules from PackageInterface
*/
interface RootPackageInterface extends CompletePackageInterface
{
@ -122,7 +125,8 @@ interface RootPackageInterface extends CompletePackageInterface
/**
* Set the autoload mapping
*
* @param array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>} $autoload Mapping of autoloading rules
* @param array $autoload Mapping of autoloading rules
* @phpstan-param AutoloadRules $autoload
*
* @return void
*/
@ -131,7 +135,8 @@ interface RootPackageInterface extends CompletePackageInterface
/**
* Set the dev autoload mapping
*
* @param array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>} $devAutoload Mapping of dev autoloading rules
* @param array $devAutoload Mapping of dev autoloading rules
* @phpstan-param DevAutoloadRules $devAutoload
*
* @return void
*/

Loading…
Cancel
Save