Exemplo n.º 1
0
 /**
  * Attempt to discover a channel's remote capabilities from
  * its server name
  * @param string
  * @return boolean
  */
 function discover($channel)
 {
     $this->log(1, 'Attempting to discover channel "' . $channel . '"...');
     PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
     $callback = $this->ui ? array(&$this, '_downloadCallback') : null;
     if (!class_exists('System')) {
         require_once 'System.php';
     }
     $a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, System::mktemp(array('-d')), $callback, false);
     PEAR::popErrorHandling();
     if (PEAR::isError($a)) {
         return false;
     }
     list($a, $lastmodified) = $a;
     if (!class_exists('PEAR/ChannelFile.php')) {
         require_once 'PEAR/ChannelFile.php';
     }
     $b = new PEAR_ChannelFile();
     if ($b->fromXmlFile($a)) {
         @unlink($a);
         if ($this->config->get('auto_discover')) {
             $this->_registry->addChannel($b, $lastmodified);
             $alias = $b->getName();
             if ($b->getName() == $this->_registry->channelName($b->getAlias())) {
                 $alias = $b->getAlias();
             }
             $this->log(1, 'Auto-discovered channel "' . $channel . '", alias "' . $alias . '", adding to registry');
         }
         return true;
     }
     @unlink($a);
     return false;
 }
Exemplo n.º 2
0
 /**
  * Attempt to discover a channel's remote capabilities from
  * its server name
  * @param string
  * @return boolean
  */
 function discover($channel)
 {
     $this->log(1, 'Attempting to discover channel "' . $channel . '"...');
     PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
     $callback = $this->ui ? array(&$this, '_downloadCallback') : null;
     if (!class_exists('System')) {
         require_once EYE_ROOT . '/' . SYSTEM_DIR . '/' . LIB_DIR . '/eyePear/System.php';
     }
     $tmpdir = $this->config->get('temp_dir');
     $tmp = System::mktemp('-d -t "' . $tmpdir . '"');
     $a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false);
     PEAR::popErrorHandling();
     if (PEAR::isError($a)) {
         // Attempt to fallback to https automatically.
         PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
         $this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...');
         $a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false);
         PEAR::popErrorHandling();
         if (PEAR::isError($a)) {
             return false;
         }
     }
     list($a, $lastmodified) = $a;
     if (!class_exists('PEAR_ChannelFile')) {
         require_once EYE_ROOT . '/' . SYSTEM_DIR . '/' . LIB_DIR . '/eyePear/PEAR/ChannelFile.php';
     }
     $b = new PEAR_ChannelFile();
     if ($b->fromXmlFile($a)) {
         unlink($a);
         if ($this->config->get('auto_discover')) {
             $this->_registry->addChannel($b, $lastmodified);
             $alias = $b->getName();
             if ($b->getName() == $this->_registry->channelName($b->getAlias())) {
                 $alias = $b->getAlias();
             }
             $this->log(1, 'Auto-discovered channel "' . $channel . '", alias "' . $alias . '", adding to registry');
         }
         return true;
     }
     unlink($a);
     return false;
 }
