PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/php/PHP_CodeSniffer/src/Util/Standards.php

http://github.com/jonswar/perl-code-tidyall
PHP | 326 lines | 207 code | 39 blank | 80 comment | 29 complexity | 2bb7b41c5a08ab26b1f8ee8a2f3cdf59 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, 0BSD, MIT
  1. <?php
  2. /**
  3. * Functions for helping process standards.
  4. *
  5. * @author Greg Sherwood <gsherwood@squiz.net>
  6. * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  7. * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  8. */
  9. namespace PHP_CodeSniffer\Util;
  10. use PHP_CodeSniffer\Config;
  11. class Standards
  12. {
  13. /**
  14. * Get a list paths where standards are installed.
  15. *
  16. * @return array
  17. */
  18. public static function getInstalledStandardPaths()
  19. {
  20. $ds = DIRECTORY_SEPARATOR;
  21. $installedPaths = [dirname(dirname(__DIR__)).$ds.'src'.$ds.'Standards'];
  22. $configPaths = Config::getConfigData('installed_paths');
  23. if ($configPaths !== null) {
  24. $installedPaths = array_merge($installedPaths, explode(',', $configPaths));
  25. }
  26. $resolvedInstalledPaths = [];
  27. foreach ($installedPaths as $installedPath) {
  28. if (substr($installedPath, 0, 1) === '.') {
  29. $installedPath = Common::realPath(__DIR__.$ds.'..'.$ds.'..'.$ds.$installedPath);
  30. }
  31. $resolvedInstalledPaths[] = $installedPath;
  32. }
  33. return $resolvedInstalledPaths;
  34. }//end getInstalledStandardPaths()
  35. /**
  36. * Get the details of all coding standards installed.
  37. *
  38. * Coding standards are directories located in the
  39. * CodeSniffer/Standards directory. Valid coding standards
  40. * include a Sniffs subdirectory.
  41. *
  42. * The details returned for each standard are:
  43. * - path: the path to the coding standard's main directory
  44. * - name: the name of the coding standard, as sourced from the ruleset.xml file
  45. * - namespace: the namespace used by the coding standard, as sourced from the ruleset.xml file
  46. *
  47. * If you only need the paths to the installed standards,
  48. * use getInstalledStandardPaths() instead as it performs less work to
  49. * retrieve coding standard names.
  50. *
  51. * @param boolean $includeGeneric If true, the special "Generic"
  52. * coding standard will be included
  53. * if installed.
  54. * @param string $standardsDir A specific directory to look for standards
  55. * in. If not specified, PHP_CodeSniffer will
  56. * look in its default locations.
  57. *
  58. * @return array
  59. * @see getInstalledStandardPaths()
  60. */
  61. public static function getInstalledStandardDetails(
  62. $includeGeneric=false,
  63. $standardsDir=''
  64. ) {
  65. $rulesets = [];
  66. if ($standardsDir === '') {
  67. $installedPaths = self::getInstalledStandardPaths();
  68. } else {
  69. $installedPaths = [$standardsDir];
  70. }
  71. foreach ($installedPaths as $standardsDir) {
  72. // Check if the installed dir is actually a standard itself.
  73. $csFile = $standardsDir.'/ruleset.xml';
  74. if (is_file($csFile) === true) {
  75. $rulesets[] = $csFile;
  76. continue;
  77. }
  78. if (is_dir($standardsDir) === false) {
  79. continue;
  80. }
  81. $di = new \DirectoryIterator($standardsDir);
  82. foreach ($di as $file) {
  83. if ($file->isDir() === true && $file->isDot() === false) {
  84. $filename = $file->getFilename();
  85. // Ignore the special "Generic" standard.
  86. if ($includeGeneric === false && $filename === 'Generic') {
  87. continue;
  88. }
  89. // Valid coding standard dirs include a ruleset.
  90. $csFile = $file->getPathname().'/ruleset.xml';
  91. if (is_file($csFile) === true) {
  92. $rulesets[] = $csFile;
  93. }
  94. }
  95. }
  96. }//end foreach
  97. $installedStandards = [];
  98. foreach ($rulesets as $rulesetPath) {
  99. $ruleset = @simplexml_load_string(file_get_contents($rulesetPath));
  100. if ($ruleset === false) {
  101. continue;
  102. }
  103. $standardName = (string) $ruleset['name'];
  104. $dirname = basename(dirname($rulesetPath));
  105. if (isset($ruleset['namespace']) === true) {
  106. $namespace = (string) $ruleset['namespace'];
  107. } else {
  108. $namespace = $dirname;
  109. }
  110. $installedStandards[$dirname] = [
  111. 'path' => dirname($rulesetPath),
  112. 'name' => $standardName,
  113. 'namespace' => $namespace,
  114. ];
  115. }//end foreach
  116. return $installedStandards;
  117. }//end getInstalledStandardDetails()
  118. /**
  119. * Get a list of all coding standards installed.
  120. *
  121. * Coding standards are directories located in the
  122. * CodeSniffer/Standards directory. Valid coding standards
  123. * include a Sniffs subdirectory.
  124. *
  125. * @param boolean $includeGeneric If true, the special "Generic"
  126. * coding standard will be included
  127. * if installed.
  128. * @param string $standardsDir A specific directory to look for standards
  129. * in. If not specified, PHP_CodeSniffer will
  130. * look in its default locations.
  131. *
  132. * @return array
  133. * @see isInstalledStandard()
  134. */
  135. public static function getInstalledStandards(
  136. $includeGeneric=false,
  137. $standardsDir=''
  138. ) {
  139. $installedStandards = [];
  140. if ($standardsDir === '') {
  141. $installedPaths = self::getInstalledStandardPaths();
  142. } else {
  143. $installedPaths = [$standardsDir];
  144. }
  145. foreach ($installedPaths as $standardsDir) {
  146. // Check if the installed dir is actually a standard itself.
  147. $csFile = $standardsDir.'/ruleset.xml';
  148. if (is_file($csFile) === true) {
  149. $installedStandards[] = basename($standardsDir);
  150. continue;
  151. }
  152. if (is_dir($standardsDir) === false) {
  153. // Doesn't exist.
  154. continue;
  155. }
  156. $di = new \DirectoryIterator($standardsDir);
  157. foreach ($di as $file) {
  158. if ($file->isDir() === true && $file->isDot() === false) {
  159. $filename = $file->getFilename();
  160. // Ignore the special "Generic" standard.
  161. if ($includeGeneric === false && $filename === 'Generic') {
  162. continue;
  163. }
  164. // Valid coding standard dirs include a ruleset.
  165. $csFile = $file->getPathname().'/ruleset.xml';
  166. if (is_file($csFile) === true) {
  167. $installedStandards[] = $filename;
  168. }
  169. }
  170. }
  171. }//end foreach
  172. return $installedStandards;
  173. }//end getInstalledStandards()
  174. /**
  175. * Determine if a standard is installed.
  176. *
  177. * Coding standards are directories located in the
  178. * CodeSniffer/Standards directory. Valid coding standards
  179. * include a ruleset.xml file.
  180. *
  181. * @param string $standard The name of the coding standard.
  182. *
  183. * @return boolean
  184. * @see getInstalledStandards()
  185. */
  186. public static function isInstalledStandard($standard)
  187. {
  188. $path = self::getInstalledStandardPath($standard);
  189. if ($path !== null && strpos($path, 'ruleset.xml') !== false) {
  190. return true;
  191. } else {
  192. // This could be a custom standard, installed outside our
  193. // standards directory.
  194. $standard = Common::realPath($standard);
  195. // Might be an actual ruleset file itUtil.
  196. // If it has an XML extension, let's at least try it.
  197. if (is_file($standard) === true
  198. && (substr(strtolower($standard), -4) === '.xml'
  199. || substr(strtolower($standard), -9) === '.xml.dist')
  200. ) {
  201. return true;
  202. }
  203. // If it is a directory with a ruleset.xml file in it,
  204. // it is a standard.
  205. $ruleset = rtrim($standard, ' /\\').DIRECTORY_SEPARATOR.'ruleset.xml';
  206. if (is_file($ruleset) === true) {
  207. return true;
  208. }
  209. }//end if
  210. return false;
  211. }//end isInstalledStandard()
  212. /**
  213. * Return the path of an installed coding standard.
  214. *
  215. * Coding standards are directories located in the
  216. * CodeSniffer/Standards directory. Valid coding standards
  217. * include a ruleset.xml file.
  218. *
  219. * @param string $standard The name of the coding standard.
  220. *
  221. * @return string|null
  222. */
  223. public static function getInstalledStandardPath($standard)
  224. {
  225. if (strpos($standard, '.') !== false) {
  226. return null;
  227. }
  228. $installedPaths = self::getInstalledStandardPaths();
  229. foreach ($installedPaths as $installedPath) {
  230. $standardPath = $installedPath.DIRECTORY_SEPARATOR.$standard;
  231. if (file_exists($standardPath) === false) {
  232. if (basename($installedPath) !== $standard) {
  233. continue;
  234. }
  235. $standardPath = $installedPath;
  236. }
  237. $path = Common::realpath($standardPath.DIRECTORY_SEPARATOR.'ruleset.xml');
  238. if (is_file($path) === true) {
  239. return $path;
  240. } else if (Common::isPharFile($standardPath) === true) {
  241. $path = Common::realpath($standardPath);
  242. if ($path !== false) {
  243. return $path;
  244. }
  245. }
  246. }//end foreach
  247. return null;
  248. }//end getInstalledStandardPath()
  249. /**
  250. * Prints out a list of installed coding standards.
  251. *
  252. * @return void
  253. */
  254. public static function printInstalledStandards()
  255. {
  256. $installedStandards = self::getInstalledStandards();
  257. $numStandards = count($installedStandards);
  258. if ($numStandards === 0) {
  259. echo 'No coding standards are installed.'.PHP_EOL;
  260. } else {
  261. $lastStandard = array_pop($installedStandards);
  262. if ($numStandards === 1) {
  263. echo "The only coding standard installed is $lastStandard".PHP_EOL;
  264. } else {
  265. $standardList = implode(', ', $installedStandards);
  266. $standardList .= ' and '.$lastStandard;
  267. echo 'The installed coding standards are '.$standardList.PHP_EOL;
  268. }
  269. }
  270. }//end printInstalledStandards()
  271. }//end class