/**
  * Install a PEAR package.
  *
  * @param string $package Name of the package to install. PEAR2_Templates_Savant
  *
  * @return void
  */
 static function installPackage($package)
 {
     $config = \PEAR2\Pyrus\Config::singleton(self::$autoload_registry);
     $config->preferred_state = 'alpha';
     $p = new \PEAR2\Pyrus\Package($package);
     try {
         \PEAR2\Pyrus\Installer::begin();
         \PEAR2\Pyrus\Installer::prepare($p);
         \PEAR2\Pyrus\Installer::commit();
     } catch (Exception $e) {
         \PEAR2\Pyrus\Installer::rollback();
         echo $e;
     }
 }
    function rewind()
    {
        $url = $this->parent->protocols->rest['REST1.0']->baseurl . 'p/packages.xml';
        $this->packageList = $this->rest->retrieveCacheFirst($url);
        $this->packageList = $this->packageList['p'];
        if (!is_array($this->packageList)) {
            $this->packageList = array($this->packageList);
        }

        if (isset($this->stability)) {
            // filter the package list for packages of this stability or better
            $ok = \PEAR2\Pyrus\Installer::betterStates($this->stability, true);
            $filtered = array();
            foreach ($this->packageList as $lowerpackage) {
                if (isset($this->parent->protocols->rest['REST1.3'])) {
                    $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.3']->baseurl .
                                                            'r/' . $lowerpackage . '/allreleases2.xml');
                } else {
                    $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl .
                                                            'r/' . $lowerpackage . '/allreleases.xml');
                }

                if (!isset($info['r'][0])) {
                    $info['r'] = array($info['r']);
                }

                $releases = array();
                foreach ($info['r'] as $release) {
                    if (!in_array($release['s'], $ok)) {
                        continue;
                    }

                    if (!isset($release['m'])) {
                        $release['m'] = '5.2.0';
                    }

                    $releases[] = $release;
                }

                if (!count($releases)) {
                    continue;
                }

                $filtered[] = array($lowerpackage, $releases);
            }

            $this->packageList = $filtered;
        }
    }
Beispiel #3
0
    public function installCustomRole()
    {
        $pf = new \PEAR2\Pyrus\PackageFile\v2;

        $pf->name = 'PyrusBundlePlugin';
        $pf->channel = 'pear2.php.net';
        $pf->summary = 'Local';
        $pf->description = 'Description';
        $pf->notes = 'My Notes';
        $pf->maintainer['naderman']->role('lead')->email('*****@*****.**')->active('yes')->name('Nils Adermann');
        $pf->files['Bundle.xml'] = array(
            'attribs' => array('role' => 'customrole'),
        );
        $pf->files['PyrusBundlePlugin/Role/Bundle.php'] = array(
            'attribs' => array('role' => 'php'),
        );

        $package_xml = __DIR__ . '/plugin/package.xml';
        $pf->setPackagefile($package_xml);

        $package = new \PEAR2\Pyrus\Package(false);
        $xmlcontainer = new \PEAR2\Pyrus\PackageFile($pf);
        $xml = new \PEAR2\Pyrus\Package\Xml($package_xml, $package, $xmlcontainer);
        $package->setInternalPackage($xml);
        \PEAR2\Pyrus\Main::$options['install-plugins'] = true;

        \PEAR2\Pyrus\Installer::begin();
        \PEAR2\Pyrus\Installer::prepare($package);
        \PEAR2\Pyrus\Installer::commit();

        $this->readConfig();
    }
