Переглянути джерело

Load plugins before purging packages, fixes #3557

Jordi Boggiano 10 роки тому
батько
коміт
2b16a73659

+ 6 - 5
src/Composer/Factory.php

@@ -283,11 +283,6 @@ class Factory
         // add installers to the manager (must happen after download manager is created since they read it out of $composer)
         $this->createDefaultInstallers($im, $composer, $io);
 
-        // purge packages if they have been deleted on the filesystem
-        if ($rm->getLocalRepository()) {
-            $this->purgePackages($rm->getLocalRepository(), $im);
-        }
-
         if ($fullLoad) {
             $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins);
             $pm = $this->createPluginManager($io, $composer, $globalComposer);
@@ -296,6 +291,12 @@ class Factory
             if (!$disablePlugins) {
                 $pm->loadInstalledPlugins();
             }
+
+            // once we have plugins and custom installers we can
+            // purge packages from local repos if they have been deleted on the filesystem
+            if ($rm->getLocalRepository()) {
+                $this->purgePackages($rm->getLocalRepository(), $im);
+            }
         }
 
         // init locker if possible

+ 2 - 2
src/Composer/Installer/PluginInstaller.php

@@ -61,7 +61,7 @@ class PluginInstaller extends LibraryInstaller
         }
 
         parent::install($repo, $package);
-        $this->composer->getPluginManager()->registerPackage($package);
+        $this->composer->getPluginManager()->registerPackage($package, true);
     }
 
     /**
@@ -75,6 +75,6 @@ class PluginInstaller extends LibraryInstaller
         }
 
         parent::update($repo, $initial, $target);
-        $this->composer->getPluginManager()->registerPackage($target);
+        $this->composer->getPluginManager()->registerPackage($target, true);
     }
 }

+ 5 - 2
src/Composer/Plugin/PluginManager.php

@@ -190,10 +190,11 @@ class PluginManager
      * instead for BC
      *
      * @param PackageInterface $package
+     * @param bool             $failOnMissingClasses By default this silently skips plugins that can not be found, but if set to true it fails with an exception
      *
      * @throws \UnexpectedValueException
      */
-    public function registerPackage(PackageInterface $package)
+    public function registerPackage(PackageInterface $package, $failOnMissingClasses = false)
     {
         $oldInstallerPlugin = ($package->getType() === 'composer-installer');
 
@@ -242,10 +243,12 @@ class PluginManager
             if ($oldInstallerPlugin) {
                 $installer = new $class($this->io, $this->composer);
                 $this->composer->getInstallationManager()->addInstaller($installer);
-            } else {
+            } elseif (class_exists($class)) {
                 $plugin = new $class();
                 $this->addPlugin($plugin);
                 $this->registeredPlugins[] = $package->getName();
+            } elseif ($failOnMissingClasses) {
+                throw new \UnexpectedValueException('Plugin '.$package->getName().' could not be initialized, class not found: '.$class);
             }
         }
     }