/** * Install a fully downloaded package * * Using \PEAR2\Pyrus\FileTransactions and the PEAR2\Pyrus\Installer\Role* to * group files in appropriate locations, the install() method then passes * on the registration of installation to \PEAR2\Pyrus\Registry. If necessary, * Config will update the install-time snapshots of configuration * @param \PEAR2\Pyrus\Package $package */ function install(PackageInterface $package) { $this->_options = array(); $lastversion = Config::current()->registry->info($package->name, $package->channel, 'version'); $globalreplace = array('attribs' => array('from' => '@' . 'PACKAGE_VERSION@', 'to' => 'version', 'type' => 'package-info')); foreach ($package->installcontents as $file) { $channel = $package->channel; // {{{ assemble the destination paths $roles = Installer\Role::getValidRoles($package->getPackageType()); if (!in_array($file->role, $roles)) { throw new Installer\Exception('Invalid role `' . $file->role . "' for file " . $file->name); } $role = Installer\Role::factory($package->getPackageType(), $file->role); $role->setup($this, $package, $file['attribs'], $file->name); if (!$role->isInstallable()) { continue; } $transact = AtomicFileTransaction::getTransactionObject($role); $info = $role->getRelativeLocation($package, $file, true); $dir = $info[0]; $dest_file = $info[1]; // }}} // pretty much nothing happens if we are only registering the install if (isset($this->_options['register-only'])) { continue; } try { $transact->mkdir($dir, 0755); } catch (AtomicFileTransaction\Exception $e) { throw new Installer\Exception("failed to mkdir {$dir}", $e); } Logger::log(3, "+ mkdir {$dir}"); if ($file->md5sum) { $md5sum = md5_file($package->getFilePath($file->packagedname)); if (strtolower($md5sum) == strtolower($file->md5sum)) { Logger::log(2, "md5sum ok: {$dest_file}"); } else { if (!isset(Main::$options['force'])) { throw new Installer\Exception("bad md5sum for file " . $file->name); } Logger::log(0, "warning : bad md5sum for file " . $file->name); } } else { // installing from package.xml in source control, save the md5 of the current file $file->md5sum = md5_file($package->getFilePath($file->packagedname)); } if (strpos(PHP_OS, 'WIN') === false) { if ($role->isExecutable()) { $mode = ~octdec(Config::current()->umask) & 0777; Logger::log(3, "+ chmod +x {$dest_file}"); } else { $mode = ~octdec(Config::current()->umask) & 0666; } } else { $mode = null; } try { $transact->createOrOpenPath($dest_file, $package->getFileContents($file->packagedname, true), $mode); } catch (AtomicFileTransaction\Exception $e) { throw new Installer\Exception("failed writing to {$dest_file}", $e); } $tasks = $file->tasks; // only add the global replace task if it is not preprocessed if ($package->isNewPackage() && !$package->isPreProcessed()) { if (isset($tasks['tasks:replace'])) { if (isset($tasks['tasks:replace'][0])) { $tasks['tasks:replace'][] = $globalreplace; } else { $tasks['tasks:replace'] = array($tasks['tasks:replace'], $globalreplace); } } else { $tasks['tasks:replace'] = $globalreplace; } } $fp = false; foreach (new Package\Creator\TaskIterator($tasks, $package, Task\Common::INSTALL, $lastversion) as $name => $task) { if (!$fp) { $fp = $transact->openPath($dest_file); } $task->startSession($fp, $dest_file); if (!rewind($fp)) { throw new Installer\Exception('task ' . $name . ' closed the file pointer, invalid task'); } } if ($fp) { fclose($fp); } } }
/** * Uninstall a package * * Remove files * @param \PEAR2\Pyrus\Package $package */ function uninstall(PackageFileInterface $package, RegistryInterface $reg) { if (!empty($this->_options['register-only'])) { // pretty much nothing happens if we are only registering the install return; } try { $config = new Config\Snapshot($package->date . ' ' . $package->time); } catch (\Exception $e) { throw new Installer\Exception('Cannot retrieve files, config ' . 'snapshot could not be processed', $e); } $configpaths = array(); foreach (Installer\Role::getValidRoles($package->getPackageType()) as $role) { // set up a list of file role => configuration variable // for storing in the registry $roleobj = Installer\Role::factory($package->getPackageType(), $role); $configpaths[$role] = $config->{$roleobj->getLocationConfig()}; } $ret = array(); foreach ($reg->info($package->name, $package->channel, 'installedfiles') as $file) { $transact = AtomicFileTransaction::getTransactionObject($file['configpath']); $transact->removePath($file['relativepath']); } }