From 9fd0a8616d6d21a692ad682540aa2b6b24d95585 Mon Sep 17 00:00:00 2001 From: mscherer Date: Fri, 22 Nov 2024 03:40:30 +0100 Subject: [PATCH] Wildcard for plugin option. --- .gitignore | 1 + docs/Annotations.md | 3 + src/Command/Annotate/CallbacksCommand.php | 14 ++--- src/Command/Annotate/ClassesCommand.php | 31 +++++---- src/Command/Annotate/CommandsCommand.php | 8 +-- src/Command/Annotate/ComponentsCommand.php | 9 +-- src/Command/Annotate/ControllersCommand.php | 8 +-- src/Command/Annotate/HelpersCommand.php | 9 +-- src/Command/Annotate/ModelsCommand.php | 9 +-- src/Command/Annotate/TemplatesCommand.php | 8 +-- src/Command/AnnotateCommand.php | 69 ++++++++++++++++++++- 11 files changed, 110 insertions(+), 59 deletions(-) diff --git a/.gitignore b/.gitignore index 05d1ab23..567e7224 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /phpunit.phar /.phpunit.result.cache +/.phpunit.cache/ /vendor/ /tmp/ /composer.lock diff --git a/docs/Annotations.md b/docs/Annotations.md index 005f28f6..26b4f004 100644 --- a/docs/Annotations.md +++ b/docs/Annotations.md @@ -39,6 +39,9 @@ You get autocompletion on any `$this->Apples->...()` usage in your controllers t Use `-p PluginName` to annotate inside a plugin. It will then use the plugin name as namespace. +Tip: Use `*` wildcard to refer to a group of plugins. Make sure to only touch internal plugins (in version control), however. +E.g. `-p SomePrefix/*` which are all inside your own `plugins/` directory - and not in `vendor/`. + ### Primary model via $modelClass definition When defining `$modelClass` it will be used instead: ```php diff --git a/src/Command/Annotate/CallbacksCommand.php b/src/Command/Annotate/CallbacksCommand.php index a20a0c6d..d0ee1232 100644 --- a/src/Command/Annotate/CallbacksCommand.php +++ b/src/Command/Annotate/CallbacksCommand.php @@ -6,7 +6,6 @@ use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; use Cake\Core\Configure; -use Cake\Core\Plugin; use IdeHelper\Annotator\CallbackAnnotator; use IdeHelper\Command\AnnotateCommand; @@ -38,13 +37,12 @@ protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOption public function execute(Arguments $args, ConsoleIo $io): int { parent::execute($args, $io); - $plugin = (string)$args->getOption('plugin') ?: null; - - $path = $plugin ? Plugin::classPath($plugin) : ROOT . DS . APP_DIR . DS; - - $folders = glob($path . '*', GLOB_ONLYDIR) ?: []; - foreach ($folders as $folder) { - $this->_callbacks($folder . DS); + $paths = $this->getPaths(); + foreach ($paths as $path) { + $folders = glob($path . '*', GLOB_ONLYDIR) ?: []; + foreach ($folders as $folder) { + $this->_callbacks($folder . DS); + } } if ($args->getOption('ci') && $this->_annotatorMadeChanges()) { diff --git a/src/Command/Annotate/ClassesCommand.php b/src/Command/Annotate/ClassesCommand.php index 8471cc7e..41dedc89 100644 --- a/src/Command/Annotate/ClassesCommand.php +++ b/src/Command/Annotate/ClassesCommand.php @@ -6,7 +6,6 @@ use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; use Cake\Core\Configure; -use Cake\Core\Plugin; use IdeHelper\Annotator\ClassAnnotator; use IdeHelper\Annotator\ClassAnnotatorTask\TestClassAnnotatorTask; use IdeHelper\Annotator\ClassAnnotatorTaskCollection; @@ -40,13 +39,12 @@ protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOption public function execute(Arguments $args, ConsoleIo $io): int { parent::execute($args, $io); - $plugin = (string)$args->getOption('plugin') ?: null; - - $path = $plugin ? Plugin::classPath($plugin) : ROOT . DS . APP_DIR . DS; - - $folders = glob($path . '*', GLOB_ONLYDIR) ?: []; - foreach ($folders as $folder) { - $this->_classes($folder . DS); + $paths = $this->getPaths(); + foreach ($paths as $path) { + $folders = glob($path . '*', GLOB_ONLYDIR) ?: []; + foreach ($folders as $folder) { + $this->_classes($folder . DS); + } } $collection = new ClassAnnotatorTaskCollection(); @@ -55,15 +53,16 @@ public function execute(Arguments $args, ConsoleIo $io): int { return static::CODE_SUCCESS; } - $path = $plugin ? Plugin::path($plugin) : ROOT . DS; - $path .= 'tests' . DS . 'TestCase' . DS; - if (!is_dir($path)) { - return static::CODE_SUCCESS; - } + foreach ($paths as $path) { + $path .= 'tests' . DS . 'TestCase' . DS; + if (!is_dir($path)) { + continue; + } - $folders = glob($path . '*', GLOB_ONLYDIR) ?: []; - foreach ($folders as $folder) { - $this->_classes($folder . DS); + $folders = glob($path . '*', GLOB_ONLYDIR) ?: []; + foreach ($folders as $folder) { + $this->_classes($folder . DS); + } } if ($args->getOption('ci') && $this->_annotatorMadeChanges()) { diff --git a/src/Command/Annotate/CommandsCommand.php b/src/Command/Annotate/CommandsCommand.php index d6ccc5c9..f5ba3ffd 100644 --- a/src/Command/Annotate/CommandsCommand.php +++ b/src/Command/Annotate/CommandsCommand.php @@ -4,7 +4,6 @@ use Cake\Console\Arguments; use Cake\Console\ConsoleIo; -use Cake\Core\App; use IdeHelper\Annotator\CommandAnnotator; use IdeHelper\Command\AnnotateCommand; @@ -25,11 +24,10 @@ public static function getDescription(): string { public function execute(Arguments $args, ConsoleIo $io): int { parent::execute($args, $io); - $plugin = (string)$args->getOption('plugin') ?: null; - $folders = App::classPath('Command', $plugin); + $paths = $this->getPaths('Command'); - foreach ($folders as $folder) { - $this->_commands($folder); + foreach ($paths as $path) { + $this->_commands($path); } if ($args->getOption('ci') && $this->_annotatorMadeChanges()) { diff --git a/src/Command/Annotate/ComponentsCommand.php b/src/Command/Annotate/ComponentsCommand.php index 892ce4e0..17614d49 100644 --- a/src/Command/Annotate/ComponentsCommand.php +++ b/src/Command/Annotate/ComponentsCommand.php @@ -4,7 +4,6 @@ use Cake\Console\Arguments; use Cake\Console\ConsoleIo; -use Cake\Core\App; use IdeHelper\Annotator\ComponentAnnotator; use IdeHelper\Command\AnnotateCommand; @@ -25,11 +24,9 @@ public static function getDescription(): string { public function execute(Arguments $args, ConsoleIo $io): int { parent::execute($args, $io); - $plugin = (string)$args->getOption('plugin') ?: null; - $folders = App::classPath('Controller/Component', $plugin); - - foreach ($folders as $folder) { - $this->_components($folder); + $paths = $this->getPaths('Controller/Component'); + foreach ($paths as $path) { + $this->_components($path); } if ($args->getOption('ci') && $this->_annotatorMadeChanges()) { diff --git a/src/Command/Annotate/ControllersCommand.php b/src/Command/Annotate/ControllersCommand.php index 47d22928..3488d2f3 100644 --- a/src/Command/Annotate/ControllersCommand.php +++ b/src/Command/Annotate/ControllersCommand.php @@ -4,7 +4,6 @@ use Cake\Console\Arguments; use Cake\Console\ConsoleIo; -use Cake\Core\App; use Cake\Core\Configure; use IdeHelper\Annotator\ControllerAnnotator; use IdeHelper\Command\AnnotateCommand; @@ -26,11 +25,10 @@ public static function getDescription(): string { public function execute(Arguments $args, ConsoleIo $io): int { parent::execute($args, $io); - $plugin = (string)$args->getOption('plugin') ?: null; - $folders = App::classPath('Controller', $plugin); + $paths = $this->getPaths('Controller'); - foreach ($folders as $folder) { - $this->_controllers($folder); + foreach ($paths as $path) { + $this->_controllers($path); } if ($args->getOption('ci') && $this->_annotatorMadeChanges()) { diff --git a/src/Command/Annotate/HelpersCommand.php b/src/Command/Annotate/HelpersCommand.php index 6f5ec81e..a990ebfd 100644 --- a/src/Command/Annotate/HelpersCommand.php +++ b/src/Command/Annotate/HelpersCommand.php @@ -4,7 +4,6 @@ use Cake\Console\Arguments; use Cake\Console\ConsoleIo; -use Cake\Core\App; use IdeHelper\Annotator\HelperAnnotator; use IdeHelper\Command\AnnotateCommand; @@ -25,11 +24,9 @@ public static function getDescription(): string { public function execute(Arguments $args, ConsoleIo $io): int { parent::execute($args, $io); - $plugin = (string)$args->getOption('plugin') ?: null; - $folders = App::classPath('View/Helper', $plugin); - - foreach ($folders as $folder) { - $this->_helpers($folder); + $paths = $this->getPaths('View/Helper'); + foreach ($paths as $path) { + $this->_helpers($path); } if ($args->getOption('ci') && $this->_annotatorMadeChanges()) { diff --git a/src/Command/Annotate/ModelsCommand.php b/src/Command/Annotate/ModelsCommand.php index 9f7e7ea1..9dd622d5 100644 --- a/src/Command/Annotate/ModelsCommand.php +++ b/src/Command/Annotate/ModelsCommand.php @@ -4,7 +4,6 @@ use Cake\Console\Arguments; use Cake\Console\ConsoleIo; -use Cake\Core\App; use IdeHelper\Annotator\ModelAnnotator; use IdeHelper\Command\AnnotateCommand; @@ -25,11 +24,9 @@ public static function getDescription(): string { public function execute(Arguments $args, ConsoleIo $io): int { parent::execute($args, $io); - $plugin = (string)$args->getOption('plugin') ?: null; - $folders = App::classPath('Model/Table', $plugin); - - foreach ($folders as $folder) { - $this->_models($folder); + $paths = $this->getPaths('Model/Table'); + foreach ($paths as $path) { + $this->_models($path); } if ($args->getOption('ci') && $this->_annotatorMadeChanges()) { diff --git a/src/Command/Annotate/TemplatesCommand.php b/src/Command/Annotate/TemplatesCommand.php index 85c63f60..c022e9d6 100644 --- a/src/Command/Annotate/TemplatesCommand.php +++ b/src/Command/Annotate/TemplatesCommand.php @@ -4,7 +4,6 @@ use Cake\Console\Arguments; use Cake\Console\ConsoleIo; -use Cake\Core\App; use IdeHelper\Annotator\TemplateAnnotator; use IdeHelper\Command\AnnotateCommand; @@ -25,11 +24,10 @@ public static function getDescription(): string { public function execute(Arguments $args, ConsoleIo $io): int { parent::execute($args, $io); - $plugin = (string)$args->getOption('plugin') ?: null; - $folders = App::path('templates', $plugin); + $paths = $this->getPaths('templates'); - foreach ($folders as $folder) { - $this->_templates($folder); + foreach ($paths as $path) { + $this->_templates($path); } if ($args->getOption('ci') && $this->_annotatorMadeChanges()) { diff --git a/src/Command/AnnotateCommand.php b/src/Command/AnnotateCommand.php index 825079cd..1a6a6162 100644 --- a/src/Command/AnnotateCommand.php +++ b/src/Command/AnnotateCommand.php @@ -9,6 +9,10 @@ use Cake\Core\Configure; use IdeHelper\Annotator\AbstractAnnotator; use IdeHelper\Console\Io; +use IdeHelper\Utility\App; +use IdeHelper\Utility\AppPath; +use IdeHelper\Utility\Plugin; +use IdeHelper\Utility\PluginPath; abstract class AnnotateCommand extends Command { @@ -96,7 +100,7 @@ protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOption ], 'plugin' => [ 'short' => 'p', - 'help' => 'The plugin to run. Defaults to the application otherwise.', + 'help' => 'The plugin(s) to run. Defaults to the application otherwise. Supports wildcard `*` for partial match.', 'default' => null, ], 'remove' => [ @@ -147,7 +151,7 @@ protected function _shouldSkip(string $fileName): bool { return false; } - return !(bool)preg_match('/' . preg_quote($filter, '/') . '/i', $fileName); + return !preg_match('/' . preg_quote($filter, '/') . '/i', $fileName); } /** @@ -190,4 +194,65 @@ protected function _annotatorMadeChanges(): bool { return AbstractAnnotator::$output !== false; } + /** + * @param string|null $type + * @return array + */ + protected function getPaths(?string $type = null): array { + $plugin = (string)$this->args->getOption('plugin') ?: null; + if (!$plugin) { + if (!$type) { + return [ROOT . DS . APP_DIR . DS]; + } + + return $type === 'templates' ? App::path('templates') : AppPath::get($type); + } + + $plugins = $this->getPlugins($plugin); + + $paths = []; + foreach ($plugins as $plugin) { + if (!$type) { + $pluginPaths = [PluginPath::classPath($plugin)]; + } else { + $pluginPaths = $type === 'templates' ? App::path('templates', $plugin) : AppPath::get($type, $plugin); + } + foreach ($pluginPaths as $pluginPath) { + $paths[] = $pluginPath; + } + } + + return $paths; + } + + /** + * @param string $plugin + * + * @return array + */ + protected function getPlugins(string $plugin): array { + if (!str_contains($plugin, '*')) { + return [$plugin]; + } + + $loaded = Plugin::loaded(); + $plugins = []; + foreach ($loaded as $name) { + $plugins[Plugin::path($name)] = $name; + } + + return $this->filterPlugins($plugins, $plugin); + } + + /** + * @param array $plugins + * @param string $pattern + * @return array + */ + protected function filterPlugins(array $plugins, string $pattern): array { + return array_filter($plugins, function($plugin, $path) use ($pattern) { + return fnmatch($pattern, $plugin); + }, ARRAY_FILTER_USE_BOTH); + } + }