Beispiel #4
0
 /**
  * install a local or remote package
  *
  * @param array $args
  */
 function install($args, $options)
 {
     if ($options['plugin']) {
         \PEAR2\Pyrus\Main::$options['install-plugins'] = true;
     }
     if ($options['force']) {
         \PEAR2\Pyrus\Main::$options['force'] = true;
     }
     if (isset($options['packagingroot']) && $options['packagingroot']) {
         \PEAR2\Pyrus\Main::$options['packagingroot'] = $options['packagingroot'];
     }
     if ($options['optionaldeps']) {
         \PEAR2\Pyrus\Main::$options['optionaldeps'] = $options['optionaldeps'];
     }
     \PEAR2\Pyrus\Installer::begin();
     try {
         $packages = array();
         foreach ($args['package'] as $arg) {
             \PEAR2\Pyrus\Installer::prepare($packages[] = new \PEAR2\Pyrus\Package($arg));
         }
         \PEAR2\Pyrus\Installer::commit();
         foreach (\PEAR2\Pyrus\Installer::getInstalledPackages() as $package) {
             echo 'Installed ' . $package->channel . '/' . $package->name . '-' . $package->version['release'] . "\n";
             if ($package->type === 'extsrc' || $package->type === 'zendextsrc') {
                 echo " ==> To build this PECL package, use the build command\n";
             }
         }
         $optionals = \PEAR2\Pyrus\Installer::getIgnoredOptionalDeps();
         if (count($optionals)) {
             echo "Optional dependencies that will not be installed, use --optionaldeps:\n";
         }
         foreach ($optionals as $dep => $packages) {
             echo $dep, ' depended on by ', implode(', ', array_keys($packages)), "\n";
         }
     } catch (\Exception $e) {
         if ($e instanceof \PEAR2\Pyrus\Channel\Exception && strpos($arg, '/') === false) {
             echo "Sorry there was an error retrieving " . \PEAR2\Pyrus\Config::current()->default_channel . "/{$arg} from the default channel\n";
         }
         // If this is an undiscovered channel, handle it gracefully
         if ($e instanceof \PEAR2\Pyrus\Package\Exception && $e->getPrevious() instanceof \PEAR2\Pyrus\ChannelRegistry\Exception && $e->getPrevious()->getPrevious() instanceof \PEAR2\Pyrus\ChannelRegistry\ParseException && $e->getPrevious()->getPrevious()->why == 'channel' && strpos($arg, '/') !== false) {
             $channel = substr($arg, 0, strrpos($arg, '/'));
             echo "Sorry, the channel \"{$channel}\" is unknown.\n";
             return $this->installUnknownChannelExceptionHandler($args, $options, $e, $channel);
         }
         if ($e instanceof \PEAR2\Pyrus\ChannelRegistry\Exception && $e->getPrevious() instanceof \PEAR2\Pyrus\ChannelRegistry\ParseException && $e->getPrevious()->why == 'channel' && preg_match('/^unknown channel \\"(.*)\\" in \\"(.*)\\"$/', $e->getPrevious()->getMessage(), $matches)) {
             echo "Sorry, {$arg} references an unknown channel {$matches[1]} for {$matches[2]}\n";
             return $this->installUnknownChannelExceptionHandler($args, $options, $e, $matches[1]);
         }
         $this->exceptionHandler($e);
         exit(1);
     }
 }
Beispiel #5
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 \PEAR2\Pyrus\PackageInterface|NULL
     */
    function retrieve(\PEAR2\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(\PEAR2\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 = \PEAR2\Pyrus\Installer::betterStates($stability);
                $parentstability = \PEAR2\Pyrus\Installer::betterStates($this->node->getExplicitState());
                if (count($parentstability) > count($installedstability)) {
                    $stability = $this->node->getExplicitState();
                }
            } else {
                $installedstability = \PEAR2\Pyrus\Installer::betterStates($stability);
                $prefstability = \PEAR2\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 \PEAR2\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 \PEAR2\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 \PEAR2\Pyrus\Package\Remote($info->channel . '/' . $info->name . '-' .
                                                  $this->node->getExplicitState());
            if ($canupgrade) {
                $ret->setUpgradeable();
            }

            $this->addChild($ret);
            return;
        }

        $ret = new \PEAR2\Pyrus\Package\Remote($info->channel . '/' . $info->name);
        if ($canupgrade) {
            $ret->setUpgradeable();
        }

        $this->addChild($ret);
        return;
    }
Beispiel #6
0
    /**
     *
     * @param string|array pass in an array of format
     *                     array(
     *                      'package' => 'pname',
     *                     ['channel' => 'channame',]
     *                     ['version' => 'version',]
     *                     ['state' => 'state',])
     *                     or a string of format [channame/]pname[-version|-state]
     */
    protected function fromString($param)
    {
        try {
            $pname = Config::parsePackageName($param, true);
        } catch (\PEAR2\Pyrus\ChannelRegistry\ParseException $e) {
            if ($e->why !== 'channel') {
                throw new Exception('invalid package name/package file "' . $param . '"', $e);
            }

            if (Config::current()->auto_discover) {
                try {
                    try {
                        $chan = new \PEAR2\Pyrus\Channel(
                                    new \PEAR2\Pyrus\ChannelFile('https://' . $e->params['channel'] . '/channel.xml',
                                                                false, true));
                    } catch (\Exception $e) {
                        $chan = new \PEAR2\Pyrus\Channel(
                                    new \PEAR2\Pyrus\ChannelFile('http://' . $e->params['channel'] . '/channel.xml',
                                                                false, true));
                    }
                } catch (\Exception $e) {
                    throw new Exception('Cannot auto-discover channel ' . $e->params['channel'], $e);
                }

                Config::current()->channelregistry[] = $chan;
                try {
                    Config::parsePackageName($param, Config::current()->default_channel);
                } catch (\Exception $e) {
                    throw new Exception('invalid package name/package file "' . $param . '"', $e);
                }
            } else {
                \PEAR2\Pyrus\Logger::log(0, 'Channel "' . $param['channel'] .
                    '" is not initialized, use ' .
                    '"pyrus channel-discover ' . $param['channel'] . '" to initialize' .
                    'or pyrus set auto_discover 1');
            }
        }

        $this->parsedname    = $pname;
        $this->explicitVersion = isset($pname['version']) ? $pname['version'] : false;
        $this->explicitState = isset($pname['state']) ? $pname['state'] : false;
        $this->explicitGroup = isset($pname['group']) ? true            : false;

        $reg = Config::current()->registry;
        $version = $reg->info($pname['package'], $pname['channel'], 'version');
        $stability = $reg->info($pname['package'], $pname['channel'], 'state');

        if (!isset(\PEAR2\Pyrus\Main::$options['force']) &&
              !isset(\PEAR2\Pyrus\Main::$options['downloadonly']) &&
              $version && $this->explicitVersion &&
              !isset($pname['group'])) {
            if (version_compare($version, $pname['version'], '>=')) {
                throw new InstalledException(
                    Config::parsedPackageNameToString($pname, true) .
                    ' is already installed and is newer than detected ' .
                    'release version ' . $pname['version']);
            }
        }
        if (!$this->explicitVersion && $stability) {
            // if installed, use stability of the installed package,
            // but only if it is less restrictive than preferred_state.
            // This allows automatic upgrade to a newer beta for 1 package
            // even if preferred_state is stable, for instance.
            $states = \PEAR2\Pyrus\Installer::betterStates(Config::current()->preferred_state);
            $newstates = \PEAR2\Pyrus\Installer::betterStates($stability);
            if (count($newstates) > count($states)) {
                $this->explicitState = $stability;
            }
        }

        $this->type = 'abstract';
        $ret = $this->getRemotePackage($pname);
        if ($this->explicitVersion) {
            $ret->setExplicitVersion($this->explicitVersion);
            $ret->version['release'] = $this->explicitVersion;
        }
        if ($this->explicitState) {
            $ret->setExplicitState($this->explicitState);
        }
        return $ret;
    }
