[Console] Add a factory command loader for standalone application with lazy-loading needs
This commit is contained in:
parent
de5c60de0e
commit
9b40b4af65
@ -4,7 +4,8 @@ CHANGELOG
|
|||||||
3.4.0
|
3.4.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
* added `CommandLoaderInterface` and PSR-11 `ContainerCommandLoader`
|
* added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
|
||||||
|
`ContainerCommandLoader` for commands lazy-loading
|
||||||
|
|
||||||
3.3.0
|
3.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Console\CommandLoader;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple command loader using factories to instantiate commands lazily.
|
||||||
|
*
|
||||||
|
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
|
||||||
|
*/
|
||||||
|
class FactoryCommandLoader implements CommandLoaderInterface
|
||||||
|
{
|
||||||
|
private $factories;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param callable[] $factories Indexed by command names
|
||||||
|
*/
|
||||||
|
public function __construct(array $factories)
|
||||||
|
{
|
||||||
|
$this->factories = $factories;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function has($name)
|
||||||
|
{
|
||||||
|
return isset($this->factories[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function get($name)
|
||||||
|
{
|
||||||
|
if (!isset($this->factories[$name])) {
|
||||||
|
throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
|
||||||
|
}
|
||||||
|
|
||||||
|
$factory = $this->factories[$name];
|
||||||
|
|
||||||
|
return $factory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getNames()
|
||||||
|
{
|
||||||
|
return array_keys($this->factories);
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ namespace Symfony\Component\Console\Tests;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
|
use Symfony\Component\Console\CommandLoader\FactoryCommandLoader;
|
||||||
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
|
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
|
||||||
use Symfony\Component\Console\Helper\HelperSet;
|
use Symfony\Component\Console\Helper\HelperSet;
|
||||||
use Symfony\Component\Console\Helper\FormatterHelper;
|
use Symfony\Component\Console\Helper\FormatterHelper;
|
||||||
@ -35,7 +35,6 @@ use Symfony\Component\Console\Event\ConsoleExceptionEvent;
|
|||||||
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
|
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
|
||||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\ServiceLocator;
|
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||||
|
|
||||||
class ApplicationTest extends TestCase
|
class ApplicationTest extends TestCase
|
||||||
@ -129,10 +128,9 @@ class ApplicationTest extends TestCase
|
|||||||
$commands = $application->all('foo');
|
$commands = $application->all('foo');
|
||||||
$this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
|
$this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
|
||||||
|
|
||||||
$application->setCommandLoader(new ContainerCommandLoader(
|
$application->setCommandLoader(new FactoryCommandLoader(array(
|
||||||
new ServiceLocator(array('foo-bar' => function () { return new \Foo1Command(); })),
|
'foo:bar1' => function () { return new \Foo1Command(); },
|
||||||
array('foo:bar1' => 'foo-bar')
|
)));
|
||||||
));
|
|
||||||
$commands = $application->all('foo');
|
$commands = $application->all('foo');
|
||||||
$this->assertCount(2, $commands, '->all() takes a namespace as its first argument');
|
$this->assertCount(2, $commands, '->all() takes a namespace as its first argument');
|
||||||
$this->assertInstanceOf(\FooCommand::class, $commands['foo:bar'], '->all() returns the registered commands');
|
$this->assertInstanceOf(\FooCommand::class, $commands['foo:bar'], '->all() returns the registered commands');
|
||||||
@ -202,9 +200,9 @@ class ApplicationTest extends TestCase
|
|||||||
$this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name');
|
$this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name');
|
||||||
$this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias');
|
$this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias');
|
||||||
|
|
||||||
$application->setCommandLoader(new ContainerCommandLoader(new ServiceLocator(array(
|
$application->setCommandLoader(new FactoryCommandLoader(array(
|
||||||
'foo-bar' => function () { return new \Foo1Command(); },
|
'foo:bar1' => function () { return new \Foo1Command(); },
|
||||||
)), array('foo:bar1' => 'foo-bar', 'afoobar1' => 'foo-bar')));
|
)));
|
||||||
|
|
||||||
$this->assertTrue($application->has('afoobar'), '->has() returns true if an instance is registered for an alias even with command loader');
|
$this->assertTrue($application->has('afoobar'), '->has() returns true if an instance is registered for an alias even with command loader');
|
||||||
$this->assertEquals($foo, $application->get('foo:bar'), '->get() returns an instance by name even with command loader');
|
$this->assertEquals($foo, $application->get('foo:bar'), '->get() returns an instance by name even with command loader');
|
||||||
@ -321,9 +319,9 @@ class ApplicationTest extends TestCase
|
|||||||
public function testFindWithCommandLoader()
|
public function testFindWithCommandLoader()
|
||||||
{
|
{
|
||||||
$application = new Application();
|
$application = new Application();
|
||||||
$application->setCommandLoader(new ContainerCommandLoader(new ServiceLocator(array(
|
$application->setCommandLoader(new FactoryCommandLoader(array(
|
||||||
'foo-bar' => $f = function () { return new \FooCommand(); },
|
'foo:bar' => $f = function () { return new \FooCommand(); },
|
||||||
)), array('foo:bar' => 'foo-bar')));
|
)));
|
||||||
|
|
||||||
$this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists');
|
$this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists');
|
||||||
$this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists');
|
$this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists');
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Console\Tests\CommandLoader;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\CommandLoader\FactoryCommandLoader;
|
||||||
|
|
||||||
|
class FactoryCommandLoaderTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testHas()
|
||||||
|
{
|
||||||
|
$loader = new FactoryCommandLoader(array(
|
||||||
|
'foo' => function () { return new Command('foo'); },
|
||||||
|
'bar' => function () { return new Command('bar'); },
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertTrue($loader->has('foo'));
|
||||||
|
$this->assertTrue($loader->has('bar'));
|
||||||
|
$this->assertFalse($loader->has('baz'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGet()
|
||||||
|
{
|
||||||
|
$loader = new FactoryCommandLoader(array(
|
||||||
|
'foo' => function () { return new Command('foo'); },
|
||||||
|
'bar' => function () { return new Command('bar'); },
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Command::class, $loader->get('foo'));
|
||||||
|
$this->assertInstanceOf(Command::class, $loader->get('bar'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||||
|
*/
|
||||||
|
public function testGetUnknownCommandThrows()
|
||||||
|
{
|
||||||
|
(new FactoryCommandLoader(array()))->get('unknown');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetCommandNames()
|
||||||
|
{
|
||||||
|
$loader = new FactoryCommandLoader(array(
|
||||||
|
'foo' => function () { return new Command('foo'); },
|
||||||
|
'bar' => function () { return new Command('bar'); },
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertSame(array('foo', 'bar'), $loader->getNames());
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user