Skip to content

Commit d03f650

Browse files
[12.x] Add commandFileFinder method and exclude test files from command discovery (#58017)
* wip * formatting --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent d2d4a9e commit d03f650

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

src/Illuminate/Foundation/Console/Kernel.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ protected function load($paths)
366366

367367
$namespace = $this->app->getNamespace();
368368

369-
foreach (Finder::create()->in($paths)->files() as $file) {
369+
foreach ($this->findCommands($paths) as $file) {
370370
$command = $this->commandClassFromFile($file, $namespace);
371371

372372
if (is_subclass_of($command, Command::class) &&
@@ -378,6 +378,17 @@ protected function load($paths)
378378
}
379379
}
380380

381+
/**
382+
* Get the Finder instance for discovering command files.
383+
*
384+
* @param array $paths
385+
* @return \Symfony\Component\Finder\Finder
386+
*/
387+
protected function findCommands(array $paths)
388+
{
389+
return Finder::create()->in($paths)->notName('*Test.php')->files();
390+
}
391+
381392
/**
382393
* Extract the command class name from the given file path.
383394
*

tests/Console/ConsoleApplicationTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
99
use Illuminate\Events\Dispatcher as EventsDispatcher;
1010
use Illuminate\Foundation\Application as FoundationApplication;
11+
use Illuminate\Foundation\Console\Kernel;
1112
use Illuminate\Tests\Console\Fixtures\FakeCommandWithArrayInputPrompting;
1213
use Illuminate\Tests\Console\Fixtures\FakeCommandWithInputPrompting;
1314
use Mockery as m;
@@ -241,6 +242,35 @@ public function testCallMethodCanCallArtisanCommandUsingCommandClassObject()
241242
$this->assertSame(0, $exitCode);
242243
}
243244

245+
public function testLoadIgnoresTestFiles()
246+
{
247+
$dir = __DIR__.'/laravel';
248+
@mkdir($dir.'/app/Console/Commands', 0755, true);
249+
file_put_contents($dir.'/composer.json', json_encode(['autoload' => ['psr-4' => ['App\\' => 'app/']]]));
250+
file_put_contents($dir.'/app/Console/Commands/ExampleCommand.php', '<?php namespace App\Console\Commands; class ExampleCommand extends \Illuminate\Console\Command { protected $signature = "example"; public function handle() {} }');
251+
file_put_contents($dir.'/app/Console/Commands/ExampleCommandTest.php', '<?php namespace App\Console\Commands; class ExampleCommandTest extends \Illuminate\Console\Command { protected $signature = "example-test"; public function handle() {} }');
252+
253+
try {
254+
$app = new FoundationApplication($dir);
255+
$events = new EventsDispatcher($app);
256+
$app->instance('events', $events);
257+
258+
$kernel = new TestKernel($app, $events);
259+
$kernel->loadFrom([$dir.'/app/Console/Commands']);
260+
261+
$this->assertContains('App\Console\Commands\ExampleCommand', $kernel->loadedCommands);
262+
$this->assertNotContains('App\Console\Commands\ExampleCommandTest', $kernel->loadedCommands);
263+
} finally {
264+
@unlink($dir.'/app/Console/Commands/ExampleCommand.php');
265+
@unlink($dir.'/app/Console/Commands/ExampleCommandTest.php');
266+
@unlink($dir.'/composer.json');
267+
@rmdir($dir.'/app/Console/Commands');
268+
@rmdir($dir.'/app/Console');
269+
@rmdir($dir.'/app');
270+
@rmdir($dir);
271+
}
272+
}
273+
244274
protected function getMockConsole(array $methods)
245275
{
246276
$app = m::mock(ApplicationContract::class, ['version' => '6.0']);
@@ -273,3 +303,18 @@ class CommandWithAliasViaProperty extends Command
273303
public $name = 'command-name';
274304
public $aliases = ['command-alias'];
275305
}
306+
307+
class TestKernel extends Kernel
308+
{
309+
public $loadedCommands = [];
310+
311+
public function loadFrom($paths)
312+
{
313+
$this->load($paths);
314+
}
315+
316+
protected function commandClassFromFile(\SplFileInfo $file, string $namespace): string
317+
{
318+
return tap(parent::commandClassFromFile($file, $namespace), fn ($command) => $this->loadedCommands[] = $command);
319+
}
320+
}

0 commit comments

Comments
 (0)