Skip to content

Commit d70e372

Browse files
authored
[12.x] Allow passing command class instances directly to Schedule::command() and Artisan::call() (#56530)
* feat: Run command using command class object * fix: style ci * fix tests: call get_class only on objects * fix: style ci
1 parent c01b73d commit d70e372

File tree

7 files changed

+60
-6
lines changed

7 files changed

+60
-6
lines changed

src/Illuminate/Console/Application.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public static function forgetBootstrappers()
147147
/**
148148
* Run an Artisan console command by name.
149149
*
150-
* @param string $command
150+
* @param \Symfony\Component\Console\Command\Command|string $command
151151
* @param array $parameters
152152
* @param \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer
153153
* @return int
@@ -170,7 +170,7 @@ public function call($command, array $parameters = [], $outputBuffer = null)
170170
/**
171171
* Parse the incoming Artisan command and its input.
172172
*
173-
* @param string $command
173+
* @param \Symfony\Component\Console\Command\Command|string $command
174174
* @param array $parameters
175175
* @return array
176176
*/
@@ -179,6 +179,10 @@ protected function parseCommand($command, $parameters)
179179
if (is_subclass_of($command, SymfonyCommand::class)) {
180180
$callingClass = true;
181181

182+
if (is_object($command)) {
183+
$command = get_class($command);
184+
}
185+
182186
$command = $this->laravel->make($command)->getName();
183187
}
184188

src/Illuminate/Console/Scheduling/Schedule.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Illuminate\Support\ProcessUtils;
1919
use Illuminate\Support\Traits\Macroable;
2020
use RuntimeException;
21+
use Symfony\Component\Console\Command\Command as SymfonyCommand;
2122

2223
use function Illuminate\Support\enum_value;
2324

@@ -149,12 +150,22 @@ public function call($callback, array $parameters = [])
149150
/**
150151
* Add a new Artisan command event to the schedule.
151152
*
152-
* @param string $command
153+
* @param \Symfony\Component\Console\Command\Command|string $command
153154
* @param array $parameters
154155
* @return \Illuminate\Console\Scheduling\Event
155156
*/
156157
public function command($command, array $parameters = [])
157158
{
159+
if ($command instanceof SymfonyCommand) {
160+
$command = get_class($command);
161+
162+
$command = Container::getInstance()->make($command);
163+
164+
return $this->exec(
165+
Application::formatCommandString($command->getName()), $parameters,
166+
)->description($command->getDescription());
167+
}
168+
158169
if (class_exists($command)) {
159170
$command = Container::getInstance()->make($command);
160171

src/Illuminate/Foundation/Console/Kernel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ public function registerCommand($command)
408408
/**
409409
* Run an Artisan console command by name.
410410
*
411-
* @param string $command
411+
* @param \Symfony\Component\Console\Command\Command|string $command
412412
* @param array $parameters
413413
* @param \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer
414414
* @return int

src/Illuminate/Support/Facades/Artisan.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* @method static \Illuminate\Console\Scheduling\Schedule resolveConsoleSchedule()
1313
* @method static \Illuminate\Foundation\Console\ClosureCommand command(string $signature, \Closure $callback)
1414
* @method static void registerCommand(\Symfony\Component\Console\Command\Command $command)
15-
* @method static int call(string $command, array $parameters = [], \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer = null)
15+
* @method static int call(\Symfony\Component\Console\Command\Command|string $command, array $parameters = [], \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer = null)
1616
* @method static \Illuminate\Foundation\Bus\PendingDispatch queue(string $command, array $parameters = [])
1717
* @method static array all()
1818
* @method static string output()

src/Illuminate/Support/Facades/Schedule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
/**
88
* @method static \Illuminate\Console\Scheduling\CallbackEvent call(string|callable $callback, array $parameters = [])
9-
* @method static \Illuminate\Console\Scheduling\Event command(string $command, array $parameters = [])
9+
* @method static \Illuminate\Console\Scheduling\Event command(\Symfony\Component\Console\Command\Command|string $command, array $parameters = [])
1010
* @method static \Illuminate\Console\Scheduling\CallbackEvent job(object|string $job, \UnitEnum|string|null $queue = null, \UnitEnum|string|null $connection = null)
1111
* @method static \Illuminate\Console\Scheduling\Event exec(string $command, array $parameters = [])
1212
* @method static void group(\Closure $events)

tests/Console/ConsoleApplicationTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,25 @@ public function testCommandInputDoesntPromptWhenRequiredArgumentsArePassed()
222222
$this->assertSame(0, $statusCode);
223223
}
224224

225+
public function testCallMethodCanCallArtisanCommandUsingCommandClassObject()
226+
{
227+
$app = new Application(
228+
$laravel = new \Illuminate\Foundation\Application(__DIR__),
229+
$events = m::mock(Dispatcher::class, ['dispatch' => null, 'fire' => null]),
230+
'testing'
231+
);
232+
233+
$app->addCommands([$command = new FakeCommandWithInputPrompting()]);
234+
235+
$command->setLaravel($laravel);
236+
237+
$statusCode = $app->call($command);
238+
239+
$this->assertTrue($command->prompted);
240+
$this->assertSame('foo', $command->argument('name'));
241+
$this->assertSame(0, $statusCode);
242+
}
243+
225244
protected function getMockConsole(array $methods)
226245
{
227246
$app = m::mock(ApplicationContract::class, ['version' => '6.0']);

tests/Console/ConsoleEventSchedulerTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,26 @@ public function testCreateNewArtisanCommandUsingCommandClass()
117117
$this->assertEquals($phpBinary.' '.$artisanBinary.' foo:bar --force', $events[0]->command);
118118
}
119119

120+
public function testCreateNewArtisanCommandUsingCommandClassObject()
121+
{
122+
$command = new class extends Command
123+
{
124+
protected $signature = 'foo:bar';
125+
126+
public function handle()
127+
{
128+
}
129+
};
130+
131+
$schedule = $this->schedule;
132+
$schedule->command($command, ['--force']);
133+
134+
$events = $schedule->events();
135+
$phpBinary = Application::phpBinary();
136+
$artisanBinary = Application::artisanBinary();
137+
$this->assertEquals($phpBinary.' '.$artisanBinary.' foo:bar --force', $events[0]->command);
138+
}
139+
120140
public function testItUsesCommandDescriptionAsEventDescription()
121141
{
122142
$schedule = $this->schedule;

0 commit comments

Comments
 (0)