Exemple #1
0
    /**
     * @param string
     * @param string file name of the channel.xml
     *
     * @return \PEAR2\Pyrus\ChannelFile\v1
     */
    function parse($data, $file = false, $class = 'PEAR2\Pyrus\ChannelFile\v1')
    {
        $ret = new $class;
        if (!$ret instanceof \PEAR2\Pyrus\ChannelFile\v1) {
            throw new \PEAR2\Pyrus\ChannelFile\Exception('Class ' . $class .
                ' passed to parse() must be a child class of \PEAR2\Pyrus\ChannelFile\v1');
        }

        $schema = \PEAR2\Pyrus\Main::getDataPath() . '/channel-1.0.xsd';
        // for running out of svn
        if (!file_exists($schema)) {
            $schema = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/channel-1.0.xsd';
        }

        try {
            if ($file) {
                $ret->fromArray(parent::parse($data, $schema));
            } else {
                $ret->fromArray(parent::parseString($data, $schema));
            }
        } catch (\Exception $e) {
            throw new \PEAR2\Pyrus\ChannelFile\Exception('Invalid channel.xml', null, $e);
        }

        return $ret;
    }
    protected function __construct($rolepath)
    {
        if (isset(Main::$options['packagingroot'])) {
            $rolepath = Main::prepend(Main::$options['packagingroot'], $rolepath);
        }
        $rolepath = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $rolepath);

        $this->rolepath = $rolepath;
        $path = dirname($rolepath) . DIRECTORY_SEPARATOR;

        $this->backuppath  = $path . '.old-' . basename($rolepath);
        $this->journalpath = $path . '.journal-' . basename($rolepath);
        $this->defaultMode = 0777 & ~octdec(Config::current()->umask);
    }
 function validate(\PEAR2\Pyrus\PackageInterface $package, array $file)
 {
     $parser = new \PEAR2\Pyrus\XMLParser();
     $schemapath = \PEAR2\Pyrus\Main::getDataPath();
     if (!file_exists(\PEAR2\Pyrus\Main::getDataPath() . '/customcommand-2.0.xsd')) {
         $schemapath = realpath(__DIR__ . '/../../../../../data');
     }
     $taskschema = $schemapath . '/customcommand-2.0.xsd';
     try {
         $taskinfo = $parser->parse($package->getFilePath($file['attribs']['name']), $taskschema);
     } catch (\Exception $e) {
         throw new \PEAR2\Pyrus\Installer\Role\Exception('Invalid custom command definition file,' . ' file does not conform to the schema', $e);
     }
 }
Exemple #4
0
    /**
     * Initialize the registry
     *
     * @param string $path
     */
    function __construct($path, $readonly = false)
    {
        $this->readonly = $readonly;
        if (isset(Main::$options['packagingroot'])) {
            $path = Main::prepend(Main::$options['packagingroot'], $path);
        }

        $this->path = $path;
        $this->channelpath = $path . DIRECTORY_SEPARATOR . '.xmlregistry' . DIRECTORY_SEPARATOR . 'channels';
        if (1 === $this->exists('pear.php.net')) {
            $this->initialized = false;
        } else {
            $this->initialized = true;
        }
    }
Exemple #5
0
    function __construct($path, $readonly = false)
    {
        $this->readonly = $readonly;
        if (!file_exists($path . '/.registry') && basename($path) !== 'php') {
            $path = $path . DIRECTORY_SEPARATOR . 'php';
        }

        $this->path = $path;
        if (isset(\PEAR2\Pyrus\Main::$options['packagingroot'])) {
            $path = \PEAR2\Pyrus\Main::prepend(\PEAR2\Pyrus\Main::$options['packagingroot'], $path);
        }

        $this->_channelPath = $path . DIRECTORY_SEPARATOR . '.channels';
        $this->_aliasPath   = $this->_channelPath . DIRECTORY_SEPARATOR . '.alias';
        if (!file_exists($this->_channelPath) || !is_dir($this->_channelPath)) {
            if ($readonly) {
                throw new Exception('Cannot initialize PEAR1 channel registry, directory' .
                                    ' does not exist and registry is read-only');
            }

            if (!@mkdir($this->_channelPath, 0755, true)) {
                throw new Exception('Cannot initialize PEAR1 channel registry, channel' .
                                    ' directory could not be initialized');
            }
        }

        if (!file_exists($this->_aliasPath) || !is_dir($this->_aliasPath)) {
            if ($readonly) {
                throw new Exception('Cannot initialize PEAR1 channel registry, aliasdirectory ' .
                                    'does not exist and registry is read-only');
            }

            if (!@mkdir($this->_aliasPath, 0755, true)) {
                throw new Exception('Cannot initialize PEAR1 channel registry, channel ' .
                                    'aliasdirectory could not be initialized');
            }
        }

        if (1 === $this->exists('pear.php.net')) {
            $this->initialized = false;
        } else {
            $this->initialized = true;
        }
    }
