From 8abf50639a245bd4d71b772541c5e515f1a287aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Sun, 12 Feb 2012 17:53:56 +0100 Subject: [PATCH] [Console] Added abbreviation into search for bad command / namespace --- src/Symfony/Component/Console/Application.php | 59 ++++++++++++------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 03c7d18a6c..ab91a81206 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -491,7 +491,11 @@ class Application if (!isset($abbrevs[$part])) { $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); - if ($alternatives = $this->findAlternativeNamespace($namespace)) { + if (1 <= $i) { + $part = implode(':',$found).':'.$part; + } + + if ($alternatives = $this->findAlternativeNamespace($part, $abbrevs)) { $message .= "\n\nDid you mean one of these?\n "; $message .= implode("\n ", $alternatives); } @@ -562,11 +566,11 @@ class Application } } - $abbrevs = static::getAbbreviations(array_unique($aliases)); - if (!isset($abbrevs[$searchName])) { + $aliases = static::getAbbreviations(array_unique($aliases)); + if (!isset($aliases[$searchName])) { $message = sprintf('Command "%s" is not defined.', $name); - if ($alternatives = $this->findAlternativeCommands($searchName)) { + if ($alternatives = $this->findAlternativeCommands($searchName, $abbrevs)) { $message .= "\n\nDid you mean one of these?\n "; $message .= implode("\n ", $alternatives); } @@ -574,11 +578,11 @@ class Application throw new \InvalidArgumentException($message); } - if (count($abbrevs[$searchName]) > 1) { - throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $this->getAbbreviationSuggestions($abbrevs[$searchName]))); + if (count($aliases[$searchName]) > 1) { + throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $this->getAbbreviationSuggestions($aliases[$searchName]))); } - return $this->get($abbrevs[$searchName][0]); + return $this->get($aliases[$searchName][0]); } /** @@ -933,45 +937,49 @@ class Application /** * Finds alternative commands of $name * - * @param string $name The full name of the command + * @param string $name The full name of the command + * @param array $abbrevs The abbreviations * * @return array A sorted array of similar commands */ - private function findAlternativeCommands($name) + private function findAlternativeCommands($name, $abbrevs) { - $getNameCallback = function($command) { - return $command->getName(); + $callback = function($item) { + return $item->getName(); }; - return $this->findAlternatives($name, $this->commands, $getNameCallback); + return $this->findAlternatives($name, $this->commands, $abbrevs, $callback); } /** * Finds alternative namespace of $name * - * @param string $name The full name of the namespace + * @param string $name The full name of the namespace + * @param array $abbrevs The abbreviations * * @return array A sorted array of similar namespace */ - private function findAlternativeNamespace($name) + private function findAlternativeNamespace($name, $abbrevs) { - return $this->findAlternatives($name, $this->getNamespaces()); + return $this->findAlternatives($name, $this->getNamespaces(), $abbrevs); } /** - * Finds alternative of $name among $collection + * Finds alternative of $name among $collection, + * if nothing is found in $collection, try in $abbrevs * * @param string $name The string - * @param array|Traversable $collection The collection - * @param Closure|string|array $callback The callable to transform item before comparison + * @param array|Traversable $collection The collecion + * @param array $abbrevs The abbreviations + * @param Closure|string|array $callback The callable to transform collection item before comparison * * @return array A sorted array of similar string */ - private function findAlternatives($name, $collection, $callback = null) { + private function findAlternatives($name, $collection, $abbrevs, $callback = null) { $alternatives = array(); foreach ($collection as $item) { - if (null !== $callback) { + if(null !== $callback) { $item = call_user_func($callback, $item); } @@ -981,6 +989,17 @@ class Application } } + if (!$alternatives) { + foreach ($abbrevs as $key => $values) { + $lev = levenshtein($name, $key); + if ($lev <= strlen($name) / 3 || false !== strpos($key, $name)) { + foreach ($values as $value) { + $alternatives[$value] = $lev; + } + } + } + } + asort($alternatives); return array_keys($alternatives);