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

Create a service adapter for drush.services.yml #5553

Merged
merged 31 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8b5789f
Add a basic Drush service adapter. Feed it from the existing drush.se…
greg-1-anderson May 4, 2023
fb89bd4
Use our own service discovery class instead of Symfony DI container c…
greg-1-anderson May 5, 2023
6b47912
Code style
greg-1-anderson May 5, 2023
62a9682
Fix module command discovery
greg-1-anderson May 6, 2023
705f2fd
Fix typo in Console command handling
greg-1-anderson May 6, 2023
9e02f9a
Rename DrushServiceFinder to LegacyServiceFinder and add ServiceManag…
greg-1-anderson May 8, 2023
51834e0
Code style
greg-1-anderson May 8, 2023
f993888
Move ModuleGeneratorTest to the functional tests, because integration…
greg-1-anderson May 8, 2023
dc97db7
Merge branch '12.x' into drush-service-adapter
greg-1-anderson May 8, 2023
aa661d3
Skip failing archive:restore test.
greg-1-anderson May 8, 2023
ece54ea
Simplify LegacyServiceInstantiator; remove unnecessary containers.
greg-1-anderson May 8, 2023
674207b
Code style
greg-1-anderson May 8, 2023
2025668
Remove unused class DrushServiceModifier, and also remove some unused…
greg-1-anderson May 9, 2023
36cc20f
Remove container test, because Drush is no longer involved with conta…
greg-1-anderson May 9, 2023
dbcdbbb
Move PSR-4 command discovery out of Generate command and into the Ser…
greg-1-anderson May 9, 2023
da8f93b
Remove unused FindCommandsCompilerPass
greg-1-anderson May 9, 2023
170b5ad
Move command discovery to the service manager.
greg-1-anderson May 9, 2023
c74ec7e
Code style
greg-1-anderson May 9, 2023
077f123
Fix typo in LegacyServiceFinder
greg-1-anderson May 9, 2023
971aff9
Use module handler instead of container.modules in DrupalBoot8.
greg-1-anderson May 9, 2023
e5fad4e
Move module discovery methods to the service manager
greg-1-anderson May 9, 2023
c9428ba
Move discovery code out of DrupalKernelTrait and into LegacyServiceIn…
greg-1-anderson May 10, 2023
c979e3c
Code style
greg-1-anderson May 10, 2023
ebfa31f
Merge branch '12.x' into drush-service-adapter
greg-1-anderson May 11, 2023
503fa6f
Move bootstrap classes from Application to ServiceManager
greg-1-anderson May 11, 2023
d59b343
Declare FilterHooks in ServiceManager
greg-1-anderson May 11, 2023
f003f14
Explicitly instantiate command info alterers
greg-1-anderson May 11, 2023
b092149
Add some docblock comments
greg-1-anderson May 11, 2023
ce2ce5d
Throw Symfony ParameterNotFoundException when service cannot be initi…
greg-1-anderson May 11, 2023
d3998b7
Merge branch '12.x' into drush-service-adapter
greg-1-anderson May 11, 2023
c598710
Typehints and docblock comments for service manager
greg-1-anderson May 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 11 additions & 127 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,14 @@

use Composer\Autoload\ClassLoader;
use Consolidation\AnnotatedCommand\AnnotatedCommand;
use Consolidation\AnnotatedCommand\CommandFileDiscovery;
use Consolidation\Filter\Hooks\FilterHooks;
use Consolidation\SiteAlias\SiteAliasManager;
use Drush\Boot\BootstrapManager;
use Drush\Boot\DrupalBootLevels;
use Drush\Command\RemoteCommandProxy;
use Drush\Commands\DrushCommands;
use Drush\Config\ConfigAwareTrait;
use Drush\Runtime\RedispatchHook;
use Drush\Runtime\TildeExpansionHook;
use Grasmash\YamlCli\Command\GetValueCommand;
use Grasmash\YamlCli\Command\LintCommand;
use Grasmash\YamlCli\Command\UnsetKeyCommand;
use Grasmash\YamlCli\Command\UpdateKeyCommand;
use Grasmash\YamlCli\Command\UpdateValueCommand;
use Drush\Runtime\ServiceManager;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Robo\ClassDiscovery\RelativeNamespaceDiscovery;
Expand Down Expand Up @@ -58,8 +51,8 @@ class Application extends SymfonyApplication implements LoggerAwareInterface, Co
/** @var TildeExpansionHook */
protected $tildeExpansionHook;

/** @var string[] */
protected array $bootstrapCommandClasses = [];
/** @var ServiceManager */
protected $serviceManager;

/**
* Add global options to the Application and their default values to Config.
Expand Down Expand Up @@ -137,6 +130,11 @@ public function setTildeExpansionHook(TildeExpansionHook $tildeExpansionHook)
$this->tildeExpansionHook = $tildeExpansionHook;
}

public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
}

/**
* Return the framework uri selected by the user.
*/
Expand Down Expand Up @@ -184,11 +182,6 @@ public function selectUri($cwd)
return $this->bootstrapManager()->selectUri($cwd);
}