Exemple #6
0
    static private function _init($path, $readonly)
    {
        if (!$path) {
            $path = ':memory:';
        } else {
            $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
        }

        if (static::existsRegistry($path)) {
            return;
        }

        $dbpath = $path;
        if ($path != ':memory:' && isset(Main::$options['packagingroot'])) {
            $dbpath = Main::prepend(Main::$options['packagingroot'], $path);
        }

        if ($path != ':memory:' && !file_exists(dirname($dbpath))) {
            if ($readonly) {
                throw new Exception('Cannot create SQLite3 registry, registry is read-only');
            }
            @mkdir(dirname($dbpath), 0755, true);
        }

        if ($readonly && $path != ':memory:' && !file_exists($dbpath)) {
            throw new Exception('Cannot create SQLite3 registry, registry is read-only');
        }

        static::$databases[$path] = new \SQLite3($dbpath);
        // ScottMac needs to fix sqlite3 FIXME
        if (static::$databases[$path]->lastErrorCode()) {
            $error = static::$databases[$path]->lastErrorMsg();
            throw new Exception('Cannot open SQLite3 registry: ' . $error);
        }

        $sql = 'SELECT version FROM pearregistryversion';
        if (@static::getRegistry($path)->querySingle($sql) == '1.0.0') {
            return;
        }

        if ($readonly) {
            throw new Exception('Cannot create SQLite3 registry, registry is read-only');
        }

        $a = new Sqlite3\Creator;
        try {
            $a->create(static::$databases[$path]);
        } catch (\Exception $e) {
            unset(static::$databases[$path]);
            $a = get_class($e);
            throw new $a('Database initialization failed', 0, $e);
        }
    }
