/** * Processes a short (-e) command line argument. * * @param string $arg The command line argument. * @param int $pos The position of the argument on the command line. * * @return void */ public function processShortArgument($arg, $pos) { switch ($arg) { case 'h': case '?': $this->printUsage(); exit(0); case 'i': Util\Standards::printInstalledStandards(); exit(0); case 'v': if ($this->quiet === true) { // Ignore when quiet mode is enabled. break; } $this->verbosity++; $this->overriddenDefaults['verbosity'] = true; break; case 'l': $this->local = true; $this->overriddenDefaults['local'] = true; break; case 's': $this->showSources = true; $this->overriddenDefaults['showSources'] = true; break; case 'a': $this->interactive = true; $this->overriddenDefaults['interactive'] = true; break; case 'e': $this->explain = true; $this->overriddenDefaults['explain'] = true; break; case 'p': if ($this->quiet === true) { // Ignore when quiet mode is enabled. break; } $this->showProgress = true; $this->overriddenDefaults['showProgress'] = true; break; case 'q': // Quiet mode disables a few other settings as well. $this->quiet = true; $this->showProgress = false; $this->verbosity = 0; $this->overriddenDefaults['quiet'] = true; break; case 'm': $this->recordErrors = false; $this->overriddenDefaults['recordErrors'] = true; break; case 'd': $ini = explode('=', $this->cliArgs[$pos + 1]); $this->cliArgs[$pos + 1] = ''; if (isset($ini[1]) === true) { ini_set($ini[0], $ini[1]); } else { ini_set($ini[0], true); } break; case 'n': if (isset($this->overriddenDefaults['warningSeverity']) === false) { $this->warningSeverity = 0; $this->overriddenDefaults['warningSeverity'] = true; } break; case 'w': if (isset($this->overriddenDefaults['warningSeverity']) === false) { $this->warningSeverity = $this->errorSeverity; $this->overriddenDefaults['warningSeverity'] = true; } break; default: if ($this->dieOnUnknownArg === false) { $this->values[$arg] = $arg; } else { $this->processUnknownArgument('-' . $arg, $pos); } } //end switch }
/** * 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 }
/** * Init the rulesets and other high-level settings. * * @return void */ private function init() { // Ensure this option is enabled or else line endings will not always // be detected properly for files created on a Mac with the /r line ending. ini_set('auto_detect_line_endings', true); // Check that the standards are valid. foreach ($this->config->standards as $standard) { if (Util\Standards::isInstalledStandard($standard) === false) { // They didn't select a valid coding standard, so help them // out by letting them know which standards are installed. echo 'ERROR: the "' . $standard . '" coding standard is not installed. '; Util\Standards::printInstalledStandards(); exit(3); } } // Saves passing the Config object into other objects that only need // the verbostity flag for deubg output. if (defined('PHP_CODESNIFFER_VERBOSITY') === false) { define('PHP_CODESNIFFER_VERBOSITY', $this->config->verbosity); } // Create this class so it is autoloaded and sets up a bunch // of PHP_CodeSniffer-specific token type constants. $tokens = new Util\Tokens(); // The ruleset contains all the information about how the files // should be checked and/or fixed. $this->ruleset = new Ruleset($this->config); }