コード例 #1
0
ファイル: GitModified.php プロジェクト: thekabal/tki
 /**
  * Get a list of whitelisted file paths.
  *
  * @return array
  */
 protected function getWhitelist()
 {
     $modified = array();
     $cmd = 'git ls-files -o -m --exclude-standard -- ' . $this->basedir;
     $output = array();
     exec($cmd, $output);
     $basedir = $this->basedir;
     if (is_dir($basedir) === false) {
         $basedir = dirname($basedir);
     }
     foreach ($output as $path) {
         $path = Util\Common::realpath($path);
         do {
             $modified[$path] = true;
             $path = dirname($path);
         } while ($path !== $basedir);
     }
     return $modified;
 }
コード例 #2
0
ファイル: Filter.php プロジェクト: thekabal/tki
 /**
  * Check whether the current element of the iterator is acceptable.
  *
  * Files are checked for allowed extensions and ignore patterns.
  * Directories are checked for ignore patterns only.
  *
  * @return bool
  */
 public function accept()
 {
     $filePath = Util\Common::realpath($this->current());
     if ($filePath === false) {
         return false;
     }
     if (is_dir($filePath) === true) {
         if ($this->config->local === true) {
             return false;
         }
     } else {
         if ($this->shouldProcessFile($filePath) === false) {
             return false;
         }
     }
     if ($this->shouldIgnorePath($filePath) === true) {
         return false;
     }
     return true;
 }
コード例 #3
0
ファイル: ExactMatch.php プロジェクト: thekabal/tki
 /**
  * Check whether the current element of the iterator is acceptable.
  *
  * If a file is both blacklisted and whitelisted, it will be deemed unacceptable.
  *
  * @return bool
  */
 public function accept()
 {
     if (parent::accept() === false) {
         return false;
     }
     if ($this->blacklist === null) {
         $this->blacklist = $this->getblacklist();
     }
     if ($this->whitelist === null) {
         $this->whitelist = $this->getwhitelist();
     }
     $filePath = Util\Common::realpath($this->current());
     // If file is both blacklisted and whitelisted, the blacklist takes precedence.
     if (isset($this->blacklist[$filePath]) === true) {
         return false;
     }
     if (empty($this->whitelist) === true && empty($this->blacklist) === false) {
         // We are only checking a blacklist, so everything else should be whitelisted.
         return true;
     }
     return isset($this->whitelist[$filePath]);
 }
