diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 57c1517854..859515b3ca 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -11,7 +11,7 @@ Replace this notice by a short README for your feature/bugfix. This will help people understand your PR and can be used as a start for the documentation. -Additionally (see https://symfony.com/roadmap): +Additionally (see https://symfony.com/releases): - Always add tests and ensure they pass. - Never break backward compatibility (see https://symfony.com/bc). - Bug fixes must be submitted against the lowest maintained branch where they apply diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig index c085303213..4e4a59d1b3 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig @@ -153,7 +153,7 @@ {{ collector.symfonyeom }} {{ collector.symfonyeol }} - View roadmap + View roadmap diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 3de7a04d52..26d8d92b65 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -647,7 +647,15 @@ class Application implements ResetInterface // filter out aliases for commands which are already on the list if (\count($commands) > 1) { $commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands; - $commands = array_unique(array_filter($commands, function ($nameOrAlias) use (&$commandList, $commands, &$aliases) { + + if (isset($commandList[$name])) { + return $this->get($name); + } + + foreach ($commands as $k => $nameOrAlias) { + if ($nameOrAlias === $name) { + return $this->get($nameOrAlias); + } if (!$commandList[$nameOrAlias] instanceof Command) { $commandList[$nameOrAlias] = $this->commandLoader->get($nameOrAlias); } @@ -656,8 +664,14 @@ class Application implements ResetInterface $aliases[$nameOrAlias] = $commandName; - return $commandName === $nameOrAlias || !\in_array($commandName, $commands); - })); + if ($commandName === $nameOrAlias || !\in_array($commandName, $commands)) { + continue; + } + + unset($commands[$k]); + } + + $commands = array_unique($commands); } if (\count($commands) > 1) { diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index df8d8e46fe..cd8904ea72 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -1692,6 +1692,31 @@ class ApplicationTest extends TestCase $this->assertArrayNotHasKey('disabled', $application->all()); } + public function testFindAlternativesDoesNotLoadSameNamespaceCommandsOnExactMatch() + { + $application = new Application(); + $application->setAutoExit(false); + + $loaded = []; + + $application->setCommandLoader(new FactoryCommandLoader([ + 'foo:bar' => function () use (&$loaded) { + $loaded['foo:bar'] = true; + + return (new Command('foo:bar'))->setCode(function () {}); + }, + 'foo' => function () use (&$loaded) { + $loaded['foo'] = true; + + return (new Command('foo'))->setCode(function () {}); + }, + ])); + + $application->run(new ArrayInput(['command' => 'foo']), new NullOutput()); + + $this->assertSame(['foo' => true], $loaded); + } + protected function getDispatcher($skipCommand = false) { $dispatcher = new EventDispatcher(); diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index da1c6ab7fd..e1bcea35d2 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -782,6 +782,10 @@ class Finder implements \IteratorAggregate, \Countable */ private function normalizeDir(string $dir): string { + if ('/' === $dir) { + return $dir; + } + $dir = rtrim($dir, '/'.\DIRECTORY_SEPARATOR); if (preg_match('#^(ssh2\.)?s?ftp://#', $dir)) { diff --git a/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php b/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php index 3facef58a0..7616b14a24 100644 --- a/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php +++ b/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php @@ -70,7 +70,11 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator } $subPathname .= $this->getFilename(); - return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname); + if ('/' !== $basePath = $this->rootPath) { + $basePath .= $this->directorySeparator; + } + + return new SplFileInfo($basePath.$subPathname, $this->subPath, $subPathname); } /** diff --git a/src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php b/src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php index a10741a84d..a18fbd31f4 100644 --- a/src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php +++ b/src/Symfony/Component/HttpKernel/Event/ExceptionEvent.php @@ -21,7 +21,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; * current request. The propagation of this event is stopped as soon as a * response is set. * - * You can also call setException() to replace the thrown exception. This + * You can also call setThrowable() to replace the thrown exception. This * exception will be thrown if no response is set during processing of this * event. *