/** * Runs PHP_CodeSniffer over files and directories. * * @param array $values An array of values determined from CLI args. * * @return int The number of error and warning messages shown. * @see getCommandLineValues() */ public function process($values = array()) { if (empty($values) === true) { $values = $this->getCommandLineValues(); } else { $values = array_merge($this->getDefaults(), $values); $this->values = $values; } if ($values['generator'] !== '') { $phpcs = new PHP_CodeSniffer($values['verbosity']); if ($values['standard'] === null) { $values['standard'] = $this->validateStandard(null); } foreach ($values['standard'] as $standard) { $phpcs->generateDocs($standard, $values['sniffs'], $values['generator']); } exit(0); } // If no standard is supplied, get the default. $values['standard'] = $this->validateStandard($values['standard']); foreach ($values['standard'] as $standard) { if (PHP_CodeSniffer::isInstalledStandard($standard) === false) { // They didn't select a valid coding standard, so help them // out by letting them know which standards are installed. echo 'ERROR: the "' . $standard . '" coding standard is not installed. '; $this->printInstalledStandards(); exit(2); } } if ($values['explain'] === true) { foreach ($values['standard'] as $standard) { $this->explainStandard($standard); } exit(0); } $phpcs = new PHP_CodeSniffer($values['verbosity'], null, null, null); $phpcs->setCli($this); $phpcs->initStandard($values['standard'], $values['sniffs']); $values = $this->values; $phpcs->setTabWidth($values['tabWidth']); $phpcs->setEncoding($values['encoding']); $phpcs->setInteractive($values['interactive']); // Set file extensions if they were specified. Otherwise, // let PHP_CodeSniffer decide on the defaults. if (empty($values['extensions']) === false) { $phpcs->setAllowedFileExtensions($values['extensions']); } // Set ignore patterns if they were specified. if (empty($values['ignored']) === false) { $ignorePatterns = array_merge($phpcs->getIgnorePatterns(), $values['ignored']); $phpcs->setIgnorePatterns($ignorePatterns); } // Set some convenience member vars. if ($values['errorSeverity'] === null) { $this->errorSeverity = PHPCS_DEFAULT_ERROR_SEV; } else { $this->errorSeverity = $values['errorSeverity']; } if ($values['warningSeverity'] === null) { $this->warningSeverity = PHPCS_DEFAULT_WARN_SEV; } else { $this->warningSeverity = $values['warningSeverity']; } if (empty($values['reports']) === true) { $values['reports']['full'] = $values['reportFile']; $this->values['reports'] = $values['reports']; } // Include bootstrap files. foreach ($values['bootstrap'] as $bootstrap) { include $bootstrap; } $phpcs->processFiles($values['files'], $values['local']); if (empty($values['files']) === true || $values['stdin'] !== null) { $fileContents = $values['stdin']; if ($fileContents === null) { // Check if they are passing in the file contents. $handle = fopen('php://stdin', 'r'); stream_set_blocking($handle, true); $fileContents = stream_get_contents($handle); fclose($handle); } if ($fileContents === '') { // No files and no content passed in. echo 'ERROR: You must supply at least one file or directory to process.' . PHP_EOL . PHP_EOL; $this->printUsage(); exit(2); } else { $phpcs->processFile('STDIN', $fileContents); } } // Interactive runs don't require a final report and it doesn't really // matter what the retun value is because we know it isn't being read // by a script. if ($values['interactive'] === true) { return 0; } return $this->printErrorReport($phpcs, $values['reports'], $values['showSources'], $values['reportFile'], $values['reportWidth']); }
public function testPlugins() { $plugin_path = dirname(__FILE__) . '/../../fannie/modules/plugins2.0/'; $first = array('CwReportDataSource' => ''); $files = array(); foreach (FannieAPI::listFiles($plugin_path) as $file) { $class = substr(basename($file), 0, strlen(basename($file)) - 4); if (isset($first[$class])) { $first[$class] = $file; } else { $files[] = $file; } } foreach ($first as $class => $file) { array_unshift($files, $file); } $functions = get_defined_functions(); $sniffer = null; $standard = dirname(__FILE__) . '/CodingStandard/CORE_PSR1/'; if (getenv('TRAVIS') === false && class_exists('PHP_CodeSniffer')) { $sniffer = new PHP_CodeSniffer(); $sniffer->initStandard($standard); $sniffer->cli->setCommandLineValues(array('--report=Json')); $sniffer->cli->setCommandLineValues($files); $sniffer->processFiles($files); ob_start(); $sniffer->reporting->printReport('Json', true, $sniffer->cli->getCommandLineValues(), null); $json = ob_get_clean(); $json = json_decode($json, true); $errors = 0; $errorMsg = ''; $json = $json['files']; foreach ($json as $filename => $jsonfile) { foreach ($jsonfile['messages'] as $message) { if ($message['type'] == 'ERROR') { $errors++; $errorMsg .= $filename . ': ' . $message['message'] . "\n"; } else { echo "Coding Standard Warning: " . $filename . ': ' . $message['message'] . "\n"; } } } $this->assertEquals(0, $errors, $errorMsg); } else { echo "PHP_CodeSniffer is not installed. This test will be less effective.\n"; echo "Use composer to install it.\n"; } foreach ($files as $file) { $file = realpath($file); $class_name = substr(basename($file), 0, strlen(basename($file)) - 4); $namespaced_class_name = FannieAPI::pathToClass($file); if (class_exists($class_name, false)) { // may have already been included $reflect = new ReflectionClass($class_name); $this->assertEquals($file, $reflect->getFileName(), $class_name . ' is defined by ' . $file . ' AND ' . $reflect->getFileName()); } elseif (class_exists($namespaced_class_name, false)) { // may have already been included $reflect = new ReflectionClass($namespaced_class_name); $this->assertEquals($file, $reflect->getFileName(), $namespaced_class_name . ' is defined by ' . $file . ' AND ' . $reflect->getFileName()); } else { ob_start(); include $file; $output = ob_get_clean(); $this->assertEquals('', $output, $file . ' produces output when included'); $current_functions = get_defined_functions(); $this->assertEquals(count($functions['user']), count($current_functions['user']), $file . ' has defined additional functions: ' . $this->detailedFunctionDiff($current_functions['user'], $functions['user'])); $classes = get_declared_classes(); $this->assertThat($classes, $this->logicalOr($this->contains($class_name), $this->contains($namespaced_class_name), $this->contains(ltrim($namespaced_class_name, '\\'))), $file . ' does not define ' . $class_name . ' or ' . $namespaced_class_name); } } }