PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file Runner.php

Documentation is available at Runner.php

  1. <?php
  2. /**
  3.  * Responsible for running PHPCS and PHPCBF.
  4.  *
  5.  * After creating an object of this class, you probably just want to
  6.  * call runPHPCS() or runPHPCBF().
  7.  *
  8.  * @author    Greg Sherwood <gsherwood@squiz.net>
  9.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  10.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  11.  */
  12.  
  13. namespace PHP_CodeSniffer;
  14.  
  15. use PHP_CodeSniffer\Files\FileList;
  16. use PHP_CodeSniffer\Files\File;
  17. use PHP_CodeSniffer\Files\DummyFile;
  18. use PHP_CodeSniffer\Util\Cache;
  19. use PHP_CodeSniffer\Util\Common;
  20. use PHP_CodeSniffer\Util\Standards;
  21. use PHP_CodeSniffer\Exceptions\RuntimeException;
  22. use PHP_CodeSniffer\Exceptions\DeepExitException;
  23.  
  24. class Runner
  25. {
  26.  
  27.     /**
  28.      * The config data for the run.
  29.      *
  30.      * @var \PHP_CodeSniffer\Config 
  31.      */
  32.     public $config = null;
  33.  
  34.     /**
  35.      * The ruleset used for the run.
  36.      *
  37.      * @var \PHP_CodeSniffer\Ruleset 
  38.      */
  39.     public $ruleset = null;
  40.  
  41.     /**
  42.      * The reporter used for generating reports after the run.
  43.      *
  44.      * @var \PHP_CodeSniffer\Reporter 
  45.      */
  46.     public $reporter = null;
  47.  
  48.  
  49.     /**
  50.      * Run the PHPCS script.
  51.      *
  52.      * @return array 
  53.      */
  54.     public function runPHPCS()
  55.     {
  56.         try {
  57.             Util\Timing::startTiming();
  58.             Runner::checkRequirements();
  59.  
  60.             if (defined('PHP_CODESNIFFER_CBF'=== false{
  61.                 define('PHP_CODESNIFFER_CBF'false);
  62.             }
  63.  
  64.             // Creating the Config object populates it with all required settings
  65.             // based on the CLI arguments provided to the script and any config
  66.             // values the user has set.
  67.             $this->config = new Config();
  68.  
  69.             // Init the run and load the rulesets to set additional config vars.
  70.             $this->init();
  71.  
  72.             // Print a list of sniffs in each of the supplied standards.
  73.             // We fudge the config here so that each standard is explained in isolation.
  74.             if ($this->config->explain === true{
  75.                 $standards $this->config->standards;
  76.                 foreach ($standards as $standard{
  77.                     $this->config->standards = array($standard);
  78.                     $ruleset = new Ruleset($this->config);
  79.                     $ruleset->explain();
  80.                 }
  81.  
  82.                 return 0;
  83.             }
  84.  
  85.             // Generate documentation for each of the supplied standards.
  86.             if ($this->config->generator !== null{
  87.                 $standards $this->config->standards;
  88.                 foreach ($standards as $standard{
  89.                     $this->config->standards = array($standard);
  90.                     $ruleset   = new Ruleset($this->config);
  91.                     $class     'PHP_CodeSniffer\Generators\\'.$this->config->generator;
  92.                     $generator = new $class($ruleset);
  93.                     $generator->generate();
  94.                 }
  95.  
  96.                 return 0;
  97.             }
  98.  
  99.             // Other report formats don't really make sense in interactive mode
  100.             // so we hard-code the full report here and when outputting.
  101.             // We also ensure parallel processing is off because we need to do one file at a time.
  102.             if ($this->config->interactive === true{
  103.                 $this->config->reports      = array('full' => null);
  104.                 $this->config->parallel     = 1;
  105.                 $this->config->showProgress = false;
  106.             }
  107.  
  108.             // Disable caching if we are processing STDIN as we can't be 100%
  109.             // sure where the file came from or if it will change in the future.
  110.             if ($this->config->stdin === true{
  111.                 $this->config->cache = false;
  112.             }
  113.  
  114.             $numErrors $this->run();
  115.  
  116.             // Print all the reports for this run.
  117.             $toScreen $this->reporter->printReports();
  118.  
  119.             // Only print timer output if no reports were
  120.             // printed to the screen so we don't put additional output
  121.             // in something like an XML report. If we are printing to screen,
  122.             // the report types would have already worked out who should
  123.             // print the timer info.
  124.             if ($this->config->interactive === false
  125.                 && ($toScreen === false
  126.                 || (($this->reporter->totalErrors + $this->reporter->totalWarnings=== 0 && $this->config->showProgress === true))
  127.             {
  128.                 Util\Timing::printRunTime();
  129.             }
  130.         catch (DeepExitException $e{
  131.             echo $e->getMessage();
  132.             return $e->getCode();
  133.         }//end try
  134.  
  135.         if ($numErrors === 0{
  136.             // No errors found.
  137.             return 0;
  138.         else if ($this->reporter->totalFixable === 0{
  139.             // Errors found, but none of them can be fixed by PHPCBF.
  140.             return 1;
  141.         else {
  142.             // Errors found, and some can be fixed by PHPCBF.
  143.             return 2;
  144.         }
  145.  
  146.     }//end runPHPCS()
  147.  
  148.  
  149.     /**
  150.      * Run the PHPCBF script.
  151.      *
  152.      * @return array 
  153.      */
  154.     public function runPHPCBF()
  155.     {
  156.         if (defined('PHP_CODESNIFFER_CBF'=== false{
  157.             define('PHP_CODESNIFFER_CBF'true);
  158.         }
  159.  
  160.         try {
  161.             Util\Timing::startTiming();
  162.             Runner::checkRequirements();
  163.  
  164.             // Creating the Config object populates it with all required settings
  165.             // based on the CLI arguments provided to the script and any config
  166.             // values the user has set.
  167.             $this->config = new Config();
  168.  
  169.             // When processing STDIN, we can't output anything to the screen
  170.             // or it will end up mixed in with the file output.
  171.             if ($this->config->stdin === true{
  172.                 $this->config->verbosity = 0;
  173.             }
  174.  
  175.             // Init the run and load the rulesets to set additional config vars.
  176.             $this->init();
  177.  
  178.             // Override some of the command line settings that might break the fixes.
  179.             $this->config->generator    = null;
  180.             $this->config->explain      = false;
  181.             $this->config->interactive  = false;
  182.             $this->config->cache        = false;
  183.             $this->config->showSources  = false;
  184.             $this->config->recordErrors = false;
  185.             $this->config->reportFile   = null;
  186.             $this->config->reports      = array('cbf' => null);
  187.  
  188.             // If a standard tries to set command line arguments itself, some
  189.             // may be blocked because PHPCBF is running, so stop the script
  190.             // dying if any are found.
  191.             $this->config->dieOnUnknownArg = false;
  192.  
  193.             $numErrors $this->run();
  194.             $this->reporter->printReports();
  195.  
  196.             echo PHP_EOL;
  197.             Util\Timing::printRunTime();
  198.         catch (DeepExitException $e{
  199.             echo $e->getMessage();
  200.             return $e->getCode();
  201.         }//end try
  202.  
  203.         if ($this->reporter->totalFixed === 0{
  204.             // Nothing was fixed by PHPCBF.
  205.             if ($this->reporter->totalFixable === 0{
  206.                 // Nothing found that could be fixed.
  207.                 return 0;
  208.             else {
  209.                 // Something failed to fix.
  210.                 return 2;
  211.             }
  212.         }
  213.  
  214.         if ($this->reporter->totalFixable === 0{
  215.             // PHPCBF fixed all fixable errors.
  216.             return 1;
  217.         }
  218.  
  219.         // PHPCBF fixed some fixable errors, but others failed to fix.
  220.         return 2;
  221.  
  222.     }//end runPHPCBF()
  223.  
  224.  
  225.     /**
  226.      * Exits if the minimum requirements of PHP_CodSniffer are not met.
  227.      *
  228.      * @return array 
  229.      */
  230.     public function checkRequirements()
  231.     {
  232.         // Check the PHP version.
  233.         if (PHP_VERSION_ID < 50400{
  234.             $error 'ERROR: PHP_CodeSniffer requires PHP version 5.4.0 or greater.'.PHP_EOL;
  235.             throw new DeepExitException($error3);
  236.         }
  237.  
  238.         if (extension_loaded('tokenizer'=== false{
  239.             $error 'ERROR: PHP_CodeSniffer requires the tokenizer extension to be enabled.'.PHP_EOL;
  240.             throw new DeepExitException($error3);
  241.         }
  242.  
  243.     }//end checkRequirements()
  244.  
  245.  
  246.     /**
  247.      * Init the rulesets and other high-level settings.
  248.      *
  249.      * @return void 
  250.      */
  251.     public function init()
  252.     {
  253.         if (defined('PHP_CODESNIFFER_CBF'=== false{
  254.             define('PHP_CODESNIFFER_CBF'false);
  255.         }
  256.  
  257.         // Ensure this option is enabled or else line endings will not always
  258.         // be detected properly for files created on a Mac with the /r line ending.
  259.         ini_set('auto_detect_line_endings'true);
  260.  
  261.         // Check that the standards are valid.
  262.         foreach ($this->config->standards as $standard{
  263.             if (Util\Standards::isInstalledStandard($standard=== false{
  264.                 // They didn't select a valid coding standard, so help them
  265.                 // out by letting them know which standards are installed.
  266.                 $error 'ERROR: the "'.$standard.'" coding standard is not installed. ';
  267.                 ob_start();
  268.                 Util\Standards::printInstalledStandards();
  269.                 $error .= ob_get_contents();
  270.                 ob_end_clean();
  271.                 throw new DeepExitException($error3);
  272.             }
  273.         }
  274.  
  275.         // Saves passing the Config object into other objects that only need
  276.         // the verbostity flag for deubg output.
  277.         if (defined('PHP_CODESNIFFER_VERBOSITY'=== false{
  278.             define('PHP_CODESNIFFER_VERBOSITY'$this->config->verbosity);
  279.         }
  280.  
  281.         // Create this class so it is autoloaded and sets up a bunch
  282.         // of PHP_CodeSniffer-specific token type constants.
  283.         $tokens = new Util\Tokens();
  284.  
  285.         // Allow autoloading of custom files inside installed standards.
  286.         $installedStandards = Standards::getInstalledStandardDetails();
  287.         foreach ($installedStandards as $name => $details{
  288.             Autoload::addSearchPath($details['path']$details['namespace']);
  289.         }
  290.  
  291.         // The ruleset contains all the information about how the files
  292.         // should be checked and/or fixed.
  293.         try {
  294.             $this->ruleset = new Ruleset($this->config);
  295.         catch (RuntimeException $e{
  296.             $error  'ERROR: '.$e->getMessage().PHP_EOL.PHP_EOL;
  297.             $error .= $this->config->printShortUsage(true);
  298.             throw new DeepExitException($error3);
  299.         }
  300.  
  301.     }//end init()
  302.  
  303.  
  304.     /**
  305.      * Performs the run.
  306.      *
  307.      * @return int The number of errors and warnings found.
  308.      */
  309.     private function run()
  310.     {
  311.         // The class that manages all reporters for the run.
  312.         $this->reporter = new Reporter($this->config);
  313.  
  314.         // Include bootstrap files.
  315.         foreach ($this->config->bootstrap as $bootstrap{
  316.             include $bootstrap;
  317.         }
  318.  
  319.         if ($this->config->stdin === true{
  320.             $fileContents $this->config->stdinContent;
  321.             if ($fileContents === null{
  322.                 $handle fopen('php://stdin''r');
  323.                 stream_set_blocking($handletrue);
  324.                 $fileContents stream_get_contents($handle);
  325.                 fclose($handle);
  326.             }
  327.  
  328.             $todo  = new FileList($this->config$this->ruleset);
  329.             $dummy = new DummyFile($fileContents$this->ruleset$this->config);
  330.             $todo->addFile($dummy->path$dummy);
  331.         else {
  332.             if (empty($this->config->files=== true{
  333.                 $error  'ERROR: You must supply at least one file or directory to process.'.PHP_EOL.PHP_EOL;
  334.                 $error .= $this->config->printShortUsage(true);
  335.                 throw new DeepExitException($error3);
  336.             }
  337.  
  338.             if (PHP_CODESNIFFER_VERBOSITY > 0{
  339.                 echo 'Creating file list... ';
  340.             }
  341.  
  342.             $todo = new FileList($this->config$this->ruleset);
  343.  
  344.             if (PHP_CODESNIFFER_VERBOSITY > 0{
  345.                 $numFiles count($todo);
  346.                 echo "DONE ($numFiles files in queue)".PHP_EOL;
  347.             }
  348.  
  349.             if ($this->config->cache === true{
  350.                 if (PHP_CODESNIFFER_VERBOSITY > 0{
  351.                     echo 'Loading cache... ';
  352.                 }
  353.  
  354.                 Cache::load($this->ruleset$this->config);
  355.  
  356.                 if (PHP_CODESNIFFER_VERBOSITY > 0{
  357.                     $size = Cache::getSize();
  358.                     echo "DONE ($size files in cache)".PHP_EOL;
  359.                 }
  360.             }
  361.         }//end if
  362.  
  363.         // Turn all sniff errors into exceptions.
  364.         set_error_handler(array($this'handleErrors'));
  365.  
  366.         // If verbosity is too high, turn off parallelism so the
  367.         // debug output is clean.
  368.         if (PHP_CODESNIFFER_VERBOSITY > 1{
  369.             $this->config->parallel = 1;
  370.         }
  371.  
  372.         // If the PCNTL extension isn't installed, we can't fork.
  373.         if (function_exists('pcntl_fork'=== false{
  374.             $this->config->parallel = 1;
  375.         }
  376.  
  377.         $lastDir  '';
  378.         $numFiles count($todo);
  379.  
  380.         if ($this->config->parallel === 1{
  381.             // Running normally.
  382.             $numProcessed = 0;
  383.             foreach ($todo as $path => $file{
  384.                 if ($file->ignored === false{
  385.                     $currDir dirname($path);
  386.                     if ($lastDir !== $currDir{
  387.                         if (PHP_CODESNIFFER_VERBOSITY > 0{
  388.                             echo 'Changing into directory '.Common::stripBasepath($currDir$this->config->basepath).PHP_EOL;
  389.                         }
  390.  
  391.                         $lastDir $currDir;
  392.                     }
  393.  
  394.                     $this->processFile($file);
  395.                 else if (PHP_CODESNIFFER_VERBOSITY > 0{
  396.                     echo 'Skipping '.basename($file->path).PHP_EOL;
  397.                 }
  398.  
  399.                 $numProcessed++;
  400.                 $this->printProgress($file$numFiles$numProcessed);
  401.             }
  402.         else {
  403.             // Batching and forking.
  404.             $childProcs  = array();
  405.             $numPerBatch ceil($numFiles $this->config->parallel);
  406.  
  407.             for ($batch = 0; $batch $this->config->parallel; $batch++{
  408.                 $startAt ($batch $numPerBatch);
  409.                 if ($startAt >= $numFiles{
  410.                     break;
  411.                 }
  412.  
  413.                 $endAt ($startAt $numPerBatch);
  414.                 if ($endAt $numFiles{
  415.                     $endAt $numFiles;
  416.                 }
  417.  
  418.                 $childOutFilename tempnam(sys_get_temp_dir()'phpcs-child');
  419.                 $pid pcntl_fork();
  420.                 if ($pid === -1{
  421.                     throw new RuntimeException('Failed to create child process');
  422.                 else if ($pid !== 0{
  423.                     $childProcs[= array(
  424.                                      'pid' => $pid,
  425.                                      'out' => $childOutFilename,
  426.                                     );
  427.                 else {
  428.                     // Move forward to the start of the batch.
  429.                     $todo->rewind();
  430.                     for ($i = 0; $i $startAt$i++{
  431.                         $todo->next();
  432.                     }
  433.  
  434.                     // Reset the reporter to make sure only figures from this
  435.                     // file batch are recorded.
  436.                     $this->reporter->totalFiles    = 0;
  437.                     $this->reporter->totalErrors   = 0;
  438.                     $this->reporter->totalWarnings = 0;
  439.                     $this->reporter->totalFixable  = 0;
  440.                     $this->reporter->totalFixed    = 0;
  441.  
  442.                     // Process the files.
  443.                     $pathsProcessed = array();
  444.                     ob_start();
  445.                     for ($i $startAt$i $endAt$i++{
  446.                         $path $todo->key();
  447.                         $file $todo->current();
  448.  
  449.                         if ($file->ignored === true{
  450.                             continue;
  451.                         }
  452.  
  453.                         $currDir dirname($path);
  454.                         if ($lastDir !== $currDir{
  455.                             if (PHP_CODESNIFFER_VERBOSITY > 0{
  456.                                 echo 'Changing into directory '.Common::stripBasepath($currDir$this->config->basepath).PHP_EOL;
  457.                             }
  458.  
  459.                             $lastDir $currDir;
  460.                         }
  461.  
  462.                         $this->processFile($file);
  463.  
  464.                         $pathsProcessed[$path;
  465.                         $todo->next();
  466.                     }//end for
  467.  
  468.                     $debugOutput ob_get_contents();
  469.                     ob_end_clean();
  470.  
  471.                     // Write information about the run to the filesystem
  472.                     // so it can be picked up by the main process.
  473.                     $childOutput = array(
  474.                                     'totalFiles'    => $this->reporter->totalFiles,
  475.                                     'totalErrors'   => $this->reporter->totalErrors,
  476.                                     'totalWarnings' => $this->reporter->totalWarnings,
  477.                                     'totalFixable'  => $this->reporter->totalFixable,
  478.                                     'totalFixed'    => $this->reporter->totalFixed,
  479.                                    );
  480.  
  481.                     $output  '<'.'?php'."\n".' $childOutput = ';
  482.                     $output .= var_export($childOutputtrue);
  483.                     $output .= ";\n\$debugOutput = ";
  484.                     $output .= var_export($debugOutputtrue);
  485.  
  486.                     if ($this->config->cache === true{
  487.                         $childCache = array();
  488.                         foreach ($pathsProcessed as $path{
  489.                             $childCache[$path= Cache::get($path);
  490.                         }
  491.  
  492.                         $output .= ";\n\$childCache = ";
  493.                         $output .= var_export($childCachetrue);
  494.                     }
  495.  
  496.                     $output .= ";\n?".'>';
  497.                     file_put_contents($childOutFilename$output);
  498.                     exit($pid);
  499.                 }//end if
  500.             }//end for
  501.  
  502.             $this->processChildProcs($childProcs);
  503.         }//end if
  504.  
  505.         restore_error_handler();
  506.  
  507.         if (PHP_CODESNIFFER_VERBOSITY === 0
  508.             && $this->config->interactive === false
  509.             && $this->config->showProgress === true
  510.         {
  511.             echo PHP_EOL.PHP_EOL;
  512.         }
  513.  
  514.         if ($this->config->cache === true{
  515.             Cache::save();
  516.         }
  517.  
  518.         $ignoreWarnings = Config::getConfigData('ignore_warnings_on_exit');
  519.         $ignoreErrors   = Config::getConfigData('ignore_errors_on_exit');
  520.  
  521.         $return ($this->reporter->totalErrors + $this->reporter->totalWarnings);
  522.         if ($ignoreErrors !== null{
  523.             $ignoreErrors = (bool) $ignoreErrors;
  524.             if ($ignoreErrors === true{
  525.                 $return -= $this->reporter->totalErrors;
  526.             }
  527.         }
  528.  
  529.         if ($ignoreWarnings !== null{
  530.             $ignoreWarnings = (bool) $ignoreWarnings;
  531.             if ($ignoreWarnings === true{
  532.                 $return -= $this->reporter->totalWarnings;
  533.             }
  534.         }
  535.  
  536.         return $return;
  537.  
  538.     }//end run()
  539.  
  540.  
  541.     /**
  542.      * Converts all PHP errors into exceptions.
  543.      *
  544.      * This method forces a sniff to stop processing if it is not
  545.      * able to handle a specific piece of code, instead of continuing
  546.      * and potentially getting into a loop.
  547.      *
  548.      * @param int    $code    The level of error raised.
  549.      * @param string $message The error message.
  550.      * @param string $file    The path of the file that raised the error.
  551.      * @param int    $line    The line number the error was raised at.
  552.      *
  553.      * @return void 
  554.      */
  555.     public function handleErrors($code$message$file$line)
  556.     {
  557.         throw new RuntimeException("$message in $file on line $line");
  558.  
  559.     }//end handleErrors()
  560.  
  561.  
  562.     /**
  563.      * Processes a single file, including checking and fixing.
  564.      *
  565.      * @param \PHP_CodeSniffer\Files\File $file The file to be processed.
  566.      *
  567.      * @return void 
  568.      */
  569.     public function processFile($file)
  570.     {
  571.         if (PHP_CODESNIFFER_VERBOSITY > 0{
  572.             $startTime microtime(true);
  573.             echo 'Processing '.basename($file->path).' ';
  574.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  575.                 echo PHP_EOL;
  576.             }
  577.         }
  578.  
  579.         try {
  580.             $file->process();
  581.  
  582.             if (PHP_CODESNIFFER_VERBOSITY > 0{
  583.                 $timeTaken ((microtime(true$startTime* 1000);
  584.                 if ($timeTaken < 1000{
  585.                     $timeTaken round($timeTaken);
  586.                     echo "DONE in {$timeTaken}ms";
  587.                 else {
  588.                     $timeTaken round(($timeTaken / 1000)2);
  589.                     echo "DONE in $timeTaken secs";
  590.                 }
  591.  
  592.                 if (PHP_CODESNIFFER_CBF === true{
  593.                     $errors $file->getFixableCount();
  594.                     echo " ($errors fixable violations)".PHP_EOL;
  595.                 else {
  596.                     $errors   $file->getErrorCount();
  597.                     $warnings $file->getWarningCount();
  598.                     echo " ($errors errors, $warnings warnings)".PHP_EOL;
  599.                 }
  600.             }
  601.         catch (\Exception $e{
  602.             $error 'An error occurred during processing; checking has been aborted. The error message was: '.$e->getMessage();
  603.             $file->addErrorOnLine($error1'Internal.Exception');
  604.         }//end try
  605.  
  606.         $this->reporter->cacheFileReport($file$this->config);
  607.  
  608.         if ($this->config->interactive === true{
  609.             /*
  610.                 Running interactively.
  611.                 Print the error report for the current file and then wait for user input.
  612.             */
  613.  
  614.             // Get current violations and then clear the list to make sure
  615.             // we only print violations for a single file each time.
  616.             $numErrors = null;
  617.             while ($numErrors !== 0{
  618.                 $numErrors ($file->getErrorCount($file->getWarningCount());
  619.                 if ($numErrors === 0{
  620.                     continue;
  621.                 }
  622.  
  623.                 $this->reporter->printReport('full');
  624.  
  625.                 echo '<ENTER> to recheck, [s] to skip or [q] to quit : ';
  626.                 $input fgets(STDIN);
  627.                 $input trim($input);
  628.  
  629.                 switch ($input{
  630.                 case 's':
  631.                     break(2);
  632.                 case 'q':
  633.                     throw new DeepExitException(''0);
  634.                 default:
  635.                     // Repopulate the sniffs because some of them save their state
  636.                     // and only clear it when the file changes, but we are rechecking
  637.                     // the same file.
  638.                     $file->ruleset->populateTokenListeners();
  639.                     $file->reloadContent();
  640.                     $file->process();
  641.                     $this->reporter->cacheFileReport($file$this->config);
  642.                     break;
  643.                 }
  644.             }//end while
  645.         }//end if
  646.  
  647.         // Clean up the file to save (a lot of) memory.
  648.         $file->cleanUp();
  649.  
  650.     }//end processFile()
  651.  
  652.  
  653.     /**
  654.      * Waits for child processes to complete and cleans up after them.
  655.      *
  656.      * The reporting information returned by each child process is merged
  657.      * into the main reporter class.
  658.      *
  659.      * @param array $childProcs An array of child processes to wait for.
  660.      *
  661.      * @return void 
  662.      */
  663.     private function processChildProcs($childProcs)
  664.     {
  665.         $numProcessed = 0;
  666.         $totalBatches count($childProcs);
  667.  
  668.         while (count($childProcs> 0{
  669.             foreach ($childProcs as $key => $procData{
  670.                 $res pcntl_waitpid($procData['pid']$statusWNOHANG);
  671.                 if ($res === $procData['pid']{
  672.                     if (file_exists($procData['out']=== true{
  673.                         include $procData['out'];
  674.                         if (isset($childOutput=== true{
  675.                             $this->reporter->totalFiles    += $childOutput['totalFiles'];
  676.                             $this->reporter->totalErrors   += $childOutput['totalErrors'];
  677.                             $this->reporter->totalWarnings += $childOutput['totalWarnings'];
  678.                             $this->reporter->totalFixable  += $childOutput['totalFixable'];
  679.                             $this->reporter->totalFixed    += $childOutput['totalFixed'];
  680.                         }
  681.  
  682.                         if (isset($debugOutput=== true{
  683.                             echo $debugOutput;
  684.                         }
  685.  
  686.                         if (isset($childCache=== true{
  687.                             foreach ($childCache as $path => $cache{
  688.                                 Cache::set($path$cache);
  689.                             }
  690.                         }
  691.  
  692.                         unlink($procData['out']);
  693.                         unset($childProcs[$key]);
  694.  
  695.                         $numProcessed++;
  696.  
  697.                         // Fake a processed file so we can print progress output for the batch.
  698.                         $file = new DummyFile(null$this->ruleset$this->config);
  699.                         $file->setErrorCounts(
  700.                             $childOutput['totalErrors'],
  701.                             $childOutput['totalWarnings'],
  702.                             $childOutput['totalFixable'],
  703.                             $childOutput['totalFixed']
  704.                         );
  705.                         $this->printProgress($file$totalBatches$numProcessed);
  706.                     }//end if
  707.                 }//end if
  708.             }//end foreach
  709.         }//end while
  710.  
  711.     }//end processChildProcs()
  712.  
  713.  
  714.     /**
  715.      * Print progress information for a single processed file.
  716.      *
  717.      * @param File $file         The file that was processed.
  718.      * @param int  $numFiles     The total number of files to process.
  719.      * @param int  $numProcessed The number of files that have been processed,
  720.      *                            including this one.
  721.      *
  722.      * @return void 
  723.      */
  724.     function printProgress($file$numFiles$numProcessed)
  725.     {
  726.         if (PHP_CODESNIFFER_VERBOSITY > 0
  727.             || $this->config->showProgress === false
  728.         {
  729.             return;
  730.         }
  731.  
  732.         // Show progress information.
  733.         if ($file->ignored === true{
  734.             echo 'S';
  735.         else {
  736.             $errors   $file->getErrorCount();
  737.             $warnings $file->getWarningCount();
  738.             $fixable  $file->getFixableCount();
  739.             $fixed    $file->getFixedCount();
  740.  
  741.             if (PHP_CODESNIFFER_CBF === true{
  742.                 // Files with fixed errors or warnings are F (green).
  743.                 // Files with unfixable errors or warnings are E (red).
  744.                 // Files with no errors or warnings are . (black).
  745.                 if ($fixable > 0{
  746.                     if ($this->config->colors === true{
  747.                         echo "\033[31m";
  748.                     }
  749.  
  750.                     echo 'E';
  751.  
  752.                     if ($this->config->colors === true{
  753.                         echo "\033[0m";
  754.                     }
  755.                 else if ($fixed > 0{
  756.                     if ($this->config->colors === true{
  757.                         echo "\033[32m";
  758.                     }
  759.  
  760.                     echo 'F';
  761.  
  762.                     if ($this->config->colors === true{
  763.                         echo "\033[0m";
  764.                     }
  765.                 else {
  766.                     echo '.';
  767.                 }//end if
  768.             else {
  769.                 // Files with errors are E (red).
  770.                 // Files with fixable errors are E (green).
  771.                 // Files with warnings are W (yellow).
  772.                 // Files with fixable warnings are W (green).
  773.                 // Files with no errors or warnings are . (black).
  774.                 if ($errors > 0{
  775.                     if ($this->config->colors === true{
  776.                         if ($fixable > 0{
  777.                             echo "\033[32m";
  778.                         else {
  779.                             echo "\033[31m";
  780.                         }
  781.                     }
  782.  
  783.                     echo 'E';
  784.  
  785.                     if ($this->config->colors === true{
  786.                         echo "\033[0m";
  787.                     }
  788.                 else if ($warnings > 0{
  789.                     if ($this->config->colors === true{
  790.                         if ($fixable > 0{
  791.                             echo "\033[32m";
  792.                         else {
  793.                             echo "\033[33m";
  794.                         }
  795.                     }
  796.  
  797.                     echo 'W';
  798.  
  799.                     if ($this->config->colors === true{
  800.                         echo "\033[0m";
  801.                     }
  802.                 else {
  803.                     echo '.';
  804.                 }//end if
  805.             }//end if
  806.         }//end if
  807.  
  808.         $numPerLine = 60;
  809.         if ($numProcessed !== $numFiles && ($numProcessed $numPerLine!== 0{
  810.             return;
  811.         }
  812.  
  813.         $percent round(($numProcessed $numFiles* 100);
  814.         $padding (strlen($numFilesstrlen($numProcessed));
  815.         if ($numProcessed === $numFiles && $numFiles $numPerLine{
  816.             $padding += ($numPerLine ($numFiles (floor($numFiles $numPerLine$numPerLine)));
  817.         }
  818.  
  819.         echo str_repeat(' '$padding)." $numProcessed / $numFiles ($percent%)".PHP_EOL;
  820.  
  821.     }//end printProgress()
  822.  
  823.  
  824. }//end class

Documentation generated on Mon, 11 Mar 2019 15:27:44 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.