create-pear 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #!/usr/bin/env php
  2. <?php
  3. /*
  4. * This file is part of the Predis package.
  5. *
  6. * (c) Daniele Alessandri <suppakilla@gmail.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. // -------------------------------------------------------------------------- //
  12. // In order to be able to execute this script to create a PEAR package of Predis
  13. // the `pear` binary must be available and executable in your $PATH.
  14. // The parts used to parse author and version strings are taken from Onion (used
  15. // by this library in the past) just to keep on relying on the package.ini file
  16. // to simplify things. We might consider to switch to using the PEAR classes
  17. // directly in the future.
  18. // -------------------------------------------------------------------------- //
  19. function executeWithBackup($file, $callback)
  20. {
  21. $exception = null;
  22. $backup = "$file.backup";
  23. copy($file, $backup);
  24. try {
  25. call_user_func($callback, $file);
  26. } catch (Exception $exception) {
  27. // NOOP
  28. }
  29. unlink($file);
  30. rename($backup, $file);
  31. if ($exception) {
  32. throw $exception;
  33. }
  34. }
  35. function parseAuthor($string)
  36. {
  37. $author = array();
  38. if (preg_match('/^\s*(.+?)\s*(?:"(\S+)"\s*)?<(\S+)>\s*$/x', $string , $regs)) {
  39. if (count($regs) == 4) {
  40. list($_,$name,$user,$email) = $regs;
  41. $author['name'] = $name;
  42. $author['user'] = $user;
  43. $author['email'] = $email;
  44. } elseif (count($regs) == 3) {
  45. list($_,$name,$email) = $regs;
  46. $author['name'] = $name;
  47. $author['email'] = $email;
  48. }
  49. } else {
  50. $author['name'] = $string;
  51. }
  52. return $author;
  53. }
  54. function parseVersion($string)
  55. {
  56. $version_pattern = '([0-9.]+)';
  57. if (preg_match("/^\s*$version_pattern\s*\$/x", $string, $regs)) {
  58. return array('min' => $regs[1] ?: '0.0.0');
  59. } elseif (preg_match("/^\s*[>=]+\s*$version_pattern\s*\$/x", $string, $regs)) {
  60. return array('min' => $regs[1] ?: '0.0.0');
  61. } elseif (preg_match("/^\s*[<=]+\s*$version_pattern\s*\$/x", $string, $regs)) {
  62. return array('max' => $regs[1]);
  63. } elseif (preg_match("/^\s*$version_pattern\s*<=>\s*$version_pattern\s*\$/x", $string, $regs)) {
  64. return array(
  65. 'min' => $regs[1] ?: '0.0.0',
  66. 'max' => $regs[2],
  67. );
  68. }
  69. return null;
  70. }
  71. function addRolePath($pkg, $path, $role)
  72. {
  73. if (is_dir($path)) {
  74. $dirRoot = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
  75. $dirTree = new RecursiveIteratorIterator($dirRoot, RecursiveIteratorIterator::CHILD_FIRST);
  76. foreach ($dirTree as $fileinfo) {
  77. if ($fileinfo->isFile()) {
  78. addPackageFile($pkg, $fileinfo, $role, $path);
  79. }
  80. }
  81. } else {
  82. foreach (glob($path) as $filename) {
  83. addPackageFile($pkg, new SplFileInfo($filename), $role);
  84. }
  85. }
  86. }
  87. function addPackageFile($pkg, $fileinfo, $role, $baseDir = '')
  88. {
  89. $fileNode = $pkg->contents->dir->addChild('file');
  90. $fileNode->addAttribute('name', $filepath = $fileinfo->getPathname());
  91. $fileNode->addAttribute('role', $role);
  92. $fileNode->addAttribute('md5sum', md5_file($filepath));
  93. $installNode = $pkg->phprelease->filelist->addChild('install');
  94. $installNode->addAttribute('name', $filepath);
  95. $installNode->addAttribute('as', !$baseDir ? basename($filepath) : substr($filepath, strlen($baseDir) + 1));
  96. }
  97. function generatePackageXml($packageINI)
  98. {
  99. $XML = <<<XML
  100. <?xml version="1.0"?>
  101. <package packagerversion="1.4.10" version="2.0"
  102. xmlns="http://pear.php.net/dtd/package-2.0"
  103. xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
  104. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  105. xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
  106. http://pear.php.net/dtd/tasks-1.0.xsd
  107. http://pear.php.net/dtd/package-2.0
  108. http://pear.php.net/dtd/package-2.0.xsd" />
  109. XML;
  110. $cfg = parse_ini_file($packageINI, true);
  111. $pkg = new SimpleXMLElement($XML);
  112. $pkg->name = $cfg['package']['name'];
  113. $pkg->channel = $cfg['package']['channel'];
  114. $pkg->summary = $cfg['package']['desc'];
  115. $pkg->description = $cfg['package']['desc'];
  116. $author = parseAuthor($cfg['package']['author']);
  117. $pkg->addChild('lead');
  118. $pkg->lead->name = $author['name'];
  119. $pkg->lead->user = $author['user'];
  120. $pkg->lead->email = $author['email'];
  121. $pkg->lead->active = 'yes';
  122. $datetime = new DateTime('now');
  123. $pkg->date = $datetime->format('Y-m-d');
  124. $pkg->time = $datetime->format('H:i:s');
  125. $pkg->addChild('version');
  126. $pkg->version->release = $cfg['package']['version'];
  127. $pkg->version->api = $cfg['package']['version'];
  128. $pkg->addChild('stability');
  129. $pkg->stability->release = $cfg['package']['stability'];
  130. $pkg->stability->api = $cfg['package']['stability'];
  131. $pkg->license = $cfg['package']['license'];
  132. $pkg->notes = '-';
  133. $pkg->addChild('contents')->addChild('dir')->addAttribute('name', '/');
  134. $pkg->addChild('dependencies')->addChild('required');
  135. foreach ($cfg['require'] as $required => $version) {
  136. $version = parseVersion($version);
  137. $pkg->dependencies->required->addChild($required);
  138. if (isset($version['min'])) {
  139. $pkg->dependencies->required->$required->min = $version['min'];
  140. }
  141. if (isset($version['max'])) {
  142. $pkg->dependencies->required->$required->min = $version['max'];
  143. }
  144. }
  145. $pkg->addChild('phprelease')->addChild('filelist');
  146. $pathToRole = array(
  147. 'doc' => 'doc', 'docs' => 'doc', 'examples' => 'doc',
  148. 'lib' => 'php', 'src' => 'php',
  149. 'test' => 'test', 'tests' => 'test',
  150. );
  151. foreach (array_merge($pathToRole, $cfg['roles'] ?: array()) as $path => $role) {
  152. addRolePath($pkg, $path, $role);
  153. }
  154. return $pkg;
  155. }
  156. function rewritePackageInstallAs($pkg)
  157. {
  158. foreach ($pkg->phprelease->filelist->install as $file) {
  159. if (preg_match('/^src\//', $file['name'])) {
  160. $file['as'] = "Predis/{$file['as']}";
  161. }
  162. }
  163. }
  164. function savePackageXml($xml)
  165. {
  166. $dom = new DOMDocument("1.0");
  167. $dom->preserveWhiteSpace = false;
  168. $dom->formatOutput = true;
  169. $dom->loadXML($xml->asXML());
  170. file_put_contents('package.xml', $dom->saveXML());
  171. }
  172. function buildPackage()
  173. {
  174. passthru('pear -q package && rm package.xml');
  175. }
  176. function modifyPhpunitXml($file)
  177. {
  178. $cfg = new SimpleXMLElement($file, null, true);
  179. $cfg[0]['bootstrap'] = str_replace('tests/', '', $cfg[0]['bootstrap']);
  180. $cfg->testsuites->testsuite->directory = str_replace('tests/', '', $cfg->testsuites->testsuite->directory);
  181. $cfg->saveXml($file);
  182. }
  183. // -------------------------------------------------------------------------- //
  184. executeWithBackup(__DIR__.'/../phpunit.xml.dist', function ($file) {
  185. modifyPhpunitXml($file);
  186. $pkg = generatePackageXml('package.ini');
  187. rewritePackageInstallAs($pkg);
  188. savePackageXml($pkg);
  189. buildPackage();
  190. });