Beispiel #7
0
 /**
  * Figure out which version is best, and use this, or error out if none work
  * @param \PEAR2\Pyrus\PackageFile\v2\Dependencies\Package $compositeDep
  *        the composite of all dependencies on this package, as calculated
  *        by {@link \PEAR2\Pyrus\Package\Dependency::getCompositeDependency()}
  */
 function figureOutBestVersion(\PEAR2\Pyrus\PackageFile\v2\Dependencies\Package $compositeDep, $versions = null, \PEAR2\Pyrus\PackageFile\v2\Dependencies\Package $compositeConflictingDep = null)
 {
     // set up release list if not done yet
     $this->rewind();
     $ok = \PEAR2\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(\PEAR2\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(\PEAR2\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(\PEAR2\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 = \PEAR2\Pyrus\Main::getParanoiaLevel();
         if (!$this->explicitVersion && $paranoia > 1) {
             // first, we check to see if we are upgrading
             if (isset(\PEAR2\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');
                     } 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');
 }
Beispiel #8
0
    /**
     * install a local or remote package
     *
     * @param array $args
     */
    function install($args, $options)
    {
        if ($options['plugin']) {
            \PEAR2\Pyrus\Main::$options['install-plugins'] = true;
        }

        if ($options['force']) {
            \PEAR2\Pyrus\Main::$options['force'] = true;
        }

        if (isset($options['packagingroot']) && $options['packagingroot']) {
            \PEAR2\Pyrus\Main::$options['packagingroot'] = $options['packagingroot'];
        }

        if ($options['optionaldeps']) {
            \PEAR2\Pyrus\Main::$options['optionaldeps'] = $options['optionaldeps'];
        }

        \PEAR2\Pyrus\Installer::begin();
        try {
            $packages = array();
            foreach ($args['package'] as $arg) {
                \PEAR2\Pyrus\Installer::prepare($packages[] = new \PEAR2\Pyrus\Package($arg));
            }

            \PEAR2\Pyrus\Installer::commit();
            foreach (\PEAR2\Pyrus\Installer::getInstalledPackages() as $package) {
                echo 'Installed ' . $package->channel . '/' . $package->name . '-' .
                    $package->version['release'] . "\n";
                if ($package->type === 'extsrc' || $package->type === 'zendextsrc') {
                    echo " ==> To build this PECL package, use the build command\n";
                }
            }

            $optionals = \PEAR2\Pyrus\Installer::getIgnoredOptionalDeps();
            if (count($optionals)) {
                echo "Optional dependencies that will not be installed, use --optionaldeps:\n";
            }

            foreach ($optionals as $dep => $packages) {
                echo $dep, ' depended on by ', implode(', ', array_keys($packages)), "\n";
            }
        } catch (\Exception $e) {

            // If this is an undiscovered channel, handle it gracefully
            if ($e instanceof \PEAR2\Pyrus\Package\Exception
                && $e->getPrevious() instanceof \PEAR2\Pyrus\ChannelRegistry\Exception
                && $e->getPrevious()->getPrevious() instanceof \PEAR2\Pyrus\ChannelRegistry\ParseException
                && $e->getPrevious()->getPrevious()->why == 'channel'
                && strpos($arg, '/') !== false) {

                $channel = strstr($arg, '/', true);

                echo "Sorry, the channel \"{$channel}\" is unknown.\n";

                if ('yes' === $this->ask('Do you want to add this channel and continue the install?', array('yes', 'no'), 'yes')) {
                    $this->channelDiscover(array('channel' => $channel));
                    $this->install($args, $options);
                    return;
                }
                echo "Ok. I understand.\n";
            }

            $this->exceptionHandler($e);
            exit -1;
        }
    }