Esempio n. 1
0
 function getFilePath($file)
 {
     $role = \Pyrus\Installer\Role::factory($this->packagefile->getPackageType(), $this->packagefile->packagingcontents[$file]['attribs']['role']);
     list(, $path) = $role->getRelativeLocation($this->packagefile, new \Pyrus\PackageFile\v2Iterator\FileTag($this->packagefile->packagingcontents[$file], '', $this->packagefile), true);
     $dir = \Pyrus\Config::singleton($this->registry->getPath())->{$role->getLocationConfig()};
     return $dir . DIRECTORY_SEPARATOR . $path;
 }
Esempio n. 2
0
 /**
  * Construct simple channel server
  *
  * @param Pyrus\SimpleChannelServer\Channel $channel   channel object
  * @param string $webpath   full path to web files eg: /var/www/pear/
  * @param string $pyruspath Path to the pyrus controlled PEAR installation
  */
 function __construct($channel, $webpath, $pyruspath = null)
 {
     if (!realpath($webpath) || !is_writable($webpath)) {
         throw new Exception('Path to channel web files ' . $webpath . ' must exist and be writable');
     } else {
         $this->webpath = $webpath;
     }
     if (!$pyruspath) {
         $pyruspath = __DIR__;
     }
     $rest = $channel->protocols->rest;
     foreach ($rest as $restpath) {
         if (preg_match('/https?:\\/\\/' . $channel->name . '\\//', $restpath, $matches)) {
             $this->uri = $matches[0];
             $restpath = str_replace($matches[0], '', $restpath);
             break;
         }
     }
     if (dirname($restpath . 'a') . '/' !== $restpath) {
         $restpath .= '/';
     }
     $this->restpath = $webpath . '/' . $restpath;
     $this->channel = $channel;
     $this->rest = new REST\Manager($this->restpath, $channel, $restpath);
     $this->get = new Get($webpath . '/get', $pyruspath);
     try {
         $a = \Pyrus\Config::singleton($pyruspath);
     } catch (Exception $e) {
         throw new Exception('Cannot initialize Pyrus Config', $e);
     }
 }
Esempio n. 3
0
 /**
  * Construct simple channel server
  *
  * @param PEAR2_SimpleChannelServer_Channel $channel   channel object
  * @param string $webpath   full path to web files eg: /var/www/pear/
  * @param string $pyruspath Path to the pyrus controlled PEAR installation
  */
 function __construct(\Pyrus\Channel $channel, $webpath, $pyruspath = null)
 {
     if (!realpath($webpath) || !is_writable($webpath)) {
         throw new PEAR2_SimpleChannelServer_Exception('Path to channel web files ' . $webpath . ' must exist and be writable');
     } else {
         $this->webpath = $webpath;
     }
     if (!$pyruspath) {
         $pyruspath = __DIR__;
     }
     $rest = $channel->protocols->rest;
     foreach ($rest as $restpath) {
         $restpath = str_replace('http://' . $channel->name . '/', '', $restpath);
         break;
     }
     if (dirname($restpath . 'a') . '/' !== $restpath) {
         $restpath .= '/';
     }
     $this->uri = 'http://' . $channel->name . '/';
     $this->channel = $channel;
     $this->rest = new PEAR2_SimpleChannelServer_REST_Manager($webpath . '/' . $restpath, $channel->name, $restpath);
     $this->get = new PEAR2_SimpleChannelServer_Get($webpath . '/get', $pyruspath);
     try {
         $a = \Pyrus\Config::singleton($pyruspath);
     } catch (Exception $e) {
         throw new PEAR2_SimpleChannelServer_Exception('Cannot initialize Pyrus Config', $e);
     }
 }
Esempio n. 4
0
 function isUpgradeable()
 {
     if (!isset(\Pyrus\Main::$options['upgrade'])) {
         // we don't attempt to upgrade a dep unless we're upgrading
         return false;
     }
     $reg = \Pyrus\Config::current()->registry;
     $version = $reg->info($this->name, $this->channel, 'version');
     if (version_compare($this->version['release'], $version, '<=')) {
         return !isset(\Pyrus\Main::$options['force']);
     }
     return true;
 }
Esempio n. 5
0
 function __construct($coverage, $recursive)
 {
     $this->ini_overwrites[] = 'error_reporting=' . E_ALL;
     if ($coverage) {
         $this->_options['coverage'] = true;
     }
     if ($recursive) {
         $this->_options['recur'] = true;
     }
     $this->windows = substr(PHP_OS, 0, 3) == 'WIN';
     $this->_php = \Pyrus\Config::current()->php_bin;
     $this->xdebug_loaded = extension_loaded('xdebug');
 }
Esempio n. 6
0
 function __construct($__DIR__)
 {
     set_include_path($__DIR__);
     $c = \Pyrus\Config::singleton(dirname($__DIR__), dirname($__DIR__) . '/pearconfig.xml');
     $c->bin_dir = $__DIR__ . '/bin';
     restore_include_path();
     $c->saveConfig();
     $chan = new PEAR2\SimpleChannelServer\Channel('pear2.php.net', 'unit test channel');
     $scs = new PEAR2\SimpleChannelServer\Main($chan, $__DIR__, dirname($__DIR__) . '/PEAR2');
     $scs->saveChannel();
     $this->chan = $chan;
     $this->scs = $scs;
     $this->__DIR__ = $__DIR__;
 }
Esempio n. 7
0
File: Base.php Progetto: helgi/Pyrus
 function cloneRegistry(Base $registry)
 {
     try {
         $packageiterator = $registry->package;
         foreach (\Pyrus\Config::current()->channelregistry->listChannels() as $channel) {
             $packageiterator->setIteratorChannel($channel);
             foreach ($packageiterator as $package) {
                 if ($this->exists($package->name, $package->channel)) {
                     $old = $this->toPackageFile($package->name, $package->channel);
                     if ($old->date == $package->date && $old->time == $package->time) {
                         continue;
                     }
                 }
                 $this->replace($package);
             }
         }
     } catch (\Exception $e) {
         throw new Exception('Cannot clone registry', $e);
     }
 }
