1616use Symfony \Bundle \MakerBundle \Generator ;
1717use Symfony \Bundle \MakerBundle \InputConfiguration ;
1818use Symfony \Bundle \MakerBundle \Str ;
19+ use Symfony \Bundle \MakerBundle \Util \ClassNameDetails ;
1920use Symfony \Bundle \MakerBundle \Util \PhpCompatUtil ;
2021use Symfony \Bundle \MakerBundle \Util \UseStatementGenerator ;
22+ use Symfony \Component \Console \Attribute \Argument ;
2123use Symfony \Component \Console \Attribute \AsCommand ;
24+ use Symfony \Component \Console \Attribute \Option ;
2225use Symfony \Component \Console \Command \Command ;
2326use Symfony \Component \Console \Command \LazyCommand ;
2427use Symfony \Component \Console \Input \InputArgument ;
2528use Symfony \Component \Console \Input \InputInterface ;
2629use Symfony \Component \Console \Input \InputOption ;
2730use Symfony \Component \Console \Output \OutputInterface ;
2831use Symfony \Component \Console \Style \SymfonyStyle ;
32+ use Symfony \Component \HttpKernel \Kernel ;
2933
3034/**
3135 * @author Javier Eguiluz <javier.eguiluz@gmail.com>
@@ -60,15 +64,19 @@ public function configureCommand(Command $command, InputConfiguration $inputConf
6064 ->addArgument ('name ' , InputArgument::OPTIONAL , \sprintf ('Choose a command name (e.g. <fg=yellow>app:%s</>) ' , Str::asCommand (Str::getRandomTerm ())))
6165 ->setHelp ($ this ->getHelpFileContents ('MakeCommand.txt ' ))
6266 ;
67+
68+ if ($ this ->supportsInvokableCommand ()) {
69+ $ command ->addOption ('invokable ' , 'i ' , InputOption::VALUE_NONE , 'Use this option to create an invokable command ' );
70+ }
6371 }
6472
6573 public function generate (InputInterface $ input , ConsoleStyle $ io , Generator $ generator ): void
6674 {
67- $ this ->generateInheritanceCommand ($ input , $ io , $ generator );
68- }
75+ if (true !== $ input ->getOption ('invokable ' ) && $ this ->supportsInvokableCommand ()) {
76+ $ wantsInvokable = $ io ->confirm ('Would you like this command to be inokvable? ' , false );
77+ $ input ->setOption ('invokable ' , $ wantsInvokable );
78+ }
6979
70- private function generateInheritanceCommand (InputInterface $ input , ConsoleStyle $ io , Generator $ generator ): void
71- {
7280 $ commandName = trim ($ input ->getArgument ('name ' ));
7381 $ commandNameHasAppPrefix = str_starts_with ($ commandName , 'app: ' );
7482
@@ -79,6 +87,13 @@ private function generateInheritanceCommand(InputInterface $input, ConsoleStyle
7987 \sprintf ('The "%s" command name is not valid because it would be implemented by "%s" class, which is not valid as a PHP class name (it must start with a letter or underscore, followed by any number of letters, numbers, or underscores). ' , $ commandName , Str::asClassName ($ commandName , 'Command ' ))
8088 );
8189
90+ $ input ->getOption ('invokable ' ) ?
91+ $ this ->generateInvokableCommand ($ commandName , $ commandClassNameDetails , $ io , $ generator ) :
92+ $ this ->generateInheritanceCommand ($ commandName , $ commandClassNameDetails , $ io , $ generator );
93+ }
94+
95+ private function generateInheritanceCommand (string $ commandName , ClassNameDetails $ commandClassNameDetails , ConsoleStyle $ io , Generator $ generator ): void
96+ {
8297 $ useStatements = new UseStatementGenerator ([
8398 Command::class,
8499 InputArgument::class,
@@ -91,7 +106,7 @@ private function generateInheritanceCommand(InputInterface $input, ConsoleStyle
91106
92107 $ generator ->generateClass (
93108 $ commandClassNameDetails ->getFullName (),
94- 'command/Command .tpl.php ' ,
109+ 'command/InheritanceCommand .tpl.php ' ,
95110 [
96111 'use_statements ' => $ useStatements ,
97112 'command_name ' => $ commandName ,
@@ -108,11 +123,44 @@ private function generateInheritanceCommand(InputInterface $input, ConsoleStyle
108123 ]);
109124 }
110125
126+ private function generateInvokableCommand (string $ commandName , ClassNameDetails $ commandClassNameDetails , ConsoleStyle $ io , Generator $ generator ): void
127+ {
128+ $ useStatements = new UseStatementGenerator ([
129+ Argument::class,
130+ AsCommand::class,
131+ Command::class,
132+ Option::class,
133+ SymfonyStyle::class,
134+ ]);
135+
136+ $ generator ->generateClass (
137+ $ commandClassNameDetails ->getFullName (),
138+ 'command/Command.tpl.php ' ,
139+ [
140+ 'use_statements ' => $ useStatements ,
141+ 'command_name ' => $ commandName ,
142+ ]
143+ );
144+
145+ $ generator ->writeChanges ();
146+
147+ $ this ->writeSuccessMessage ($ io );
148+ $ io ->text ([
149+ 'Next: open your new command class and customize it! ' ,
150+ 'Find the documentation at <fg=yellow>https://symfony.com/doc/current/console.html</> ' ,
151+ ]);
152+ }
153+
111154 public function configureDependencies (DependencyBuilder $ dependencies ): void
112155 {
113156 $ dependencies ->addClassDependency (
114157 Command::class,
115158 'console '
116159 );
117160 }
161+
162+ private function supportsInvokableCommand (): bool
163+ {
164+ return Kernel::VERSION_ID >= 70300 ;
165+ }
118166}
0 commit comments