function RecipeCommand::execute
Same name in other branches
- 10 core/lib/Drupal/Core/Recipe/RecipeCommand.php \Drupal\Core\Recipe\RecipeCommand::execute()
File
-
core/
lib/ Drupal/ Core/ Recipe/ RecipeCommand.php, line 57
Class
- RecipeCommand
- Applies recipe.
Namespace
Drupal\Core\RecipeCode
protected function execute(InputInterface $input, OutputInterface $output) : int {
$io = new SymfonyStyle($input, $output);
$recipe_path = $input->getArgument('path');
if (!is_string($recipe_path) || !is_dir($recipe_path)) {
$io->error(sprintf('The supplied path %s is not a directory', $recipe_path));
return 1;
}
// Recipes can only be applied to an already-installed site.
$container = $this->boot()
->getContainer();
/** @var \Drupal\Core\Config\Checkpoint\CheckpointStorageInterface $checkpoint_storage */
$checkpoint_storage = $container->get('config.storage.checkpoint');
$recipe = Recipe::createFromDirectory($recipe_path);
// Collect input for this recipe and all the recipes it directly and
// indirectly applies.
$recipe->input
->collectAll(new ConsoleInputCollector($input, $io));
if ($checkpoint_storage instanceof LoggerAwareInterface) {
$logger = new ConsoleLogger($output, [
// The checkpoint storage logs a notice if it decides to not create a
// checkpoint, and we want to be sure those notices are seen even
// without additional verbosity.
LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL,
]);
$checkpoint_storage->setLogger($logger);
}
$backup_checkpoint = $checkpoint_storage->checkpoint("Backup before the '{$recipe->name}' recipe.");
try {
$steps = RecipeRunner::toBatchOperations($recipe);
$progress_bar = $io->createProgressBar();
$progress_bar->setFormat("%current%/%max% [%bar%]\n%message%\n");
$progress_bar->setMessage($this->toPlainString(t('Applying recipe')));
$progress_bar->start(count($steps));
/** @var array{message?: \Stringable|string, results: array{module?: string[], theme?: string[], content?: string[], recipe?: string[]}} $context */
$context = [
'results' => [],
];
foreach ($steps as $step) {
call_user_func_array($step[0], array_merge($step[1], [
&$context,
]));
if (isset($context['message'])) {
$progress_bar->setMessage($this->toPlainString($context['message']));
}
unset($context['message']);
$progress_bar->advance();
}
if ($io->isVerbose()) {
if (!empty($context['results']['module'])) {
$io->section($this->toPlainString(t('Modules installed')));
$modules = array_map(fn($module) => \Drupal::service('extension.list.module')->getName($module), $context['results']['module']);
sort($modules, SORT_NATURAL);
$io->listing($modules);
}
if (!empty($context['results']['theme'])) {
$io->section($this->toPlainString(t('Themes installed')));
$themes = array_map(fn($theme) => \Drupal::service('extension.list.theme')->getName($theme), $context['results']['theme']);
sort($themes, SORT_NATURAL);
$io->listing($themes);
}
if (!empty($context['results']['content'])) {
$io->section($this->toPlainString(t('Content created for recipes')));
$io->listing($context['results']['content']);
}
if (!empty($context['results']['recipe'])) {
$io->section($this->toPlainString(t('Recipes applied')));
$io->listing($context['results']['recipe']);
}
}
$io->success($this->toPlainString(t('%recipe applied successfully', [
'%recipe' => $recipe->name,
])));
return 0;
} catch (\Throwable $e) {
try {
$this->rollBackToCheckpoint($backup_checkpoint);
} catch (ConfigImporterException $importer_exception) {
$io->error($importer_exception->getMessage());
}
throw $e;
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.