PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/www/bin/classmap_generator.php

https://bitbucket.org/Ppito/kawaiviewmodel2
PHP | 218 lines | 156 code | 24 blank | 38 comment | 26 complexity | 9138ce180b9282b845df19d6a6b226fd MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #!/usr/bin/env php
  2. <?php
  3. /**
  4. * Zend Framework (http://framework.zend.com/)
  5. *
  6. * @link http://github.com/zendframework/zf2 for the canonical source repository
  7. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  8. * @license http://framework.zend.com/license/new-bsd New BSD License
  9. */
  10. use Zend\Console;
  11. use Zend\File\ClassFileLocator;
  12. use Zend\Loader\StandardAutoloader;
  13. /**
  14. * Generate class maps for use with autoloading.
  15. *
  16. * Usage:
  17. * --help|-h Get usage message
  18. * --library|-l [ <string> ] Library to parse; if none provided, assumes
  19. * current directory
  20. * --output|-o [ <string> ] Where to write autoload file; if not provided,
  21. * assumes "autoload_classmap.php" in library directory
  22. * --append|-a Append to autoload file if it exists
  23. * --overwrite|-w Whether or not to overwrite existing autoload
  24. * file
  25. */
  26. $zfLibraryPath = __DIR__ . '/../libs/';
  27. if (is_dir($zfLibraryPath)) {
  28. // Try to load StandardAutoloader from library
  29. if (false === include($zfLibraryPath . '/Zend/Loader/StandardAutoloader.php')) {
  30. echo 'Unable to locate autoloader via library; aborting' . PHP_EOL;
  31. exit(2);
  32. }
  33. } else {
  34. // Try to load StandardAutoloader from include_path
  35. if (false === include('Zend/Loader/StandardAutoloader.php')) {
  36. echo 'Unable to locate autoloader via include_path; aborting' . PHP_EOL;
  37. exit(2);
  38. }
  39. }
  40. $libraryPath = getcwd();
  41. // Setup autoloading
  42. $loader = new StandardAutoloader(array('autoregister_zf' => true));
  43. $loader->register();
  44. $rules = array(
  45. 'help|h' => 'Get usage message',
  46. 'library|l-s' => 'Library to parse; if none provided, assumes current directory',
  47. 'output|o-s' => 'Where to write autoload file; if not provided, assumes "autoload_classmap.php" in library directory',
  48. 'append|a' => 'Append to autoload file if it exists',
  49. 'overwrite|w' => 'Whether or not to overwrite existing autoload file',
  50. );
  51. try {
  52. $opts = new Console\Getopt($rules);
  53. $opts->parse();
  54. } catch (Console\Exception\RuntimeException $e) {
  55. echo $e->getUsageMessage();
  56. exit(2);
  57. }
  58. if ($opts->getOption('h')) {
  59. echo $opts->getUsageMessage();
  60. exit(0);
  61. }
  62. $relativePathForClassmap = '';
  63. if (isset($opts->l)) {
  64. if (!is_dir($opts->l)) {
  65. echo 'Invalid library directory provided' . PHP_EOL
  66. . PHP_EOL;
  67. echo $opts->getUsageMessage();
  68. exit(2);
  69. }
  70. $libraryPath = $opts->l;
  71. }
  72. $libraryPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath($libraryPath));
  73. $usingStdout = false;
  74. $appending = $opts->getOption('a');
  75. $output = $libraryPath . '/autoload_classmap.php';
  76. if (isset($opts->o)) {
  77. $output = $opts->o;
  78. if ('-' == $output) {
  79. $output = STDOUT;
  80. $usingStdout = true;
  81. } elseif (is_dir($output)) {
  82. echo 'Invalid output file provided' . PHP_EOL
  83. . PHP_EOL;
  84. echo $opts->getUsageMessage();
  85. exit(2);
  86. } elseif (!is_writeable(dirname($output))) {
  87. echo "Cannot write to '$output'; aborting." . PHP_EOL
  88. . PHP_EOL
  89. . $opts->getUsageMessage();
  90. exit(2);
  91. } elseif (file_exists($output) && !$opts->getOption('w') && !$appending) {
  92. echo "Autoload file already exists at '$output'," . PHP_EOL
  93. . "but 'overwrite' or 'appending' flag was not specified; aborting." . PHP_EOL
  94. . PHP_EOL
  95. . $opts->getUsageMessage();
  96. exit(2);
  97. } else {
  98. // We need to add the $libraryPath into the relative path that is created in the classmap file.
  99. $classmapPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath(dirname($output)));
  100. // Simple case: $libraryPathCompare is in $classmapPathCompare
  101. if (strpos($libraryPath, $classmapPath) === 0) {
  102. $relativePathForClassmap = substr($libraryPath, strlen($classmapPath) + 1) . '/';
  103. } else {
  104. $libraryPathParts = explode('/', $libraryPath);
  105. $classmapPathParts = explode('/', $classmapPath);
  106. // Find the common part
  107. $count = count($classmapPathParts);
  108. for ($i = 0; $i < $count; $i++) {
  109. if (!isset($libraryPathParts[$i]) || $libraryPathParts[$i] != $classmapPathParts[$i]) {
  110. // Common part end
  111. break;
  112. }
  113. }
  114. // Add parent dirs for the subdirs of classmap
  115. $relativePathForClassmap = str_repeat('../', $count - $i);
  116. // Add library subdirs
  117. $count = count($libraryPathParts);
  118. for (; $i < $count; $i++) {
  119. $relativePathForClassmap .= $libraryPathParts[$i] . '/';
  120. }
  121. }
  122. }
  123. }
  124. if (!$usingStdout) {
  125. if ($appending) {
  126. echo "Appending to class file map '$output' for library in '$libraryPath'..." . PHP_EOL;
  127. } else {
  128. echo "Creating class file map for library in '$libraryPath'..." . PHP_EOL;
  129. }
  130. }
  131. // Get the ClassFileLocator, and pass it the library path
  132. $l = new ClassFileLocator($libraryPath);
  133. // Iterate over each element in the path, and create a map of
  134. // classname => filename, where the filename is relative to the library path
  135. $map = new stdClass;
  136. foreach ($l as $file) {
  137. $filename = str_replace($libraryPath . '/', '', str_replace(DIRECTORY_SEPARATOR, '/', $file->getPath()) . '/' . $file->getFilename());
  138. // Add in relative path to library
  139. $filename = $relativePathForClassmap . $filename;
  140. foreach ($file->getClasses() as $class) {
  141. $map->{$class} = $filename;
  142. }
  143. }
  144. if ($appending) {
  145. $content = var_export((array) $map, true) . ';';
  146. // Prefix with __DIR__; modify the generated content
  147. $content = preg_replace("#(=> ')#", "=> __DIR__ . '/", $content);
  148. // Fix \' strings from injected DIRECTORY_SEPARATOR usage in iterator_apply op
  149. $content = str_replace("\\'", "'", $content);
  150. // Convert to an array and remove the first "array("
  151. $content = explode(PHP_EOL, $content);
  152. array_shift($content);
  153. // Load existing class map file and remove the closing "bracket ");" from it
  154. $existing = file($output, FILE_IGNORE_NEW_LINES);
  155. array_pop($existing);
  156. // Merge
  157. $content = implode(PHP_EOL, array_merge($existing, $content));
  158. } else {
  159. // Create a file with the class/file map.
  160. // Stupid syntax highlighters make separating < from PHP declaration necessary
  161. $content = '<' . "?php\n"
  162. . "// Generated by ZF2's ./bin/classmap_generator.php\n"
  163. . 'return ' . var_export((array) $map, true) . ';';
  164. // Prefix with __DIR__; modify the generated content
  165. $content = preg_replace("#(=> ')#", "=> __DIR__ . '/", $content);
  166. // Fix \' strings from injected DIRECTORY_SEPARATOR usage in iterator_apply op
  167. $content = str_replace("\\'", "'", $content);
  168. }
  169. // Remove unnecessary double-backslashes
  170. $content = str_replace('\\\\', '\\', $content);
  171. // Exchange "array (" width "array("
  172. $content = str_replace('array (', 'array(', $content);
  173. // Align "=>" operators to match coding standard
  174. preg_match_all('(\n\s+([^=]+)=>)', $content, $matches, PREG_SET_ORDER);
  175. $maxWidth = 0;
  176. foreach ($matches as $match) {
  177. $maxWidth = max($maxWidth, strlen($match[1]));
  178. }
  179. $content = preg_replace('(\n\s+([^=]+)=>)e', "'\n \\1' . str_repeat(' ', " . $maxWidth . " - strlen('\\1')) . '=>'", $content);
  180. // Write the contents to disk
  181. file_put_contents($output, $content);
  182. if (!$usingStdout) {
  183. echo "Wrote classmap file to '" . realpath($output) . "'" . PHP_EOL;
  184. }