Esempio n. 8
0
 /**
  * Get/Create a transaction.
  *
  * @param string|Pyrus\Installer\Role\Common $path The directory path.
  * @return Transaction A Pyrus\AtomicFileTransaction\Transaction instance
  */
 public function getTransaction($path)
 {
     if ($path instanceof \Pyrus\Installer\Role\Common) {
         $path = \Pyrus\Config::current()->{$path->getLocationConfig()};
     }
     $path = FS::path((string) $path);
     if (isset($this->transactions[$path])) {
         return $this->transactions[$path];
     }
     // Create new transaction object
     $class = $this->getTransactionClass();
     try {
         $this->transactions[$path] = new $class($path, $this);
         return $this->transactions[$path];
     } catch (\Exception $e) {
         $errs = new MultiErrors();
         $errs->E_ERROR[] = $e;
         $errs->merge($this->rollbackTransactions());
         throw new MultiException('Unable to begin transaction', $errs);
     }
 }
Esempio n. 9
0
 function getRelativeLocation(\Pyrus\PackageFileInterface $pkg, \Pyrus\PackageFile\v2Iterator\FileTag $file, $retDir = false)
 {
     if ($this->md5 === null) {
         return parent::getRelativeLocation($pkg, $file, $retDir);
     }
     $info = parent::getRelativeLocation($pkg, $file, $retDir);
     $path = \Pyrus\Config::current()->cfg_dir . DIRECTORY_SEPARATOR;
     if ($retDir) {
         $filepath = $info[1];
     } else {
         $filepath = $info;
     }
     if (@file_exists($path . $filepath)) {
         // configuration has already been installed, check for modifications
         // made by the user
         $md5 = md5_file($path . $filepath);
         $newmd5 = $pkg->files[$file->packagedname]['attribs'];
         if (!isset($newmd5['md5sum'])) {
             $newmd5 = md5_file($pkg->getFilePath($file->packagedname));
         } else {
             $newmd5 = $newmd5['md5sum'];
         }
         // first check to see if the user modified the file
         // next check to see if the config file changed from the last installed version
         // if both tests are satisfied, install the new file under another name and display a warning
         if ($md5 !== $this->md5 && $md5 !== $newmd5) {
             // configuration has been modified, so save our version as
             // configfile.new-version
             $old = $filepath;
             $filepath .= '.new-' . $pkg->version['release'];
             \Pyrus\Logger::log(0, "WARNING: configuration file {$old} is being installed as {$filepath}, " . "you should manually merge in changes to the existing configuration file");
         }
     }
     if ($retDir) {
         $info[1] = $filepath;
     } else {
         $info = $filepath;
     }
     return $info;
 }
Esempio n. 10
0
/**
 * In order to test excluding all possible versions
 * 
 * Create a dependency tree like so:
 *
 * P1 -> P2 min 1.1.0, exclude 1.2.0
 * P3 -> P2 max 1.3.0, exclude 1.2.3
 *
 * P2 only has releases for 1.0.0, 1.2.0, 1.2.3, and 1.3.1
 *
 * to test composite dep failure
 */
require __DIR__ . '/../../../../../autoload.php';
set_include_path(__DIR__);
$c = \Pyrus\Config::singleton(dirname(__DIR__), dirname(__DIR__) . '/pearconfig.xml');
$c->bin_dir = __DIR__ . '/bin';
restore_include_path();
$c->saveConfig();
$chan = new PEAR2\SimpleChannelServer\Channel('pear2.php.net', 'unit test channel');
$scs = new PEAR2\SimpleChannelServer\Main($chan, __DIR__, dirname(__DIR__) . '/PEAR2');
$scs->saveChannel();
$pf = new \Pyrus\PackageFile\v2();
for ($i = 1; $i <= 6; $i++) {
    file_put_contents(__DIR__ . "/glooby{$i}", 'hi');
}
$pf->name = 'P1';
$pf->channel = 'pear2.php.net';
$pf->summary = 'testing';
$pf->version['release'] = '1.0.0';
$pf->stability['release'] = 'stable';
Esempio n. 11
0
 protected function getMode($mode = null)
 {
     if ($mode === null) {
         return 0777 & ~octdec(\Pyrus\Config::current()->umask);
     }
     return $mode & 0777;
 }
Esempio n. 12
0
 /**
  * @param array output of {@link parsePackageName()}
  * @return \Pyrus\Channel\RemotePackage
  * @access private
  */
 function getRemotePackage($parr)
 {
     // getDownloadURL returns an array.  On error, it only contains information
     // on the latest release as array(version, info).  On success it contains
     // array(version, info, download url string)
     $state = isset($parr['state']) ? $parr['state'] : Config::current()->preferred_state;
     if (!isset(Config::current()->channelregistry[$parr['channel']])) {
         throw new Exception('Unknown remote channel: ' . $parr['channel']);
     }
     try {
         $chan = Config::current()->channelregistry[$parr['channel']];
     } catch (\Exception $e) {
         throw new Exception('Cannot retrieve download information ' . 'for remote abstract package ' . $parr['channel'] . '/' . $parr['package'], $e);
     }
     $p_mirror = Config::current()->preferred_mirror;
     $mirror = isset($chan->mirrors[$p_mirror]) ? $chan->mirrors[$p_mirror] : $chan;
     return $mirror->remotepackage[$parr['package']];
 }
