Merge branch '4.3' into 4.4
* 4.3: Do not include hidden commands in suggested alternatives [DependencyInjection] Fix wrong exception when service is synthetic
This commit is contained in:
commit
399e0fb06f
|
@ -557,6 +557,10 @@ class Application implements ResetInterface
|
||||||
{
|
{
|
||||||
$namespaces = [];
|
$namespaces = [];
|
||||||
foreach ($this->all() as $command) {
|
foreach ($this->all() as $command) {
|
||||||
|
if ($command->isHidden()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
|
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
|
||||||
|
|
||||||
foreach ($command->getAliases() as $alias) {
|
foreach ($command->getAliases() as $alias) {
|
||||||
|
@ -654,6 +658,11 @@ class Application implements ResetInterface
|
||||||
$message = sprintf('Command "%s" is not defined.', $name);
|
$message = sprintf('Command "%s" is not defined.', $name);
|
||||||
|
|
||||||
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
|
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
|
||||||
|
// remove hidden commands
|
||||||
|
$alternatives = array_filter($alternatives, function ($name) {
|
||||||
|
return !$this->get($name)->isHidden();
|
||||||
|
});
|
||||||
|
|
||||||
if (1 == \count($alternatives)) {
|
if (1 == \count($alternatives)) {
|
||||||
$message .= "\n\nDid you mean this?\n ";
|
$message .= "\n\nDid you mean this?\n ";
|
||||||
} else {
|
} else {
|
||||||
|
@ -662,7 +671,7 @@ class Application implements ResetInterface
|
||||||
$message .= implode("\n ", $alternatives);
|
$message .= implode("\n ", $alternatives);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CommandNotFoundException($message, $alternatives);
|
throw new CommandNotFoundException($message, array_values($alternatives));
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter out aliases for commands which are already on the list
|
// filter out aliases for commands which are already on the list
|
||||||
|
@ -685,13 +694,18 @@ class Application implements ResetInterface
|
||||||
}
|
}
|
||||||
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) {
|
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) {
|
||||||
if (!$commandList[$cmd] instanceof Command) {
|
if (!$commandList[$cmd] instanceof Command) {
|
||||||
return $cmd;
|
$commandList[$cmd] = $this->commandLoader->get($cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($commandList[$cmd]->isHidden()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription();
|
$abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription();
|
||||||
|
|
||||||
return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
|
return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
|
||||||
}, array_values($commands));
|
}, array_values($commands));
|
||||||
$suggestions = $this->getAbbreviationSuggestions($abbrevs);
|
$suggestions = $this->getAbbreviationSuggestions(array_filter($abbrevs));
|
||||||
|
|
||||||
throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands));
|
throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands));
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ class ApplicationTest extends TestCase
|
||||||
require_once self::$fixturesPath.'/FooWithoutAliasCommand.php';
|
require_once self::$fixturesPath.'/FooWithoutAliasCommand.php';
|
||||||
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering.php';
|
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering.php';
|
||||||
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php';
|
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php';
|
||||||
|
require_once self::$fixturesPath.'/FooHiddenCommand.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function normalizeLineBreaks($text)
|
protected function normalizeLineBreaks($text)
|
||||||
|
@ -664,6 +665,7 @@ class ApplicationTest extends TestCase
|
||||||
$application->add(new \Foo1Command());
|
$application->add(new \Foo1Command());
|
||||||
$application->add(new \Foo2Command());
|
$application->add(new \Foo2Command());
|
||||||
$application->add(new \Foo3Command());
|
$application->add(new \Foo3Command());
|
||||||
|
$application->add(new \FooHiddenCommand());
|
||||||
|
|
||||||
$expectedAlternatives = [
|
$expectedAlternatives = [
|
||||||
'afoobar',
|
'afoobar',
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class FooHiddenCommand extends Command
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('foo:hidden')
|
||||||
|
->setAliases(['afoohidden'])
|
||||||
|
->setHidden(true)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -113,6 +113,10 @@ abstract class AbstractRecursivePass implements CompilerPassInterface
|
||||||
*/
|
*/
|
||||||
protected function getConstructor(Definition $definition, $required)
|
protected function getConstructor(Definition $definition, $required)
|
||||||
{
|
{
|
||||||
|
if ($definition->isSynthetic()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (\is_string($factory = $definition->getFactory())) {
|
if (\is_string($factory = $definition->getFactory())) {
|
||||||
if (!\function_exists($factory)) {
|
if (!\function_exists($factory)) {
|
||||||
throw new RuntimeException(sprintf('Invalid service "%s": function "%s" does not exist.', $this->currentId, $factory));
|
throw new RuntimeException(sprintf('Invalid service "%s": function "%s" does not exist.', $this->currentId, $factory));
|
||||||
|
|
|
@ -568,12 +568,10 @@ class AutowirePassTest extends TestCase
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @exceptedExceptionMessage Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy": method "setLogger()" does not exist.
|
|
||||||
*/
|
|
||||||
public function testWithNonExistingSetterAndAutowiring()
|
public function testWithNonExistingSetterAndAutowiring()
|
||||||
{
|
{
|
||||||
$this->expectException(RuntimeException::class);
|
$this->expectException(RuntimeException::class);
|
||||||
|
$this->expectExceptionMessage('Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass": method "setLogger()" does not exist.');
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
|
||||||
$definition = $container->register(CaseSensitiveClass::class, CaseSensitiveClass::class)->setAutowired(true);
|
$definition = $container->register(CaseSensitiveClass::class, CaseSensitiveClass::class)->setAutowired(true);
|
||||||
|
|
|
@ -15,9 +15,11 @@ use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass;
|
use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\DefinitionErrorExceptionPass;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
|
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
|
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
||||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
|
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
|
||||||
|
@ -131,4 +133,25 @@ class ResolveBindingsPassTest extends TestCase
|
||||||
$pass = new ResolveBindingsPass();
|
$pass = new ResolveBindingsPass();
|
||||||
$pass->process($container);
|
$pass->process($container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSyntheticServiceWithBind()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$argument = new BoundArgument('bar');
|
||||||
|
|
||||||
|
$container->register('foo', 'stdClass')
|
||||||
|
->addArgument(new Reference('synthetic.service'));
|
||||||
|
|
||||||
|
$container->register('synthetic.service')
|
||||||
|
->setSynthetic(true)
|
||||||
|
->setBindings(['$apiKey' => $argument]);
|
||||||
|
|
||||||
|
$container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class)
|
||||||
|
->setBindings(['$apiKey' => $argument]);
|
||||||
|
|
||||||
|
(new ResolveBindingsPass())->process($container);
|
||||||
|
(new DefinitionErrorExceptionPass())->process($container);
|
||||||
|
|
||||||
|
$this->assertSame([1 => 'bar'], $container->getDefinition(NamedArgumentsDummy::class)->getArguments());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue