[Console] Added namespace suggest on bad namespace name
This commit is contained in:
parent
117359a196
commit
c6203bcffa
@ -489,7 +489,14 @@ class Application
|
|||||||
$abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $allNamespaces)))));
|
$abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $allNamespaces)))));
|
||||||
|
|
||||||
if (!isset($abbrevs[$part])) {
|
if (!isset($abbrevs[$part])) {
|
||||||
throw new \InvalidArgumentException(sprintf('There are no commands defined in the "%s" namespace.', $namespace));
|
$message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
|
||||||
|
|
||||||
|
if ($alternatives = $this->findAlternativeNamespace($namespace)) {
|
||||||
|
$message .= "\n\nDid you mean one of these?\n ";
|
||||||
|
$message .= implode("\n ", $alternatives);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \InvalidArgumentException($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($abbrevs[$part]) > 1) {
|
if (count($abbrevs[$part]) > 1) {
|
||||||
@ -560,7 +567,7 @@ class Application
|
|||||||
$message = sprintf('Command "%s" is not defined.', $name);
|
$message = sprintf('Command "%s" is not defined.', $name);
|
||||||
|
|
||||||
if ($alternatives = $this->findAlternativeCommands($searchName)) {
|
if ($alternatives = $this->findAlternativeCommands($searchName)) {
|
||||||
$message .= "\nDid you mean one of these?\n ";
|
$message .= "\n\nDid you mean one of these?\n ";
|
||||||
$message .= implode("\n ", $alternatives);
|
$message .= implode("\n ", $alternatives);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,17 +934,50 @@ class Application
|
|||||||
* Finds alternative commands of $name
|
* Finds alternative commands of $name
|
||||||
*
|
*
|
||||||
* @param string $name The full name of the command
|
* @param string $name The full name of the command
|
||||||
|
*
|
||||||
* @return array A sorted array of similar commands
|
* @return array A sorted array of similar commands
|
||||||
*/
|
*/
|
||||||
private function findAlternativeCommands($name)
|
private function findAlternativeCommands($name)
|
||||||
{
|
{
|
||||||
|
$getNameCallback = function($command) {
|
||||||
|
return $command->getName();
|
||||||
|
};
|
||||||
|
|
||||||
|
return $this->findAlternatives($name, $this->commands, $getNameCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds alternative namespace of $name
|
||||||
|
*
|
||||||
|
* @param string $name The full name of the namespace
|
||||||
|
*
|
||||||
|
* @return array A sorted array of similar namespace
|
||||||
|
*/
|
||||||
|
private function findAlternativeNamespace($name)
|
||||||
|
{
|
||||||
|
return $this->findAlternatives($name, $this->getNamespaces());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds alternative of $name among $collection
|
||||||
|
*
|
||||||
|
* @param string $name The string
|
||||||
|
* @param array|Traversable $collection The collection
|
||||||
|
* @param Closure|string|array $callback The callable to transform item before comparison
|
||||||
|
*
|
||||||
|
* @return array A sorted array of similar string
|
||||||
|
*/
|
||||||
|
private function findAlternatives($name, $collection, $callback = null) {
|
||||||
$alternatives = array();
|
$alternatives = array();
|
||||||
|
|
||||||
foreach ($this->commands as $command) {
|
foreach ($collection as $item) {
|
||||||
$commandName = $command->getName();
|
if (null !== $callback) {
|
||||||
$lev = levenshtein($name, $commandName);
|
$item = call_user_func($callback, $item);
|
||||||
if ($lev <= strlen($name) / 3 || false !== strpos($commandName, $name)) {
|
}
|
||||||
$alternatives[$commandName] = $lev;
|
|
||||||
|
$lev = levenshtein($name, $item);
|
||||||
|
if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
|
||||||
|
$alternatives[$item] = $lev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +242,35 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFindAlternativeNamespace()
|
||||||
|
{
|
||||||
|
$application = new Application();
|
||||||
|
|
||||||
|
$application->add(new \FooCommand());
|
||||||
|
$application->add(new \Foo1Command());
|
||||||
|
$application->add(new \Foo2Command());
|
||||||
|
$application->add(new \foo3Command());
|
||||||
|
|
||||||
|
try {
|
||||||
|
$application->find('Unknow-namespace:Unknow-command');
|
||||||
|
$this->fail('->find() throws an \InvalidArgumentException if namespace does not exist');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if namespace does not exist');
|
||||||
|
$this->assertEquals('There are no commands defined in the "Unknow-namespace" namespace.', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, without alternatives');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$application->find('foo2:command');
|
||||||
|
$this->fail('->find() throws an \InvalidArgumentException if namespace does not exist');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if namespace does not exist');
|
||||||
|
$this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative');
|
||||||
|
$this->assertRegExp('/foo/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo"');
|
||||||
|
$this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo1"');
|
||||||
|
$this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo3"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function testSetCatchExceptions()
|
public function testSetCatchExceptions()
|
||||||
{
|
{
|
||||||
$application = new Application();
|
$application = new Application();
|
||||||
|
Reference in New Issue
Block a user