Esempio n. 13
0
 /**
  * Detect any files already installed that would be overwritten by
  * files inside the package represented by $package
  */
 public function detectFileConflicts(\Pyrus\PackageFileInterface $package)
 {
     if (!static::existsRegistry($this->_path)) {
         throw new \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;
 }
Esempio n. 14
0
 function warning($msg)
 {
     $package = Config::parsedPackageNameToString($this->_currentPackage, true);
     $this->errs->E_WARNING[] = new Exception(sprintf($msg, $package));
     return true;
 }
Esempio n. 15
0
File: Set.php Progetto: helgi/Pyrus
 function getDependenciesOn($info)
 {
     $name = $info->name;
     $channel = $info->channel;
     $packages = \Pyrus\Config::current()->registry->getDependentPackages($info->getPackageFileObject());
     $ret = array();
     foreach ($packages as $package) {
         $deps = $package->dependencies;
         foreach (array('package', 'subpackage') as $type) {
             foreach (array('required', 'optional') as $required) {
                 foreach ($deps[$required]->{$type} as $dep) {
                     if ($dep->channel != $channel || $dep->name != $name) {
                         continue;
                     }
                     $ret[] = $dep;
                 }
             }
         }
     }
     return $ret;
 }
Esempio n. 16
0
 /**
  * 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 \Pyrus\Package $package
  * @param array $extrafiles
  */
 function render(\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 \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 = \Pyrus\Config::current()->temp_dir . DIRECTORY_SEPARATOR . 'pyrpackage';
     if (file_exists($packagingloc)) {
         \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 = \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(\Pyrus\Config::current()->registry->package[$package->channel . '/' . $package->name])) {
             $version = \Pyrus\Config::current()->registry->info($package->name, $package->channel, 'version');
         } else {
             $version = null;
         }
         foreach (new Creator\TaskIterator($info, $package, \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();
     }
     \Pyrus\Filesystem::rmrf($packagingloc, false, false);
 }
Esempio n. 17
0
 /**
  * @param \Pyrus\PackageFile\v2
  * @param int
  */
 function validate(\Pyrus\PackageInterface $pf, $state = \Pyrus\Validate::NORMAL)
 {
     $this->errors = new \PEAR2\MultiErrors();
     if (!$pf->schemaOK) {
         // this package.xml was created from scratch, not loaded from an existing
         // package.xml
         $dom = new \DOMDocument();
         libxml_use_internal_errors(true);
         libxml_clear_errors();
         $dom->loadXML($pf);
         $a = $pf->toArray();
         if ($a['package']['attribs']['version'] == '2.1') {
             $schema = \Pyrus\Main::getDataPath() . '/package-2.1.xsd';
         } else {
             $schema = \Pyrus\Main::getDataPath() . '/package-2.0.xsd';
         }
         // libxml can't process these from within a phar (pity)
         if (strpos($schema, 'phar://') === 0) {
             if (!file_exists($temp = \Pyrus\Config::current()->temp_dir . DIRECTORY_SEPARATOR . 'schema')) {
                 mkdir($temp, 0755, true);
             }
             $tmpschema = $temp . DIRECTORY_SEPARATOR . basename($schema);
             copy($schema, $tmpschema);
             $dom->schemaValidate($tmpschema);
         } else {
             $dom->schemaValidate($schema);
         }
         $causes = array();
         foreach (libxml_get_errors() as $error) {
             $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception("Line " . $error->line . ': ' . $error->message);
         }
         if (count($this->errors)) {
             throw new \Pyrus\PackageFile\Exception('Invalid package.xml, does' . ' not validate against schema', $this->errors);
         }
     }
     $this->_pf = $pf;
     $this->_curState = $state;
     $this->_packageInfo = $this->_pf->toArray();
     $this->_packageInfo = $this->_packageInfo['package'];
     if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) {
         return false;
     }
     $myversion = self::VERSION;
     if ($myversion === '@PACKAGE_VERSION@') {
         // we're running from CVS, assume we're 2.0.0
         $myversion = '2.0.0';
     }
     $test = $this->_packageInfo;
     if (isset($test['dependencies']) && isset($test['dependencies']['required']) && isset($test['dependencies']['required']['pearinstaller']) && isset($test['dependencies']['required']['pearinstaller']['min']) && version_compare($myversion, $test['dependencies']['required']['pearinstaller']['min'], '<')) {
         $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception('This package.xml requires PEAR version ' . $test['dependencies']['required']['pearinstaller']['min'] . ' to parse properly, we are version ' . $myversion);
     }
     $fail = false;
     foreach ($pf->contents as $file) {
         // leverage the hidden iterators to do our validation
         $name = $file->dir . $file->name;
         if ($name[0] == '.' && $name[1] == '/') {
             // name is something like "./doc/whatever.txt"
             $this->errors->E_ERROR[] = new \Pyrus\Package\Exception('File "' . $name . '" cannot begin with "."');
             continue;
         }
         if (!$this->_validateRole($file->role)) {
             if (isset($this->_packageInfo['usesrole'])) {
                 $roles = $this->_packageInfo['usesrole'];
                 if (!isset($roles[0])) {
                     $roles = array($roles);
                 }
                 foreach ($roles as $role) {
                     if ($role['role'] = $file->role) {
                         if (isset($role['uri'])) {
                             $package = $role['uri'];
                         } else {
                             $package = \Pyrus\Config::parsedPackageNameToString(array('package' => $role['package'], 'channel' => $role['channel']), true);
                         }
                         $msg = 'This package contains role "' . $file->role . '" and requires package "' . $package . '" to be used';
                         $this->errors->E_WARNING[] = new \Pyrus\PackageFile\Exception($msg);
                     }
                 }
             }
             $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception('File "' . $name . '" has invalid role "' . $file->role . '", should be one of ' . implode(', ', \Pyrus\Installer\Role::getValidRoles($this->_pf->getPackageType())));
         }
         if (count($file->tasks) && $this->_curState != \Pyrus\Validate::DOWNLOADING) {
             // has tasks
             $save = $file->getArrayCopy();
             foreach ($file->tasks as $task => $value) {
                 if ($tagClass = \Pyrus\Task\Common::getTask($task)) {
                     if (!is_array($value) || !isset($value[0])) {
                         $value = array($value);
                     }
                     foreach ($value as $v) {
                         try {
                             $ret = $tagClass::validateXml($this->_pf, $v, $save['attribs'], $file->name);
                         } catch (\Pyrus\Task\Exception $e) {
                             $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception('Invalid task $task', $e);
                         }
                     }
                 } else {
                     if (isset($this->_packageInfo['usestask'])) {
                         $roles = $this->_packageInfo['usestask'];
                         if (!isset($roles[0])) {
                             $roles = array($roles);
                         }
                         foreach ($roles as $role) {
                             if ($role['task'] = $task) {
                                 if (isset($role['uri'])) {
                                     $package = $role['uri'];
                                 } else {
                                     $package = \Pyrus\Config::parsedPackageNameToString(array('package' => $role['package'], 'channel' => $role['channel']), true);
                                 }
                                 $msg = 'This package contains task "' . str_replace($this->_pf->getTasksNs() . ':', '', $task) . '" and requires package "' . $package . '" to be used';
                                 $this->errors->E_WARNING[] = new \Pyrus\PackageFile\Exception($msg);
                             }
                         }
                     }
                     $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception('Unknown task "' . $task . '" passed in file <file name="' . $name . '">');
                 }
             }
         }
     }
     $this->_validateRelease();
     if (count($this->errors->E_ERROR)) {
         throw new \Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors);
     }
     try {
         $validator = \Pyrus\Config::current()->channelregistry[$this->_pf->channel]->getValidationObject($this->_pf->name);
     } catch (\Pyrus\Config\Exception $e) {
         throw new \Pyrus\PackageFile\Exception('Unable to process channel-specific configuration for channel ' . $this->_pf->getChannel(), $e);
     } catch (\Exception $e) {
         $valpack = \Pyrus\Config::current()->channelregistry[$this->_pf->channel]->getValidationPackage();
         $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception('Unknown channel ' . $this->_pf->channel);
         $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception('package "' . $this->_pf->channel . '/' . $this->_pf->name . '" cannot be properly validated without validation package "' . $this->_pf->channel . '/' . $valpack['name'] . '-' . $valpack['version'] . '"');
     }
     try {
         $validator->setPackageFile($this->_pf);
         $validator->setChannel(\Pyrus\Config::current()->channelregistry[$this->_pf->channel]);
         $validator->validate($state);
         // merge in errors from channel-specific validation
         $this->errors[] = $validator->getFailures();
     } catch (\Exception $e) {
         $this->errors->E_ERROR[] = $e;
     }
     if (count($this->errors->E_ERROR)) {
         throw new \Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors);
     }
     if ($state == \Pyrus\Validate::PACKAGING) {
         if ($this->_pf->type == 'bundle') {
             if (!$this->_analyzeBundledPackages()) {
                 throw new \Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors);
             }
         } else {
             if (!$this->_analyzePhpFiles()) {
                 throw new \Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors);
             }
         }
     }
     return $state;
 }
Esempio n. 18
0
 /**
  * Rebuild the dependency DB by reading registry entries.
  */
 function rebuildDB()
 {
     $depdb = array('_version' => $this->_version);
     if (!$this->hasWriteAccess()) {
         // allow startup for read-only with older Registry
         return $depdb;
     }
     $reg = \Pyrus\Config::current()->registry;
     foreach (\Pyrus\Config::current()->channelregistry as $channel) {
         foreach ($reg->listPackages($channel->name) as $package) {
             $package = $reg->package[$channel->name . '/' . $package];
             $depdb = $this->_setPackageDeps($depdb, $package);
         }
     }
     $this->_writeDepDB($depdb);
 }
Esempio n. 19
0
 /** @todo Consider simply injecting the Package object as appropriate */
 function package($frontend, $args, $options)
 {
     $path = getcwd() . DIRECTORY_SEPARATOR;
     $package = new \Pyrus\Package(null);
     if (!isset($args['packagexml']) && !file_exists($path . 'package.xml') && !file_exists($path . 'package2.xml')) {
         throw new \Pyrus\PackageFile\Exception("No package.xml or package2.xml found in " . $path);
     }
     if (isset($args['packagexml'])) {
         $package = new \Pyrus\Package($args['packagexml']);
     } else {
         // first try ./package.xml
         if (file_exists($path . 'package.xml')) {
             try {
                 $package = new \Pyrus\Package($path . 'package.xml');
             } catch (\Pyrus\PackageFile\Exception $e) {
                 if ($e->getCode() != -3) {
                     throw $e;
                 }
                 if (!file_exists($path . 'package2.xml')) {
                     throw $e;
                 }
                 $package = new \Pyrus\Package($path . 'package2.xml');
                 // now the creator knows to do the magic of package2.xml/package.xml
                 $package->thisIsOldAndCrustyCompatible();
             }
         }
         // Alternatively; there's only a package2.xml
         if (file_exists($path . 'package2.xml') && !file_exists($path . 'package.xml')) {
             $package = new \Pyrus\Package($path . 'package2.xml');
         }
     }
     if ($package->isNewPackage()) {
         if (!$options['phar'] && !$options['zip'] && !$options['tar'] && !$options['tgz']) {
             // try tgz first
             if (extension_loaded('zlib')) {
                 $options['tgz'] = true;
             } else {
                 $options['tar'] = true;
             }
         }
         if ($options['phar'] && ini_get('phar.readonly')) {
             throw new \Pyrus\Developer\Creator\Exception("Cannot create phar archive, pass -dphar.readonly=0");
         }
     } else {
         if ($options['zip'] || $options['phar']) {
             echo "Zip and Phar archives can only be created for PEAR2 packages, ignoring\n";
         }
         if (extension_loaded('zlib')) {
             $options['tgz'] = true;
         } else {
             $options['tar'] = true;
         }
     }
     // get openssl cert if set, and password
     if (\Pyrus\Config::current()->openssl_cert) {
         if ('yes' == $frontend->ask('Sign package?', array('yes', 'no'), 'yes')) {
             $cert = \Pyrus\Config::current()->openssl_cert;
             if (!file_exists($cert)) {
                 throw new \Pyrus\Developer\Creator\Exception('OpenSSL certificate ' . $cert . ' does not exist');
             }
             $releaser = \Pyrus\Config::current()->handle;
             $maintainers = array();
             foreach ($package->maintainer as $maintainer) {
                 $maintainers[] = $maintainer->user;
             }
             if (!strlen($releaser)) {
                 throw new \Pyrus\Developer\Creator\Exception('handle configuration variable must be from ' . 'package.xml (one of ' . implode(', ', $maintainers) . ')');
             }
             if (!in_array($releaser, $maintainers)) {
                 throw new \Pyrus\Developer\Creator\Exception('handle configuration variable must be from ' . 'package.xml (one of ' . implode(', ', $maintainers) . ')');
             }
             $passphrase = $frontend->ask('passphrase for OpenSSL PKCS#12 certificate?');
             if (!$passphrase) {
                 $passphrase = '';
             }
         } else {
             $releaser = $cert = null;
             $passphrase = '';
         }
     } else {
         $releaser = $cert = null;
         $passphrase = '';
     }
     $sourcepath = \Pyrus\Main::getSourcePath();
     if (0 !== strpos($sourcepath, 'phar://')) {
         // running from svn, assume we're in a standard package layout with a vendor dir
         // TODO: Improve this to automatically find latest releases from pear2.php.net
         $exceptionpath = $autoloadpath = $multierrorspath = realpath($sourcepath . '/../vendor/php') . '/PEAR2';
         if (!file_exists($exceptionpath . '/Exception.php')) {
             throw new \Pyrus\Developer\Creator\Exception('Cannot locate PEAR2/Exception in a local vendor/ dir. ' . 'It is best to install the latest versions of these locally.');
         }
     } else {
         $exceptionpath = $autoloadpath = $multierrorspath = dirname($sourcepath) . '/PEAR2';
     }
     $extras = array();
     $stub = false;
     if ($options['tgz'] && extension_loaded('zlib')) {
         $mainfile = $package->name . '-' . $package->version['release'] . '.tgz';
         $mainformat = \Phar::TAR;
         $maincompress = \Phar::GZ;
     } elseif ($options['tgz']) {
         $options['tar'] = true;
     }
     if ($options['tar']) {
         if (isset($mainfile)) {
             $extras[] = array('tar', \Phar::TAR, \Phar::NONE);
         } else {
             $mainfile = $package->name . '-' . $package->version['release'] . '.tar';
             $mainformat = \Phar::TAR;
             $maincompress = \Phar::NONE;
         }
     }
     if ($options['phar']) {
         if (isset($mainfile)) {
             $extras[] = array('phar', \Phar::PHAR, \Phar::GZ);
         } else {
             $mainfile = $package->name . '-' . $package->version['release'] . '.phar';
             $mainformat = \Phar::PHAR;
             $maincompress = \Phar::NONE;
         }
         if (!$options['stub'] && file_exists(dirname($package->archivefile) . '/stub.php')) {
             $stub = file_get_contents(dirname($package->archivefile) . '/stub.php');
         } elseif ($options['stub'] && file_exists($options['stub'])) {
             $stub = file_get_contents($options['stub']);
         }
         $stub = str_replace('@PACKAGE_VERSION' . '@', $package->version['release'], $stub);
     }
     if ($options['zip']) {
         if (isset($mainfile)) {
             $extras[] = array('zip', \Phar::ZIP, \Phar::NONE);
         } else {
             $mainfile = $package->name . '-' . $package->version['release'] . '.zip';
             $mainformat = \Phar::ZIP;
             $maincompress = \Phar::NONE;
         }
     }
     if (isset($options['outputfile'])) {
         $mainfile = $options['outputfile'];
     }
     echo "Creating ", $mainfile, "\n";
     if (null == $cert) {
         $cloner = new \Pyrus\Package\Cloner($mainfile);
         $clone = $extras;
         $extras = array();
     } else {
         foreach ($extras as $stuff) {
             echo "Creating ", $package->name, '-', $package->version['release'], '.', $stuff[0], "\n";
         }
         $clone = array();
     }
     $creator = new \Pyrus\Package\Creator(array(new \Pyrus\Developer\Creator\Phar($mainfile, $stub, $mainformat, $maincompress, $extras, $releaser, $package, $cert, $passphrase)), $exceptionpath, $autoloadpath, $multierrorspath);
     if (!$options['extrasetup'] && file_exists(dirname($package->archivefile) . '/extrasetup.php')) {
         $options['extrasetup'] = 'extrasetup.php';
     }
     if ($options['extrasetup']) {
         // encapsulate the extrafiles inside a closure so there is no access to the variables in this function
         $getinfo = function () use($options, $package) {
             $file = $options['extrasetup'];
             if (!file_exists(dirname($package->archivefile) . '/' . $file)) {
                 throw new \Pyrus\Developer\Creator\Exception('extrasetup file must be in the same directory as package.xml');
             }
             include dirname($package->archivefile) . '/' . $file;
             if (!isset($extrafiles)) {
                 throw new \Pyrus\Developer\Creator\Exception('extrasetup file must set $extrafiles variable to an array of files');
             }
             if (!is_array($extrafiles)) {
                 throw new \Pyrus\Developer\Creator\Exception('extrasetup file must set $extrafiles variable to an array of files');
             }
             foreach ($extrafiles as $path => $file) {
                 if (is_object($file)) {
                     if ($file instanceof \Pyrus\PackageInterface || $file instanceof \Pyrus\PackageFileInterface) {
                         continue;
                     }
                     throw new \Pyrus\Developer\Creator\Exception('extrasetup file object must implement \\Pyrus\\PackageInterface or \\Pyrus\\PackageFileInterface');
                 }
                 if (!file_exists($file)) {
                     throw new \Pyrus\Developer\Creator\Exception('extrasetup file ' . $file . ' does not exist');
                 }
                 if (!is_string($path)) {
                     throw new \Pyrus\Developer\Creator\Exception('extrasetup file ' . $file . ' index should be the path to save in the' . ' release');
                 }
             }
             return $extrafiles;
         };
         $extrafiles = $getinfo();
     } else {
         $extrafiles = array();
     }
     $creator->render($package, $extrafiles);
     if (count($clone)) {
         foreach ($clone as $extra) {
             echo "Creating ", $package->name, '-', $package->version['release'], '.', $extra[0], "\n";
             $cloner->{'to' . $extra[0]}();
         }
     }
     echo "done\n";
 }
