Skip to content

Commit

Permalink
Allow requesting a custom report using the report name or FQN
Browse files Browse the repository at this point in the history
This allows for external standards to provide portable custom reports while installed in an arbitrary directory.

* The external standard has to make sure it includes an `<autoload>` directive in the ruleset and sort out the loading of the custom report classes through a `spl_autoload_register()`-ed autoloader.
* The name of the custom report class can be provided either on the command line using `--report=...` or via the ruleset using `<arg name="report" value=".."/>`.
* The name of the custom report class can be either the Fully Qualified report class name òr just the class name.
    - The FQN does not have to be prefixed with an `\`, but things will work just fine if it is.
    - If just the class name is provided, PHPCS will try to find the report in any of the namespaces as registered by the installed standards.
    - If the report class is not found in any of these, a `DeepExitException` will be thrown.

Fixes 1942
  • Loading branch information
jrfnl committed Mar 21, 2018
1 parent cfe7de3 commit 4233886
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
12 changes: 12 additions & 0 deletions autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,18 @@ public static function addSearchPath($path, $nsPrefix='')
}//end addSearchPath()


/**
* Retrieve the namespaces and paths registered by external standards.
*
* @return array
*/
public static function getSearchPaths()
{
return self::$searchPaths;

}//end getSearchPaths()


/**
* Gets the class name for the given file path.
*
Expand Down
27 changes: 26 additions & 1 deletion src/Reporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public function __construct(Config $config)
$output = $config->reportFile;
}

$reportClassName = '';
if (strpos($type, '.') !== false) {
// This is a path to a custom report class.
$filename = realpath($type);
Expand All @@ -114,8 +115,32 @@ public function __construct(Config $config)
}

$reportClassName = Autoload::loadFile($filename);
} else {
} else if (class_exists('PHP_CodeSniffer\Reports\\'.$type) === true) {
// PHPCS native report.
$reportClassName = 'PHP_CodeSniffer\Reports\\'.$type;
} else if (class_exists($type) === true) {
// FQN of a custom report.
$reportClassName = $type;
} else {
// OK, so not a FQN, try and find the report using the registered namespaces.
$registeredNamespaces = Autoload::getSearchPaths();
$trimmedType = ltrim($type, '\\');

foreach ($registeredNamespaces as $nsPrefix) {
if ($nsPrefix === '') {
continue;
}

if (class_exists($nsPrefix.'\\'.$trimmedType) === true) {
$reportClassName = $nsPrefix.'\\'.$trimmedType;
break;
}
}
}//end if

if ($reportClassName === '') {
$error = "ERROR: Class file for report \"$type\" not found".PHP_EOL;
throw new DeepExitException($error, 3);
}

$reportClass = new $reportClassName();
Expand Down

0 comments on commit 4233886

Please sign in to comment.