2024-04-27 22:21:12 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Console\Commands\Bundle;
|
|
|
|
|
|
|
|
use App\Classes\Bundle;
|
|
|
|
use Illuminate\Console\Command;
|
2024-05-06 21:20:43 +02:00
|
|
|
use Illuminate\Contracts\Filesystem\Filesystem;
|
2024-04-27 22:21:12 +02:00
|
|
|
use Illuminate\Support\Facades\Process;
|
|
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
|
2024-05-03 16:16:19 +02:00
|
|
|
use function Laravel\Prompts\confirm;
|
2024-04-27 22:21:12 +02:00
|
|
|
use function Laravel\Prompts\progress;
|
|
|
|
|
|
|
|
class Render extends Command
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* The console command description.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $description = 'Render bundles';
|
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
protected Filesystem $sourceDisk;
|
|
|
|
|
|
|
|
protected Filesystem $targetDisk;
|
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
$this->signature = 'bundle:render
|
|
|
|
{ --a|assets : Rebuild assets - implies <info>-c</info> }
|
|
|
|
{ --c|clear-cache : Clear cache before rendering }
|
2024-05-08 15:15:14 +02:00
|
|
|
{ --deploy : Deploy without asking }
|
2024-05-06 21:20:43 +02:00
|
|
|
{ --d|dry-run : Show what would be done but do nothing }
|
|
|
|
{ --no-deploy : Do not deploy, do not ask to deploy }
|
|
|
|
{ --r|recursive : Also render sub-bundles }
|
|
|
|
{ --source-disk= : Use specified content disk - Defaults to <info>' . env('CONTENT_DISK') . '</info> }
|
|
|
|
{ --target-disk= : Use specified rendering disk - Defaults to <info>' . env('DIST_DISK') . '</info> }
|
|
|
|
{ path? : Path to a specific bundle to render - Default to <info>/</info> }
|
|
|
|
';
|
|
|
|
|
|
|
|
parent::__construct();
|
|
|
|
}
|
|
|
|
|
2024-04-27 22:21:12 +02:00
|
|
|
/**
|
|
|
|
* Execute the console command.
|
|
|
|
*/
|
|
|
|
public function handle()
|
|
|
|
{
|
2024-05-06 21:20:43 +02:00
|
|
|
$this->showDisclaimer()
|
|
|
|
->selectDisk()
|
|
|
|
->renderAssets()
|
|
|
|
->clearCache()
|
|
|
|
->render()
|
|
|
|
->deploy();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show a "disclaimer" for running dry-mode
|
|
|
|
*/
|
|
|
|
private function showDisclaimer(): self
|
|
|
|
{
|
|
|
|
if (!$this->option('dry-run')) {
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->newLine();
|
|
|
|
$this->warn('Running dry-mode: no modification will be done');
|
|
|
|
$this->newLine();
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Select the disk we will be working on
|
|
|
|
*/
|
|
|
|
private function selectDisk(): self
|
|
|
|
{
|
|
|
|
$sourceDisk = $this->option('source-disk') ?? env('CONTENT_DISK');
|
|
|
|
$targetDisk = $this->option('target-disk') ?? env('DIST_DISK');
|
|
|
|
|
|
|
|
$this->sourceDisk = Storage::disk($sourceDisk);
|
|
|
|
$this->targetDisk = Storage::disk($targetDisk);
|
|
|
|
|
2024-05-08 14:55:39 +02:00
|
|
|
$this->line(
|
2024-05-06 21:20:43 +02:00
|
|
|
sprintf(
|
2024-05-08 14:55:39 +02:00
|
|
|
'Using <info>%s</info> as source disk and <info>%s</info> as target disk for generated content',
|
2024-05-06 21:20:43 +02:00
|
|
|
$sourceDisk,
|
|
|
|
$targetDisk
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build assets, and clear cache afterwise
|
|
|
|
*/
|
|
|
|
private function renderAssets(): self
|
|
|
|
{
|
|
|
|
// Do not re-generate assets if we didn't explicitely asked for it
|
|
|
|
if (!$this->option('assets')) {
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->output->write('Building assets... ');
|
|
|
|
|
|
|
|
if (!$this->option('dry-run')) {
|
2024-04-28 11:34:20 +02:00
|
|
|
Process::run('npm run build')->throw();
|
2024-05-06 21:20:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->info('OK');
|
2024-04-28 11:34:20 +02:00
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear application cache
|
|
|
|
*/
|
|
|
|
private function clearCache(): self
|
|
|
|
{
|
|
|
|
// Do not clear cache if we didn't explicitely asked for it
|
|
|
|
if (!$this->option('clear-cache') && !$this->option('assets')) {
|
|
|
|
return $this;
|
2024-04-28 11:34:20 +02:00
|
|
|
}
|
2024-04-27 22:21:12 +02:00
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
// For now, we need to clear the cache, otherwise rendered HTML will
|
|
|
|
// still reference old assets
|
|
|
|
$this->output->write('Clearing cache... ');
|
2024-04-27 22:21:12 +02:00
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
if (!$this->option('dry-run')) {
|
|
|
|
$this->call('cache:clear', ['--quiet']);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->info('OK');
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Collect a list of bundles to render
|
|
|
|
*/
|
|
|
|
private function getBundles()
|
|
|
|
{
|
|
|
|
$path = $this->argument('path') ?? '/';
|
2024-05-08 14:55:39 +02:00
|
|
|
$comment = sprintf('Rendering <info>%s</info>', $path);
|
2024-05-06 21:20:43 +02:00
|
|
|
|
|
|
|
if ($this->option('recursive')) {
|
2024-05-08 14:55:39 +02:00
|
|
|
$comment .= ' and <info>all sub-bundles</info>';
|
2024-05-06 21:20:43 +02:00
|
|
|
}
|
|
|
|
|
2024-05-08 14:55:39 +02:00
|
|
|
$this->line($comment);
|
2024-05-06 21:20:43 +02:00
|
|
|
$this->output->write('Collecting bundles... ');
|
|
|
|
|
|
|
|
if ($this->option('recursive')) {
|
|
|
|
$bundles = Bundle::findBundles($this->sourceDisk, $path, true);
|
|
|
|
} else {
|
|
|
|
$bundles = [new Bundle($path, $this->sourceDisk)];
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->info('OK');
|
|
|
|
|
|
|
|
return $bundles;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform rendering
|
|
|
|
*/
|
|
|
|
private function render(): self
|
|
|
|
{
|
|
|
|
$bundles = $this->getBundles();
|
2024-04-27 22:21:12 +02:00
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
progress(
|
|
|
|
label: 'Rendering... ',
|
|
|
|
steps: $bundles,
|
|
|
|
callback: fn (Bundle $bundle, $progress) => $this->handleBundle($bundle, $progress)
|
|
|
|
);
|
2024-04-27 22:21:12 +02:00
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle specific bundle
|
|
|
|
*/
|
|
|
|
private function handleBundle(Bundle $bundle, $progress)
|
|
|
|
{
|
|
|
|
$progress->label(sprintf('Rendering %s ...', $bundle->getPath()));
|
2024-05-08 14:55:39 +02:00
|
|
|
$progress->hint('Rendering the bundle');
|
2024-05-06 21:20:43 +02:00
|
|
|
|
|
|
|
if ($this->option('dry-run')) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$result = $bundle->render();
|
|
|
|
|
|
|
|
foreach ($result as $path => $content) {
|
|
|
|
if (!Str::contains($path, '.')) {
|
|
|
|
$path = Str::finish($path, '/') . 'index.html';
|
2024-04-27 22:21:12 +02:00
|
|
|
}
|
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
$progress->hint(sprintf('Storing %s', $path));
|
|
|
|
|
|
|
|
$this->targetDisk->put($path, $content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deploy to remote server
|
|
|
|
*/
|
|
|
|
private function deploy()
|
|
|
|
{
|
|
|
|
// Do not even ask if --no-deploy was used
|
|
|
|
if ($this->option('no-deploy')) {
|
|
|
|
return;
|
2024-04-27 22:21:12 +02:00
|
|
|
}
|
|
|
|
|
2024-05-08 15:15:14 +02:00
|
|
|
if (!$this->option('deploy')) {
|
|
|
|
// Ask for confirmation
|
|
|
|
if (!confirm('Ready to deploy?')) {
|
|
|
|
$this->comment('OK, not deploying!');
|
2024-04-27 22:21:12 +02:00
|
|
|
|
2024-05-08 15:15:14 +02:00
|
|
|
return;
|
|
|
|
}
|
2024-05-06 21:20:43 +02:00
|
|
|
}
|
2024-04-27 22:21:12 +02:00
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
$source = Str::finish($this->targetDisk->path('/'), '/');
|
|
|
|
$target = env('DEPLOY_TARGET');
|
|
|
|
$command = __(env('DEPLOY_COMMAND'), [
|
|
|
|
'source' => $source,
|
|
|
|
'target' => $target,
|
|
|
|
]);
|
2024-04-27 22:21:12 +02:00
|
|
|
|
2024-05-06 21:20:43 +02:00
|
|
|
$this->output->write(sprintf('Deploying using `%s` ... ', $command));
|
|
|
|
|
|
|
|
if (!$this->option('dry-run')) {
|
2024-05-03 16:16:19 +02:00
|
|
|
Process::run($command)->throw();
|
|
|
|
}
|
2024-05-06 21:20:43 +02:00
|
|
|
|
|
|
|
$this->info('OK');
|
2024-04-27 22:21:12 +02:00
|
|
|
}
|
|
|
|
}
|