Esempio n. 20
0
 /**
  * Unlike other tasks, the installed file name is passed in instead of the file contents,
  * because this task is handled post-installation
  * @param \Pyrus\PackageInterface
  * @param string path to the post-install script
  * @return bool false to skip this file
  */
 function setupPostInstall()
 {
     $files = \Pyrus\Config::current()->registry->info($this->pkg->name, $this->pkg->channel, 'installedfiles');
     foreach ($files as $path => $info) {
         if ($info['name'] == $this->_filename) {
             break;
         }
     }
     Logger::log(0, 'Including external post-installation script "' . $path . '" - any errors are in this script');
     include $path;
     if (class_exists($this->scriptClass) === false) {
         throw new Exception('init of post-install script class "' . $this->scriptClass . '" failed');
     }
     Logger::log(0, 'Inclusion succeeded');
     $this->obj = new $this->scriptClass();
     Logger::log(1, 'running post-install script "' . $this->scriptClass . '->init()"');
     try {
         $this->obj->init2($this->pkg, $this->lastVersion);
     } catch (\Exception $e) {
         throw new Exception('init of post-install script "' . $this->scriptClass . '->init()" failed', $e);
     }
     Logger::log(0, 'init succeeded');
     return true;
 }
Esempio n. 21
0
 function log($level, $message)
 {
     static $data = array();
     if (\Pyrus\Config::initializing()) {
         // we can't check verbose until initializing is complete, so save
         // the message, and only display the log after config is initialized
         $data[] = array($level, $message);
         return;
     }
     if (count($data)) {
         $save = $data;
         $data = array();
         foreach ($save as $info) {
             $this->log($info[0], $info[1]);
         }
     }
     if ($level <= $this->verbose) {
         if (strlen($message) && $message[strlen($message) - 1] !== "\r") {
             echo $message . "\n";
         } else {
             echo $message;
         }
     }
 }
