1
0

Refactoring

This commit is contained in:
Richard Dern 2024-05-06 21:20:43 +02:00
parent 454ce181b3
commit c254e29cca

View File

@ -4,6 +4,7 @@
use App\Classes\Bundle;
use Illuminate\Console\Command;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Support\Facades\Process;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
@ -13,13 +14,6 @@
class Render extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'bundle:render { --a|assets : Rebuild assets }';
/**
* The console command description.
*
@ -27,49 +21,219 @@ class Render extends Command
*/
protected $description = 'Render bundles';
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 }
{ --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();
}
/**
* Execute the console command.
*/
public function handle()
{
if ($this->option('assets')) {
$this->output->write('Building assets... ');
Process::run('npm run build')->throw();
$this->info('OK');
$this->showDisclaimer()
->selectDisk()
->renderAssets()
->clearCache()
->render()
->deploy();
}
$this->call('cache:clear');
/**
* Show a "disclaimer" for running dry-mode
*/
private function showDisclaimer(): self
{
if (!$this->option('dry-run')) {
return $this;
}
$path = '/';
$bundles = Bundle::findBundles(Storage::disk(env('CONTENT_DISK')), $path, true);
$progress = progress(label: 'Rendering... ', steps: count($bundles));
$progress->start();
$this->newLine();
$this->warn('Running dry-mode: no modification will be done');
$this->newLine();
foreach ($bundles as $bundle) {
$result = $bundle->render();
return $this;
}
foreach ($result as $path => $content) {
if (!Str::contains($path, '.')) {
$path = Str::finish($path, '/') . 'index.html';
}
/**
* 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');
Storage::disk(env('DIST_DISK'))->put($path, $content);
$this->sourceDisk = Storage::disk($sourceDisk);
$this->targetDisk = Storage::disk($targetDisk);
$this->comment(
sprintf(
'Using `%s` as source disk and `%s` as target disk for generated content',
$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')) {
Process::run('npm run build')->throw();
}
$this->info('OK');
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;
}
// For now, we need to clear the cache, otherwise rendered HTML will
// still reference old assets
$this->output->write('Clearing cache... ');
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') ?? '/';
$comment = sprintf('Rendering %s', $path);
if ($this->option('recursive')) {
$comment .= ' and all sub-bundles';
}
$this->comment($comment);
$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();
progress(
label: 'Rendering... ',
steps: $bundles,
callback: fn (Bundle $bundle, $progress) => $this->handleBundle($bundle, $progress)
);
return $this;
}
/**
* Handle specific bundle
*/
private function handleBundle(Bundle $bundle, $progress)
{
$progress->label(sprintf('Rendering %s ...', $bundle->getPath()));
if ($this->option('dry-run')) {
return;
}
$progress->hint('Rendering the bundle');
$result = $bundle->render();
foreach ($result as $path => $content) {
if (!Str::contains($path, '.')) {
$path = Str::finish($path, '/') . 'index.html';
}
$progress->advance();
}
$progress->hint(sprintf('Storing %s', $path));
$progress->finish();
if (confirm('Ready to deploy?')) {
$this->output->write('Deploying... ');
$source = Str::finish(Storage::disk(env('DIST_DISK'))->path('/'), '/');
$target = env('DEPLOY_TARGET');
$command = sprintf('rsync -az -L --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --chown=caddy:caddy --delete "%s" "%s"', $source, $target);
Process::run($command)->throw();
$this->info('OK');
$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;
}
// Ask for confirmation
if (!confirm('Ready to deploy?')) {
$this->comment('OK, not deploying!');
return;
}
$source = Str::finish($this->targetDisk->path('/'), '/');
$target = env('DEPLOY_TARGET');
$command = __(env('DEPLOY_COMMAND'), [
'source' => $source,
'target' => $target,
]);
$this->output->write(sprintf('Deploying using `%s` ... ', $command));
if (!$this->option('dry-run')) {
Process::run($command)->throw();
}
$this->info('OK');
}
}