| 
#!/usr/bin/env php<?php
 
 /*
 * This file is part of the Predis package.
 *
 * (c) Daniele Alessandri <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
 
 // -------------------------------------------------------------------------- //
 // In order to be able to execute this script to create a PEAR package of Predis
 // the `pear` binary must be available and executable in your $PATH.
 // The parts used to parse author and version strings are taken from Onion (used
 // by this library in the past) just to keep on relying on the package.ini file
 // to simplify things. We might consider to switch to using the PEAR classes
 // directly in the future.
 // -------------------------------------------------------------------------- //
 
 function executeWithBackup($file, $callback)
 {
 $exception = null;
 $backup = "$file.backup";
 
 copy($file, $backup);
 
 try {
 call_user_func($callback, $file);
 } catch (Exception $exception) {
 // NOOP
 }
 
 unlink($file);
 rename($backup, $file);
 
 if ($exception) {
 throw $exception;
 }
 }
 
 function parseAuthor($string)
 {
 $author = array();
 
 if (preg_match('/^\s*(.+?)\s*(?:"(\S+)"\s*)?<(\S+)>\s*$/x', $string , $regs)) {
 if (count($regs) == 4) {
 list($_,$name,$user,$email) = $regs;
 $author['name'] = $name;
 $author['user'] = $user;
 $author['email'] = $email;
 } elseif (count($regs) == 3) {
 list($_,$name,$email) = $regs;
 $author['name'] = $name;
 $author['email'] = $email;
 }
 } else {
 $author['name'] = $string;
 }
 
 return $author;
 }
 
 function parseVersion($string)
 {
 $version_pattern = '([0-9.]+)';
 
 if (preg_match("/^\s*$version_pattern\s*\$/x", $string, $regs)) {
 return array('min' => $regs[1] ?: '0.0.0');
 } elseif (preg_match("/^\s*[>=]+\s*$version_pattern\s*\$/x", $string, $regs)) {
 return array('min' => $regs[1] ?: '0.0.0');
 } elseif (preg_match("/^\s*[<=]+\s*$version_pattern\s*\$/x", $string, $regs)) {
 return array('max' => $regs[1]);
 } elseif (preg_match("/^\s*$version_pattern\s*<=>\s*$version_pattern\s*\$/x", $string, $regs)) {
 return array(
 'min' => $regs[1] ?: '0.0.0',
 'max' => $regs[2],
 );
 }
 
 return null;
 }
 
 function addRolePath($pkg, $path, $role)
 {
 if (is_dir($path)) {
 $dirRoot = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
 $dirTree = new RecursiveIteratorIterator($dirRoot, RecursiveIteratorIterator::CHILD_FIRST);
 
 foreach ($dirTree as $fileinfo) {
 if ($fileinfo->isFile()) {
 addPackageFile($pkg, $fileinfo, $role, $path);
 }
 }
 } else {
 foreach (glob($path) as $filename) {
 addPackageFile($pkg, new SplFileInfo($filename), $role);
 }
 }
 }
 
 function addPackageFile($pkg, $fileinfo, $role, $baseDir = '')
 {
 $fileNode = $pkg->contents->dir->addChild('file');
 $fileNode->addAttribute('name', $filepath = $fileinfo->getPathname());
 $fileNode->addAttribute('role', $role);
 $fileNode->addAttribute('md5sum', md5_file($filepath));
 
 $installNode = $pkg->phprelease->filelist->addChild('install');
 $installNode->addAttribute('name', $filepath);
 $installNode->addAttribute('as', !$baseDir ? basename($filepath) : substr($filepath, strlen($baseDir) + 1));
 }
 
 function generatePackageXml($packageINI)
 {
 $XML = <<<XML
 <?xml version="1.0"?>
 <package packagerversion="1.4.10" version="2.0"
 xmlns="http://pear.php.net/dtd/package-2.0"
 xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
 http://pear.php.net/dtd/tasks-1.0.xsd
 http://pear.php.net/dtd/package-2.0
 http://pear.php.net/dtd/package-2.0.xsd" />
 XML;
 
 $cfg = parse_ini_file($packageINI, true);
 $pkg = new SimpleXMLElement($XML);
 
 $pkg->name = $cfg['package']['name'];
 $pkg->channel = $cfg['package']['channel'];
 $pkg->summary = $cfg['package']['desc'];
 $pkg->description = $cfg['package']['desc'];
 
 $author = parseAuthor($cfg['package']['author']);
 $pkg->addChild('lead');
 $pkg->lead->name = $author['name'];
 $pkg->lead->user = $author['user'];
 $pkg->lead->email = $author['email'];
 $pkg->lead->active = 'yes';
 
 $datetime = new DateTime('now');
 $pkg->date = $datetime->format('Y-m-d');
 $pkg->time = $datetime->format('H:i:s');
 
 $pkg->addChild('version');
 $pkg->version->release = $cfg['package']['version'];
 $pkg->version->api = $cfg['package']['version'];
 
 $pkg->addChild('stability');
 $pkg->stability->release = $cfg['package']['stability'];
 $pkg->stability->api = $cfg['package']['stability'];
 
 $pkg->license = $cfg['package']['license'];
 $pkg->notes = '-';
 
 $pkg->addChild('contents')->addChild('dir')->addAttribute('name', '/');
 
 $pkg->addChild('dependencies')->addChild('required');
 foreach ($cfg['require'] as $required => $version) {
 $version = parseVersion($version);
 $pkg->dependencies->required->addChild($required);
 
 if (isset($version['min'])) {
 $pkg->dependencies->required->$required->min = $version['min'];
 }
 if (isset($version['max'])) {
 $pkg->dependencies->required->$required->min = $version['max'];
 }
 }
 
 $pkg->addChild('phprelease')->addChild('filelist');
 
 $pathToRole = array(
 'doc' => 'doc', 'docs' => 'doc', 'examples' => 'doc',
 'lib' => 'php', 'src' => 'php',
 'test' => 'test', 'tests' => 'test',
 );
 
 foreach (array_merge($pathToRole, $cfg['roles'] ?: array()) as $path => $role) {
 addRolePath($pkg, $path, $role);
 }
 
 return $pkg;
 }
 
 function rewritePackageInstallAs($pkg)
 {
 foreach ($pkg->phprelease->filelist->install as $file) {
 if (preg_match('/^src\//', $file['name'])) {
 $file['as'] = "Predis/{$file['as']}";
 }
 }
 }
 
 function savePackageXml($xml)
 {
 $dom = new DOMDocument("1.0");
 $dom->preserveWhiteSpace = false;
 $dom->formatOutput = true;
 $dom->loadXML($xml->asXML());
 
 file_put_contents('package.xml', $dom->saveXML());
 }
 
 function buildPackage()
 {
 passthru('pear -q package && rm package.xml');
 }
 
 function modifyPhpunitXml($file)
 {
 $cfg = new SimpleXMLElement($file, null, true);
 
 $cfg[0]['bootstrap'] = str_replace('tests/', '', $cfg[0]['bootstrap']);
 $cfg->testsuites->testsuite->directory = str_replace('tests/', '', $cfg->testsuites->testsuite->directory);
 
 $cfg->saveXml($file);
 }
 
 // -------------------------------------------------------------------------- //
 
 executeWithBackup(__DIR__.'/../phpunit.xml.dist', function ($file) {
 modifyPhpunitXml($file);
 
 $pkg = generatePackageXml('package.ini');
 rewritePackageInstallAs($pkg);
 savePackageXml($pkg);
 
 buildPackage();
 });
 
 |