diff --git a/README.md b/README.md index c247fbeb..682edc72 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,20 @@ referenced from other script configurations, as follows: For more details about Composer scripts, please refer to [the section on scripts in the Composer manual][composer-manual-scripts]. +### Changing the Coding Standards search depth + +By default, this plugin searches up for Coding Standards up to three directories +deep. In most cases, this should be sufficient. However, this plugin allows +you to customize the search depth setting if needed. + +```json +{ + "extra": { + "phpcodesniffer-search-depth": 5 + } +} +``` + ### Caveats When this plugin is installed globally, composer will load the _global_ plugin rather diff --git a/src/Plugin.php b/src/Plugin.php index 6a10f780..f36a7774 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -32,6 +32,11 @@ */ class Plugin implements PluginInterface, EventSubscriberInterface { + + const KEY_MAX_DEPTH = 'phpcodesniffer-search-depth'; + + const MESSAGE_ERROR_WRONG_MAX_DEPTH = + 'The value of "%s" (in the composer.json "extra".section) must be an integer larger then %d, %s given.'; const MESSAGE_RUNNING_INSTALLER = 'Running PHPCodeSniffer Composer Installer'; const MESSAGE_NOTHING_TO_INSTALL = 'Nothing to install or update'; const MESSAGE_NOT_INSTALLED = 'PHPCodeSniffer is not installed'; @@ -280,15 +285,11 @@ private function updateInstalledPaths() $finder->files() ->ignoreUnreadableDirs() ->ignoreVCS(true) - ->depth('< 4') + ->depth('<= ' . $this->getMaxDepth()) + ->depth('>= ' . $this->getMinDepth()) ->name('ruleset.xml') ->in($searchPaths); - // Only version 3.x and higher has support for having coding standard in the root of the directory. - if ($this->isPHPCodeSnifferInstalled('>= 3.0.0') !== true) { - $finder->depth('>= 1'); - } - // Process each found possible ruleset. foreach ($finder as $ruleset) { $standardsPath = $ruleset->getPath(); @@ -437,4 +438,56 @@ private function getRelativePath($to) } return implode('/', $relPath); } + + /** + * Determines the maximum search depth when searching for Coding Standards. + * + * @return int + * + * @throws \InvalidArgumentException + */ + private function getMaxDepth() + { + $maxDepth = 3; + + $extra = $this->composer->getPackage()->getExtra(); + + if (array_key_exists(self::KEY_MAX_DEPTH, $extra)) { + $maxDepth = $extra[self::KEY_MAX_DEPTH]; + $minDepth = $this->getMinDepth(); + + if (is_int($maxDepth) === false /* Must be an integer */ + || $maxDepth <= $minDepth /* Larger than the minimum */ + || is_float($maxDepth) === true /* Within the boundaries of integer */ + ) { + $message = vsprintf( + self::MESSAGE_ERROR_WRONG_MAX_DEPTH, + array( + 'key' => self::KEY_MAX_DEPTH, + 'min' => $minDepth, + 'given' => var_export($maxDepth, true), + ) + ); + + throw new \InvalidArgumentException($message); + } + } + + return $maxDepth; + } + + /** + * Returns the minimal search depth for Coding Standard packages. + * + * Usually this is 0, unless PHP_CodeSniffer >= 3 is used. + * + * @return int + */ + private function getMinDepth() + { + if ($this->isPHPCodeSnifferInstalled('>= 3.0.0') !== true) { + return 1; + } + return 0; + } }