first step

This commit is contained in:
team2
2026-04-29 20:21:02 +02:00
parent e39a57e00b
commit a460eee429
4 changed files with 501 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace App\Command;
use App\Config\ConfigSourceAuditProvider;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
#[AsCommand(
name: 'mto:agent:config:audit-source',
description: 'Audit YAML-backed configuration versus remaining PHP defaults'
)]
final class ConfigSourceAuditCommand extends Command
{
public function __construct(private readonly ConfigSourceAuditProvider $provider)
{
parent::__construct();
}
protected function configure(): void
{
$this
->addOption('json', null, InputOption::VALUE_NONE, 'Render the full audit result as JSON.')
->addOption('details', null, InputOption::VALUE_NONE, 'Render detailed fallback rows in the console summary.');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$result = $this->provider->audit();
if ((bool) $input->getOption('json')) {
$json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$output->writeln(is_string($json) ? $json : '{}');
return Command::SUCCESS;
}
$this->renderSummary(new SymfonyStyle($input, $output), $result, (bool) $input->getOption('details'));
return Command::SUCCESS;
}
/**
* @param array<string, mixed> $result
*/
private function renderSummary(SymfonyStyle $io, array $result, bool $details): void
{
$io->title('RetrieX configuration source audit');
$summary = is_array($result['summary'] ?? null) ? $result['summary'] : [];
$io->definitionList(
['status' => (string) ($result['status'] ?? 'UNKNOWN')],
['yaml_parameter_paths' => (string) ($summary['yaml_parameter_paths'] ?? 0)],
['php_constants' => (string) ($summary['php_constants'] ?? 0)],
['php_only_constants' => (string) ($summary['php_only_constants'] ?? 0)],
['fallback_accessors' => (string) ($summary['fallback_accessors'] ?? 0)],
['fallback_accessors_with_yaml' => (string) ($summary['fallback_accessors_with_yaml'] ?? 0)],
['fallback_accessors_missing_yaml' => (string) ($summary['fallback_accessors_missing_yaml'] ?? 0)],
['constructor_defaults' => (string) ($summary['constructor_defaults'] ?? 0)],
['constructor_defaults_without_yaml_mapping' => (string) ($summary['constructor_defaults_without_yaml_mapping'] ?? 0)]
);
$warnings = is_array($result['warnings'] ?? null) ? $result['warnings'] : [];
if ($warnings !== []) {
$io->section('Warnings');
foreach ($warnings as $warning) {
$io->writeln('- ' . (string) $warning);
}
}
if (!$details) {
$io->note('Use --details for fallback rows or --json for the complete machine-readable audit.');
return;
}
$fallbackRows = [];
foreach (($result['fallback_accessors'] ?? []) as $item) {
if (!is_array($item)) {
continue;
}
$fallbackRows[] = [
(string) ($item['class'] ?? ''),
(string) ($item['line'] ?? ''),
(string) ($item['key'] ?? ''),
((bool) ($item['yaml_present'] ?? false)) ? 'yes' : 'no',
(string) ($item['source'] ?? ''),
];
}
if ($fallbackRows !== []) {
$io->section('Fallback accessors');
$io->table(['Class', 'Line', 'Key', 'YAML', 'Source'], $fallbackRows);
}
}
}