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 = [];
|
||||
foreach ($this->all() as $command) {
|
||||
if ($command->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
|
||||
|
||||
foreach ($command->getAliases() as $alias) {
|
||||
|
@ -654,6 +658,11 @@ class Application implements ResetInterface
|
|||
$message = sprintf('Command "%s" is not defined.', $name);
|
||||
|
||||
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
|
||||
// remove hidden commands
|
||||
$alternatives = array_filter($alternatives, function ($name) {
|
||||
return !$this->get($name)->isHidden();
|
||||
});
|
||||
|
||||
if (1 == \count($alternatives)) {
|
||||
$message .= "\n\nDid you mean this?\n ";
|
||||
} else {
|
||||
|
@ -662,7 +671,7 @@ class Application implements ResetInterface
|
|||
$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
|
||||
|
@ -685,13 +694,18 @@ class Application implements ResetInterface
|
|||
}
|
||||
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) {
|
||||
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();
|
||||
|
||||
return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
|
||||
}, 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));
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ class ApplicationTest extends TestCase
|
|||
require_once self::$fixturesPath.'/FooWithoutAliasCommand.php';
|
||||
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering.php';
|
||||
require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php';
|
||||
require_once self::$fixturesPath.'/FooHiddenCommand.php';
|
||||
}
|
||||
|
||||
protected function normalizeLineBreaks($text)
|
||||
|
@ -664,6 +665,7 @@ class ApplicationTest extends TestCase
|
|||
$application->add(new \Foo1Command());
|
||||
$application->add(new \Foo2Command());
|
||||
$application->add(new \Foo3Command());
|
||||
$application->add(new \FooHiddenCommand());
|
||||
|
||||
$expectedAlternatives = [
|
||||
'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)
|
||||
{
|
||||
if ($definition->isSynthetic()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (\is_string($factory = $definition->getFactory())) {
|
||||
if (!\function_exists($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()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass": method "setLogger()" does not exist.');
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$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\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass;
|
||||
use Symfony\Component\DependencyInjection\Compiler\DefinitionErrorExceptionPass;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
|
||||
|
@ -131,4 +133,25 @@ class ResolveBindingsPassTest extends TestCase
|
|||
$pass = new ResolveBindingsPass();
|
||||
$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