/** * 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; } }
/** * 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; } }