diff --git a/src/Composer/Command/RemoveCommand.php b/src/Composer/Command/RemoveCommand.php index 535739fd0..39aa02891 100644 --- a/src/Composer/Command/RemoveCommand.php +++ b/src/Composer/Command/RemoveCommand.php @@ -210,6 +210,10 @@ EOT return 0; } + if ($composer = $this->getComposer(false)) { + $composer->getPluginManager()->deactivateInstalledPlugins(); + } + // Update packages $this->resetComposer(); $composer = $this->getComposer(true, $input->getOption('no-plugins')); diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index aa5a4e105..b2c5239fb 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -278,6 +278,8 @@ EOT return 0; } + $composer->getPluginManager()->deactivateInstalledPlugins(); + try { return $this->doUpdate($input, $output, $io, $requirements, $requireKey, $removeKey); } catch (\Exception $e) { diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php index 87dc2d6d5..7c8734811 100644 --- a/src/Composer/Plugin/PluginManager.php +++ b/src/Composer/Plugin/PluginManager.php @@ -90,6 +90,25 @@ class PluginManager } } + /** + * Deactivate all plugins from currently installed plugin packages + * + * @return void + */ + public function deactivateInstalledPlugins() + { + if ($this->disablePlugins) { + return; + } + + $repo = $this->composer->getRepositoryManager()->getLocalRepository(); + $globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null; + $this->deactivateRepository($repo, false); + if ($globalRepo) { + $this->deactivateRepository($globalRepo, true); + } + } + /** * Gets all currently active plugin instances * @@ -428,6 +447,34 @@ class PluginManager } } + /** + * Deactivate all plugins and installers from a repository + * + * If a plugin requires another plugin, the required one will be deactivated last + * + * @param RepositoryInterface $repo Repository to scan for plugins to install + * @param bool $isGlobalRepo + * + * @return void + */ + private function deactivateRepository(RepositoryInterface $repo, $isGlobalRepo) + { + $packages = $repo->getPackages(); + $sortedPackages = array_reverse(PackageSorter::sortPackages($packages)); + + foreach ($sortedPackages as $package) { + if (!($package instanceof CompletePackage)) { + continue; + } + if ('composer-plugin' === $package->getType()) { + $this->deactivatePackage($package); + // Backward compatibility + } elseif ('composer-installer' === $package->getType()) { + $this->deactivatePackage($package); + } + } + } + /** * Recursively generates a map of package names to packages for all deps *