Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add completion for pimcore:bundle:(un)install #16932

Open
wants to merge 1 commit into
base: 11.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 31 additions & 30 deletions bundles/CoreBundle/src/Command/Bundle/AbstractBundleCommand.php
Expand Up @@ -17,37 +17,28 @@

namespace Pimcore\Bundle\CoreBundle\Command\Bundle;

use InvalidArgumentException;
use Pimcore\Console\AbstractCommand;
use Pimcore\Extension\Bundle\Installer\InstallerInterface;
use Pimcore\Extension\Bundle\PimcoreBundleInterface;
use Pimcore\Extension\Bundle\PimcoreBundleManager;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;

/**
* @internal
*/
abstract class AbstractBundleCommand extends AbstractCommand
{
public function __construct(protected PimcoreBundleManager $bundleManager, ?string $name = null)
{
public function __construct(
protected PimcoreBundleManager $bundleManager,
?string $name = null
) {
parent::__construct($name);
}

/**
* @return $this
*/
protected function configureDescriptionAndHelp(string $description, string $help = null): static
{
if (null === $help) {
$help = 'Bundle can be passed as fully qualified class name or as bundle short name (e.g. <comment>PimcoreEcommerceFrameworkBundle</comment>).';
}

$this
->setDescription($description)
->setHelp(sprintf('%s. %s', $description, $help));

return $this;
}

/**
* @return $this
*/
Expand All @@ -63,22 +54,34 @@ protected function configureFailWithoutErrorOption(): static
return $this;
}

protected function buildName(string $name): string
protected function completeBundleArgument(CompletionInput $input, CompletionSuggestions $suggestions): void
{
return sprintf('pimcore:bundle:%s', $name);
if ($input->mustSuggestArgumentValuesFor('bundle') === true) {
$suggestions->suggestValues(
array_reduce(
$this->bundleManager->getActiveBundles(false),
static function (array $result, BundleInterface $bundle) {
$result[] = $bundle->getName();

return $result;
},
[]
)
);
}
}

protected function handlePrerequisiteError(string $message): int
{
if ($this->io->getInput()->getOption('fail-without-error')) {
$this->io->warning($message);

return 0;
} else {
$this->io->error($message);

return 1;
return self::SUCCESS;
}

$this->io->error($message);

return self::FAILURE;
}

protected function getBundle(): PimcoreBundleInterface
Expand All @@ -88,8 +91,6 @@ protected function getBundle(): PimcoreBundleInterface

$activeBundles = $this->bundleManager->getActiveBundles(false);

$bundle = null;

if (isset($activeBundles[$bundleId])) {
// try to load bundle via fully qualified class name first
$bundle = $activeBundles[$bundleId];
Expand All @@ -100,7 +101,7 @@ protected function getBundle(): PimcoreBundleInterface
}

if (!$bundle instanceof PimcoreBundleInterface) {
throw new \InvalidArgumentException(sprintf(
throw new InvalidArgumentException(sprintf(
'Bundle "%s" does not implement %s',
$bundle->getName(),
PimcoreBundleInterface::class
Expand All @@ -110,7 +111,7 @@ protected function getBundle(): PimcoreBundleInterface
return $bundle;
}

protected function setupInstaller(PimcoreBundleInterface $bundle): ?\Pimcore\Extension\Bundle\Installer\InstallerInterface
protected function setupInstaller(PimcoreBundleInterface $bundle): ?InstallerInterface
{
$installer = $this->bundleManager->getInstaller($bundle);
if (null === $installer) {
Expand All @@ -128,7 +129,7 @@ protected function normalizeBundleIdentifier(string $bundleIdentifier): string
protected function getShortClassName(string $className): ?string
{
if (!class_exists($className)) {
throw new \InvalidArgumentException(sprintf('Class "%s" does not exist', $className));
throw new InvalidArgumentException(sprintf('Class "%s" does not exist', $className));
}

$parts = explode('\\', $className);
Expand Down
32 changes: 14 additions & 18 deletions bundles/CoreBundle/src/Command/Bundle/Helper/PostStateChange.php
Expand Up @@ -28,13 +28,15 @@

/**
* @internal
*
* @TODO: Make class readonly and remove readonly from properties when PHP 8.1 support is dropped
*/
class PostStateChange
{
public function __construct(
private CacheClearer $cacheClearer,
private AssetsInstaller $assetsInstaller,
private EventDispatcherInterface $eventDispatcher
private readonly CacheClearer $cacheClearer,
private readonly AssetsInstaller $assetsInstaller,
private readonly EventDispatcherInterface $eventDispatcher
) {
}

Expand All @@ -45,16 +47,12 @@ public static function configureStateChangeCommandOptions(Command $command): voi
null,
InputOption::VALUE_NONE,
'Do not run any post change commands (<comment>assets:install</comment>, <comment>cache:clear</comment>) after successful state change'
);

$command->addOption(
)->addOption(
'no-assets-install',
null,
InputOption::VALUE_NONE,
'Do not run <comment>assets:install</comment> command after successful state change'
);

$command->addOption(
)->addOption(
'no-cache-clear',
null,
InputOption::VALUE_NONE,
Expand All @@ -70,30 +68,28 @@ public function runPostStateChangeCommands(PimcoreStyle $io, string $environment
return;
}

$runAssetsInstall = $input->getOption('no-assets-install') ? false : true;
$runCacheClear = $input->getOption('no-cache-clear') ? false : true;
$runAssetsInstall = !$input->getOption('no-assets-install');
$runCacheClear = !$input->getOption('no-cache-clear');

if (!$runAssetsInstall && !$runCacheClear) {
return;
}

$runCallback = function ($type, $buffer) use ($io) {
$io->write($buffer);
};
$runCallback = static fn ($type, $buffer) => $io->write($buffer);

$io->newLine();
$io->section('Running post state change commands');

if ($runAssetsInstall) {
$io->comment('Running bin/console assets:install...');
$io->simpleSection('Running bin/console assets:install...');

try {
$this->assetsInstaller->setRunCallback($runCallback);
$this->assetsInstaller->install([
'env' => $environment,
'ansi' => $io->isDecorated(),
]);
} catch (ProcessFailedException $e) {
} catch (ProcessFailedException) {
// noop - output should be enough
}
}
Expand All @@ -104,14 +100,14 @@ public function runPostStateChangeCommands(PimcoreStyle $io, string $environment
$this->eventDispatcher->removeListener(ConsoleEvents::TERMINATE, $listener);
}

$io->comment('Running bin/console cache:clear...');
$io->simpleSection('Running bin/console cache:clear...');

try {
$this->cacheClearer->setRunCallback($runCallback);
$this->cacheClearer->clear($environment, [
'ansi' => $io->isDecorated(),
]);
} catch (ProcessFailedException $e) {
} catch (ProcessFailedException) {
// noop - output should be enough
}
}
Expand Down
34 changes: 25 additions & 9 deletions bundles/CoreBundle/src/Command/Bundle/InstallCommand.php
Expand Up @@ -19,32 +19,48 @@

use Pimcore\Bundle\CoreBundle\Command\Bundle\Helper\PostStateChange;
use Pimcore\Extension\Bundle\PimcoreBundleManager;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;

/**
* @internal
*/
#[AsCommand(
name: 'pimcore:bundle:install',
description: 'Installs a bundle'
)]
class InstallCommand extends AbstractBundleCommand
{
public function __construct(PimcoreBundleManager $bundleManager, private PostStateChange $postStateChangeHelper)
{
public function __construct(
protected PimcoreBundleManager $bundleManager,
private readonly PostStateChange $postStateChangeHelper
) {
parent::__construct($bundleManager);
}

protected function configure(): void
{
$this
->setName($this->buildName('install'))
->configureDescriptionAndHelp('Installs a bundle')
->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to install')
->configureFailWithoutErrorOption()
;
$this->addArgument(
'bundle',
InputArgument::REQUIRED,
'The bundle to install'
)->configureFailWithoutErrorOption();

PostStateChange::configureStateChangeCommandOptions($this);
}

public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
{
parent::complete($input, $suggestions);

$this->completeBundleArgument($input, $suggestions);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$bundle = $this->getBundle();
Expand All @@ -65,6 +81,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->getApplication()->getKernel()->getEnvironment()
);

return 0;
return self::SUCCESS;
}
}