Esempio n. 22
0
 /**
  * Detect any files already installed that would be overwritten by
  * files inside the package represented by $package
  */
 public function detectFileConflicts(\Pyrus\PackageFileInterface $package)
 {
     // construct list of all installed files
     $filesByPackage = $allfiles = array();
     $config = \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;
 }
Esempio n. 23
0
<?php

/**
 * This file generates the pyrus.phar file and PEAR2 package for Pyrus.
 */
$current = \Pyrus\Config::current();
$config = \Pyrus\Config::singleton(__DIR__ . '/vendor');
$extrafiles = array($config->registry->toPackage('PEAR2_HTTP_Request', 'pear2.php.net'), $config->registry->toPackage('PEAR2_Console_CommandLine', 'pear2.php.net'), $config->registry->toPackage('PEAR2_Exception', 'pear2.php.net'), $config->registry->toPackage('PEAR2_MultiErrors', 'pear2.php.net'));
\Pyrus\Config::setCurrent($current->path);
Esempio n. 24
0
 function offsetUnset($offset)
 {
     $info = Config::current()->channelregistry->parseName($offset);
     $this->reg->uninstall($info['package'], $info['channel']);
 }
ini_set('display_errors', true);
// Get the autoloader
require __DIR__ . '/../../../autoload.php';
/*
$channel = new Pyrus_SimpleChannelServer('pear2.php.net','/Library/WebServer/Documents/pearserver', null, '/Users/bbieber/pyrus', array('saltybeagle','cellog'));
if (!@unserialize(file_get_contents('/tmp/categories.inf'))) {
      $cat = Pyrus_SimpleChannelServer_Categories::create('Name1',
          'Description 1', 'Alias1')->
          create('Name2', 'Description 2')->
          create('Name3', 'Description 3', 'Alias3')->
          create('Name4', 'Description 4');
      file_put_contents('/tmp/categories.inf', serialize($cat));
}

$categories = Pyrus_SimpleChannelServer_Categories::getCategories();
$categories = $channel->listCategories();
foreach($categories as $category) {
    var_dump($category);
}
*/
$channel = new Pyrus\SimpleChannelServer\Channel('pear2.php.net', 'Brett Bieber\'s PEAR Channel', 'salty');
//$scs = new Pyrus\SimpleChannelServer\Main($channel,'/Library/WebServer/Documents/pearserver','/home/bbieber/pyrus/php');
$scs = new Pyrus\SimpleChannelServer\Main($channel, '/home/cellog/testapache/htdocs', \Pyrus\Config::current()->location);
$categories = Pyrus\SimpleChannelServer\Categories::create('Default', 'This is the default category');
$scs->saveChannel();
$scs->saveRelease(new \Pyrus\Package(dirname(__FILE__) . '/../package.xml'), 'cellog');
echo 'did it' . PHP_EOL;
/*
$manager = new Pyrus\SimpleChannelServer\REST_Manager('/Library/WebServer/Documents/pearserver','pear2.php.net','rest/',array('cellog'));
var_dump($manager->saveRelease(new \Pyrus\Package(dirname(__FILE__) . '/../package.xml'),'cellog'));
*/
Esempio n. 26
0
 protected function getPackage($package)
 {
     $releases = array();
     if (isset($package['a']) && $package['a']) {
         $releases = $package['a']['r'];
         if (!isset($releases[0])) {
             $releases = array($releases);
         }
         foreach ($releases as $i => $release) {
             if (!isset($release['m'])) {
                 $releases[$i]['m'] = '5.2.0';
             }
         }
     }
     $pxml = new RemotePackage($this->parent, $releases);
     $pxml->channel = $package['p']['c'];
     $pxml->name = $package['p']['n'];
     $pxml->license = $package['p']['l'];
     $pxml->summary = $package['p']['s'];
     $pxml->description = $package['p']['d'];
     $reg = \Pyrus\Config::current()->registry;
     if ($reg->exists($package['p']['n'], $package['p']['c'])) {
         $pxml->setExplicitState($version = $reg->info($package['p']['n'], $package['p']['c'], 'version'));
         $found = false;
         foreach ($pxml as $remoteversion => $rinfo) {
             if (version_compare($remoteversion, $version, '<=')) {
                 continue;
             }
             if (version_compare($rinfo['minimumphp'], phpversion(), '>')) {
                 continue;
             }
             // found one, so upgrade is possible if dependencies pass
             $found = true;
             break;
         }
         // the installed package version satisfies this dependency, don't do anything
         if ($found) {
             $pxml->setUpgradeable();
         }
     } else {
         $pxml->setExplicitState($this->minimumStability);
     }
     return $pxml;
 }