コード例 #4
0
ファイル: Cache.php プロジェクト: thekabal/tki
 /**
  * Loads existing cache data for the run, if any.
  *
  * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
  * @param \PHP_CodeSniffer\Config  $config  The config data for the run.
  *
  * @return void
  */
 public static function load(Ruleset $ruleset, Config $config)
 {
     // Look at every loaded sniff class so far and use their file contents
     // to generate a hash for the code used during the run.
     // At this point, the loaded class list contains the core PHPCS code
     // and all sniffs that have been loaded as part of the run.
     if (PHP_CODESNIFFER_VERBOSITY > 1) {
         echo PHP_EOL . "\tGenerating loaded file list for code hash" . PHP_EOL;
     }
     $codeHash = '';
     $classes = array_keys(Autoload::getLoadedClasses());
     sort($classes);
     $installDir = dirname(__DIR__);
     $installDirLen = strlen($installDir);
     $standardDir = $installDir . DIRECTORY_SEPARATOR . 'Standards';
     $standardDirLen = strlen($standardDir);
     foreach ($classes as $file) {
         if (substr($file, 0, $standardDirLen) !== $standardDir) {
             if (substr($file, 0, $installDirLen) === $installDir) {
                 // We are only interested in sniffs here.
                 continue;
             }
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo "\t\t=> external file: {$file}" . PHP_EOL;
             }
         } else {
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo "\t\t=> internal sniff: {$file}" . PHP_EOL;
             }
         }
         $codeHash .= md5_file($file);
     }
     // Add the content of the used rulesets to the hash so that sniff setting
     // changes in the ruleset invalidate the cache.
     $rulesets = $ruleset->paths;
     sort($rulesets);
     foreach ($rulesets as $file) {
         if (substr($file, 0, $standardDirLen) !== $standardDir) {
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo "\t\t=> external ruleset: {$file}" . PHP_EOL;
             }
         } else {
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo "\t\t=> internal ruleset: {$file}" . PHP_EOL;
             }
         }
         $codeHash .= md5_file($file);
     }
     // Go through the core PHPCS code and add those files to the file
     // hash. This ensures that core PHPCS changes will also invalidate the cache.
     // Note that we ignore sniffs here, and any files that don't affect
     // the outcome of the run.
     $di = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($installDir), 0, \RecursiveIteratorIterator::CATCH_GET_CHILD);
     $di = new \RecursiveDirectoryIterator($installDir);
     $filter = new \RecursiveCallbackFilterIterator($di, function ($file, $key, $iterator) {
         // Skip hidden files.
         $filename = $file->getFilename();
         if (substr($filename, 0, 1) === '.') {
             return false;
         }
         $filePath = Common::realpath($file->getPathname());
         if ($filePath === false) {
             return false;
         }
         if (is_dir($filePath) === true && ($filename === 'Standards' || $filename === 'Exceptions' || $filename === 'Reports' || $filename === 'Generators')) {
             return false;
         }
         return true;
     });
     $iterator = new \RecursiveIteratorIterator($filter);
     foreach ($iterator as $file) {
         if (PHP_CODESNIFFER_VERBOSITY > 1) {
             echo "\t\t=> core file: {$file}" . PHP_EOL;
         }
         $codeHash .= md5_file($file);
     }
     $codeHash = md5($codeHash);
     // Along with the code hash, use various settings that can affect
     // the results of a run to create a new hash. This hash will be used
     // in the cache file name.
     $rulesetHash = md5(var_export($ruleset->ignorePatterns, true) . var_export($ruleset->includePatterns, true));
     $configData = array('tabWidth' => $config->tabWidth, 'encoding' => $config->encoding, 'recordErrors' => $config->recordErrors, 'codeHash' => $codeHash, 'rulesetHash' => $rulesetHash);
     $configString = implode(',', $configData);
     $cacheHash = substr(sha1($configString), 0, 12);
     if (PHP_CODESNIFFER_VERBOSITY > 1) {
         echo "\tGenerating cache key data" . PHP_EOL;
         echo "\t\t=> tabWidth: " . $configData['tabWidth'] . PHP_EOL;
         echo "\t\t=> encoding: " . $configData['encoding'] . PHP_EOL;
         echo "\t\t=> recordErrors: " . (int) $configData['recordErrors'] . PHP_EOL;
         echo "\t\t=> codeHash: " . $configData['codeHash'] . PHP_EOL;
         echo "\t\t=> rulesetHash: " . $configData['rulesetHash'] . PHP_EOL;
         echo "\t\t=> cacheHash: {$cacheHash}" . PHP_EOL;
     }
     if ($config->cacheFile !== null) {
         $cacheFile = $config->cacheFile;
     } else {
         // Determine the common paths for all files being checked.
         // We can use this to locate an existing cache file, or to
         // determine where to create a new one.
         if (PHP_CODESNIFFER_VERBOSITY > 1) {
             echo "\tChecking possible cache file paths" . PHP_EOL;
         }
         $paths = array();
         foreach ($config->files as $file) {
             $file = Common::realpath($file);
             while ($file !== DIRECTORY_SEPARATOR) {
                 if (isset($paths[$file]) === false) {
                     $paths[$file] = 1;
                 } else {
                     $paths[$file]++;
                 }
                 $lastFile = $file;
                 $file = dirname($file);
                 if ($file === $lastFile) {
                     // Just in case something went wrong,
                     // we don't want to end up in an infinite loop.
                     break;
                 }
             }
         }
         ksort($paths);
         $paths = array_reverse($paths);
         $numFiles = count($config->files);
         $tmpDir = sys_get_temp_dir();
         $cacheFile = null;
         foreach ($paths as $file => $count) {
             if ($count !== $numFiles) {
                 unset($paths[$file]);
                 continue;
             }
             $fileHash = substr(sha1($file), 0, 12);
             $testFile = $tmpDir . DIRECTORY_SEPARATOR . "phpcs.{$fileHash}.{$cacheHash}.cache";
             if ($cacheFile === null) {
                 // This will be our default location if we can't find
                 // an existing file.
                 $cacheFile = $testFile;
             }
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo "\t\t=> {$testFile}" . PHP_EOL;
                 echo "\t\t\t * based on shared location: {$file} *" . PHP_EOL;
             }
             if (file_exists($testFile) === true) {
                 $cacheFile = $testFile;
                 break;
             }
         }
         //end foreach
         if ($cacheFile === null) {
             // Unlikely, but just in case $paths is empty for some reason.
             $cacheFile = $tmpDir . DIRECTORY_SEPARATOR . "phpcs.{$cacheHash}.cache";
         }
     }
     //end if
     self::$path = $cacheFile;
     if (PHP_CODESNIFFER_VERBOSITY > 1) {
         echo "\t=> Using cache file: " . self::$path . PHP_EOL;
     }
     if (file_exists(self::$path) === true) {
         self::$cache = json_decode(file_get_contents(self::$path), true);
         // Verify the contents of the cache file.
         if (self::$cache['config'] !== $configData) {
             self::$cache = array();
             if (PHP_CODESNIFFER_VERBOSITY > 1) {
                 echo "\t* cache was invalid and has been cleared *" . PHP_EOL;
             }
         }
     } else {
         if (PHP_CODESNIFFER_VERBOSITY > 1) {
             echo "\t* cache file does not exist *" . PHP_EOL;
         }
     }
     self::$cache['config'] = $configData;
 }
