function key() { $curfile = $this->current(); $role = \PEAR2\Pyrus\Installer\Role::factory(self::$_parent->getPackageType(), $curfile['attribs']['role']); // add the install-as attribute to retrieve packaging location return $role->getPackagingLocation(self::$_parent, $curfile['attribs']); }
function getFilePath($file) { $role = \PEAR2\Pyrus\Installer\Role::factory($this->packagefile->getPackageType(), $this->packagefile->packagingcontents[$file]['attribs']['role']); list(, $path) = $role->getRelativeLocation($this->packagefile, new \PEAR2\Pyrus\PackageFile\v2Iterator\FileTag($this->packagefile->packagingcontents[$file], '', $this->packagefile), true); $dir = \PEAR2\Pyrus\Config::singleton($this->registry->getPath())->{$role->getLocationConfig()}; return $dir . DIRECTORY_SEPARATOR . $path; }
/** * Detect any files already installed that would be overwritten by * files inside the package represented by $package */ public function detectFileConflicts(\PEAR2\Pyrus\PackageFileInterface $package) { // construct list of all installed files $filesByPackage = $allfiles = array(); $config = \PEAR2\Pyrus\Config::current(); foreach ($config->channelregistry as $channel) { foreach ($this->listPackages($channel->name) as $packagename) { $files = $this->info($packagename, $channel->name, 'installedfiles'); $newfiles = array(); foreach ($files as $file) { $newfiles[$file['installed_as']] = $file; } $filesByPackage[$channel->name . '/' . $packagename] = $newfiles; $allfiles = array_merge($allfiles, $newfiles); } } // now iterate over each file in the package, and note all the conflicts $roles = array(); foreach (Role::getValidRoles($package->getPackageType()) as $role) { // set up a list of file role => configuration variable // for storing in the registry $roles[$role] = Role::factory($package->getPackageType(), $role); } $ret = array(); foreach ($package->installcontents as $file) { $relativepath = $roles[$file->role]->getRelativeLocation($package, $file); if (!$relativepath) { continue; } $testpath = $config->{$roles[$file->role]->getLocationConfig()} . DIRECTORY_SEPARATOR . $relativepath; if (isset($allfiles[$testpath])) { foreach ($filesByPackage as $pname => $files) { if (isset($files[$testpath])) { $ret[] = array($relativepath => $pname); break; } } } } return $ret; }
/** * Scan the directories top populate the package file contents. * * @param string $packagepath */ function scanFiles($packagepath, $scanoptions) { $base_install_dirs = array('src' => implode('/', $packagepath), 'customrole' => '/', 'customtask' => '/', 'customcommand' => '/', 'data' => '/', 'docs' => '/', 'tests' => '/', 'scripts' => '/', 'www' => '/'); if (isset($scanoptions['baseinstalldirs'])) { if (!is_array($scanoptions['baseinstalldirs'])) { throw new \PEAR2\Pyrus\Developer\Creator\Exception('invalid scan options,' . 'baseinstalldirs must ' . 'be an array'); } $base_install_dirs = array_merge($base_install_dirs, $scanoptions['baseinstalldirs']); } $this->setBaseInstallDirs($base_install_dirs); $rolemap = array('src' => 'php', 'data' => 'data', 'customrole' => 'customrole', 'customtask' => 'customtask', 'customcommand' => 'customcommand', 'docs' => 'doc', 'tests' => 'test', 'examples' => 'doc', 'scripts' => 'script', 'www' => 'www'); if (isset($scanoptions['rolemap'])) { if (!is_array($scanoptions['rolemap'])) { throw new \PEAR2\Pyrus\Developer\Creator\Exception('invalid scan options,' . 'rolemap must ' . 'be an array'); } $rolemap = array_merge($rolemap, $scanoptions['rolemap']); } if (!isset($scanoptions['mappath'])) { $scanoptions['mappath'] = array(); } elseif (!is_array($scanoptions['mappath'])) { throw new \PEAR2\Pyrus\Developer\Creator\Exception('invalid scan options,' . 'mappath must ' . 'be an array'); } if (!isset($scanoptions['ignore'])) { $scanoptions['ignore'] = array(); } else { if (!is_array($scanoptions['ignore'])) { throw new \PEAR2\Pyrus\Developer\Creator\Exception('invalid scan options,' . 'ignore must ' . 'be an array'); } foreach ($scanoptions['ignore'] as $path => $type) { if (!is_string($path)) { throw new \PEAR2\Pyrus\Developer\Creator\Exception('invalid scan options,' . 'ignore must ' . 'be an associative array ' . 'mapping path to type of ignore'); } if ($type !== 'file' && $type !== 'dir') { throw new \PEAR2\Pyrus\Developer\Creator\Exception('invalid scan options,' . 'ignore of ' . $path . ' must be either file or dir, but was ' . $type); } } } foreach ($rolemap as $dir => $role) { if (file_exists($this->path . DIRECTORY_SEPARATOR . $dir)) { $basepath = $dir === 'examples' ? 'examples' : ''; foreach (new \PEAR2\Pyrus\Developer\PackageFile\PEAR2SVN\Filter($scanoptions['ignore'], $this->path . DIRECTORY_SEPARATOR . $dir, new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->path . DIRECTORY_SEPARATOR . $dir), \RecursiveIteratorIterator::LEAVES_ONLY), $role) as $file) { $curpath = str_replace($this->path . DIRECTORY_SEPARATOR . $dir, '', $file->getPathName()); if ($curpath && $curpath[0] === DIRECTORY_SEPARATOR) { $curpath = substr($curpath, 1); } if (isset($scanoptions['mappath'][$dir])) { $curpath = $scanoptions['mappath'][$dir] . '/' . $curpath; } else { $curpath = $dir . '/' . $curpath; } $curpath = str_replace(array('\\', '//'), '/', $curpath); $this->pxml->files[$curpath] = array('attribs' => array('role' => $role)); if ($this->doCompatible) { $roleobject = \PEAR2\Pyrus\Installer\Role::factory($this->pxml->type, $role); if ($role == 'customcommand' || $role == 'customrole' || $role == 'customtask') { $compatiblerole = 'data'; } else { $compatiblerole = $role; } $attribs = array('name' => $curpath, 'role' => $compatiblerole); $baseinstalldir = $this->pxml_compatible->getBaseinstallDir($curpath); if ($baseinstalldir && $baseinstalldir != '/') { $attribs['baseinstalldir'] = $baseinstalldir; } $curpath = $roleobject->getPackagingLocation($this->pxml_compatible, $attribs); $packagepath = $roleobject->getCompatibleInstallAs($this->pxml_compatible, $attribs); $this->pxml_compatible->files[$curpath] = array('attribs' => array('role' => $compatiblerole)); $this->pxml_compatible->release[0]->installAs($curpath, $packagepath); } } } } if ($this->doCompatible) { $this->pxml_compatible->dependencies['required']->pearinstaller->min = '1.4.8'; } }
/** * Render packages from the creators passed into the constructor. * * This will take any package source and an array mapping internal * path => file name and create new packages in the formats requested. * * All files in package.xml will have the string @PACKAGE_VERSION@ * automatically replaced with the current package's version * @param \PEAR2\Pyrus\Package $package * @param array $extrafiles */ function render(\PEAR2\Pyrus\Package $package, array $extrafiles = array()) { foreach ($this->_creators as $creator) { $creator->init(); } $this->prepend = $prepend = $package->name . '-' . $package->version['release']; if ($package->isNewPackage()) { $packagexml = $prepend . '/.xmlregistry/packages/' . str_replace('/', '!', $package->channel) . '/' . $package->name . '/' . $package->version['release'] . '-info.xml'; } else { if ($package->isOldAndCrustyCompatible()) { $packagexml = 'package2.xml'; $old = file_get_contents('package.xml'); } else { $packagexml = 'package.xml'; } } if (self::VERSION === '@' . 'PACKAGE_VERSION@') { // we're running straight from SVN, so pretend to be 2.0.0 $package->packagerversion = '2.0.0'; } else { $package->packagerversion = self::VERSION; } // get packaging package.xml $packageingstr = (string) new \PEAR2\Pyrus\XMLWriter($package->toArray(true)); foreach ($this->_creators as $creator) { $creator->addFile($packagexml, $packageingstr); } if ($package->isOldAndCrustyCompatible()) { foreach ($this->_creators as $creator) { $creator->addFile('package.xml', $old); } } if ($package->getInternalPackage() instanceof Xml) { // check for package_compatible.xml if ($package->isNewPackage() && file_exists($package->getFilePath('package_compatible.xml'))) { foreach ($this->_creators as $creator) { $creator->addFile('package.xml', file_get_contents($package->getFilePath('package_compatible.xml'))); } } } $packagingloc = \PEAR2\Pyrus\Config::current()->temp_dir . DIRECTORY_SEPARATOR . 'pyrpackage'; if (file_exists($packagingloc)) { \PEAR2\Pyrus\Filesystem::rmrf($packagingloc, false, false); } mkdir($packagingloc, 0777, true); // $packageat is the relative path within the archive // $info is an array of format: // array('attribs' => array('name' => ...)[, 'tasks:blah' ...]) $alreadyPackaged = array(); $globalreplace = array('attribs' => array('from' => '@' . 'PACKAGE_VERSION@', 'to' => 'version', 'type' => 'package-info')); foreach ($package->packagingcontents as $packageat => $info) { $role = \PEAR2\Pyrus\Installer\Role::factory($package->getPackageType(), $info['attribs']['role']); try { $role->packageTimeValidate($package, $info); } catch (\Exception $e) { throw new Creator\Exception('Invalid file ' . $packageat . ': ' . $e->getMessage(), $e); } $packageat = str_replace('\\', '/', $packageat); $packageat = str_replace('//', '/', $packageat); if ($packageat[0] === '/' || strlen($packageat) > 2 && ($packageat[1] === ':' && $packageat[2] == '/')) { throw new Creator\Exception('Invalid path, cannot save a root path ' . $packageat); } if (preg_match('@^\\.\\.?/|/\\.\\.?\\z|/\\.\\./@', $packageat)) { throw new Creator\Exception('Invalid path, cannot use directory ' . 'reference . or .. ' . $packageat); } $alreadyPackaged[$packageat] = true; $packageat = $prepend . '/' . $packageat; $contents = $package->getFileContents($info['attribs']['name'], true); if (!file_exists(dirname($packagingloc . DIRECTORY_SEPARATOR . $packageat))) { mkdir(dirname($packagingloc . DIRECTORY_SEPARATOR . $packageat), 0777, true); } $fp = fopen($packagingloc . DIRECTORY_SEPARATOR . $packageat, 'wb+'); ftruncate($fp, 0); stream_copy_to_stream($contents, $fp); fclose($contents); rewind($fp); if ($package->isNewPackage() && $info['attribs']['role'] == 'php') { if (isset($info['tasks:replace'])) { if (isset($info['tasks:replace'][0])) { $info['tasks:replace'][] = $globalreplace; } else { $info['tasks:replace'] = array($info['tasks:replace'], $globalreplace); } } else { $info['tasks:replace'] = $globalreplace; } } if (isset(\PEAR2\Pyrus\Config::current()->registry->package[$package->channel . '/' . $package->name])) { $version = \PEAR2\Pyrus\Config::current()->registry->info($package->name, $package->channel, 'version'); } else { $version = null; } foreach (new Creator\TaskIterator($info, $package, \PEAR2\Pyrus\Task\Common::PACKAGE, $version) as $task) { // do pre-processing of file contents try { $task->startSession($fp, $packageat); } catch (\Exception $e) { // TODO: handle exceptions } } fclose($fp); } foreach ($this->_creators as $creator) { $creator->addDir($packagingloc); } if ($package->isNewPackage()) { $this->addPEAR2Stuff($alreadyPackaged); } $this->addExtraFiles($extrafiles); foreach ($this->_creators as $creator) { $creator->close(); } \PEAR2\Pyrus\Filesystem::rmrf($packagingloc, false, false); }
/** * Detect any files already installed that would be overwritten by * files inside the package represented by $package */ public function detectFileConflicts(\PEAR2\Pyrus\PackageFileInterface $package) { if (!static::existsRegistry($this->_path)) { throw new \PEAR2\Pyrus\ChannelRegistry\Exception('Error: no existing SQLite3 channel registry for ' . $this->_path); } $database = static::getRegistry($this->_path); $ret = array(); $sql = 'SELECT packages_channel, packages_name FROM files WHERE packagepath = :path ORDER BY packages_channel, packages_name'; $stmt = $database->prepare($sql); // now iterate over each file in the package, and note all the conflicts $roles = array(); foreach (Role::getValidRoles($package->getPackageType()) as $role) { // set up a list of file role => configuration variable // for storing in the registry $roles[$role] = Role::factory($package->getPackageType(), $role); } $ret = array(); $config = Config::current(); foreach ($package->installcontents as $file) { $stmt->reset(); $relativepath = $roles[$file->role]->getRelativeLocation($package, $file); if (!$relativepath) { continue; } $testpath = $config->{$roles[$file->role]->getLocationConfig()} . DIRECTORY_SEPARATOR . $relativepath; $stmt->bindValue(':path', $testpath, SQLITE3_TEXT); $result = $stmt->execute(); while ($res = $result->fetchArray(SQLITE3_ASSOC)) { $pn = $this->info($res['packages_name'], $res['packages_channel'], 'name'); $ret[] = array($relativepath => $res['packages_channel'] . '/' . $pn); } } return $ret; }
/** * This is here to allow role extension through plugins * @param string */ function _validateRole($role) { return in_array($role, \PEAR2\Pyrus\Installer\Role::getValidRoles($this->_pf->getPackageType())); }
/** * Retrieve configuration information about a file role from its XML info * * @param string $role role name * @return array */ static function getInfo($role) { return \PEAR2\Pyrus\Installer\Role::getInfo($role); }
/** * Detect any files already installed that would be overwritten by * files inside the package represented by $package */ public function detectFileConflicts(\PEAR2\Pyrus\PackageFileInterface $package) { $filemap = $this->readFileMap(); if (!$filemap) { return array(); } // now iterate over each file in the package, and note all the conflicts $roles = array(); foreach (Role::getValidRoles($package->getPackageType()) as $role) { // set up a list of file role => configuration variable // for storing in the registry $roles[$role] = Role::factory($package->getPackageType(), $role); } $ret = array(); foreach ($package->installcontents as $file) { $relativepath = $roles[$file->role]->getRelativeLocation($package, $file); if (!$relativepath) { continue; } if (isset($filemap[$file->role][$relativepath])) { if (is_array($filemap[$file->role][$relativepath])) { $ret[] = array($relativepath => $filemap[$file->role][$relativepath][0] . '/' . $this->info($filemap[$file->role][$relativepath][1], $filemap[$file->role][$relativepath][0], 'name')); } else { $ret[] = array($relativepath => 'pear.php.net/' . $this->info($filemap[$file->role][$relativepath], 'pear.php.net', 'name')); } } } return $ret; }