Example #1
0
 /**
  * Performs the run.
  *
  * @return int The number of errors and warnings found.
  */
 private function run()
 {
     // The class that manages all reporters for the run.
     $this->reporter = new Reporter($this->config);
     // Include bootstrap files.
     foreach ($this->config->bootstrap as $bootstrap) {
         include $bootstrap;
     }
     if ($this->config->stdin === true) {
         $fileContents = $this->config->stdinContent;
         if ($fileContents === null) {
             $handle = fopen('php://stdin', 'r');
             stream_set_blocking($handle, true);
             $fileContents = stream_get_contents($handle);
             fclose($handle);
         }
         $todo = new FileList($this->config, $this->ruleset);
         $dummy = new DummyFile($fileContents, $this->ruleset, $this->config);
         $todo->addFile($dummy->path, $dummy);
         $numFiles = 1;
     } else {
         if (empty($this->config->files) === true) {
             echo 'ERROR: You must supply at least one file or directory to process.' . PHP_EOL . PHP_EOL;
             $this->config->printUsage();
             exit(0);
         }
         if (PHP_CODESNIFFER_VERBOSITY > 0) {
             echo 'Creating file list... ';
         }
         $todo = new FileList($this->config, $this->ruleset);
         $numFiles = count($todo);
         if (PHP_CODESNIFFER_VERBOSITY > 0) {
             echo "DONE ({$numFiles} files in queue)" . PHP_EOL;
         }
         if ($this->config->cache === true) {
             if (PHP_CODESNIFFER_VERBOSITY > 0) {
                 echo 'Loading cache... ';
             }
             Cache::load($this->ruleset, $this->config);
             if (PHP_CODESNIFFER_VERBOSITY > 0) {
                 $size = Cache::getSize();
                 echo "DONE ({$size} files in cache)" . PHP_EOL;
             }
         }
     }
     //end if
     // Turn all sniff errors into exceptions.
     set_error_handler(array($this, 'handleErrors'));
     // If verbosity is too high, turn off parallelism so the
     // debug output is clean.
     if (PHP_CODESNIFFER_VERBOSITY > 1) {
         $this->config->parallel = 1;
     }
     // If the PCNTL extension isn't installed, we can't fork.
     if (function_exists('pcntl_fork') === false) {
         $this->config->parallel = 1;
     }
     $lastDir = '';
     if ($this->config->parallel === 1) {
         // Running normally.
         $numProcessed = 0;
         foreach ($todo as $path => $file) {
             $currDir = dirname($path);
             if ($lastDir !== $currDir) {
                 if (PHP_CODESNIFFER_VERBOSITY > 0) {
                     echo 'Changing into directory ' . Common::stripBasepath($currDir, $this->config->basepath) . PHP_EOL;
                 }
                 $lastDir = $currDir;
             }
             $this->processFile($file);
             $numProcessed++;
             $this->printProgress($file, $numFiles, $numProcessed);
         }
     } else {
         // Batching and forking.
         $childProcs = array();
         $numFiles = count($todo);
         $numPerBatch = ceil($numFiles / $this->config->parallel);
         for ($batch = 0; $batch < $this->config->parallel; $batch++) {
             $startAt = $batch * $numPerBatch;
             if ($startAt >= $numFiles) {
                 break;
             }
             $endAt = $startAt + $numPerBatch;
             if ($endAt > $numFiles) {
                 $endAt = $numFiles;
             }
             $childOutFilename = tempnam(sys_get_temp_dir(), 'phpcs-child');
             $pid = pcntl_fork();
             if ($pid === -1) {
                 throw new RuntimeException('Failed to create child process');
             } else {
                 if ($pid !== 0) {
                     $childProcs[] = array('pid' => $pid, 'out' => $childOutFilename);
                 } else {
                     // Move forward to the start of the batch.
                     $todo->rewind();
                     for ($i = 0; $i < $startAt; $i++) {
                         $todo->next();
                     }
                     // Reset the reporter to make sure only figures from this
                     // file batch are recorded.
                     $this->reporter->totalFiles = 0;
                     $this->reporter->totalErrors = 0;
                     $this->reporter->totalWarnings = 0;
                     $this->reporter->totalFixable = 0;
                     // Process the files.
                     $pathsProcessed = array();
                     ob_start();
                     for ($i = $startAt; $i < $endAt; $i++) {
                         $path = $todo->key();
                         $file = $todo->current();
                         $currDir = dirname($path);
                         if ($lastDir !== $currDir) {
                             if (PHP_CODESNIFFER_VERBOSITY > 0) {
                                 echo 'Changing into directory ' . Common::stripBasepath($currDir, $this->config->basepath) . PHP_EOL;
                             }
                             $lastDir = $currDir;
                         }
                         $this->processFile($file);
                         $pathsProcessed[] = $path;
                         $todo->next();
                     }
                     $debugOutput = ob_get_contents();
                     ob_end_clean();
                     // Write information about the run to the filesystem
                     // so it can be picked up by the main process.
                     $childOutput = array('totalFiles' => $this->reporter->totalFiles, 'totalErrors' => $this->reporter->totalErrors, 'totalWarnings' => $this->reporter->totalWarnings, 'totalFixable' => $this->reporter->totalFixable, 'totalFixed' => $this->reporter->totalFixed);
                     $output = '<' . '?php' . "\n" . ' $childOutput = ';
                     $output .= var_export($childOutput, true);
                     $output .= ";\n\$debugOutput = ";
                     $output .= var_export($debugOutput, true);
                     if ($this->config->cache === true) {
                         $childCache = array();
                         foreach ($pathsProcessed as $path) {
                             $childCache[$path] = Cache::get($path);
                         }
                         $output .= ";\n\$childCache = ";
                         $output .= var_export($childCache, true);
                     }
                     $output .= ";\n?" . '>';
                     file_put_contents($childOutFilename, $output);
                     exit($pid);
                 }
             }
             //end if
         }
         //end for
         $this->processChildProcs($childProcs);
     }
     //end if
     restore_error_handler();
     if (PHP_CODESNIFFER_VERBOSITY === 0 && $this->config->interactive === false && $this->config->showProgress === true) {
         echo PHP_EOL . PHP_EOL;
     }
     if ($this->config->cache === true) {
         Cache::save();
     }
     $ignoreWarnings = Config::getConfigData('ignore_warnings_on_exit');
     $ignoreErrors = Config::getConfigData('ignore_errors_on_exit');
     $return = $this->reporter->totalErrors + $this->reporter->totalWarnings;
     if ($ignoreErrors !== null) {
         $ignoreErrors = (bool) $ignoreErrors;
         if ($ignoreErrors === true) {
             $return -= $this->reporter->totalErrors;
         }
     }
     if ($ignoreWarnings !== null) {
         $ignoreWarnings = (bool) $ignoreWarnings;
         if ($ignoreWarnings === true) {
             $return -= $this->reporter->totalWarnings;
         }
     }
     return $return;
 }