Example #1
0
 /**
  * Install packages slated for installation during transaction
  */
 static function commit()
 {
     if (static::$inTransaction === false) {
         return false;
     }
     try {
         static::preCommitDependencyResolve();
         $installer = new Installer();
         // validate dependencies
         $errs = new \PEAR2\MultiErrors();
         foreach (static::$installPackages as $package) {
             $package->validateDependencies(static::$installPackages, $errs);
         }
         if (count($errs->E_ERROR)) {
             throw new Installer\Exception('Dependency validation failed ' . 'for some packages to install, installation aborted', $errs);
         }
         // download non-local packages
         foreach (static::$installPackages as $package) {
             $fullPackageName = $package->channel . '/' . $package->name;
             Logger::log(1, 'Downloading ' . $fullPackageName);
             $package->download();
             if ($package->isPlugin()) {
                 // check for downloaded packages
                 if (!isset(Main::$options['install-plugins'])) {
                     // Check the plugin registry so we can provide more info
                     $command = 'install';
                     if (Config::current()->pluginregistry->exists($package->name, $package->channel)) {
                         $command = 'upgrade';
                     }
                     Logger::log(0, 'Skipping plugin ' . $fullPackageName . PHP_EOL . 'Plugins modify the installer and cannot be installed at the same time as regular packages.' . PHP_EOL . 'Add the -p option to manage plugins, for example:' . PHP_EOL . ' php pyrus.phar ' . $command . ' -p ' . $fullPackageName);
                     unset(static::$installPackages[$fullPackageName]);
                 }
             }
         }
         // now validate everything to the fine-grained level
         foreach (static::$installPackages as $package) {
             $package->validate(Validate::INSTALLING);
         }
         // create dependency connections and load them into the directed graph
         $graph = new DirectedGraph();
         foreach (static::$installPackages as $package) {
             $package->makeConnections($graph, static::$installPackages);
         }
         // topologically sort packages and install them via iterating over the graph
         $packages = $graph->topologicalSort();
         $reg = Config::current()->registry;
         try {
             AtomicFileTransaction::begin();
             $reg->begin();
             if (isset(Main::$options['upgrade'])) {
                 foreach ($packages as $package) {
                     $fullPackageName = $package->channel . '/' . $package->name;
                     if ($reg->exists($package->name, $package->channel)) {
                         static::$wasInstalled[$fullPackageName] = $reg->package[$fullPackageName];
                         $reg->uninstall($package->name, $package->channel);
                     }
                 }
             }
             static::detectDownloadConflicts($packages, $reg);
             foreach ($packages as $package) {
                 if (isset(static::$installedPackages[$package->channel . '/' . $package->name])) {
                     continue;
                 }
                 $installer->install($package);
                 static::$installedPackages[$package->channel . '/' . $package->name] = $package;
             }
             foreach (static::$installedPackages as $package) {
                 try {
                     $previous = $reg->toPackageFile($package->name, $package->channel, true);
                 } catch (\Exception $e) {
                     $previous = null;
                 }
                 $reg->install($package->getPackageFile()->info);
                 static::$registeredPackages[] = array($package, $previous);
             }
             static::$installPackages = array();
             AtomicFileTransaction::commit();
             $reg->commit();
         } catch (AtomicFileTransaction\Exception $e) {
             $errs = new \PEAR2\MultiErrors();
             $errs->E_ERROR[] = $e;
             try {
                 AtomicFileTransaction::rollback();
             } catch (\Exception $ex) {
                 $errs->E_WARNING[] = $ex;
             }
             try {
                 $reg->rollback();
             } catch (\Exception $ex) {
                 $errs->E_WARNING[] = $ex;
             }
             throw new Installer\Exception('Installation failed', $errs);
         }
         Config::current()->saveConfig();
         // success
         AtomicFileTransaction::removeBackups();
         static::$inTransaction = false;
         if (isset(Main::$options['install-plugins'])) {
             Config::setCurrent(self::$lastCurrent->path);
         }
     } catch (\Exception $e) {
         static::rollback();
         throw $e;
     }
 }
Example #2
0
    /**
     * Install packages slated for installation during transaction
     */
    static function commit()
    {
        if (self::$inTransaction === false) {
            return false;
        }

        $installer = new Uninstaller;
        // validate dependencies
        $errs = new \PEAR2\MultiErrors;
        $reg = Config::current()->registry;
        try {
            foreach (self::$uninstallPackages as $package) {
                $package->validateUninstallDependencies(self::$uninstallPackages, $errs);
            }

            if (count($errs->E_ERROR)) {
                throw new Installer\Exception('Dependency validation failed ' .
                    'for some installed packages, installation aborted', $errs);
            }

            // create dependency connections and load them into the directed graph
            $graph = new DirectedGraph;
            foreach (self::$uninstallPackages as $package) {
                $package->makeUninstallConnections($graph, self::$uninstallPackages);
            }

            // topologically sort packages and install them via iterating over the graph
            $actual = array();
            foreach ($graph as $package) {
                $actual[] = $package;
            }

            // easy reverse topological sort
            array_reverse($actual);

            AtomicFileTransaction::begin();
            $reg->begin();
            try {
                foreach ($actual as $package) {
                    $installer->uninstall($package, $reg);
                    self::$uninstalledPackages[] = $package;
                }

                $dirtrees = array();
                foreach (self::$uninstalledPackages as $package) {
                    $dirtrees[] = $reg->info($package->name, $package->channel, 'dirtree');
                    $previous   = $reg->toPackageFile($package->name, $package->channel, true);
                    self::$registeredPackages[] = array($package, $previous);
                    $reg->uninstall($package->name, $package->channel);
                }

                AtomicFileTransaction::rmEmptyDirs($dirtrees);
                AtomicFileTransaction::commit();
                $reg->commit();
                AtomicFileTransaction::removeBackups();
            } catch (\Exception $e) {
                if (AtomicFileTransaction::inTransaction()) {
                    AtomicFileTransaction::rollback();
                }

                $reg->rollback();
                throw $e;
            }

            self::$uninstallPackages = array();
            Config::current()->saveConfig();
            if (isset(Main::$options['install-plugins'])) {
                Config::setCurrent(self::$lastCurrent->path);
            }
        } catch (\Exception $e) {
            self::rollback();
            throw $e;
        }
    }