Exemple #7
0
 /**
  * @param \PEAR2\Pyrus\PackageFile\v2
  * @param int
  */
 function validate(\PEAR2\Pyrus\PackageInterface $pf, $state = \PEAR2\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 = \PEAR2\Pyrus\Main::getDataPath() . '/package-2.1.xsd';
             // for running out of cvs
             if (!file_exists($schema)) {
                 $schema = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/package-2.1.xsd';
             }
         } else {
             $schema = \PEAR2\Pyrus\Main::getDataPath() . '/package-2.0.xsd';
             // for running out of cvs
             if (!file_exists($schema)) {
                 $schema = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/package-2.0.xsd';
             }
         }
         $dom->schemaValidate($schema);
         $causes = array();
         foreach (libxml_get_errors() as $error) {
             $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception("Line " .
                  $error->line . ': ' . $error->message);
         }
         if (count($this->errors)) {
             throw new \PEAR2\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 \PEAR2\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 \PEAR2\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 = \PEAR2\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 \PEAR2\Pyrus\PackageFile\Exception($msg);
                     }
                 }
             }
             $this->errors->E_ERROR[] =
                 new \PEAR2\Pyrus\PackageFile\Exception(
                 'File "' . $name . '" has invalid role "' .
                 $file->role . '", should be one of ' . implode(', ',
                 \PEAR2\Pyrus\Installer\Role::getValidRoles($this->_pf->getPackageType())));
         }
         if (count($file->tasks) && $this->_curState != \PEAR2\Pyrus\Validate::DOWNLOADING) { // has tasks
             $save = $file->getArrayCopy();
             foreach ($file->tasks as $task => $value) {
                 if ($tagClass = \PEAR2\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 (\PEAR2\Pyrus\Task\Exception $e) {
                             $this->errors->E_ERROR[] =
                                 new \PEAR2\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 = \PEAR2\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 \PEAR2\Pyrus\PackageFile\Exception($msg);
                             }
                         }
                     }
                     $this->errors->E_ERROR[] =
                         new \PEAR2\Pyrus\PackageFile\Exception(
                         'Unknown task "' . $task . '" passed in file <file name="' .
                         $name . '">');
                 }
             }
         }
     }
     $this->_validateRelease();
     if (count($this->errors->E_ERROR)) {
         throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors);
     }
     try {
         $validator = \PEAR2\Pyrus\Config::current()
             ->channelregistry[$this->_pf->channel]
             ->getValidationObject($this->_pf->name);
     } catch (\PEAR2\Pyrus\Config\Exception $e) {
         throw new \PEAR2\Pyrus\PackageFile\Exception(
             'Unable to process channel-specific configuration for channel ' .
             $this->_pf->getChannel(), $e);
     } catch (\Exception $e) {
         $valpack = \PEAR2\Pyrus\Config::current()
             ->channelregistry[$this->_pf->channel]->getValidationPackage();
         $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception(
             'Unknown channel ' . $this->_pf->channel);
         $this->errors->E_ERROR[] = new \PEAR2\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(\PEAR2\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 \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml',
             $this->errors);
     }
     if ($state == \PEAR2\Pyrus\Validate::PACKAGING) {
         if ($this->_pf->type == 'bundle') {
             if (!$this->_analyzeBundledPackages()) {
                 throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml',
                     $this->errors);
             }
         } else {
             if (!$this->_analyzePhpFiles()) {
                 throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml',
                     $this->errors);
             }
         }
     }
     return $state;
 }
Exemple #8
0
    /**
     * Scan through the Command directory looking for classes
     * and see what commands they implement.
     * @param string which directory to look for classes, defaults to
     *               the Installer/Roles subdirectory of
     *               the directory from where this file (__FILE__) is
     *               included.
     *
     * @return bool TRUE on success, a PEAR error on failure
     * @access public
     * @static
     */
    static function registerRoles($dir = null)
    {
        self::$_roles = array();
        $parser = new \PEAR2\Pyrus\XMLParser;
        if ($dir === null) {
            $dir = __DIR__ . '/Role';
        }

        if (!file_exists($dir) || !is_dir($dir)) {
            throw new Role\Exception("registerRoles: opendir($dir) failed");
        }

        $dp = @opendir($dir);
        if (empty($dp)) {
            throw new Role\Exception("registerRoles: opendir($dir) failed");
        }

        $schemapath = \PEAR2\Pyrus\Main::getDataPath() . '/customrole-2.0.xsd';
        if (!file_exists($schemapath)) {
            $schemapath = realpath(__DIR__ . '/../../../data/customrole-2.0.xsd');
        }

        while ($entry = readdir($dp)) {
            if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
                continue;
            }

            $role = strtolower(basename($entry, '.xml'));
            // List of roles
            if (!isset(self::$_roles[$role])) {
                $file = "$dir/$entry";
                $data = $parser->parse($file, $schemapath);
                $data = $data['role'];
                if (!is_array($data['releasetypes'])) {
                    $data['releasetypes'] = array($data['releasetypes']);
                }

                self::$_roles[$role] = $data;
            }
        }

        closedir($dp);
        $roles = self::$_roles;
        ksort($roles);
        self::$_roles = $roles;
        self::getBaseinstallRoles(true);
        self::getInstallableRoles(true);
        self::getValidRoles('****', true);
        return true;
    }
