1
0
Fork 0

Merge branch '2.5'

pull/11334/head
Jordi Boggiano 2023-02-10 13:24:19 +01:00
commit a9b79ba470
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
3 changed files with 24 additions and 3 deletions

View File

@ -1,3 +1,7 @@
### [2.5.3] 2023-02-10
* Added extra.plugin-optional support for allow auto-disabling unknown plugins which are not critical when running non-interactive (#11315)
### [2.5.2] 2023-02-04
* Added warning when `require` auto-selects a feature branch as that is probably not desired (#11270)
@ -1691,6 +1695,7 @@
* Initial release
[2.5.3]: https://github.com/composer/composer/compare/2.5.2...2.5.3
[2.5.2]: https://github.com/composer/composer/compare/2.5.1...2.5.2
[2.5.1]: https://github.com/composer/composer/compare/2.5.0...2.5.1
[2.5.0]: https://github.com/composer/composer/compare/2.4.4...2.5.0

View File

@ -332,6 +332,20 @@ in your composer.json to hint to Composer that the plugin should be activated as
as possible to prevent any bad side-effects from Composer assuming packages are installed
in another location than they actually are.
### plugin-optional
Because Composer plugins can be used to perform actions which are necessary for installing
a working application, like modifying which path files get stored in, skipping required
plugins unintentionally can result in broken applications. So, in non-interactive mode,
Composer will fail if a new plugin is not listed in ["allow-plugins"](../06-config.md#allow-plugins)
to force users to decide if they want to execute the plugin, to avoid silent failures.
As of Composer 2.5.3, you can use the setting `{"extra": {"plugin-optional": true}}` on
your plugin, to tell Composer that skipping the plugin has no catastrophic consequences,
and it can safely be disabled in non-interactive mode if it is not yet listed in
"allow-plugins". The next interactive run of Composer will still prompt users to choose if
they want to enable or disable the plugin.
## Plugin Autoloading
Due to plugins being loaded by Composer at runtime, and to ensure that plugins which

View File

@ -187,7 +187,7 @@ class PluginManager
}
}
if (!$this->isPluginAllowed($package->getName(), $isGlobalPlugin)) {
if (!$this->isPluginAllowed($package->getName(), $isGlobalPlugin, $package->getExtra()['plugin-optional'] ?? false)) {
$this->io->writeError('Skipped loading "'.$package->getName() . '" '.($isGlobalPlugin || $this->runningInGlobalDir ? '(installed globally) ' : '').'as it is not in config.allow-plugins', true, IOInterface::DEBUG);
return;
@ -370,7 +370,7 @@ class PluginManager
if ($sourcePackage === null) {
trigger_error('Calling PluginManager::addPlugin without $sourcePackage is deprecated, if you are using this please get in touch with us to explain the use case', E_USER_DEPRECATED);
} elseif (!$this->isPluginAllowed($sourcePackage->getName(), $isGlobalPlugin)) {
} elseif (!$this->isPluginAllowed($sourcePackage->getName(), $isGlobalPlugin, $sourcePackage->getExtra()['plugin-optional'] ?? false)) {
$this->io->writeError('Skipped loading "'.get_class($plugin).' from '.$sourcePackage->getName() . '" '.($isGlobalPlugin || $this->runningInGlobalDir ? '(installed globally) ' : '').' as it is not in config.allow-plugins', true, IOInterface::DEBUG);
return;
@ -656,7 +656,7 @@ class PluginManager
/**
* @internal
*/
public function isPluginAllowed(string $package, bool $isGlobalPlugin): bool
public function isPluginAllowed(string $package, bool $isGlobalPlugin, bool $optional = false): bool
{
if ($isGlobalPlugin) {
$rules = &$this->allowGlobalPluginRules;
@ -733,6 +733,8 @@ class PluginManager
break;
}
}
} elseif ($optional) {
return false;
}
throw new PluginBlockedException(