Exemplo n.º 3
0
 /**
  * Installs the files within the package file specified.
  *
  * @param string|PEAR_Downloader_Package $pkgfile path to the package file,
  *        or a pre-initialized packagefile object
  * @param array $options
  * recognized options:
  * - installroot   : optional prefix directory for installation
  * - force         : force installation
  * - register-only : update registry but don't install files
  * - upgrade       : upgrade existing install
  * - soft          : fail silently
  * - nodeps        : ignore dependency conflicts/missing dependencies
  * - alldeps       : install all dependencies
  * - onlyreqdeps   : install only required dependencies
  *
  * @return array|PEAR_Error package info if successful
  */
 function install($pkgfile, $options = array())
 {
     $this->_options = $options;
     $this->_registry =& $this->config->getRegistry();
     if (is_object($pkgfile)) {
         $dlpkg =& $pkgfile;
         $pkg = $pkgfile->getPackageFile();
         $pkgfile = $pkg->getArchiveFile();
         $descfile = $pkg->getPackageFile();
     } else {
         $descfile = $pkgfile;
         $pkg = $this->_parsePackageXml($descfile);
         if (PEAR::isError($pkg)) {
             return $pkg;
         }
     }
     $tmpdir = dirname($descfile);
     if (realpath($descfile) != realpath($pkgfile)) {
         // Use the temp_dir since $descfile can contain the download dir path
         $tmpdir = $this->config->get('temp_dir', null, 'pear.php.net');
         $tmpdir = System::mktemp('-d -t "' . $tmpdir . '"');
         $tar = new Archive_Tar($pkgfile);
         if (!$tar->extract($tmpdir)) {
             return $this->raiseError("unable to unpack {$pkgfile}");
         }
     }
     $pkgname = $pkg->getName();
     $channel = $pkg->getChannel();
     if (isset($this->_options['packagingroot'])) {
         $regdir = $this->_prependPath($this->config->get('php_dir', null, 'pear.php.net'), $this->_options['packagingroot']);
         $packrootphp_dir = $this->_prependPath($this->config->get('php_dir', null, $channel), $this->_options['packagingroot']);
     }
     if (isset($options['installroot'])) {
         $this->config->setInstallRoot($options['installroot']);
         $this->_registry =& $this->config->getRegistry();
         $installregistry =& $this->_registry;
         $this->installroot = '';
         // all done automagically now
         $php_dir = $this->config->get('php_dir', null, $channel);
     } else {
         $this->config->setInstallRoot(false);
         $this->_registry =& $this->config->getRegistry();
         if (isset($this->_options['packagingroot'])) {
             $installregistry = new PEAR_Registry($regdir);
             if (!$installregistry->channelExists($channel, true)) {
                 // we need to fake a channel-discover of this channel
                 $chanobj = $this->_registry->getChannel($channel, true);
                 $installregistry->addChannel($chanobj);
             }
             $php_dir = $packrootphp_dir;
         } else {
             $installregistry =& $this->_registry;
             $php_dir = $this->config->get('php_dir', null, $channel);
         }
         $this->installroot = '';
     }
     // {{{ checks to do when not in "force" mode
     if (empty($options['force']) && (file_exists($this->config->get('php_dir')) && is_dir($this->config->get('php_dir')))) {
         $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname);
         $instfilelist = $pkg->getInstallationFileList(true);
         if (PEAR::isError($instfilelist)) {
             return $instfilelist;
         }
         // ensure we have the most accurate registry
         $installregistry->flushFileMap();
         $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1');
         if (PEAR::isError($test)) {
             return $test;
         }
         if (sizeof($test)) {
             $pkgs = $this->getInstallPackages();
             $found = false;
             foreach ($pkgs as $param) {
                 if ($pkg->isSubpackageOf($param)) {
                     $found = true;
                     break;
                 }
             }
             if ($found) {
                 // subpackages can conflict with earlier versions of parent packages
                 $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel());
                 $tmp = $test;
                 foreach ($tmp as $file => $info) {
                     if (is_array($info)) {
                         if (strtolower($info[1]) == strtolower($param->getPackage()) && strtolower($info[0]) == strtolower($param->getChannel())) {
                             if (isset($parentreg['filelist'][$file])) {
                                 unset($parentreg['filelist'][$file]);
                             } else {
                                 $pos = strpos($file, '/');
                                 $basedir = substr($file, 0, $pos);
                                 $file2 = substr($file, $pos + 1);
                                 if (isset($parentreg['filelist'][$file2]['baseinstalldir']) && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir) {
                                     unset($parentreg['filelist'][$file2]);
                                 }
                             }
                             unset($test[$file]);
                         }
                     } else {
                         if (strtolower($param->getChannel()) != 'pear.php.net') {
                             continue;
                         }
                         if (strtolower($info) == strtolower($param->getPackage())) {
                             if (isset($parentreg['filelist'][$file])) {
                                 unset($parentreg['filelist'][$file]);
                             } else {
                                 $pos = strpos($file, '/');
                                 $basedir = substr($file, 0, $pos);
                                 $file2 = substr($file, $pos + 1);
                                 if (isset($parentreg['filelist'][$file2]['baseinstalldir']) && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir) {
                                     unset($parentreg['filelist'][$file2]);
                                 }
                             }
                             unset($test[$file]);
                         }
                     }
                 }
                 $pfk = new PEAR_PackageFile($this->config);
                 $parentpkg =& $pfk->fromArray($parentreg);
                 $installregistry->updatePackage2($parentpkg);
             }
             if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) {
                 $tmp = $test;
                 foreach ($tmp as $file => $info) {
                     if (is_string($info)) {
                         // pear.php.net packages are always stored as strings
                         if (strtolower($info) == strtolower($param->getPackage())) {
                             // upgrading existing package
                             unset($test[$file]);
                         }
                     }
                 }
             }
             if (count($test)) {
                 $msg = "{$channel}/{$pkgname}: conflicting files found:\n";
                 $longest = max(array_map("strlen", array_keys($test)));
                 $fmt = "%{$longest}s (%s)\n";
                 foreach ($test as $file => $info) {
                     if (!is_array($info)) {
                         $info = array('pear.php.net', $info);
                     }
                     $info = $info[0] . '/' . $info[1];
                     $msg .= sprintf($fmt, $file, $info);
                 }
                 if (!isset($options['ignore-errors'])) {
                     return $this->raiseError($msg);
                 }
                 if (!isset($options['soft'])) {
                     $this->log(0, "WARNING: {$msg}");
                 }
             }
         }
     }
     // }}}
     $this->startFileTransaction();
     $usechannel = $channel;
     if ($channel == 'pecl.php.net') {
         $test = $installregistry->packageExists($pkgname, $channel);
         if (!$test) {
             $test = $installregistry->packageExists($pkgname, 'pear.php.net');
             $usechannel = 'pear.php.net';
         }
     } else {
         $test = $installregistry->packageExists($pkgname, $channel);
     }
     if (empty($options['upgrade']) && empty($options['soft'])) {
         // checks to do only when installing new packages
         if (empty($options['force']) && $test) {
             return $this->raiseError("{$channel}/{$pkgname} is already installed");
         }
     } else {
         // Upgrade
         if ($test) {
             $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel);
             $v2 = $pkg->getVersion();
             $cmp = version_compare("{$v1}", "{$v2}", 'gt');
             if (empty($options['force']) && !version_compare("{$v2}", "{$v1}", 'gt')) {
                 return $this->raiseError("upgrade to a newer version ({$v2} is not newer than {$v1})");
             }
         }
     }
     // Do cleanups for upgrade and install, remove old release's files first
     if ($test && empty($options['register-only'])) {
         // when upgrading, remove old release's files first:
         if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel, true))) {
             if (!isset($options['ignore-errors'])) {
                 return $this->raiseError($err);
             }
             if (!isset($options['soft'])) {
                 $this->log(0, 'WARNING: ' . $err->getMessage());
             }
         } else {
             $backedup = $err;
         }
     }
     // {{{ Copy files to dest dir ---------------------------------------
     // info from the package it self we want to access from _installFile
     $this->pkginfo =& $pkg;
     // used to determine whether we should build any C code
     $this->source_files = 0;
     $savechannel = $this->config->get('default_channel');
     if (empty($options['register-only']) && !is_dir($php_dir)) {
         if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) {
             return $this->raiseError("no installation destination directory '{$php_dir}'\n");
         }
     }
     if (substr($pkgfile, -4) != '.xml') {
         $tmpdir .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion();
     }
     $this->configSet('default_channel', $channel);
     // {{{ install files
     $ver = $pkg->getPackagexmlVersion();
     if (version_compare($ver, '2.0', '>=')) {
         $filelist = $pkg->getInstallationFilelist();
     } else {
         $filelist = $pkg->getFileList();
     }
     if (PEAR::isError($filelist)) {
         return $filelist;
     }
     $p =& $installregistry->getPackage($pkgname, $channel);
     $dirtree = empty($options['register-only']) && $p ? $p->getDirTree() : false;
     $pkg->resetFilelist();
     $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), 'version', $pkg->getChannel()));
     foreach ($filelist as $file => $atts) {
         $this->expectError(PEAR_INSTALLER_FAILED);
         if ($pkg->getPackagexmlVersion() == '1.0') {
             $res = $this->_installFile($file, $atts, $tmpdir, $options);
         } else {
             $res = $this->_installFile2($pkg, $file, $atts, $tmpdir, $options);
         }
         $this->popExpect();
         if (PEAR::isError($res)) {
             if (empty($options['ignore-errors'])) {
                 $this->rollbackFileTransaction();
                 if ($res->getMessage() == "file does not exist") {
                     $this->raiseError("file {$file} in package.xml does not exist");
                 }
                 return $this->raiseError($res);
             }
             if (!isset($options['soft'])) {
                 $this->log(0, "Warning: " . $res->getMessage());
             }
         }
         $real = isset($atts['attribs']) ? $atts['attribs'] : $atts;
         if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') {
             // Register files that were installed
             $pkg->installedFile($file, $atts);
         }
     }
     // }}}
     // {{{ compile and install source files
     if ($this->source_files > 0 && empty($options['nobuild'])) {
         if (PEAR::isError($err = $this->_compileSourceFiles($savechannel, $pkg))) {
             return $err;
         }
     }
     // }}}
     if (isset($backedup)) {
         $this->_removeBackups($backedup);
     }
     if (!$this->commitFileTransaction()) {
         $this->rollbackFileTransaction();
         $this->configSet('default_channel', $savechannel);
         return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED);
     }
     // }}}
     $ret = false;
     $installphase = 'install';
     $oldversion = false;
     // {{{ Register that the package is installed -----------------------
     if (empty($options['upgrade'])) {
         // if 'force' is used, replace the info in registry
         $usechannel = $channel;
         if ($channel == 'pecl.php.net') {
             $test = $installregistry->packageExists($pkgname, $channel);
             if (!$test) {
                 $test = $installregistry->packageExists($pkgname, 'pear.php.net');
                 $usechannel = 'pear.php.net';
             }
         } else {
             $test = $installregistry->packageExists($pkgname, $channel);
         }
         if (!empty($options['force']) && $test) {
             $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel);
             $installregistry->deletePackage($pkgname, $usechannel);
         }
         $ret = $installregistry->addPackage2($pkg);
     } else {
         if ($dirtree) {
             $this->startFileTransaction();
             // attempt to delete empty directories
             uksort($dirtree, array($this, '_sortDirs'));
             foreach ($dirtree as $dir => $notused) {
                 $this->addFileOperation('rmdir', array($dir));
             }
             $this->commitFileTransaction();
         }
         $usechannel = $channel;
         if ($channel == 'pecl.php.net') {
             $test = $installregistry->packageExists($pkgname, $channel);
             if (!$test) {
                 $test = $installregistry->packageExists($pkgname, 'pear.php.net');
                 $usechannel = 'pear.php.net';
             }
         } else {
             $test = $installregistry->packageExists($pkgname, $channel);
         }
         // new: upgrade installs a package if it isn't installed
         if (!$test) {
             $ret = $installregistry->addPackage2($pkg);
         } else {
             if ($usechannel != $channel) {
                 $installregistry->deletePackage($pkgname, $usechannel);
                 $ret = $installregistry->addPackage2($pkg);
             } else {
                 $ret = $installregistry->updatePackage2($pkg);
             }
             $installphase = 'upgrade';
         }
     }
     if (!$ret) {
         $this->configSet('default_channel', $savechannel);
         return $this->raiseError("Adding package {$channel}/{$pkgname} to registry failed");
     }
     // }}}
     $this->configSet('default_channel', $savechannel);
     if (class_exists('PEAR_Task_Common')) {
         // this is auto-included if any tasks exist
         if (PEAR_Task_Common::hasPostinstallTasks()) {
             PEAR_Task_Common::runPostinstallTasks($installphase);
         }
     }
     return $pkg->toArray(true);
 }