Exemple #9
0
 /**
  * This method acts as a controller which dispatches the request to the
  * correct command/method.
  *
  * <code>
  * $cli = \PEAR2\Pyrus\ScriptFrontend\Commands();
  * $cli->run($args = array (0 => 'install',
  *                          1 => 'PEAR2/Pyrus_Developer/package.xml'));
  * </code>
  *
  * The above code will dispatch to the install command
  *
  * @param array $args An array of command line arguments.
  *
  * @return void
  */
 function run($args)
 {
     try {
         $sig = \PEAR2\Pyrus\Main::getSignature();
         if ($sig) {
             echo "Pyrus version ", \PEAR2\Pyrus\Main::VERSION, ' ', $sig['hash_type'], ': ', $sig['hash'], "\n";
         }
         $this->_findPEAR($args);
         $this->verbose = \PEAR2\Pyrus\Config::current()->verbose;
         // scan for custom commands/roles/tasks
         \PEAR2\Pyrus\Config::current()->pluginregistry->scan();
         if (!isset(static::$commandParser->commands['make'])) {
             $this->addDeveloperCommands('developer');
         }
         if (!isset(static::$commandParser->commands['scs-update'])) {
             $this->addDeveloperCommands('scs');
         }
         $result = static::$commandParser->parse(count($args) + 1, array_merge(array('cruft'), $args));
         if ($result->options['verbose']) {
             $this->verbose = $result->options['verbose'];
         }
         if ($result->options['paranoid']) {
             \PEAR2\Pyrus\Main::$paranoid = $result->options['paranoid'];
         }
         if ($info = \PEAR2\Pyrus\PluginRegistry::getCommandInfo($result->command_name)) {
             if ($this instanceof $info['class']) {
                 if ($info['function'] == 'dummyStub' || $info['function'] == 'scsDummyStub') {
                     $this->{$info['function']}($result);
                 } else {
                     $this->{$info['function']}($result->command->args, $result->command->options);
                 }
             } else {
                 $class = new $info['class']();
                 $class->{$info['function']}($this, $result->command->args, $result->command->options);
             }
         } else {
             $this->help(array('command' => isset($args[0]) ? $args[0] : null));
         }
     } catch (\PEAR2\Console\CommandLine\Exception $e) {
         static::$commandParser->displayError($e->getMessage(), false);
         static::$commandParser->displayUsage(false);
     }
 }
Exemple #10
0
    /**
     * remotely connect to a channel server and grab the channel information,
     * then add it to the current pyrus managed repo
     *
     * @param array $args $args[0] should be the channel name, eg:pear.unl.edu
     */
    function channelDiscover($args)
    {
        // try secure first
        $chan = 'https://' . $args['channel'] . '/channel.xml';
        try {
            $response = \PEAR2\Pyrus\Main::download($chan);
            if ($response->code != 200) {
                throw new \PEAR2\Pyrus\Exception('Download of channel.xml failed');
            }
        } catch (\Exception $e) {
            try {
                $chan = 'http://' . $args['channel'] . '/channel.xml';
                $response = \PEAR2\Pyrus\Main::download($chan);
                if ($response->code != 200) {
                    throw new \PEAR2\Pyrus\Exception('Download of channel.xml failed');
                }
            } catch (\Exception $e) {
                // failed, re-throw original error
                echo "Discovery of channel ", $args['channel'], " failed: ", $e->getMessage(), "\n";
                return;
            }
        }

        $chan = new \PEAR2\Pyrus\Channel(new \PEAR2\Pyrus\ChannelFile($response->body, true));
        \PEAR2\Pyrus\Config::current()->channelregistry->add($chan);
        echo "Discovery of channel ", $chan->name, " successful\n";
    }
