Merge branch '2.2' into main
commit
40de07569d
|
@ -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)
|
||||
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…
Reference in New Issue