295 lines
11 KiB
PHP
Executable File
295 lines
11 KiB
PHP
Executable File
<?php
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\File;
|
|
use Illuminate\Support\Facades\Process;
|
|
|
|
class NetgesconDevelopmentSnapshotCommand extends Command
|
|
{
|
|
protected $signature = 'netgescon:development-snapshot
|
|
{--output= : Output markdown custom}
|
|
{--json= : Output JSON custom}';
|
|
|
|
protected $description = 'Rigenera una snapshot locale di continuita sviluppo per Supporto > Modifiche';
|
|
|
|
public function handle(): int
|
|
{
|
|
$generatedDir = storage_path('app/support/generated');
|
|
File::ensureDirectoryExists($generatedDir);
|
|
|
|
$outputPath = trim((string) $this->option('output')) !== ''
|
|
? trim((string) $this->option('output'))
|
|
: $generatedDir . '/CONTINUITA-SVILUPPO-SNAPSHOT.md';
|
|
|
|
$jsonPath = trim((string) $this->option('json')) !== ''
|
|
? trim((string) $this->option('json'))
|
|
: $generatedDir . '/CONTINUITA-SVILUPPO-SNAPSHOT.json';
|
|
|
|
$manualPath = base_path('docs/support/MANUALE-SVILUPPO-OPERATIVO.md');
|
|
$bugPath = base_path('docs/support/BUG-RISOLTI-E-VALIDAZIONI.md');
|
|
$continuityPath = base_path('docs/support/CONTINUITA-SVILUPPO-AGENT.md');
|
|
$pbxPath = base_path('docs/support/PBX-PANASONIC-STATO-OPERATIVO.md');
|
|
|
|
$manual = is_file($manualPath) ? (string) @file_get_contents($manualPath) : '';
|
|
$bugs = is_file($bugPath) ? (string) @file_get_contents($bugPath) : '';
|
|
$continuity = is_file($continuityPath) ? (string) @file_get_contents($continuityPath) : '';
|
|
$pbx = is_file($pbxPath) ? (string) @file_get_contents($pbxPath) : '';
|
|
|
|
$branch = $this->gitValue(['rev-parse', '--abbrev-ref', 'HEAD']) ?? '-';
|
|
$commit = $this->gitValue(['rev-parse', '--short', 'HEAD']) ?? '-';
|
|
|
|
$recentCommits = $this->recentCommits();
|
|
$recentPages = $this->recentPages();
|
|
$commitNotes = $this->recentCommitNotes();
|
|
|
|
$snapshot = [];
|
|
$snapshot[] = '# Snapshot continuita sviluppo';
|
|
$snapshot[] = '';
|
|
$snapshot[] = 'Generata automaticamente il ' . now()->format('d/m/Y H:i:s') . '.';
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Stato Git corrente';
|
|
$snapshot[] = '';
|
|
$snapshot[] = '- Branch: `' . $branch . '`';
|
|
$snapshot[] = '- Commit: `' . $commit . '`';
|
|
$snapshot[] = '- Workspace: `' . base_path() . '`';
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Focus operativo';
|
|
$snapshot[] = '';
|
|
$snapshot[] = $this->normalizeSectionLines($this->extractSection($manual, '## Implementazioni recenti da tenere come riferimento'));
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Stato PBX Panasonic';
|
|
$snapshot[] = '';
|
|
$snapshot[] = $this->normalizeSectionLines($this->extractSection($pbx, '## Stato attuale'));
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Validazioni ancora aperte';
|
|
$snapshot[] = '';
|
|
$snapshot[] = $this->normalizeSectionLines($this->extractSection($bugs, '## Validazioni ancora aperte'));
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Prossimi passi consigliati';
|
|
$snapshot[] = '';
|
|
$snapshot[] = $this->normalizeSectionLines($this->extractSection($manual, '## Prossimi passi consigliati'));
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Regole di continuita';
|
|
$snapshot[] = '';
|
|
$snapshot[] = $this->normalizeSectionLines($this->extractSection($continuity, '## Regola semplice'));
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Ultimi commit';
|
|
$snapshot[] = '';
|
|
$snapshot[] = '| Data | Commit | Messaggio |';
|
|
$snapshot[] = '| --- | --- | --- |';
|
|
foreach ($recentCommits as $row) {
|
|
$snapshot[] = '| ' . $row['date'] . ' | `' . $row['hash'] . '` | ' . str_replace('|', '-', $row['message']) . ' |';
|
|
}
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Note commit recenti';
|
|
$snapshot[] = '';
|
|
if ($commitNotes === []) {
|
|
$snapshot[] = '- Nessuna nota commit strutturata disponibile tra gli ultimi commit.';
|
|
} else {
|
|
foreach ($commitNotes as $row) {
|
|
$snapshot[] = '- `' . $row['hash'] . '` ' . $row['message'];
|
|
$snapshot[] = ' - Nota: ' . $row['note'];
|
|
}
|
|
}
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Pagine toccate di recente';
|
|
$snapshot[] = '';
|
|
if ($recentPages === []) {
|
|
$snapshot[] = '- Nessuna pagina recente rilevata.';
|
|
} else {
|
|
foreach ($recentPages as $row) {
|
|
$snapshot[] = '- `' . $row['commit'] . '` ' . $row['page'] . ' -> `' . $row['path'] . '`';
|
|
}
|
|
}
|
|
$snapshot[] = '';
|
|
$snapshot[] = '## Fonti da leggere per ripartire';
|
|
$snapshot[] = '';
|
|
$snapshot[] = '- `docs/support/MANUALE-SVILUPPO-OPERATIVO.md`';
|
|
$snapshot[] = '- `docs/support/PBX-PANASONIC-STATO-OPERATIVO.md`';
|
|
$snapshot[] = '- `docs/support/BUG-RISOLTI-E-VALIDAZIONI.md`';
|
|
$snapshot[] = '- `docs/support/CONTINUITA-SVILUPPO-AGENT.md`';
|
|
|
|
File::put($outputPath, implode(PHP_EOL, $snapshot) . PHP_EOL);
|
|
File::put($jsonPath, json_encode([
|
|
'generated_at' => now()->toIso8601String(),
|
|
'branch' => $branch,
|
|
'commit' => $commit,
|
|
'output_path' => $outputPath,
|
|
'source_files' => [
|
|
'docs/support/MANUALE-SVILUPPO-OPERATIVO.md',
|
|
'docs/support/PBX-PANASONIC-STATO-OPERATIVO.md',
|
|
'docs/support/BUG-RISOLTI-E-VALIDAZIONI.md',
|
|
'docs/support/CONTINUITA-SVILUPPO-AGENT.md',
|
|
],
|
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
$this->info('Snapshot continuita sviluppo aggiornata.');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function gitValue(array $arguments): ?string
|
|
{
|
|
$result = Process::path(base_path())
|
|
->timeout(120)
|
|
->run(array_merge(['git'], $arguments));
|
|
|
|
if (! $result->successful()) {
|
|
return null;
|
|
}
|
|
|
|
$output = trim((string) $result->output());
|
|
|
|
return $output !== '' ? $output : null;
|
|
}
|
|
|
|
/** @return array<int,array{hash:string,date:string,message:string}> */
|
|
private function recentCommits(): array
|
|
{
|
|
$rows = [];
|
|
$result = Process::path(base_path())->timeout(120)->run([
|
|
'git', 'log', '-n', '8', '--date=format:%d/%m/%Y %H:%M', '--pretty=format:%h|%ad|%s',
|
|
]);
|
|
|
|
if (! $result->successful()) {
|
|
return [];
|
|
}
|
|
|
|
$lines = preg_split('/\r\n|\r|\n/', trim((string) $result->output())) ?: [];
|
|
foreach ($lines as $line) {
|
|
$parts = explode('|', $line, 3);
|
|
if (count($parts) !== 3) {
|
|
continue;
|
|
}
|
|
|
|
$rows[] = [
|
|
'hash' => (string) $parts[0],
|
|
'date' => (string) $parts[1],
|
|
'message' => (string) $parts[2],
|
|
];
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
|
|
/** @return array<int,array{page:string,path:string,commit:string}> */
|
|
private function recentPages(): array
|
|
{
|
|
$rows = [];
|
|
$seen = [];
|
|
$result = Process::path(base_path())->timeout(120)->run([
|
|
'git', 'log', '-n', '12', '--name-only', '--pretty=format:@@@%h', '--', 'app/Filament/Pages', 'resources/views/filament/pages',
|
|
]);
|
|
|
|
if (! $result->successful()) {
|
|
return [];
|
|
}
|
|
|
|
$currentCommit = null;
|
|
$lines = preg_split('/\r\n|\r|\n/', (string) $result->output()) ?: [];
|
|
foreach ($lines as $line) {
|
|
$line = trim((string) $line);
|
|
if ($line === '') {
|
|
continue;
|
|
}
|
|
|
|
if (str_starts_with($line, '@@@')) {
|
|
$currentCommit = substr($line, 3);
|
|
continue;
|
|
}
|
|
|
|
if ($currentCommit === null || isset($seen[$line])) {
|
|
continue;
|
|
}
|
|
|
|
if (! str_starts_with($line, 'app/Filament/Pages/') && ! str_starts_with($line, 'resources/views/filament/pages/')) {
|
|
continue;
|
|
}
|
|
|
|
$seen[$line] = true;
|
|
$rows[] = [
|
|
'page' => basename($line),
|
|
'path' => $line,
|
|
'commit' => $currentCommit,
|
|
];
|
|
|
|
if (count($rows) >= 10) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
|
|
/** @return array<int,array{hash:string,message:string,note:string}> */
|
|
private function recentCommitNotes(): array
|
|
{
|
|
$path = storage_path('app/support/commit-notes.json');
|
|
if (! is_file($path)) {
|
|
return [];
|
|
}
|
|
|
|
$decoded = json_decode((string) @file_get_contents($path), true);
|
|
if (! is_array($decoded)) {
|
|
return [];
|
|
}
|
|
|
|
$rows = [];
|
|
foreach ($this->recentCommits() as $commit) {
|
|
$fullHash = $this->gitValue(['rev-parse', $commit['hash']]);
|
|
if (! is_string($fullHash) || ! isset($decoded[$fullHash]) || ! is_string($decoded[$fullHash])) {
|
|
continue;
|
|
}
|
|
|
|
$rows[] = [
|
|
'hash' => $commit['hash'],
|
|
'message' => $commit['message'],
|
|
'note' => trim($decoded[$fullHash]),
|
|
];
|
|
}
|
|
|
|
return array_slice($rows, 0, 5);
|
|
}
|
|
|
|
private function extractSection(string $markdown, string $heading): string
|
|
{
|
|
if ($markdown === '' || ! str_contains($markdown, $heading)) {
|
|
return '- Sezione non disponibile.';
|
|
}
|
|
|
|
$offset = strpos($markdown, $heading);
|
|
if ($offset === false) {
|
|
return '- Sezione non disponibile.';
|
|
}
|
|
|
|
$slice = substr($markdown, $offset + strlen($heading));
|
|
if (! is_string($slice)) {
|
|
return '- Sezione non disponibile.';
|
|
}
|
|
|
|
if (preg_match('/\n##\s+/', $slice, $match, PREG_OFFSET_CAPTURE) === 1) {
|
|
$slice = substr($slice, 0, (int) $match[0][1]);
|
|
}
|
|
|
|
return trim($slice) !== '' ? trim($slice) : '- Sezione non disponibile.';
|
|
}
|
|
|
|
private function normalizeSectionLines(string $text): string
|
|
{
|
|
$lines = preg_split('/\r\n|\r|\n/', trim($text)) ?: [];
|
|
$cleaned = [];
|
|
|
|
foreach ($lines as $line) {
|
|
$line = trim((string) $line);
|
|
if ($line === '') {
|
|
continue;
|
|
}
|
|
|
|
$cleaned[] = $line;
|
|
}
|
|
|
|
return $cleaned === [] ? '- Nessuna informazione disponibile.' : implode(PHP_EOL, $cleaned);
|
|
}
|
|
}
|