PageRenderTime 35ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/tr/lib/spikephpcoverage/src/cli/instrument.php

https://bitbucket.org/idler/mmp/
PHP | 305 lines | 222 code | 28 blank | 55 comment | 50 complexity | 12d8652d8acfcaa1a4c5e11febdd56e6 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0
  1. <?php
  2. /*
  3. * $Id: instrument.php 14672 2005-03-23 21:37:47Z npac $
  4. *
  5. * Copyright(c) 2004-2005, SpikeSource Inc. All Rights Reserved.
  6. * Licensed under the Open Source License version 2.1
  7. * (See http://www.spikesource.com/license.html)
  8. */
  9. ?>
  10. <?php
  11. #!/bin/php
  12. if(!defined("__PHPCOVERAGE_HOME")) {
  13. define("__PHPCOVERAGE_HOME", dirname(dirname(__FILE__)));
  14. }
  15. require_once __PHPCOVERAGE_HOME . "/conf/phpcoverage.conf.php";
  16. require_once __PHPCOVERAGE_HOME . "/util/Utility.php";
  17. ## Instruments the PHP Source files
  18. /**
  19. * Print help message and exit
  20. *
  21. * @access public
  22. */
  23. function help() {
  24. echo "Usage: " . basename(__FILE__) . " -b <application-base-path> [-p <phpcoverage-home>] [-r] [-u] [-e <exclude-file-list>]"
  25. . "[-v] [-h] [path1 [path2 [...]]]\n";
  26. echo "\n";
  27. echo " Options: \n";
  28. echo " -b <application-base-path> Application directory accessible via HTTP "
  29. . "where PHPCoverage files should be copied.\n";
  30. echo " -p <phpcoverage-home> Path to PHPCoverage Home.\n";
  31. echo " -r Recursively instrument PHP files.\n";
  32. echo " -u Undo instrumentation.\n";
  33. echo " -e <file1,file2,...> Execlude files in the file list.\n";
  34. echo " -v Be verbose.\n";
  35. echo " -h Print this help and exit.\n";
  36. echo "\n";
  37. exit(0);
  38. }
  39. /**
  40. * Print error message and exit
  41. *
  42. * @param $msg Message to write to console.
  43. * @access public
  44. */
  45. function error($msg) {
  46. echo basename(__FILE__) . ": [ERROR] " . $msg . "\n";
  47. exit(1);
  48. }
  49. /**
  50. * Write a information message
  51. *
  52. * @param $msg Message to write to console.
  53. * @access public
  54. */
  55. function writeMsg($msg) {
  56. global $VERBOSE;
  57. if($VERBOSE) {
  58. echo basename(__FILE__) . ": [INFO] " . $msg . "\n";
  59. }
  60. }
  61. /**
  62. * Instrument the PHP file.
  63. *
  64. * @param $file File path
  65. * @access public
  66. */
  67. function instrument($file) {
  68. global $LOCAL_PHPCOVERAGE_LOCATION, $top, $bottom;
  69. $tmpfile = "$file.tmp";
  70. $contents = file_get_contents($file);
  71. $len = strlen($contents);
  72. if(strpos($contents, $top) === 0 && strrpos($contents, $bottom) === ($len - strlen($bottom)-1)) {
  73. writeMsg("Skipping $file.");
  74. return;
  75. }
  76. $fp = fopen($tmpfile, "w");
  77. if(!$fp) {
  78. error("Cannot write to file: $tmpfile");
  79. }
  80. fputs($fp, $top);
  81. fwrite($fp, $contents);
  82. fputs($fp, $bottom);
  83. fclose($fp);
  84. // Delete if already exists - 'rename()' on Windows will return false otherwise
  85. if(file_exists($file)) {
  86. unlink($file);
  87. }
  88. $ret = rename($tmpfile, $file);
  89. if(!$ret) {
  90. error("Cannot save file: $file");
  91. }
  92. writeMsg("Instrumented: $file.");
  93. }
  94. /**
  95. * Uninstrument the PHP file
  96. *
  97. * @param $file File path
  98. * @access public
  99. */
  100. function uninstrument($file) {
  101. global $LOCAL_PHPCOVERAGE_LOCATION, $top, $bottom;
  102. $tmpfile = "$file.tmp";
  103. $contents = file_get_contents($file);
  104. $len = strlen($contents);
  105. if(strpos($contents, $top) !== 0 && strrpos($contents, $bottom) !== ($len - strlen($bottom)-1)) {
  106. writeMsg("Skipping $file.");
  107. return;
  108. }
  109. $fr = fopen($file, "r");
  110. $fw = fopen($tmpfile, "w");
  111. if(!$fr) {
  112. error("Cannot read file: $file");
  113. }
  114. if(!$fr) {
  115. error("Cannot write to file: $tmpfile");
  116. }
  117. while(!feof($fr)) {
  118. $line = fgets($fr);
  119. if(strpos($line, $top) === false && strpos($line, $bottom) === false) {
  120. fputs($fw, $line);
  121. }
  122. }
  123. fclose($fr);
  124. fclose($fw);
  125. // Delete if already exists - 'rename()' on Windows will return false otherwise
  126. if(file_exists($file)) {
  127. unlink($file);
  128. }
  129. $ret = rename($tmpfile, $file);
  130. if(!$ret) {
  131. error("Cannot save file: $file");
  132. }
  133. writeMsg("Uninstrumented: $file");
  134. }
  135. /**
  136. * Retrive a list of all PHP files in the given directory
  137. *
  138. * @param $dir Directory to scan
  139. * @param $recursive True is directory is scanned recursively
  140. * @return Array List of PHP files
  141. * @access public
  142. */
  143. function get_all_php_files($dir, &$excludeFiles, $recursive) {
  144. global $spc_config;
  145. $phpExtensions = $spc_config["extensions"];
  146. $dirs[] = $dir;
  147. while(count($dirs) > 0) {
  148. $currDir = realpath(array_pop($dirs));
  149. if(!is_readable($currDir)) {
  150. continue;
  151. }
  152. $currFiles = scandir($currDir);
  153. for($j = 0; $j < count($currFiles); $j++) {
  154. if($currFiles[$j] == "." || $currFiles[$j] == "..") {
  155. continue;
  156. }
  157. $currFiles[$j] = $currDir . "/" . $currFiles[$j];
  158. if(is_file($currFiles[$j])) {
  159. $pathParts = pathinfo($currFiles[$j]);
  160. // Ignore phpcoverage bottom and top stubs
  161. if(strpos($pathParts['basename'], "phpcoverage.remote.") !== false) {
  162. continue;
  163. }
  164. // Ignore files specified in the exclude list
  165. if(in_array(realpath($currFiles[$j]), $excludeFiles) !== false) {
  166. continue;
  167. }
  168. if(isset($pathParts['extension'])
  169. && in_array($pathParts['extension'], $phpExtensions)) {
  170. $files[] = $currFiles[$j];
  171. }
  172. }
  173. else if(is_dir($currFiles[$j]) && $recursive) {
  174. $dirs[] = $currFiles[$j];
  175. }
  176. }
  177. }
  178. return $files;
  179. }
  180. // Initialize
  181. $RECURSIVE = false;
  182. $UNDO = false;
  183. $top_file = "/phpcoverage.remote.top.inc.php";
  184. $bottom_file = "/phpcoverage.remote.bottom.inc.php";
  185. //print_r($argv);
  186. for($i = 1; $i < $argc; $i++) {
  187. switch($argv[$i]) {
  188. case "-r":
  189. $RECURSIVE = true;
  190. break;
  191. case "-p":
  192. $PHPCOVERAGE_HOME = $argv[++$i];
  193. break;
  194. case "-b":
  195. $LOCAL_PHPCOVERAGE_LOCATION = $argv[++$i];
  196. break;
  197. case "-u":
  198. $UNDO = true;
  199. break;
  200. case "-e":
  201. $EXCLUDE_FILES = explode(",", $argv[++$i]);
  202. break;
  203. case "-v":
  204. $VERBOSE = true;
  205. break;
  206. case "-h":
  207. help();
  208. break;
  209. default:
  210. $paths[] = $argv[$i];
  211. break;
  212. }
  213. }
  214. if(!is_dir($LOCAL_PHPCOVERAGE_LOCATION)) {
  215. error("LOCAL_PHPCOVERAGE_LOCATION [$OCAL_PHPCOVERAGE_LOCATION] not found.");
  216. }
  217. if(empty($PHPCOVERAGE_HOME) || !is_dir($PHPCOVERAGE_HOME)) {
  218. $PHPCOVERAGE_HOME = __PHPCOVERAGE_HOME;
  219. if(empty($PHPCOVERAGE_HOME) || !is_dir($PHPCOVERAGE_HOME)) {
  220. error("PHPCOVERAGE_HOME does not exist. [" . $PHPCOVERAGE_HOME . "]");
  221. }
  222. }
  223. $LOCAL_PHPCOVERAGE_LOCATION = realpath($LOCAL_PHPCOVERAGE_LOCATION);
  224. if(file_exists($LOCAL_PHPCOVERAGE_LOCATION . $top_file)) {
  225. unlink($LOCAL_PHPCOVERAGE_LOCATION . $top_file);
  226. }
  227. $ret = copy($PHPCOVERAGE_HOME . $top_file, $LOCAL_PHPCOVERAGE_LOCATION . $top_file);
  228. if(!$ret) {
  229. error("Cannot copy to $LOCAL_PHPCOVERAGE_LOCATION");
  230. }
  231. if(file_exists($LOCAL_PHPCOVERAGE_LOCATION . $bottom_file)) {
  232. unlink($LOCAL_PHPCOVERAGE_LOCATION . $bottom_file);
  233. }
  234. $ret = copy($PHPCOVERAGE_HOME . $bottom_file, $LOCAL_PHPCOVERAGE_LOCATION . $bottom_file);
  235. if(!$ret) {
  236. error("Cannot copy to $LOCAL_PHPCOVERAGE_LOCATION");
  237. }
  238. $top="<?php require_once \"" . $LOCAL_PHPCOVERAGE_LOCATION . $top_file ."\"; ?>\n";
  239. $bottom="<?php require \"" . $LOCAL_PHPCOVERAGE_LOCATION . $bottom_file . "\"; ?>\n";
  240. if(empty($paths)) {
  241. $paths[] = getcwd();
  242. }
  243. if(!isset($EXCLUDE_FILES) || empty($EXCLUDE_FILES)) {
  244. $EXCLUDE_FILES = array();
  245. }
  246. for($i = 0; $i < count($EXCLUDE_FILES); $i++) {
  247. // Remove a file from the array if it does not exist
  248. if(!file_exists($EXCLUDE_FILES[$i])) {
  249. array_splice($EXCLUDE_FILES, $i, 1);
  250. $i --;
  251. continue;
  252. }
  253. $EXCLUDE_FILES[$i] = realpath($EXCLUDE_FILES[$i]);
  254. }
  255. //print_r($paths);
  256. foreach($paths as $path) {
  257. unset($files);
  258. if(is_dir($path)) {
  259. $files = get_all_php_files($path, $EXCLUDE_FILES, $RECURSIVE);
  260. }
  261. else if(is_file($path)) {
  262. $files[] = $path;
  263. }
  264. else {
  265. error("Unknown entity: $path");
  266. }
  267. //print_r($files);
  268. foreach($files as $file) {
  269. if($UNDO) {
  270. uninstrument($file);
  271. }
  272. else {
  273. instrument($file);
  274. }
  275. }
  276. }
  277. ?>