From 152dec95bcef93962cd2e7adea76893d221c8681 Mon Sep 17 00:00:00 2001 From: k0d3r1s Date: Wed, 18 Sep 2019 16:21:11 +0300 Subject: [PATCH 1/2] [DependencyInjection] Fix wrong exception when service is synthetic --- .../Compiler/AbstractRecursivePass.php | 4 +++ .../Tests/Compiler/AutowirePassTest.php | 4 +-- .../Compiler/ResolveBindingsPassTest.php | 27 ++++++++++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php index a89bf1647a..5ca2b2246b 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php @@ -89,6 +89,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)); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index f729f72ba0..7eb7f60246 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -589,12 +589,10 @@ class AutowirePassTest extends TestCase ); } - /** - * @exceptedExceptionMessage Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy": method "setLogger()" does not exist. - */ public function testWithNonExistingSetterAndAutowiring() { $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $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); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php index a44fea4d60..fd526caa94 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php @@ -14,9 +14,11 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Argument\BoundArgument; 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; @@ -110,12 +112,10 @@ class ResolveBindingsPassTest extends TestCase $this->assertEquals([['setDefaultLocale', ['fr']]], $definition->getMethodCalls()); } - /** - * @exceptedExceptionMessage Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy": method "setLogger()" does not exist. - */ public function testWithNonExistingSetterAndBinding() { $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy": method "setLogger()" does not exist.'); $container = new ContainerBuilder(); $bindings = [ @@ -129,4 +129,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()); + } } From 8a9d173c36a6f5fd9d379f750f35d81d49e004f7 Mon Sep 17 00:00:00 2001 From: "M. Vondano" Date: Sun, 1 Sep 2019 19:33:46 +0200 Subject: [PATCH 2/2] Do not include hidden commands in suggested alternatives --- src/Symfony/Component/Console/Application.php | 20 +++++++++++++++--- .../Console/Tests/ApplicationTest.php | 2 ++ .../Tests/Fixtures/FooHiddenCommand.php | 21 +++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Component/Console/Tests/Fixtures/FooHiddenCommand.php diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 8a9bdc39bf..d181e41e80 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -529,6 +529,10 @@ class Application { $namespaces = []; foreach ($this->all() as $command) { + if ($command->isHidden()) { + continue; + } + $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName())); foreach ($command->getAliases() as $alias) { @@ -622,6 +626,11 @@ class Application $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 { @@ -630,7 +639,7 @@ class Application $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 @@ -654,13 +663,18 @@ class Application } $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)); } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 59ca5d9e15..c7e8495265 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -74,6 +74,7 @@ class ApplicationTest extends TestCase require_once self::$fixturesPath.'/FooSubnamespaced2Command.php'; require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering.php'; require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php'; + require_once self::$fixturesPath.'/FooHiddenCommand.php'; } protected function normalizeLineBreaks($text) @@ -616,6 +617,7 @@ class ApplicationTest extends TestCase $application->add(new \Foo1Command()); $application->add(new \Foo2Command()); $application->add(new \Foo3Command()); + $application->add(new \FooHiddenCommand()); $expectedAlternatives = [ 'afoobar', diff --git a/src/Symfony/Component/Console/Tests/Fixtures/FooHiddenCommand.php b/src/Symfony/Component/Console/Tests/Fixtures/FooHiddenCommand.php new file mode 100644 index 0000000000..75fbf7804d --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/FooHiddenCommand.php @@ -0,0 +1,21 @@ +setName('foo:hidden') + ->setAliases(['afoohidden']) + ->setHidden(true) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + } +}