|
13 | 13 |
|
14 | 14 | use Symfony\Component\Console\ConsoleEvents;
|
15 | 15 | use Symfony\Component\Console\Event\ConsoleErrorEvent;
|
16 |
| -use Symfony\Component\Console\Exception\NamespaceNotFoundException; |
| 16 | +use Symfony\Component\Console\Exception\CommandNotFoundException; |
17 | 17 | use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
18 | 18 |
|
19 | 19 | /**
|
|
24 | 24 | */
|
25 | 25 | final class SuggestMissingPackageSubscriber implements EventSubscriberInterface
|
26 | 26 | {
|
27 |
| - /** |
28 |
| - * Mappings between namespaces of Symfony commands and packages required to run these commands. |
29 |
| - * |
30 |
| - * @var array |
31 |
| - */ |
32 |
| - private static $suggestedPackages = [ |
| 27 | + private const PACKAGES = [ |
33 | 28 | 'doctrine' => [
|
34 |
| - 'Doctrine ORM', |
35 |
| - 'symfony/orm-pack', |
| 29 | + 'fixtures' => ['DoctrineFixturesBundle', 'doctrine/doctrine-fixtures-bundle --dev'], |
| 30 | + 'mongodb' => ['DoctrineMongoDBBundle', 'doctrine/mongodb-odm-bundle'], |
| 31 | + '_default' => ['Doctrine ORM', 'symfony/orm-pack'], |
36 | 32 | ],
|
37 | 33 | 'generate' => [
|
38 |
| - 'SensioGeneratorBundle', |
39 |
| - 'sensio/generator-bundle', |
| 34 | + '_default' => ['SensioGeneratorBundle', 'sensio/generator-bundle'], |
40 | 35 | ],
|
41 | 36 | 'make' => [
|
42 |
| - 'MakerBundle', |
43 |
| - 'symfony/maker-bundle --dev', |
| 37 | + '_default' => ['MakerBundle', 'symfony/maker-bundle --dev'], |
44 | 38 | ],
|
45 | 39 | 'server' => [
|
46 |
| - 'Symfony Web Server', |
47 |
| - 'symfony/web-server-bundle --dev', |
| 40 | + 'dump' => ['VarDumper Component', 'symfony/var-dumper --dev'], |
| 41 | + '_default' => ['WebServerBundle', 'symfony/web-server-bundle --dev'], |
48 | 42 | ],
|
49 | 43 | ];
|
50 | 44 |
|
51 |
| - public function onConsoleError(ConsoleErrorEvent $event) |
| 45 | + public function onConsoleError(ConsoleErrorEvent $event): void |
52 | 46 | {
|
53 |
| - if ($event->getError() instanceof NamespaceNotFoundException) { |
54 |
| - if (null !== $event->getInput()->getFirstArgument()) { |
55 |
| - $namespace = explode(':', $event->getInput()->getFirstArgument())[0]; |
| 47 | + if (!$event->getError() instanceof CommandNotFoundException || empty($input = $event->getInput()->getFirstArgument())) { |
| 48 | + return; |
| 49 | + } |
| 50 | + |
| 51 | + $input = explode(':', $input); |
| 52 | + $namespace = $input[0]; |
| 53 | + $command = $input[1] ?? ''; |
| 54 | + |
| 55 | + if (!isset(self::PACKAGES[$namespace])) { |
| 56 | + return; |
| 57 | + } |
56 | 58 |
|
57 |
| - if (isset(self::$suggestedPackages[$namespace])) { |
58 |
| - $suggestion = self::$suggestedPackages[$namespace]; |
59 |
| - $message = sprintf("It seems that you are trying to run a command from '%s' bundle/package, but you do not have it installed. You may try installing the missing bundle/package by running:\n\n composer require %s", $suggestion[0], $suggestion[1]); |
60 |
| - $event->setError(new NamespaceNotFoundException($message)); |
61 |
| - } |
62 |
| - } |
| 59 | + if (isset(self::PACKAGES[$namespace][$command]) && '' !== $command) { |
| 60 | + $suggestion = self::PACKAGES[$namespace][$command]; |
| 61 | + $exact = true; |
| 62 | + } else { |
| 63 | + $suggestion = self::PACKAGES[$namespace]['_default']; |
| 64 | + $exact = false; |
63 | 65 | }
|
| 66 | + |
| 67 | + $error = $event->getError(); |
| 68 | + |
| 69 | + if (!empty($error->getAlternatives()) && !$exact) { |
| 70 | + return; |
| 71 | + } |
| 72 | + |
| 73 | + $message = sprintf("%s\n\nYou may be looking for a command provided by the \"%s\" which is currently not installed. Try running \"composer require %s\".", $error->getMessage(), $suggestion[0], $suggestion[1]); |
| 74 | + $event->setError(new CommandNotFoundException($message)); |
64 | 75 | }
|
65 | 76 |
|
66 |
| - public static function getSubscribedEvents() |
| 77 | + public static function getSubscribedEvents(): array |
67 | 78 | {
|
68 | 79 | return [
|
69 | 80 | ConsoleEvents::ERROR => ['onConsoleError', 0],
|
|
0 commit comments