Esempio n. 27
0
 /**
  * Check to see if any packages in the list of packages to be installed
  * satisfy this dependency, and return one if found, otherwise
  * instantiate a new dependency package object
  * @return \Pyrus\PackageInterface|NULL
  */
 function retrieve(\Pyrus\PackageFile\v2\Dependencies\Package $info)
 {
     if (isset(self::$localPackages[$info->channel . '/' . $info->name]) || $this->childProcessed($info->channel . '/' . $info->name)) {
         // we can safely ignore this dependency, an explicit local
         // package is being installed, and we will use it
         // or the dependency has been previously processed, and we will
         // simply result in a duplicate
         return;
     }
     $reg = Config::current()->registry;
     // first check to see if the dependency is installed
     $canupgrade = false;
     if (isset($reg->package[$info->channel . '/' . $info->name])) {
         if (!isset(\Pyrus\Main::$options['upgrade'])) {
             // we don't attempt to upgrade a dep unless we're upgrading
             return;
         }
         $version = $reg->info($info->name, $info->channel, 'version');
         $stability = $reg->info($info->name, $info->channel, 'state');
         if ($this->node->isRemote() && $this->node->getExplicitState()) {
             $installedstability = \Pyrus\Installer::betterStates($stability);
             $parentstability = \Pyrus\Installer::betterStates($this->node->getExplicitState());
             if (count($parentstability) > count($installedstability)) {
                 $stability = $this->node->getExplicitState();
             }
         } else {
             $installedstability = \Pyrus\Installer::betterStates($stability);
             $prefstability = \Pyrus\Installer::betterStates(Config::current()->preferred_state);
             if (count($prefstability) > count($installedstability)) {
                 $stability = Config::current()->preferred_state;
             }
         }
         // see if there are new versions in our stability or better
         if (isset($info->uri)) {
             return;
         }
         $remote = new \Pyrus\Channel\RemotePackage(Config::current()->channelregistry[$info->channel], $stability);
         $found = false;
         foreach ($remote[$info->name] as $remoteversion => $rinfo) {
             if (version_compare($remoteversion, $version, '<=')) {
                 continue;
             }
             if (version_compare($rinfo['minimumphp'], static::getPHPversion(), '>')) {
                 continue;
             }
             // found one, so upgrade is possible if dependencies pass
             $found = true;
             break;
         }
         // the installed package version satisfies this dependency, don't do anything
         if (!$found) {
             return;
         }
         $canupgrade = true;
     }
     if (isset($info->uri)) {
         $ret = new \Pyrus\Package\Remote($info->uri);
         // set up the basics
         $ret->name = $info->name;
         $ret->uri = $info->uri;
         $this->addChild($ret);
         return;
     }
     if ($this->node->isRemote() && $this->node->getExplicitState()) {
         // pass the same explicit state to the child dependency
         $ret = new \Pyrus\Package\Remote($info->channel . '/' . $info->name . '-' . $this->node->getExplicitState());
         if ($canupgrade) {
             $ret->setUpgradeable();
         }
         $this->addChild($ret);
         return;
     }
     $ret = new \Pyrus\Package\Remote($info->channel . '/' . $info->name);
     if ($canupgrade) {
         $ret->setUpgradeable();
     }
     $this->addChild($ret);
     return;
 }
Esempio n. 28
0
 static function registerCustomRole($info)
 {
     if (!isset(self::$_roles)) {
         self::registerRoles();
     }
     self::$_roles[$info['name']] = $info;
     $roles = self::$_roles;
     ksort($roles);
     self::$_roles = $roles;
     self::getBaseinstallRoles(true);
     self::getInstallableRoles(true);
     self::getValidRoles('****', true);
     if (isset($info['configvar'])) {
         if (!isset($info['configvar'][0])) {
             $info['configvar'] = array($info['configvar']);
         }
         foreach ($info['configvar'] as $configvar) {
             if ($configvar['configtype'] == 'system' && in_array($configvar['name'], Config::current()->customsystemvars) || $configvar['configtype'] == 'user' && in_array($configvar['name'], Config::current()->customuservars) || $configvar['configtype'] == 'channel' && in_array($configvar['name'], Config::current()->customchannelvars)) {
                 continue;
             }
             $default = $configvar['default'];
             if (false !== strpos($default, '<?php')) {
                 $tmp = Config::current()->temp_dir . DIRECTORY_SEPARATOR . '.configdefault.php';
                 if (!file_exists(dirname($tmp))) {
                     mkdir(dirname($tmp), 0755, true);
                 }
                 if (file_put_contents($tmp, $default) === false) {
                     throw new Role\Exception("Cannot create custom role configuration file {$tmp}");
                 }
                 $getDefault = function () use($tmp) {
                     include $tmp;
                     return $default;
                 };
                 $default = $getDefault();
             }
             Config::addConfigValue($configvar['name'], $default, $configvar['configtype']);
         }
     }
 }
Esempio n. 29
0
 /**
  * Extract configuration from system + user configuration files
  *
  * Configuration is stored in XML format, in two locations.
  *
  * The system configuration contains all of the important directory
  * configuration variables like data_dir, and the location of php.ini and
  * the php executable php.exe or php.  This configuration is tightly bound
  * to the repository, and cannot be moved.  As such, php_dir is auto-defined
  * as dirname(/path/to/pear/.config), or /path/to/pear.
  *
  * Only 1 user configuration file is allowed, and contains user-specific
  * settings, including the locations where to download package releases
  * and where to cache files downloaded from the internet.  If false is passed
  * in, \Pyrus\Config will attempt to guess at the config file location as
  * documented in the class docblock {@link \Pyrus\Config}.
  * @param string $pearDirectory
  * @param string|false $userfile
  */
 protected function loadConfigFile($pearDirectory, $snapshot = null)
 {
     if (!file_exists($pearDirectory . DIRECTORY_SEPARATOR . '.configsnapshots')) {
         // no configurations - this may be an extracted-from-disk install.
         // in this case, we use the defaults, as this is intended
         return;
     }
     $snapshotdir = $pearDirectory . DIRECTORY_SEPARATOR . '.configsnapshots';
     $snapshotfile = $snapshotdir . DIRECTORY_SEPARATOR . $snapshot;
     if (!file_exists($snapshotfile)) {
         if (preg_match('/^\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}[-:]\\d{2}[-:]\\d{2}$/', $snapshot)) {
             // passed a date, locate a matching snapshot
             if (!strpos($snapshot, ':')) {
                 // change YYYY-MM-DD HH-MM-SS to YYYY-MM-DD HH:MM:SS
                 $snapshot = explode(' ', $snapshot);
                 $snapshot[1] = str_replace('-', ':', $snapshot[1]);
                 $snapshot = implode(' ', $snapshot);
             }
             $us = new \DateTime($snapshot);
             $dir = new \RegexIterator(new \RecursiveDirectoryIterator($snapshotdir), '/configsnapshot\\-\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}\\-\\d{2}\\-\\d{2}.xml/', \RegexIterator::MATCH, \RegexIterator::USE_KEY);
             foreach ($dir as $match) {
                 $matches[] = $match;
             }
             usort($matches, array($this, 'datediff'));
             unset($match);
             $found = false;
             foreach ($matches as $match) {
                 $match = substr($match->getFileName(), strlen('configsnapshot-'));
                 $match = str_replace('.xml', '', $match);
                 $match = explode(' ', $match);
                 $match[1] = str_replace('-', ':', $match[1]);
                 $match = implode(' ', $match);
                 $testdate = new \DateTime($match);
                 if ($testdate > $us) {
                     continue;
                 }
                 if ($testdate == $us) {
                     // found a snapshot match
                     $found = true;
                     break;
                 }
                 if ($us > $testdate) {
                     // we fall between these two snapshots, so use this one
                     $found = true;
                     break;
                 }
             }
             if (!$found) {
                 // no config snapshots
                 return parent::loadConfigFile($pearDirectory);
             }
             $snapshotfile = $snapshotdir . DIRECTORY_SEPARATOR . 'configsnapshot-' . str_replace(':', '-', $match) . '.xml';
         }
     }
     \Pyrus\Logger::log(5, 'Loading configuration snapshot ' . $snapshotfile . ' for ' . $pearDirectory);
     try {
         $this->helperLoadConfigFile($pearDirectory, $snapshotfile, 'snapshot');
     } catch (\Exception $e) {
         // no config snapshots found, so simply load the existing config
         return parent::loadConfigFile($pearDirectory);
     }
 }
