Skip to content

Commit

Permalink
feature #23869 [Console] Made console command shortcuts case insensit…
Browse files Browse the repository at this point in the history
…ive (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
  • Loading branch information
Robin Chalas committed Aug 12, 2017
2 parents eeaea83 + 04df283 commit c82ec96
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 3 deletions.
7 changes: 6 additions & 1 deletion src/Symfony/Component/Console/Application.php
Expand Up @@ -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));
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Console/CHANGELOG.md
Expand Up @@ -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
-----
Expand Down
41 changes: 39 additions & 2 deletions src/Symfony/Component/Console/Tests/ApplicationTest.php
Expand Up @@ -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';
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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'),
);
}

Expand Down
@@ -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');
}
}

0 comments on commit c82ec96

Please sign in to comment.