feature #23869 [Console] Made console command shortcuts case insensitive (thanosp)
This PR was merged into the 3.4 branch.
Discussion
----------
[Console] Made console command shortcuts case insensitive
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes <!-- don't forget updating src/**/CHANGELOG.md files -->
| BC breaks? | no
| Deprecations? | no <!-- don't forget updating UPGRADE-*.md files -->
| Tests pass? | yes
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!--highly recommended for new features-->
<!--
- Bug fixes must be submitted against the lowest branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too).
- Features and deprecations must be submitted against the 3.4,
legacy code removals go to the master branch.
- Please fill in this template according to the PR you're about to submit.
- Replace this comment by a description of what your PR is solving.
-->
This patch would save a lot of time wasted correcting typos.
Symfony commands are using `:` as a namespace separator.
Most keyboards require pressing shift to get this character.
As an accident a developer in hurry (me) when trying to use the shortcut of commands will often type the character after `:` also while pressing shift. Right now this will lead to an error effectively wasting the attempt to save time by using the shortcut.
e.g. `bin/console c:C`
Commits
-------
04df283
[Console] Added a case-insensitive fallback for console command names
This commit is contained in:
commit
c82ec965e0
@ -578,7 +578,12 @@ class Application
|
|||||||
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
|
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
|
||||||
$commands = preg_grep('{^'.$expr.'}', $allCommands);
|
$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, ':')) {
|
if (false !== $pos = strrpos($name, ':')) {
|
||||||
// check if a namespace exists and contains commands
|
// check if a namespace exists and contains commands
|
||||||
$this->findNamespace(substr($name, 0, $pos));
|
$this->findNamespace(substr($name, 0, $pos));
|
||||||
|
@ -6,6 +6,7 @@ CHANGELOG
|
|||||||
|
|
||||||
* added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
|
* added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
|
||||||
`ContainerCommandLoader` for commands lazy-loading
|
`ContainerCommandLoader` for commands lazy-loading
|
||||||
|
* added a case-insensitive command name matching fallback
|
||||||
|
|
||||||
3.3.0
|
3.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -51,6 +51,8 @@ class ApplicationTest extends TestCase
|
|||||||
require_once self::$fixturesPath.'/Foo3Command.php';
|
require_once self::$fixturesPath.'/Foo3Command.php';
|
||||||
require_once self::$fixturesPath.'/Foo4Command.php';
|
require_once self::$fixturesPath.'/Foo4Command.php';
|
||||||
require_once self::$fixturesPath.'/Foo5Command.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.'/FoobarCommand.php';
|
||||||
require_once self::$fixturesPath.'/BarBucCommand.php';
|
require_once self::$fixturesPath.'/BarBucCommand.php';
|
||||||
require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
|
require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
|
||||||
@ -317,6 +319,41 @@ class ApplicationTest extends TestCase
|
|||||||
$this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
|
$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()
|
public function testFindWithCommandLoader()
|
||||||
{
|
{
|
||||||
$application = new Application();
|
$application = new Application();
|
||||||
@ -414,8 +451,8 @@ class ApplicationTest extends TestCase
|
|||||||
public function provideInvalidCommandNamesSingle()
|
public function provideInvalidCommandNamesSingle()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
array('foo3:baR'),
|
array('foo3:barr'),
|
||||||
array('foO3:bar'),
|
array('fooo3:bar'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
|
||||||
|
class FooSameCaseLowercaseCommand extends Command
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this->setName('foo:bar')->setDescription('foo:bar command');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
|
||||||
|
class FooSameCaseUppercaseCommand extends Command
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this->setName('foo:BAR')->setDescription('foo:BAR command');
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user