diff --git a/src/Command/PluginCommand.php b/src/Command/PluginCommand.php new file mode 100644 index 00000000..a7ae1bec --- /dev/null +++ b/src/Command/PluginCommand.php @@ -0,0 +1,75 @@ +plugins = $plugins; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('kimai:plugins') + ->setDescription('Receive plugin information') + ->setHelp('This command prints detailed plugin information.') + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + + $plugins = $this->plugins->getPlugins(); + if (empty($plugins)) { + $io->warning('No plugins installed'); + + return 0; + } + + $rows = []; + foreach ($plugins as $plugin) { + $this->plugins->loadMetadata($plugin); + $meta = $plugin->getMetadata(); + $rows[] = [ + $plugin->getName(), + $meta->getVersion(), + $meta->getKimaiVersion(), + $plugin->getPath(), + ]; + } + $io->table(['Name', 'Version', 'Requires', 'Directory'], $rows); + + return 0; + } +} diff --git a/src/Plugin/PluginManager.php b/src/Plugin/PluginManager.php index c229ae8f..ac0c52d5 100644 --- a/src/Plugin/PluginManager.php +++ b/src/Plugin/PluginManager.php @@ -80,7 +80,7 @@ class PluginManager } /** - * Call this method and pass a plugin, to set its metdata. + * Call this method and pass a plugin, to set its metadata. * This is not pre-filled by default, as it would mean to parse several composer.json on each request. * * @param Plugin $plugin diff --git a/tests/Command/PluginCommandTest.php b/tests/Command/PluginCommandTest.php new file mode 100644 index 00000000..113cefc9 --- /dev/null +++ b/tests/Command/PluginCommandTest.php @@ -0,0 +1,61 @@ +getMockBuilder(PluginInterface::class)->setMethods(['getName', 'getPath'])->getMock(); + $plugin1->expects($this->exactly(3))->method('getName')->willReturn('Test-Bundle'); + $plugin1->expects($this->once())->method('getPath')->willReturn(__DIR__); + + $plugin2 = $this->getMockBuilder(PluginInterface::class)->setMethods(['getName', 'getPath'])->getMock(); + $plugin2->expects($this->exactly(3))->method('getName')->willReturn('Another one'); + $plugin2->expects($this->once())->method('getPath')->willReturn('BundleDirectory'); + + $commandTester = $this->getCommandTester([$plugin1, $plugin2], []); + $output = $commandTester->getDisplay(); + $this->assertContains(__DIR__, $output); + $this->assertContains('BundleDirectory', $output); + $this->assertContains('Test-Bundle', $output); + $this->assertContains('Another one', $output); + } + + protected function getCommandTester(array $plugins, array $options = []) + { + $kernel = self::bootKernel(); + $this->application = new Application($kernel); + $this->application->add(new PluginCommand(new PluginManager($plugins))); + + $command = $this->application->find('kimai:plugins'); + $commandTester = new CommandTester($command); + $inputs = array_merge(['command' => $command->getName()], $options); + $commandTester->execute($inputs); + + return $commandTester; + } +}