Exemple #11
0
 /**
  * Parses a string containing package xml and returns an object
  *
  * @param string       $data  data to parse
  * @param string|false $file  name of the archive this package.xml came from, if any
  * @param string       $class class name to instantiate and return.
  *                            This must be PEAR2\Pyrus\PackageFile\v2 or a subclass
  * @param int          $state what state we are currently in
  *
  * @return \PEAR2\Pyrus\PackageFile\v2
  */
 function parse($data, $file = false, $class = 'PEAR2\\Pyrus\\PackageFile\\v2', $state = \PEAR2\Pyrus\Validate::NORMAL)
 {
     $this->_inContents = false;
     $this->_path = '';
     $this->_files = array();
     $this->_lastDepth = $this->_lastFileDepth = 0;
     $this->_inFile = 0;
     $ret = new $class();
     if (!$ret instanceof \PEAR2\Pyrus\PackageFile\v2) {
         throw new \PEAR2\Pyrus\PackageFile\Exception('Class ' . $class . ' passed to parse() must be a child class of \\PEAR2\\Pyrus\\PackageFile\\v2');
     }
     if (preg_match('/<package[^>]+version="2.1"/', $data)) {
         $schema = \PEAR2\Pyrus\Main::getDataPath() . '/package-2.1.xsd';
         // for running out of cvs
         if (!file_exists($schema)) {
             $schema = dirname(dirname(dirname(dirname(dirname(__DIR__))))) . '/data/package-2.1.xsd';
         }
     } elseif (preg_match('/<package[^>]+version="2.0"/', $data)) {
         $schema = \PEAR2\Pyrus\Main::getDataPath() . '/package-2.0.xsd';
         // for running out of cvs
         if (!file_exists($schema)) {
             $schema = dirname(dirname(dirname(dirname(dirname(__DIR__))))) . '/data/package-2.0.xsd';
         }
     } else {
         throw new \PEAR2\Pyrus\PackageFile\Exception('Cannot process package.xml version 1.0', -3);
     }
     try {
         $ret->fromArray(parent::parseString($data, $schema));
     } catch (\Exception $e) {
         throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml', $e);
     }
     $ret->setFileList($this->_files);
     $ret->setBaseInstallDirs($this->_baseinstalldirs);
     $ret->setPackagefile($file);
     return $ret;
 }
Exemple #12
0
 /**
  * Returns a list of registries present in the PEAR installation at $path
  * @param string
  * @return array
  */
 public static function detectRegistries($path)
 {
     if (isset(Main::$options['packagingroot'])) {
         $path = Main::prepend(Main::$options['packagingroot'], $path);
     }
     if (file_exists($path . '/.registry') || is_dir($path . '/.registry')) {
         return array('Pear1');
     }
     if (basename($path) !== 'php') {
         $path = $path . DIRECTORY_SEPARATOR . 'php';
     }
     if (file_exists($path . '/.registry') || is_dir($path . '/.registry')) {
         return array('Pear1');
     }
     return array();
 }
Exemple #13
0
    protected function fromUrl($param, $saveparam = '')
    {
        $this->type = 'url';
        $dir = Config::current()->download_dir;
        try {
            $response = \PEAR2\Pyrus\Main::downloadWithProgress($param);
            if ($response->code != '200') {
                throw new Exception('Download failed, received ' . $response->code);
            }

            $info = parse_url($param);
            $name = urldecode(basename($info['path']));
            if (isset($response->headers['content-disposition'])) {
                if (preg_match('/filename="(.+)"/', $response->headers['content-disposition'], $match)) {
                    $name = $match[1];
                }
            }

            if (!@file_exists($dir)) {
                mkdir($dir, 0755, true);
            }

            if (false === file_put_contents($dir . DIRECTORY_SEPARATOR . $name, $response->body)) {
                throw new Exception('Unable to save package '.$name.' to downloads directory, '.$dir.'. Do we have permission to write there?');
            }

            // whew, download worked!
            $a = new \PEAR2\Pyrus\Package($dir . DIRECTORY_SEPARATOR . $name);
            return $a->getInternalPackage();
        } catch (\PEAR2\Pyrus\HTTPException $e) {
            throw $e; // pass it along
        } catch (\Exception $e) {
            if (!empty($saveparam)) {
                $saveparam = ", cannot download \"$saveparam\"";
            }
            throw new Exception('Could not download from "' . $param . '"' . $saveparam, $e);
        }
    }
