Skip to content

Commit

Permalink
[11.x] Optimize commands registry (#52928)
Browse files Browse the repository at this point in the history
* [11.x] Optimize commands registration

* formatting

---------

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
erikgaal and taylorotwell authored Oct 8, 2024
1 parent b5a17c7 commit 1f12e50
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 14 deletions.
30 changes: 22 additions & 8 deletions src/Illuminate/Foundation/Console/OptimizeClearCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Foundation\Console;

use Illuminate\Console\Command;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'optimize:clear')]
Expand Down Expand Up @@ -31,15 +32,28 @@ public function handle()
{
$this->components->info('Clearing cached bootstrap files.');

collect([
'cache' => fn () => $this->callSilent('cache:clear') == 0,
'compiled' => fn () => $this->callSilent('clear-compiled') == 0,
'config' => fn () => $this->callSilent('config:clear') == 0,
'events' => fn () => $this->callSilent('event:clear') == 0,
'routes' => fn () => $this->callSilent('route:clear') == 0,
'views' => fn () => $this->callSilent('view:clear') == 0,
])->each(fn ($task, $description) => $this->components->task($description, $task));
foreach ($this->getOptimizeClearTasks() as $description => $command) {
$this->components->task($description, fn () => $this->callSilently($command) == 0);
}

$this->newLine();
}

/**
* Get the commands that should be run to clear the "optimization" files.
*
* @return array
*/
public function getOptimizeClearTasks()
{
return [
'cache' => 'cache:clear',
'compiled' => 'clear-compiled',
'config' => 'config:clear',
'events' => 'event:clear',
'routes' => 'route:clear',
'views' => 'view:clear',
...ServiceProvider::$optimizeClearCommands,
];
}
}
26 changes: 20 additions & 6 deletions src/Illuminate/Foundation/Console/OptimizeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Foundation\Console;

use Illuminate\Console\Command;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'optimize')]
Expand Down Expand Up @@ -31,13 +32,26 @@ public function handle()
{
$this->components->info('Caching framework bootstrap, configuration, and metadata.');

collect([
'config' => fn () => $this->callSilent('config:cache') == 0,
'events' => fn () => $this->callSilent('event:cache') == 0,
'routes' => fn () => $this->callSilent('route:cache') == 0,
'views' => fn () => $this->callSilent('view:cache') == 0,
])->each(fn ($task, $description) => $this->components->task($description, $task));
foreach ($this->getOptimizeTasks() as $description => $command) {
$this->components->task($description, fn () => $this->callSilently($command) == 0);
}

$this->newLine();
}

/**
* Get the commands that should be run to optimize the framework.
*
* @return array
*/
protected function getOptimizeTasks()
{
return [
'config' => 'config:cache',
'events' => 'event:cache',
'routes' => 'route:cache',
'views' => 'view:cache',
...ServiceProvider::$optimizeCommands,
];
}
}
45 changes: 45 additions & 0 deletions src/Illuminate/Support/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Contracts\Foundation\CachesRoutes;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Database\Eloquent\Factory as ModelFactory;
use Illuminate\Support\Str;
use Illuminate\View\Compilers\BladeCompiler;

/**
Expand Down Expand Up @@ -58,6 +59,20 @@ abstract class ServiceProvider
*/
protected static $publishableMigrationPaths = [];

/**
* Commands that should be run during the "optimize" command.
*
* @var array<string, string>
*/
public static array $optimizeCommands = [];

/**
* Commands that should be run during the "optimize:clear" command.
*
* @var array<string, string>
*/
public static array $optimizeClearCommands = [];

/**
* Create a new service provider instance.
*
Expand Down Expand Up @@ -460,6 +475,36 @@ public function commands($commands)
});
}

/**
* Register commands that should run on "optimize" or "optimize:clear".
*
* @param string $optimize
* @param string $clear
* @param string|null $key
* @return void
*/
protected function optimizes(string $optimize = null, string $clear = null, ?string $key = null)
{
$key ??= (string) Str::of(get_class($this))
->classBasename()
->before('ServiceProvider')
->kebab()
->lower()
->trim();

if (empty($key)) {
$key = class_basename(get_class($this));
}

if ($optimize) {
static::$optimizeCommands[$key] = $optimize;
}

if ($clear) {
static::$optimizeClearCommands[$key] = $clear;
}
}

/**
* Get the services provided by the provider.
*
Expand Down
36 changes: 36 additions & 0 deletions tests/Integration/Foundation/Console/OptimizeClearCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Illuminate\Tests\Integration\Foundation\Console;

use Illuminate\Foundation\Console\ClosureCommand;
use Illuminate\Support\ServiceProvider;
use Illuminate\Tests\Integration\Generators\TestCase;

class OptimizeClearCommandTest extends TestCase
{
protected function getPackageProviders($app): array
{
return [ServiceProviderWithOptimizeClear::class];
}

public function testCanListenToOptimizingEvent(): void
{
$this->artisan('optimize:clear')
->assertSuccessful()
->expectsOutputToContain('ServiceProviderWithOptimizeClear');
}
}

class ServiceProviderWithOptimizeClear extends ServiceProvider
{
public function boot(): void
{
$this->commands([
new ClosureCommand('my_package:clear', fn () => 0),
]);

$this->optimizes(
clear: 'my_package:clear',
);
}
}
37 changes: 37 additions & 0 deletions tests/Integration/Foundation/Console/OptimizeCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Illuminate\Tests\Integration\Foundation\Console;

use Illuminate\Foundation\Console\ClosureCommand;
use Illuminate\Support\ServiceProvider;
use Illuminate\Tests\Integration\Generators\TestCase;

class OptimizeCommandTest extends TestCase
{
protected function getPackageProviders($app): array
{
return [ServiceProviderWithOptimize::class];
}

public function testCanListenToOptimizingEvent(): void
{
$this->artisan('optimize')
->assertSuccessful()
->expectsOutputToContain('my package');
}
}

class ServiceProviderWithOptimize extends ServiceProvider
{
public function boot(): void
{
$this->commands([
new ClosureCommand('my_package:cache', fn () => 0),
]);

$this->optimizes(
optimize: 'my_package:cache',
key: 'my package',
);
}
}

0 comments on commit 1f12e50

Please sign in to comment.