Exemple #1
0
 /**
  * Expands a ruleset reference into a list of sniff files.
  *
  * @param string $ref        The reference from the ruleset XML file.
  * @param string $rulesetDir The directory of the ruleset XML file, used to
  *                           evaluate relative paths.
  * @param int    $depth      How many nested processing steps we are in. This
  *                           is only used for debug output.
  *
  * @return array
  * @throws RuntimeException If the reference is invalid.
  */
 private function expandRulesetReference($ref, $rulesetDir, $depth = 0)
 {
     // Ignore internal sniffs codes as they are used to only
     // hide and change internal messages.
     if (substr($ref, 0, 9) === 'Internal.') {
         if (PHP_CODESNIFFER_VERBOSITY > 1) {
             echo str_repeat("\t", $depth);
             echo "\t\t* ignoring internal sniff code *" . PHP_EOL;
         }
         return array();
     }
     // As sniffs can't begin with a full stop, assume references in
     // this format are relative paths and attempt to convert them
     // to absolute paths. If this fails, let the reference run through
     // the normal checks and have it fail as normal.
     if (substr($ref, 0, 1) === '.') {
         $realpath = Util\Common::realpath($rulesetDir . '/' . $ref);
         if ($realpath !== false) {
             $ref = $realpath;
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo str_repeat("\t", $depth);
                 echo "\t\t=> " . Util\Common::stripBasepath($ref, $this->config->basepath) . PHP_EOL;
             }
         }
     }
     // As sniffs can't begin with a tilde, assume references in
     // this format are relative to the user's home directory.
     if (substr($ref, 0, 2) === '~/') {
         $realpath = Util\Common::realpath($ref);
         if ($realpath !== false) {
             $ref = $realpath;
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo str_repeat("\t", $depth);
                 echo "\t\t=> " . Util\Common::stripBasepath($ref, $this->config->basepath) . PHP_EOL;
             }
         }
     }
     if (is_file($ref) === true) {
         if (substr($ref, -9) === 'Sniff.php') {
             // A single external sniff.
             $this->rulesetDirs[] = dirname(dirname(dirname($ref)));
             return array($ref);
         }
     } else {
         // See if this is a whole standard being referenced.
         $path = Util\Standards::getInstalledStandardPath($ref);
         if (Util\Common::isPharFile($path) === true && strpos($path, 'ruleset.xml') === false) {
             // If the ruleset exists inside the phar file, use it.
             if (file_exists($path . DIRECTORY_SEPARATOR . 'ruleset.xml') === true) {
                 $path = $path . DIRECTORY_SEPARATOR . 'ruleset.xml';
             } else {
                 $path = null;
             }
         }
         if ($path !== null) {
             $ref = $path;
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo str_repeat("\t", $depth);
                 echo "\t\t=> " . Util\Common::stripBasepath($ref, $this->config->basepath) . PHP_EOL;
             }
         } else {
             if (is_dir($ref) === false) {
                 // Work out the sniff path.
                 $sepPos = strpos($ref, DIRECTORY_SEPARATOR);
                 if ($sepPos !== false) {
                     $stdName = substr($ref, 0, $sepPos);
                     $path = substr($ref, $sepPos);
                 } else {
                     $parts = explode('.', $ref);
                     $stdName = $parts[0];
                     if (count($parts) === 1) {
                         // A whole standard?
                         $path = '';
                     } else {
                         if (count($parts) === 2) {
                             // A directory of sniffs?
                             $path = DIRECTORY_SEPARATOR . 'Sniffs' . DIRECTORY_SEPARATOR . $parts[1];
                         } else {
                             // A single sniff?
                             $path = DIRECTORY_SEPARATOR . 'Sniffs' . DIRECTORY_SEPARATOR . $parts[1] . DIRECTORY_SEPARATOR . $parts[2] . 'Sniff.php';
                         }
                     }
                 }
                 $newRef = false;
                 $stdPath = Util\Standards::getInstalledStandardPath($stdName);
                 if ($stdPath !== null && $path !== '') {
                     if (Util\Common::isPharFile($stdPath) === true && strpos($stdPath, 'ruleset.xml') === false) {
                         // Phar files can only return the directory,
                         // since ruleset can be omitted if building one standard.
                         $newRef = Util\Common::realpath($stdPath . $path);
                     } else {
                         $newRef = Util\Common::realpath(dirname($stdPath) . $path);
                     }
                 }
                 if ($newRef === false) {
                     // The sniff is not locally installed, so check if it is being
                     // referenced as a remote sniff outside the install. We do this
                     // by looking through all directories where we have found ruleset
                     // files before, looking for ones for this particular standard,
                     // and seeing if it is in there.
                     foreach ($this->rulesetDirs as $dir) {
                         if (strtolower(basename($dir)) !== strtolower($stdName)) {
                             continue;
                         }
                         $newRef = Util\Common::realpath($dir . $path);
                         if ($newRef !== false) {
                             $ref = $newRef;
                         }
                     }
                 } else {
                     $ref = $newRef;
                 }
                 if (PHP_CODESNIFFER_VERBOSITY > 1) {
                     echo str_repeat("\t", $depth);
                     echo "\t\t=> " . Util\Common::stripBasepath($ref, $this->config->basepath) . PHP_EOL;
                 }
             }
         }
         //end if
     }
     //end if
     if (is_dir($ref) === true) {
         if (is_file($ref . DIRECTORY_SEPARATOR . 'ruleset.xml') === true) {
             // We are referencing an external coding standard.
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo str_repeat("\t", $depth);
                 echo "\t\t* rule is referencing a standard using directory name; processing *" . PHP_EOL;
             }
             return $this->processRuleset($ref . DIRECTORY_SEPARATOR . 'ruleset.xml', $depth + 2);
         } else {
             // We are referencing a whole directory of sniffs.
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo str_repeat("\t", $depth);
                 echo "\t\t* rule is referencing a directory of sniffs *" . PHP_EOL;
                 echo str_repeat("\t", $depth);
                 echo "\t\tAdding sniff files from directory" . PHP_EOL;
             }
             return $this->expandSniffDirectory($ref, $depth + 1);
         }
     } else {
         if (is_file($ref) === false) {
             $error = "Referenced sniff \"{$ref}\" does not exist";
             throw new RuntimeException($error);
         }
         if (substr($ref, -9) === 'Sniff.php') {
             // A single sniff.
             return array($ref);
         } else {
             // Assume an external ruleset.xml file.
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo str_repeat("\t", $depth);
                 echo "\t\t* rule is referencing a standard using ruleset path; processing *" . PHP_EOL;
             }
             return $this->processRuleset($ref, $depth + 2);
         }
     }
     //end if
 }