public function bootstrapCommandClasses(): array
{
return $this->bootstrapCommandClasses;
}

/**
* @inheritdoc
*/
Expand Down Expand Up @@ -325,28 +318,10 @@ public function configureAndRegisterCommands(InputInterface $input, OutputInterf
$this->configureIO($input, $output);

// Directly add the yaml-cli commands.
$this->addCommands($this->discoverYamlCliCommands());

$commandClasses = array_unique(array_merge(
$this->discoverCommandsFromConfiguration(),
$this->discoverCommands($commandfileSearchpath, '\Drush'),
$this->discoverPsr4Commands($classLoader),
[FilterHooks::class]
));

// If a command class has a static `create` method, then we will
// postpone instantiating it until after we bootstrap Drupal.
$this->bootstrapCommandClasses = array_filter($commandClasses, function (string $class): bool {
if (!method_exists($class, 'create')) {
return false;
}
$this->addCommands($this->serviceManager->instantiateYamlCliCommands());

$reflectionMethod = new \ReflectionMethod($class, 'create');
return $reflectionMethod->isStatic();
});

// Remove the command classes that we put into the bootstrap command classes.
$commandClasses = array_diff($commandClasses, $this->bootstrapCommandClasses);
// Find the command handlers that we can instantiate without bootstrapping Drupal
$commandClasses = $this->serviceManager->discover($commandfileSearchpath, '\Drush');

// Uncomment the lines below to use Console's built in help and list commands.
// unset($commandClasses[__DIR__ . '/Commands/help/HelpCommands.php']);
Expand All @@ -356,74 +331,6 @@ public function configureAndRegisterCommands(InputInterface $input, OutputInterf
Robo::register($this, $commandClasses);
}

protected function discoverCommandsFromConfiguration()
{
$commandList = [];
foreach ($this->config->get('drush.commands', []) as $key => $value) {
if (is_numeric($key)) {
$classname = $value;
$commandList[] = $classname;
} else {
$classname = ltrim($key, '\\');
$commandList[$value] = $classname;
}
}
$this->loadCommandClasses($commandList);
return array_values($commandList);
}

/**
* Ensure that any discovered class that is not part of the autoloader
* is, in fact, included.
*/
protected function loadCommandClasses($commandClasses)
{
foreach ($commandClasses as $file => $commandClass) {
if (!class_exists($commandClass)) {
include $file;
}
}
}

/**
* Discovers command classes.
*/
protected function discoverCommands(array $directoryList, string $baseNamespace): array
{
$discovery = new CommandFileDiscovery();
$discovery
->setIncludeFilesAtBase(true)
->setSearchDepth(3)
->ignoreNamespacePart('contrib', 'Commands')
->ignoreNamespacePart('custom', 'Commands')
->ignoreNamespacePart('src')
->setSearchLocations(['Commands', 'Hooks', 'Generators'])
->setSearchPattern('#.*(Command|Hook|Generator)s?.php$#');
$baseNamespace = ltrim($baseNamespace, '\\');
$commandClasses = $discovery->discover($directoryList, $baseNamespace);
$this->loadCommandClasses($commandClasses);
return array_values($commandClasses);
}

/**
* Discovers commands that are PSR4 auto-loaded.
*/
protected function discoverPsr4Commands(ClassLoader $classLoader): array
{
$classes = (new RelativeNamespaceDiscovery($classLoader))
->setRelativeNamespace('Drush\Commands')
->setSearchPattern('/.*DrushCommands\.php$/')
->getClasses();

return array_filter($classes, function (string $class): bool {
$reflectionClass = new \ReflectionClass($class);
return $reflectionClass->isSubclassOf(DrushCommands::class)
&& !$reflectionClass->isAbstract()
&& !$reflectionClass->isInterface()
&& !$reflectionClass->isTrait();
});
}

/**
* Renders a caught exception. Omits the command docs at end.
*/
Expand All @@ -443,27 +350,4 @@ public function renderThrowable(\Throwable $e, OutputInterface $output): void

$this->doRenderThrowable($e, $output);
}

private function discoverYamlCliCommands(): array
{
$classes_yaml = [
GetValueCommand::class,
LintCommand::class,
UpdateKeyCommand::class,
UnsetKeyCommand::class,
UpdateValueCommand::class
];

foreach ($classes_yaml as $class_yaml) {
/** @var Command $instance */
$instance = new $class_yaml();
// Namespace the commands.
$name = $instance->getName();
$instance->setName('yaml:' . $name);
$instance->setAliases(['y:' . $name]);
$instance->setHelp('See https://github.com/grasmash/yaml-cli for a README and bug reports.');
$instances[] = $instance;
}
return $instances;
}
}
Loading