Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit efb7099

Browse filesBrowse files
committed
Improve UX on not found namespace/command
1 parent 51bc35c commit efb7099
Copy full SHA for efb7099

File tree

3 files changed

+52
-10
lines changed
Filter options

3 files changed

+52
-10
lines changed

‎src/Symfony/Component/Console/Application.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Application.php
+16-4Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use Symfony\Component\Console\Command\HelpCommand;
3131
use Symfony\Component\Console\Command\ListCommand;
3232
use Symfony\Component\Console\Helper\HelperSet;
33+
use Symfony\Component\Console\Helper\Helper;
3334
use Symfony\Component\Console\Helper\FormatterHelper;
3435
use Symfony\Component\Console\Event\ConsoleCommandEvent;
3536
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
@@ -503,7 +504,7 @@ public function findNamespace($namespace)
503504

504505
$exact = in_array($namespace, $namespaces, true);
505506
if (count($namespaces) > 1 && !$exact) {
506-
throw new CommandNotFoundException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
507+
throw new CommandNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
507508
}
508509

509510
return $exact ? $namespace : reset($namespaces);
@@ -559,9 +560,20 @@ public function find($name)
559560

560561
$exact = in_array($name, $commands, true);
561562
if (count($commands) > 1 && !$exact) {
562-
$suggestions = $this->getAbbreviationSuggestions(array_values($commands));
563+
$usableWidth = $this->terminal->getWidth() - 10;
564+
$abbrevs = array_values($commands);
565+
$maxLen = 0;
566+
foreach ($abbrevs as $abbrev) {
567+
$maxLen = max(Helper::strlen($abbrev), $maxLen);
568+
}
569+
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) {
570+
$abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription();
571+
572+
return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
573+
}, array_values($commands));
574+
$suggestions = $this->getAbbreviationSuggestions($abbrevs);
563575

564-
throw new CommandNotFoundException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions), array_values($commands));
576+
throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands));
565577
}
566578

567579
return $this->get($exact ? $name : reset($commands));
@@ -944,7 +956,7 @@ protected function getDefaultHelperSet()
944956
*/
945957
private function getAbbreviationSuggestions($abbrevs)
946958
{
947-
return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
959+
return ' '.implode("\n ", $abbrevs);
948960
}
949961

950962
/**

‎src/Symfony/Component/Console/Helper/Helper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Helper/Helper.php
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ public static function strlen($string)
5858
return mb_strwidth($string, $encoding);
5959
}
6060

61+
/**
62+
* Returns the subset of a string, using mb_substr if it is available.
63+
*
64+
* @param string $string String to subset
65+
* @param int $from Start offset
66+
* @param int|null $length Length to read
67+
*
68+
* @return string The string subset
69+
*/
70+
public static function substr($string, $from, $length = null)
71+
{
72+
if (false === $encoding = mb_detect_encoding($string, null, true)) {
73+
return substr($string);
74+
}
75+
76+
return mb_substr($string, $from, $length, $encoding);
77+
}
78+
6179
public static function formatTime($secs)
6280
{
6381
static $timeFormats = array(

‎src/Symfony/Component/Console/Tests/ApplicationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/ApplicationTest.php
+18-6Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Symfony\Component\Console\Event\ConsoleCommandEvent;
2929
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
3030
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
31+
use Symfony\Component\Console\Exception\CommandNotFoundException;
3132
use Symfony\Component\EventDispatcher\EventDispatcher;
3233

3334
class ApplicationTest extends \PHPUnit_Framework_TestCase
@@ -211,16 +212,15 @@ public function testFindNamespaceWithSubnamespaces()
211212
$this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns commands even if the commands are only contained in subnamespaces');
212213
}
213214

214-
/**
215-
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
216-
* @expectedExceptionMessage The namespace "f" is ambiguous (foo, foo1).
217-
*/
218215
public function testFindAmbiguousNamespace()
219216
{
220217
$application = new Application();
221218
$application->add(new \BarBucCommand());
222219
$application->add(new \FooCommand());
223220
$application->add(new \Foo2Command());
221+
222+
$expectedMsg = "The namespace \"f\" is ambiguous.\nDid you mean one of these?\n foo\n foo1";
223+
$this->setExpectedException(CommandNotFoundException::class, $expectedMsg);
224224
$application->findNamespace('f');
225225
}
226226

@@ -279,8 +279,20 @@ public function provideAmbiguousAbbreviations()
279279
{
280280
return array(
281281
array('f', 'Command "f" is not defined.'),
282-
array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'),
283-
array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).'),
282+
array(
283+
'a',
284+
"Command \"a\" is ambiguous.\nDid you mean one of these?\n".
285+
" afoobar The foo:bar command\n".
286+
" afoobar1 The foo:bar1 command\n".
287+
' afoobar2 The foo1:bar command',
288+
),
289+
array(
290+
'foo:b',
291+
"Command \"foo:b\" is ambiguous.\nDid you mean one of these?\n".
292+
" foo:bar The foo:bar command\n".
293+
" foo:bar1 The foo:bar1 command\n".
294+
' foo1:bar The foo1:bar command',
295+
),
284296
);
285297
}
286298

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.