Skip to content

Commit

Permalink
[console] Avoid run of Request handle(). (#3575)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmolivas committed Nov 10, 2017
1 parent 3c4395b commit 1e62597
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 297 deletions.
228 changes: 61 additions & 167 deletions src/Bootstrap/AddServicesCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@

namespace Drupal\Console\Bootstrap;

use Drupal\Console\Utils\Site;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Yaml\Yaml;
use Drupal\Console\Utils\TranslatorManager;
use Drupal\Console\Extension\Extension;
use Drupal\Console\Extension\Manager;
use Drupal\Core\Cache\ListCacheBinsPass;
use GuzzleHttp\Client;

/**
* FindCommandsCompilerPass
Expand All @@ -35,214 +30,113 @@ class AddServicesCompilerPass implements CompilerPassInterface
*/
protected $rebuild;

/**
* @var YamlFileLoader
*/
protected $loader;

/**
* AddCommandsCompilerPass constructor.
*
* @param string $root
* @param string $appRoot
* @param boolean $rebuild
*/
public function __construct($root, $appRoot, $rebuild = false)
public function __construct($root)
{
$this->root = $root;
$this->appRoot = $appRoot;
$this->rebuild = $rebuild;
}

/**
* @inheritdoc
*/
public function process(ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$this->loader = new YamlFileLoader(
$container,
new FileLocator($this->root)
);

$servicesFiles = [
$this->root. DRUPAL_CONSOLE_CORE . 'services.yml',
$this->root. DRUPAL_CONSOLE . 'uninstall.services.yml',
$this->root. DRUPAL_CONSOLE . 'services.yml'
];

foreach ($servicesFiles as $servicesFile) {
if (file_exists($servicesFile)) {
$loader->load($servicesFile);
}
}
// Load DrupalConsole services
$this->addDrupalConsoleServices();

// Load configuration from directory
$container->get('console.configuration_manager')
->loadConfiguration($this->root)
->getConfiguration();

/**
* @var Site $site
*/
$site = $container->get('console.site');
// Set console.root services
$container->set(
'console.root',
$this->root
);

// Load DrupalConsole services
$this->addDrupalConsoleConfigServices();

// Load DrupalConsole extended services
$this->addDrupalConsoleExtendedServices();

// The AddServicesCompilerPass cache pass is executed before the
// ListCacheBinsPass causing exception: ParameterNotFoundException: You
// have requested a non-existent parameter "cache_default_bin_backends"
$cache_pass = new ListCacheBinsPass();
$cache_pass->process($container);

// Fix ContainerNotInitializedException: \Drupal::$container is not initialized yet.
// \Drupal::setContainer() must be called with a real container. The use of stream_wrapper.temporary
// service at cachedServicesFileExists method uses the container that in compiler pass
// is not ready to use: https://github.com/symfony/symfony/issues/22125#issuecomment-288734689
// This is workaroud works but seems that we cannot depend on services at this stage.
\Drupal::setContainer($container);

// Avoid Error: Call to undefined function
// Drupal\Core\StreamWrapper\file_directory_temp() in TemporaryStream
// that seems to be needed to the cache services and when no other
// stream wrapper is available defaults ont TemporaryStream.
$site->loadLegacyFile('/core/includes/file.inc');

if (!$this->rebuild && $site->cachedServicesFileExists()) {
$loader->load($site->getCachedServicesFile());
} else {
$site->removeCachedServicesFile();

$finder = new Finder();
$finder->files()
->name('*.yml')
->in(
sprintf(
'%s/config/services',
$this->root.DRUPAL_CONSOLE
)
);

$servicesData = [];
foreach ($finder as $file) {
$loader->load($file->getPathName());
$servicesData = $this->extractServiceData(
$file->getPathName(),
$servicesData
);
}

// Avoid to use the container to get the console.extension_manager due
// container is not ready and cause exceptions.

/**
* @var GuzzleHttp\Client $httpClient
*/
$httpClient = new Client;
/**
* @var Manager $extensionManager
*/
$extensionManager = new Manager($site, $httpClient, $this->appRoot);

/**
* @var Extension[] $modules
*/
$modules = $extensionManager->discoverModules()
->showCore()
->showNoCore()
->showInstalled()
->getList(false);

foreach ($modules as $module) {
$consoleServicesExtensionFile = $this->appRoot . '/' .
$module->getPath() . '/console.services.yml';
if (is_file($consoleServicesExtensionFile)) {
$loader->load($consoleServicesExtensionFile);
$servicesData = $this->extractServiceData(
$consoleServicesExtensionFile,
$servicesData
);
}
}
// Override TranslatorManager service definition
$translatorManagerDefinition = $container
->getDefinition('console.translator_manager');
$translatorManagerDefinition->setClass(TranslatorManager::class);

/**
* @var Extension[] $themes
*/
$themes = $extensionManager->discoverThemes()
->showNoCore()
->showInstalled()
->getList(false);

foreach ($themes as $theme) {
$consoleServicesExtensionFile = $this->appRoot . '/' .
$theme->getPath() . '/console.services.yml';
if (is_file($consoleServicesExtensionFile)) {
$loader->load($consoleServicesExtensionFile);
$servicesData = $this->extractServiceData(
$consoleServicesExtensionFile,
$servicesData
);
}
}
// Set console.service_definitions service
$container->setParameter(
'console.service_definitions',
$container->getDefinitions()
);
}

if ($servicesData) {
file_put_contents(
$site->getCachedServicesFile(),
Yaml::dump($servicesData, 4, 2)
);
protected function addDrupalConsoleServiceFiles($servicesFiles)
{
foreach ($servicesFiles as $servicesFile) {
if (file_exists($servicesFile)) {
$this->loader->load($servicesFile);
}
}
}

$extendServicesFiles = [
$this->root . DRUPAL_CONSOLE . 'extend.console.services.yml',
$this->root . DRUPAL_CONSOLE . 'extend.console.uninstall.services.yml',
protected function addDrupalConsoleServices()
{
$servicesFiles = [
$this->root. DRUPAL_CONSOLE_CORE . 'services.yml',
$this->root. DRUPAL_CONSOLE . 'uninstall.services.yml',
$this->root. DRUPAL_CONSOLE . 'services.yml'
];

foreach ($extendServicesFiles as $extendServicesFile) {
if (file_exists($extendServicesFile)) {
$loader->load($extendServicesFile);
}
}
$this->addDrupalConsoleServiceFiles($servicesFiles);
}

$configurationManager = $container->get('console.configuration_manager');
$directory = $configurationManager->getConsoleDirectory() . 'extend/';
$autoloadFile = $directory . 'vendor/autoload.php';
if (is_file($autoloadFile)) {
include_once $autoloadFile;

$extendServicesFiles = [
$directory . 'extend.console.services.yml',
$directory . 'extend.console.uninstall.services.yml',
];

foreach ($extendServicesFiles as $extendServicesFile) {
if (file_exists($extendServicesFile)) {
$loader->load($extendServicesFile);
}
}
protected function addDrupalConsoleConfigServices()
{
$finder = new Finder();
$finder->files()
->name('*.yml')
->in(
sprintf(
'%s/config/services',
$this->root.DRUPAL_CONSOLE
)
);

foreach ($finder as $file) {
$this->loader->load($file->getPathName());
}

$container->setParameter(
'console.service_definitions',
$container->getDefinitions()
);

$definition = $container->getDefinition('console.translator_manager');
$definition->setClass(TranslatorManager::class);
}

/**
* @param $filePath
* @param $servicesData
*
* @return array
*/
protected function extractServiceData($filePath, $servicesData)
protected function addDrupalConsoleExtendedServices()
{
$serviceFileData = Yaml::parse(
file_get_contents($filePath)
);

$servicesData = array_merge_recursive(
$servicesData,
$serviceFileData
);
$servicesFiles = [
$this->root . DRUPAL_CONSOLE . 'extend.console.services.yml',
$this->root . DRUPAL_CONSOLE . 'extend.console.uninstall.services.yml',
];

return $servicesData;
$this->addDrupalConsoleServiceFiles($servicesFiles);
}
}
20 changes: 3 additions & 17 deletions src/Bootstrap/Drupal.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,8 @@ public function boot()
$drupalKernel->addServiceModifier(
new DrupalServiceModifier(
$this->drupalFinder->getComposerRoot(),
$this->drupalFinder->getDrupalRoot(),
'drupal.command',
'drupal.generator',
$rebuildServicesFile
'drupal.generator'
)
);

Expand All @@ -156,21 +154,17 @@ public function boot()
// when boot is processed.
$drupalKernel->invalidateContainer();

// Looks that the boot process is handling an initializeContainer
// so looks that rebuildContainer repeats what we finally do in boot().
//$drupalKernel->rebuildContainer();

// Load legacy libraries, modules, register stream wrapper, and push
// request to request stack but without trigger processing of '/'
// request that invokes hooks like hook_page_attachments().
$drupalKernel->boot();
$drupalKernel->preHandle($request);

if ($debug) {
$io->writeln("\r\033[K\033[1A\r<info>✔</info>");
}

$container = $drupalKernel->getContainer();

$container->set(
'console.root',
$this->drupalFinder->getComposerRoot()
Expand All @@ -187,14 +181,6 @@ public function boot()
$this->drupalFinder->getComposerRoot()
);

$consoleExtendConfigFile = $this->drupalFinder
->getComposerRoot() . DRUPAL_CONSOLE
.'/extend.console.config.yml';
if (file_exists($consoleExtendConfigFile)) {
$container->get('console.configuration_manager')
->importConfigurationFile($consoleExtendConfigFile);
}

$container->get('console.renderer')
->setSkeletonDirs(
[
Expand All @@ -205,7 +191,7 @@ public function boot()

return $container;
} catch (\Exception $e) {
if ($command == 'list') {
if ($command != 'about') {
$io->error($e->getMessage());
}
$drupal = new DrupalConsoleCore(
Expand Down

0 comments on commit 1e62597

Please sign in to comment.