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

Documentation generated on Mon, 11 Mar 2019 14:23:24 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.