Refactoring
This commit is contained in:
parent
c254e29cca
commit
5dd81defbc
|
@ -4,19 +4,15 @@
|
|||
|
||||
use App\Classes\Bundle;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use JsonSchema\Constraints\Constraint;
|
||||
use Illuminate\Support\Str;
|
||||
use JsonSchema\Validator;
|
||||
|
||||
use function Laravel\Prompts\progress;
|
||||
|
||||
class Validate extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'bundle:validate { path? : Specific bundle to repair }';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
|
@ -24,57 +20,156 @@ class Validate extends Command
|
|||
*/
|
||||
protected $description = 'Validate bundles metadata';
|
||||
|
||||
protected Filesystem $sourceDisk;
|
||||
|
||||
protected array $invalid = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->signature = 'bundle:validate
|
||||
{ --r|recursive : Also render sub-bundles }
|
||||
{ --source-disk= : Use specified content disk - Defaults to <info>' . env('CONTENT_DISK') . '</info> }
|
||||
{ path? : Path to a specific bundle to render - Default to <info>/</info> }
|
||||
';
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->selectDisk()
|
||||
->validate()
|
||||
->showReport();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the disk we will be working on
|
||||
*/
|
||||
private function selectDisk(): self
|
||||
{
|
||||
$sourceDisk = $this->option('source-disk') ?? env('CONTENT_DISK');
|
||||
|
||||
$this->sourceDisk = Storage::disk($sourceDisk);
|
||||
|
||||
$this->comment(
|
||||
sprintf(
|
||||
'Using `%s` as source disk',
|
||||
$sourceDisk
|
||||
)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect a list of bundles to validate
|
||||
*/
|
||||
private function getBundles()
|
||||
{
|
||||
$path = $this->argument('path') ?? '/';
|
||||
$bundles = Bundle::findBundles(Storage::disk(env('CONTENT_DISK')), $path, true);
|
||||
$comment = sprintf('Validating %s', $path);
|
||||
|
||||
$validators = [
|
||||
'index' => json_decode(file_get_contents(resource_path('schemas/index.json'))),
|
||||
'metadata' => json_decode(file_get_contents(resource_path('schemas/metadata.json'))),
|
||||
];
|
||||
|
||||
$allValid = true;
|
||||
|
||||
foreach ($bundles as $bundle) {
|
||||
$this->output->write(sprintf('Validating %s... ', $bundle->getPath()));
|
||||
|
||||
$isValid = false;
|
||||
|
||||
foreach ($validators as $file => $schema) {
|
||||
$data = json_decode(Storage::disk(env('CONTENT_DISK'))->get($bundle->metadata($file)->getFilename()) ?? '{}');
|
||||
$validator = new Validator();
|
||||
|
||||
$validator->validate($data, $schema, Constraint::CHECK_MODE_APPLY_DEFAULTS);
|
||||
|
||||
if ($validator->isValid()) {
|
||||
$isValid = true;
|
||||
} else {
|
||||
$isValid = false;
|
||||
$allValid = false;
|
||||
|
||||
$this->error(sprintf('%s INVALID', $file));
|
||||
|
||||
foreach ($validator->getErrors() as $error) {
|
||||
$this->line(" $error[message]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($isValid) {
|
||||
$this->info('OK');
|
||||
}
|
||||
if ($this->option('recursive')) {
|
||||
$comment .= ' and all sub-bundles';
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
$this->comment($comment);
|
||||
$this->output->write('Collecting bundles... ');
|
||||
|
||||
if ($allValid) {
|
||||
$this->info('All bundles are valid');
|
||||
if ($this->option('recursive')) {
|
||||
$bundles = Bundle::findBundles($this->sourceDisk, $path, true);
|
||||
} else {
|
||||
$this->comment('Errors have been reported');
|
||||
$bundles = [new Bundle($path, $this->sourceDisk)];
|
||||
}
|
||||
|
||||
$this->info('OK');
|
||||
|
||||
return $bundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an associative array containing available bundles metadata files
|
||||
* as keys and json-decoded validation schemas as values
|
||||
*/
|
||||
private function getValidators()
|
||||
{
|
||||
return array_map(function ($path) {
|
||||
return json_decode(file_get_contents($path));
|
||||
}, config('json_validator'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform json validation on selected bundles
|
||||
*/
|
||||
private function validate(): self
|
||||
{
|
||||
$bundles = $this->getBundles();
|
||||
$validators = $this->getValidators();
|
||||
|
||||
progress(
|
||||
label: 'Validating... ',
|
||||
steps: $bundles,
|
||||
callback: fn (Bundle $bundle, $progress) => $this->handleBundle($bundle, $progress, $validators)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle specific bundle
|
||||
*/
|
||||
private function handleBundle(Bundle $bundle, $progress, $validators)
|
||||
{
|
||||
$progress->label(sprintf('Validating %s ...', $bundle->getPath()));
|
||||
|
||||
foreach ($validators as $metadataFilename => $schema) {
|
||||
$progress->hint(sprintf('Validating %s ...', $metadataFilename));
|
||||
|
||||
$filepath = $bundle->metadata($metadataFilename)->getFilename();
|
||||
|
||||
if (!$this->sourceDisk->exists($filepath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$source = $this->sourceDisk->get($filepath) ?? '{}';
|
||||
$data = json_decode($source);
|
||||
$validator = new Validator();
|
||||
|
||||
$validator->validate($data, $schema);
|
||||
|
||||
if (!$validator->isValid()) {
|
||||
$this->invalid[$bundle->getPath()] = [
|
||||
'metadata' => $metadataFilename,
|
||||
'errors' => $validator->getErrors(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a report in case of need
|
||||
*/
|
||||
private function showReport()
|
||||
{
|
||||
if (empty($this->invalid)) {
|
||||
$this->info('All files are valid');
|
||||
} else {
|
||||
$count = count($this->invalid);
|
||||
|
||||
$this->error(sprintf('%d invalid %s reported', $count, Str::plural('file', $count)));
|
||||
$this->newLine(2);
|
||||
|
||||
foreach ($this->invalid as $bundlePath => $data) {
|
||||
$this->line($bundlePath);
|
||||
$this->line(sprintf(' > In <comment>%s</comment>:', $data['metadata']));
|
||||
|
||||
foreach ($data['errors'] as $error) {
|
||||
$this->line(sprintf(' - %s', $error['message']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Keys are available bundles metadata files, values are corresponding
|
||||
* validation schema
|
||||
*/
|
||||
return [
|
||||
'index' => resource_path('schemas/index.json'),
|
||||
'metadata' => resource_path('schemas/metadata.json'),
|
||||
];
|
Loading…
Reference in New Issue