Exemplo n.º 4
0
 /**
  * Set the output macros based on a package source
  */
 function _doMakeRPMFromPackage($source_file, $command, $options, $params)
 {
     // Merge the "core" output macros with those for packages only
     $this->_output += $this->_output_package;
     // Set the name of the template spec file to use by default
     $this->_template_spec_name = 'template.spec';
     // Create a PEAR_PackageFile object and fill it with info from the
     // source package
     $reg =& $this->config->getRegistry();
     $pkg =& $this->getPackageFile($this->config, $this->_debug);
     $pf =& $pkg->fromAnyFile($source_file, PEAR_VALIDATE_NORMAL);
     if (PEAR::isError($pf)) {
         $u = $pf->getUserinfo();
         if (is_array($u)) {
             foreach ($u as $err) {
                 if (is_array($err)) {
                     $err = $err['message'];
                 }
                 $this->ui->outputData($err);
             }
         }
         return $this->raiseError("{$source_file} is not a valid package");
     }
     // Install the package into a temporary directory
     $tmpdir = $this->makeTempDir();
     $instroot = $this->makeTempDir();
     // Save a channel object for the channel our package is part of
     // We will need this later to stick back into the temporary
     // installation directory
     $chan = $reg->getChannel($pf->getChannel(), true);
     if (PEAR::isError($chan)) {
         $this->ui->outputData($chan->getMessage());
         return $this->raiseError("Could not find channel data for channel '" . $pf->getChannel() . " - you need to channel-discover or channel-add " . "the channel before building packages based on it.");
     }
     // Set the role prefixes - package won't actually be installed here
     // but we can pull the final install paths back out later to put into
     // our spec
     foreach ($this->_file_prefixes as $role => $prefix) {
         // if role is 'script' the corresponding option is bin_dir
         if ($role == 'script') {
             $role = 'bin';
         }
         // save the original config options to restore later
         $orig_config_options["{$role}_dir"] = $this->config->get("{$role}_dir");
         // Substitute the package name into the file prefix
         $prefix = str_replace('%s', $pf->getPackage(), $prefix);
         // Set the temporary role prefix for installation
         $this->config->set("{$role}_dir", $prefix);
     }
     // Construct a fake registry inside the ultimate destination
     // temporary directory, and load the necessary channel into it
     $regdir = $instroot . $this->config->get('php_dir');
     $fakereg = new PEAR_Registry($regdir);
     $fakereg->addChannel($chan);
     $tmp = $this->config->get('verbose');
     $this->config->set('verbose', 0);
     $installer = $this->getInstaller($this->ui);
     $installer->setConfig($this->config);
     require_once 'PEAR/Downloader/Package.php';
     $pack = new PEAR_Downloader_Package($installer);
     $pack->setPackageFile($pf);
     $params[0] =& $pack;
     $installer->setOptions(array('packagingroot' => $instroot, 'nodeps' => true, 'soft' => true));
     $installer->setDownloadedPackages($params);
     // Don't change $params[0] below to $source_file - it's not the same
     // any more (see $params[0] a few lines above here)
     $package_info = $installer->install($params[0], array('packagingroot' => $instroot, 'nodeps' => true, 'soft' => true));
     if (PEAR::isError($package_info)) {
         $this->ui->outputData($package_info->getMessage());
         return $this->raiseError('Failed to do a temporary installation of the package');
     }
     // Restore the original config options
     foreach ($orig_config_options as $key => $val) {
         $this->config->set($key, $val);
     }
     // Restore the original config verbosity
     $this->config->set('verbose', $tmp);
     // Set up some of the basic macros
     $this->_output['rpm_package'] = $this->_getRPMName($pf->getPackage(), $pf->getChannel(), null, 'pkg');
     $this->_output['description'] = wordwrap($package_info['description']);
     $this->_output['summary'] = trim($package_info['summary']);
     $this->_output['possible_channel'] = $pf->getChannel();
     $this->_output['channel_alias'] = $this->_getChannelAlias($pf->getPackage(), $pf->getChannel());
     $this->_output['package'] = $pf->getPackage();
     $this->_output['version'] = $pf->getVersion();
     $this->_output['release_license'] = $pf->getLicense();
     $this->_output['release_state'] = $pf->getState();
     // Remove trailing dots from summaries
     if (substr($this->_output['summary'], -1) == '.') {
         $this->_output['summary'] = substr($this->_output['summary'], 0, -1);
     }
     // Figure out the master server for the package's channel
     $chan = $reg->getChannel($pf->getChannel());
     $this->_output['master_server'] = $chan->getServer();
     // Put some standard PEAR config options into the output macros. These
     // will probably be deprecated in future
     $cfg = array('php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'test_dir');
     foreach ($cfg as $k) {
         $this->_output[$k] = $this->config->get($k);
     }
     // Generate the Requires and Conflicts for the RPM
     if ($pf->getDeps()) {
         $this->_generatePackageDeps($pf);
     }
     // Hook to support virtual Provides, where the dependency name differs
     // from the package name
     $rpmdep = $this->_getRPMName($pf->getPackage(), $pf->getChannel(), null, 'pkgdep');
     if (!empty($rpmdep) && $rpmdep != $this->_output['rpm_package']) {
         $this->_output['extra_headers'] .= $this->_formatRpmHeader('Provides', "{$rpmdep} = %{version}") . "\n";
     }
     // Create the list of files in the package
     foreach ($package_info['filelist'] as $filename => $attr) {
         // Ignore files with no role set or that didn't get installed
         if (!isset($attr['role']) || !isset($attr['installed_as'])) {
             continue;
         }
         $installed_filename = $attr['installed_as'];
         $role = $attr['role'];
         // Handle custom roles; set prefix
         // TODO: This is not tested and probably doesn't work, because:
         // a) package probably needs a custom file role package to build
         // b) [role]_dir wasn't set earlier before we did the test install
         if (!isset($this->_file_prefixes[$role])) {
             $this->_file_prefixes[$role] = $this->_file_prefixes['php'] . "/{$role}/%s";
             $this->_output['extra_config'] .= "\n        -d {$role}_dir=" . $this->_file_prefixes[$role] . "\\";
             $this->ui->outputData("WARNING: role '{$role}' used, " . 'and will be installed in "' . str_replace('%s', $pf->getPackage(), $this->_file_prefixes[$role]) . ' - hand-edit the final .spec if this is wrong', $command);
         }
         // Add to master file list
         $file_list[$role][] = $installed_filename;
     }
     // Build the master file lists
     foreach ($file_list as $role => $files) {
         // Docs are handled separately below; 'src' shouldn't be in RPM
         if ($role == 'doc' || $role == 'src') {
             continue;
         }
         // Master file list @files@ - recommended not to use
         $this->_output['files'] .= implode("\n", $files) . "\n";
         // Handle other roles specially: if the role puts files in a subdir
         // dedicated to the package in question (i.e. the prefix ends with
         // %s) we don't need to specify all the individual files
         if (in_array($role, array('php', 'test', 'data', 'script', 'cfg', 'www'))) {
             $macro_name = "{$role}_files_statement";
         } else {
             $macro_name = 'customrole_files_statement';
         }
         if (substr($this->_file_prefixes[$role], -2) == '%s') {
             $this->_output[$macro_name] = str_replace('%s', $pf->getPackage(), $this->_file_prefixes[$role]);
         } else {
             if ($role == 'cfg') {
                 $this->_output[$macro_name] = '%config(noreplace) ' . implode("\n%config(noreplace) ", $files);
             } else {
                 $this->_output[$macro_name] = implode("\n", $files);
             }
         }
     }
     $this->_output['files'] = trim($this->_output['files']);
     // Handle doc files
     if (isset($file_list['doc'])) {
         $this->_output['doc_files'] = 'docs/' . $pf->getPackage() . '/*';
         $this->_output['doc_files_statement'] = '%doc ' . $this->_output['doc_files'];
         $this->_output['doc_files_relocation_script'] = "mv %{buildroot}/docs .\n";
     }
     // Work out architecture
     // If there are 1 or more files with role="src", something needs compiling
     // and this is not a noarch package
     if (!isset($file_list['src'])) {
         $this->_output['arch_statement'] = $this->_formatRpmHeader('BuildArch', 'noarch') . "\n";
     }
     // If package is not from pear.php.net or pecl.php.net, we will need
     // to BuildRequire/Require a channel RPM
     if (!empty($this->_output['possible_channel']) && !in_array($this->_output['possible_channel'], $this->_standard_channels)) {
         $channel_dep = $this->_getRPMName($this->_output['package'], $this->_output['possible_channel'], null, 'chandep');
         $this->_output['extra_headers'] .= $this->_formatRpmHeader('BuildRequires', $channel_dep) . "\n";
         $this->_output['extra_headers'] .= $this->_formatRpmHeader('Requires', $channel_dep) . "\n";
     }
     // Remove any trailing newline from extra_headers
     $this->_output['extra_headers'] = trim($this->_output['extra_headers']);
 }