diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index b9669789eae8a..1eb1fca535fee 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -578,7 +578,12 @@ public function find($name) $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name); $commands = preg_grep('{^'.$expr.'}', $allCommands); - if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) { + if (empty($commands)) { + $commands = preg_grep('{^'.$expr.'}i', $allCommands); + } + + // if no commands matched or we just matched namespaces + if (empty($commands) || count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) { if (false !== $pos = strrpos($name, ':')) { // check if a namespace exists and contains commands $this->findNamespace(substr($name, 0, $pos)); diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index 616f70e137c0c..0c147a605ccb2 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11 `ContainerCommandLoader` for commands lazy-loading + * added a case-insensitive command name matching fallback 3.3.0 ----- diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 724b34f8468ae..5dd1e79b67a8d 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -51,6 +51,8 @@ public static function setUpBeforeClass() require_once self::$fixturesPath.'/Foo3Command.php'; require_once self::$fixturesPath.'/Foo4Command.php'; require_once self::$fixturesPath.'/Foo5Command.php'; + require_once self::$fixturesPath.'/FooSameCaseUppercaseCommand.php'; + require_once self::$fixturesPath.'/FooSameCaseLowercaseCommand.php'; require_once self::$fixturesPath.'/FoobarCommand.php'; require_once self::$fixturesPath.'/BarBucCommand.php'; require_once self::$fixturesPath.'/FooSubnamespaced1Command.php'; @@ -317,6 +319,41 @@ public function testFind() $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias'); } + public function testFindCaseSensitiveFirst() + { + $application = new Application(); + $application->add(new \FooSameCaseUppercaseCommand()); + $application->add(new \FooSameCaseLowercaseCommand()); + + $this->assertInstanceOf('FooSameCaseUppercaseCommand', $application->find('f:B'), '->find() returns a command if the abbreviation is the correct case'); + $this->assertInstanceOf('FooSameCaseUppercaseCommand', $application->find('f:BAR'), '->find() returns a command if the abbreviation is the correct case'); + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:b'), '->find() returns a command if the abbreviation is the correct case'); + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation is the correct case'); + } + + public function testFindCaseInsensitiveAsFallback() + { + $application = new Application(); + $application->add(new \FooSameCaseLowercaseCommand()); + + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:b'), '->find() returns a command if the abbreviation is the correct case'); + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:B'), '->find() will fallback to case insensitivity'); + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('FoO:BaR'), '->find() will fallback to case insensitivity'); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage Command "FoO:BaR" is ambiguous + */ + public function testFindCaseInsensitiveSuggestions() + { + $application = new Application(); + $application->add(new \FooSameCaseLowercaseCommand()); + $application->add(new \FooSameCaseUppercaseCommand()); + + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('FoO:BaR'), '->find() will find two suggestions with case insensitivity'); + } + public function testFindWithCommandLoader() { $application = new Application(); @@ -414,8 +451,8 @@ public function testFindAlternativeExceptionMessageSingle($name) public function provideInvalidCommandNamesSingle() { return array( - array('foo3:baR'), - array('foO3:bar'), + array('foo3:barr'), + array('fooo3:bar'), ); } diff --git a/src/Symfony/Component/Console/Tests/Fixtures/FooSameCaseLowercaseCommand.php b/src/Symfony/Component/Console/Tests/Fixtures/FooSameCaseLowercaseCommand.php new file mode 100644 index 0000000000000..c875be0cd7546 --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/FooSameCaseLowercaseCommand.php @@ -0,0 +1,11 @@ +setName('foo:bar')->setDescription('foo:bar command'); + } +} diff --git a/src/Symfony/Component/Console/Tests/Fixtures/FooSameCaseUppercaseCommand.php b/src/Symfony/Component/Console/Tests/Fixtures/FooSameCaseUppercaseCommand.php new file mode 100644 index 0000000000000..75c8d0024e28c --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/FooSameCaseUppercaseCommand.php @@ -0,0 +1,11 @@ +setName('foo:BAR')->setDescription('foo:BAR command'); + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy