annotate vendor/squizlabs/php_codesniffer/src/Util/Standards.php @ 19:fa3358dc1485 tip

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