1<?php 2/** 3 * Generic_Sniffs_Debug_ESLintSniff. 4 * 5 * PHP version 5 6 * 7 * @category PHP 8 * @package PHP_CodeSniffer 9 * @author Ryan McCue <ryan+gh@hmn.md> 10 * @copyright 2006-2017 Squiz Pty Ltd (ABN 77 084 670 600) 11 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 12 * @link http://pear.php.net/package/PHP_CodeSniffer 13 */ 14 15/** 16 * Generic_Sniffs_Debug_ESLintSniff. 17 * 18 * Runs eslint on the file. 19 * 20 * @category PHP 21 * @package PHP_CodeSniffer 22 * @author Ryan McCue <ryan+gh@hmn.md> 23 * @copyright 2006-2017 Squiz Pty Ltd (ABN 77 084 670 600) 24 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 25 * @version Release: @package_version@ 26 * @link http://pear.php.net/package/PHP_CodeSniffer 27 */ 28class Generic_Sniffs_Debug_ESLintSniff implements PHP_CodeSniffer_Sniff 29{ 30 /** 31 * A list of tokenizers this sniff supports. 32 * 33 * @var array 34 */ 35 public $supportedTokenizers = array('JS'); 36 37 38 /** 39 * ESLint configuration file path. 40 * 41 * @var string|null Path to eslintrc. Null to autodetect. 42 */ 43 public $configFile = null; 44 45 46 /** 47 * Returns the token types that this sniff is interested in. 48 * 49 * @return int[] 50 */ 51 public function register() 52 { 53 return array(T_OPEN_TAG); 54 55 }//end register() 56 57 58 /** 59 * Processes the tokens that this sniff is interested in. 60 * 61 * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. 62 * @param int $stackPtr The position in the stack where 63 * the token was found. 64 * 65 * @return void 66 */ 67 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 68 { 69 $filename = $phpcsFile->getFilename(); 70 $eslintPath = PHP_CodeSniffer::getConfigData('eslint_path'); 71 if ($eslintPath === null) { 72 return; 73 } 74 75 $configFile = $this->configFile; 76 if (empty($configFile) === true) { 77 // Attempt to autodetect. 78 $candidates = glob('.eslintrc{.js,.yaml,.yml,.json}', GLOB_BRACE); 79 if (empty($candidates) === false) { 80 $configFile = $candidates[0]; 81 } 82 } 83 84 $eslintOptions = array('--format json'); 85 if (empty($configFile) === false) { 86 $eslintOptions[] = '--config '.escapeshellarg($configFile); 87 } 88 89 $cmd = escapeshellcmd(escapeshellarg($eslintPath).' '.implode(' ', $eslintOptions).' '.escapeshellarg($filename)); 90 91 // Execute! 92 exec($cmd, $stdout, $code); 93 94 if ($code <= 0) { 95 // No errors, continue. 96 return ($phpcsFile->numTokens + 1); 97 } 98 99 $data = json_decode(implode("\n", $stdout)); 100 if (json_last_error() !== JSON_ERROR_NONE) { 101 // Ignore any errors. 102 return ($phpcsFile->numTokens + 1); 103 } 104 105 // Data is a list of files, but we only pass a single one. 106 $messages = $data[0]->messages; 107 foreach ($messages as $error) { 108 if (empty($error->fatal) === false || $error->severity === 2) { 109 $phpcsFile->addErrorOnLine($error->message, $error->line, $error->ruleId); 110 } else { 111 $phpcsFile->addWarningOnLine($error->message, $error->line, $error->ruleId); 112 } 113 } 114 115 // Ignore the rest of the file. 116 return ($phpcsFile->numTokens + 1); 117 118 }//end process() 119 120 121}//end class 122