コード例 #5
0
ファイル: Ruleset.php プロジェクト: thekabal/tki
 /**
  * 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
 }
コード例 #6
0
ファイル: Standards.php プロジェクト: thekabal/tki
 /**
  * Return the path of an installed coding standard.
  *
  * Coding standards are directories located in the
  * CodeSniffer/Standards directory. Valid coding standards
  * include a ruleset.xml file.
  *
  * @param string $standard The name of the coding standard.
  *
  * @return string|null
  */
 public static function getInstalledStandardPath($standard)
 {
     $installedPaths = self::getInstalledStandardPaths();
     foreach ($installedPaths as $installedPath) {
         if (basename($installedPath) === $standard) {
             $standardPath = $installedPath;
         } else {
             $standardPath = $installedPath . DIRECTORY_SEPARATOR . $standard;
         }
         $path = Common::realpath($standardPath . DIRECTORY_SEPARATOR . 'ruleset.xml');
         if (is_file($path) === true) {
             return $path;
         } else {
             if (Common::isPharFile($standardPath) === true) {
                 $path = Common::realpath($standardPath);
                 if ($path !== false) {
                     return $path;
                 }
             }
         }
     }
     return null;
 }
コード例 #7
0
ファイル: Config.php プロジェクト: thekabal/tki
 /**
  * Processes a file path and add it to the file list.
  *
  * @param string $path The path to the file to add.
  *
  * @return void
  */
 public function processFilePath($path)
 {
     // If we are processing STDIN, don't record any files to check.
     if ($this->stdin === true) {
         return;
     }
     $file = Util\Common::realpath($path);
     if (file_exists($file) === false) {
         if ($this->dieOnUnknownArg === false) {
             return;
         }
         echo 'ERROR: The file "' . $path . '" does not exist.' . PHP_EOL . PHP_EOL;
         $this->printUsage();
         exit(3);
     } else {
         $files = $this->files;
         $files[] = $file;
         $this->files = $files;
         $this->overriddenDefaults['files'] = true;
     }
 }