Esempio n. 30
0
 /**
  * Figure out which version is best, and use this, or error out if none work
  * @param \Pyrus\PackageFile\v2\Dependencies\Package $compositeDep
  *        the composite of all dependencies on this package, as calculated
  *        by {@link \Pyrus\Package\Dependency::getCompositeDependency()}
  */
 function figureOutBestVersion(\Pyrus\PackageFile\v2\Dependencies\Package $compositeDep, $versions = null, \Pyrus\PackageFile\v2\Dependencies\Package $compositeConflictingDep = null)
 {
     // set up release list if not done yet
     $this->rewind();
     $ok = \Pyrus\Installer::betterStates($this->minimumStability, true);
     $v = $this->explicitVersion;
     $n = $this->channel . '/' . $this->name;
     $failIfExplicit = function ($versioninfo) use($v, $n) {
         if ($v && $versioninfo['v'] == $v) {
             throw new Exception($n . ' Cannot be installed, it does not satisfy ' . 'all dependencies');
         }
     };
     foreach ($this->releaseList as $versioninfo) {
         if (isset(\Pyrus\Main::$options['force'])) {
             // found one
             if ($this->versionSet && $versioninfo['v'] != $this->version['release']) {
                 // inform the installer we need to reset dependencies
                 $this->version['release'] = $versioninfo['v'];
                 return true;
             }
             $this->version['release'] = $versioninfo['v'];
             return;
         }
         if ($versions && !in_array($versioninfo['v'], $versions)) {
             continue;
         }
         if (!isset(\Pyrus\Main::$options['force']) && isset($versioninfo['m'])) {
             // minimum PHP version required
             if (version_compare($versioninfo['m'], $this->getPHPVersion(), '>')) {
                 $failIfExplicit($versioninfo);
                 continue;
             }
         }
         if (!in_array($versioninfo['s'], $ok) && !isset(\Pyrus\Main::$options['force'])) {
             // release is not stable enough
             continue;
         }
         if ($this->explicitVersion && $versioninfo['v'] != $this->explicitVersion) {
             continue;
         }
         if (!$compositeDep->satisfied($versioninfo['v'])) {
             $failIfExplicit($versioninfo);
             continue;
         }
         if ($compositeConflictingDep && !$compositeConflictingDep->satisfied($versioninfo['v'])) {
             $failIfExplicit($versioninfo);
             continue;
         }
         $paranoia = \Pyrus\Main::getParanoiaLevel();
         if (!$this->explicitVersion && $paranoia > 1) {
             // first, we check to see if we are upgrading
             if (isset(\Pyrus\Main::$options['upgrade'])) {
                 // now we check to see if we are installed
                 if (isset(Config::current()->registry->package[$n])) {
                     $installed = Config::current()->registry->info($this->name, $this->channel, 'apiversion');
                     $installed = explode('.', $installed);
                     if (count($installed) == 2) {
                         $installed[] = '0';
                     }
                     if (count($installed) == 1) {
                         $installed[] = '0';
                         $installed[] = '0';
                     }
                     if (isset($this->parent->protocols->rest['REST1.3'])) {
                         $api = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.3']->baseurl . 'r/' . strtolower($this->name) . '/v2.' . $versioninfo['v'] . '.xml', false, false, 'text/xml');
                     } else {
                         throw new Exception('Channel ' . $this->channel . ' does not support ' . 'a paranoia greater than 1');
                     }
                     $api = explode('.', $api['a']);
                     if (count($api) == 2) {
                         $api[] = '0';
                     }
                     if (count($api) == 1) {
                         $api[] = '0';
                         $api[] = '0';
                     }
                     if ($paranoia > 4) {
                         $paranoia = 4;
                     }
                     switch ($paranoia) {
                         case 4:
                             if ($installed != $api) {
                                 Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API has changed');
                                 continue 2;
                             }
                             break;
                         case 3:
                             if ($installed[0] == $api[0] && $installed[1] != $api[1]) {
                                 Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API has added' . ' new features');
                                 continue 2;
                             }
                             // break intentionally omitted
                         // break intentionally omitted
                         case 2:
                             if ($installed[0] != $api[0]) {
                                 Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API breaks' . ' backwards compatibility');
                                 continue 2;
                             }
                             break;
                     }
                 }
             }
         }
         // found one
         if ($this->versionSet && $versioninfo['v'] != $this->version['release']) {
             // inform the installer we need to reset dependencies
             $this->version['release'] = $versioninfo['v'];
             return true;
         }
         $this->version['release'] = $versioninfo['v'];
         return;
     }
     throw new Exception('Unable to locate a package release for ' . $this->channel . '/' . $this->name . ' that can satisfy all dependencies');
 }