Skip to content

Commit

Permalink
You can now specify a namespace for a custom coding standard, used by…
Browse files Browse the repository at this point in the history
… the autoloader to load non-sniff helper files (ref #1469)
  • Loading branch information
gsherwood committed May 19, 2017
1 parent 6673f85 commit 3fcd5e6
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 9 deletions.
16 changes: 11 additions & 5 deletions autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,13 @@ public static function load($class)

// See if the class is inside one of our alternate search paths.
if ($path === false) {
foreach (self::$searchPaths as $searchPath) {
$path = $searchPath.$ds.str_replace('\\', $ds, $class).'.php';
foreach (self::$searchPaths as $searchPath => $nsPrefix) {
$className = $class;
if ($nsPrefix !== '' && substr($class, 0, strlen($nsPrefix)) === $nsPrefix) {
$className = substr($class, (strlen($nsPrefix) + 1));
}

$path = $searchPath.$ds.str_replace('\\', $ds, $className).'.php';
if (is_file($path) === true) {
break;
}
Expand Down Expand Up @@ -194,13 +199,14 @@ public static function loadFile($path)
/**
* Adds a directory to search during autoloading.
*
* @param string $path The path to the directory to search.
* @param string $path The path to the directory to search.
* @param string $nsPrefix The namespace prefix used by files under this path.
*
* @return void
*/
public static function addSearchPath($path)
public static function addSearchPath($path, $nsPrefix='')
{
self::$searchPaths[] = $path;
self::$searchPaths[$path] = rtrim(trim((string) $nsPrefix), '\\');

}//end addSearchPath()

Expand Down
3 changes: 3 additions & 0 deletions package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
- The autoloader is now working correctly with classes created with class_alias()
- The autoloader will now search for files inside all directories in the installed_paths config var
-- This allows autoloading of files inside included custom coding standards without manually requiring them
- You can now specify a namespace for a custom coding standard, used by the autoloader to load non-sniff helper files
-- If ommitted, the namespace is assumed to be the same as the directory name containing the ruleset.xml file
-- This value does not need to be specified if you are not using helper files
- Fixed bug #1442 : T_NULLABLE detection not working for nullable parameters and return type hints in some cases
- Fixed bug #1447 : Running the unit tests with a phpunit config file breaks the test suite
-- Unknown arguments were not being handled correctly, but are now stored in $config->unknown
Expand Down
8 changes: 7 additions & 1 deletion src/Ruleset.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,13 @@ public function __construct(Config $config)
$this->paths[] = $standard;

// Allow autoloading of custom files inside this standard.
Autoload::addSearchPath(dirname(dirname($standard)));
if (isset($ruleset['namespace']) === true) {
$namespace = (string) $ruleset['namespace'];
} else {
$namespace = basename(dirname($standard));
}

Autoload::addSearchPath(dirname($standard), $namespace);
}

if (PHP_CODESNIFFER_VERBOSITY === 1) {
Expand Down
6 changes: 3 additions & 3 deletions src/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,9 @@ public function init()
$tokens = new Util\Tokens();

// Allow autoloading of custom files inside installed standards.
$installedPaths = Standards::getInstalledStandardPaths();
foreach ($installedPaths as $path) {
Autoload::addSearchPath($path);
$installedStandards = Standards::getInstalledStandardDetails();
foreach ($installedStandards as $name => $details) {
Autoload::addSearchPath($details['path'], $details['namespace']);
}

// The ruleset contains all the information about how the files
Expand Down
94 changes: 94 additions & 0 deletions src/Util/Standards.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,100 @@ public static function getInstalledStandardPaths()
}//end getInstalledStandardPaths()


/**
* Get the details of all coding standards installed.
*
* Coding standards are directories located in the
* CodeSniffer/Standards directory. Valid coding standards
* include a Sniffs subdirectory.
*
* The details returned for each standard are:
* - path: the path to the coding standard's main directory
* - name: the name of the coding standard, as sourced from the ruleset.xml file
* - namespace: the namespace used by the coding standard, as sourced from the ruleset.xml file
*
* If you don't need all the details of a coding standard,
* use getInstalledStandards() instead as it performs less work to
* retrieve coding standard names.
*
* @param boolean $includeGeneric If true, the special "Generic"
* coding standard will be included
* if installed.
* @param string $standardsDir A specific directory to look for standards
* in. If not specified, PHP_CodeSniffer will
* look in its default locations.
*
* @return array
* @see getInstalledStandards()
*/
public static function getInstalledStandardDetails(
$includeGeneric=false,
$standardsDir=''
) {
$rulesets = array();

if ($standardsDir === '') {
$installedPaths = self::getInstalledStandardPaths();
} else {
$installedPaths = array($standardsDir);
}

foreach ($installedPaths as $standardsDir) {
// Check if the installed dir is actually a standard itself.
$csFile = $standardsDir.'/ruleset.xml';
if (is_file($csFile) === true) {
$rulesets[] = $csFile;
continue;
}

$di = new \DirectoryIterator($standardsDir);
foreach ($di as $file) {
if ($file->isDir() === true && $file->isDot() === false) {
$filename = $file->getFilename();

// Ignore the special "Generic" standard.
if ($includeGeneric === false && $filename === 'Generic') {
continue;
}

// Valid coding standard dirs include a ruleset.
$csFile = $file->getPathname().'/ruleset.xml';
if (is_file($csFile) === true) {
$rulesets[] = $csFile;
}
}
}
}//end foreach

$installedStandards = array();

foreach ($rulesets as $rulesetPath) {
$ruleset = simplexml_load_string(file_get_contents($rulesetPath));
if ($ruleset === false) {
continue;
}

$standardName = (string) $ruleset['name'];
$dirname = basename(dirname($rulesetPath));

if (isset($ruleset['namespace']) === true) {
$namespace = (string) $ruleset['namespace'];
} else {
$namespace = $dirname;
}

$installedStandards[$dirname] = array(
'path' => dirname($rulesetPath),
'name' => $standardName,
'namespace' => $namespace,
);
}//end foreach

return $installedStandards;

}//end getInstalledStandardDetails()


/**
* Get a list of all coding standards installed.
*
Expand Down

0 comments on commit 3fcd5e6

Please sign in to comment.