Exemple #14
0
 /** @todo Consider simply injecting the Package object as appropriate */
 function package($frontend, $args, $options)
 {
     $path = getcwd() . DIRECTORY_SEPARATOR;
     $package = new \PEAR2\Pyrus\Package(null);
     if (!isset($args['packagexml']) && !file_exists($path . 'package.xml') && !file_exists($path . 'package2.xml')) {
         throw new \PEAR2\Pyrus\PackageFile\Exception("No package.xml or package2.xml found in " . $path);
     }
     if (isset($args['packagexml'])) {
         $package = new \PEAR2\Pyrus\Package($args['packagexml']);
     } else {
         // first try ./package.xml
         if (file_exists($path . 'package.xml')) {
             try {
                 $package = new \PEAR2\Pyrus\Package($path . 'package.xml');
             } catch (\PEAR2\Pyrus\PackageFile\Exception $e) {
                 if ($e->getCode() != -3) {
                     throw $e;
                 }
                 if (!file_exists($path . 'package2.xml')) {
                     throw $e;
                 }
                 $package = new \PEAR2\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 \PEAR2\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 \PEAR2\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 (\PEAR2\Pyrus\Config::current()->openssl_cert) {
         if ('yes' == $frontend->ask('Sign package?', array('yes', 'no'), 'yes')) {
             $cert = \PEAR2\Pyrus\Config::current()->openssl_cert;
             if (!file_exists($cert)) {
                 throw new \PEAR2\Pyrus\Developer\Creator\Exception('OpenSSL certificate ' . $cert . ' does not exist');
             }
             $releaser = \PEAR2\Pyrus\Config::current()->handle;
             $maintainers = array();
             foreach ($package->maintainer as $maintainer) {
                 $maintainers[] = $maintainer->user;
             }
             if (!strlen($releaser)) {
                 throw new \PEAR2\Pyrus\Developer\Creator\Exception('handle configuration variable must be from ' . 'package.xml (one of ' . implode(', ', $maintainers) . ')');
             }
             if (!in_array($releaser, $maintainers)) {
                 throw new \PEAR2\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 = \PEAR2\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 \PEAR2\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 \PEAR2\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 \PEAR2\Pyrus\Package\Creator(array(new \PEAR2\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 \PEAR2\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 \PEAR2\Pyrus\Developer\Creator\Exception('extrasetup file must set $extrafiles variable to an array of files');
             }
             if (!is_array($extrafiles)) {
                 throw new \PEAR2\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 \PEAR2\Pyrus\PackageInterface || $file instanceof \PEAR2\Pyrus\PackageFileInterface) {
                         continue;
                     }
                     throw new \PEAR2\Pyrus\Developer\Creator\Exception('extrasetup file object must implement \\PEAR2\\Pyrus\\PackageInterface or \\PEAR2\\Pyrus\\PackageFileInterface');
                 }
                 if (!file_exists($file)) {
                     throw new \PEAR2\Pyrus\Developer\Creator\Exception('extrasetup file ' . $file . ' does not exist');
                 }
                 if (!is_string($path)) {
                     throw new \PEAR2\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";
 }
 /**
  * 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');
 }
Exemple #16
0
 /**
  * Returns a list of registries present in the PEAR installation at $path
  * @param string
  * @return array
  */
 public static function detectRegistries($path)
 {
     if (isset(Main::$options['packagingroot'])) {
         $path = Main::prepend(Main::$options['packagingroot'], $path);
     }
     if (file_exists($path . '/.xmlregistry') || is_dir($path . '/.xmlregistry')) {
         return array('Xml');
     }
     return array();
 }
Exemple #17
0
 protected function getDefaultChannel($channel)
 {
     $xml = \PEAR2\Pyrus\Main::getDataPath() . '/default_channels/' . $channel . '.xml';
     if (!file_exists($xml)) {
         $xml = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/default_channels/' . $channel . '.xml';
     }
     $parser = new \PEAR2\Pyrus\ChannelFile\Parser\v1();
     $info = $parser->parse($xml, true);
     return new Channel($this, $info->getArray());
 }
Exemple #18
0
 /**
  * Validate the xml against the channel schema.
  *
  */
 function validate()
 {
     if (!isset($this->_xml)) {
         $this->__toString();
     }
     $a = new \PEAR2\Pyrus\XMLParser();
     $schema = \PEAR2\Pyrus\Main::getDataPath() . '/channel-1.0.xsd';
     // for running out of svn
     if (!file_exists($schema)) {
         $schema = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/channel-1.0.xsd';
     }
     try {
         $a->parseString($this->_xml, $schema);
         return true;
     } catch (\Exception $e) {
         throw new \PEAR2\Pyrus\Channel\Exception('Invalid channel.xml', $e);
     }
 }