feat(vikon): add restoreAfterFail for crash recovery in FilesystemTask

This commit is contained in:
F4ilji
2026-07-05 02:47:40 +05:00
parent da90011ad3
commit 15f72b4de1
2 changed files with 57 additions and 0 deletions
@@ -111,6 +111,44 @@ class FilesystemTask
return $this->moveEntry($newEntryPath, $currentEntryPath, $isFile);
}
public function restoreAfterFail(string $modulePath, array $allowedEntries, int $moduleId): bool
{
$entries = File::directories($modulePath);
$entries = array_merge($entries, File::files($modulePath));
foreach ($entries as $entryPath) {
$name = basename($entryPath);
if (str_ends_with($name, '_new')) {
$baseName = substr($name, 0, -4);
if (in_array($baseName, $allowedEntries, true)) {
if (is_dir($entryPath)) {
File::deleteDirectory($entryPath);
} else {
File::delete($entryPath);
}
}
}
if (str_ends_with($name, '_old')) {
$baseName = substr($name, 0, -4);
if (in_array($baseName, $allowedEntries, true)) {
$originalPath = $modulePath . '/' . $baseName;
if (File::exists($originalPath)) {
if (is_dir($originalPath)) {
File::deleteDirectory($originalPath);
} else {
File::delete($originalPath);
}
}
rename($entryPath, $originalPath);
}
}
}
return true;
}
private function moveEntry(string $source, string $dest, bool $isFile): bool
{
if ($isFile) {
@@ -82,4 +82,23 @@ class FilesystemTaskTest extends TestCase
$this->assertFalse($result);
}
public function test_restore_after_fail_removes_new_and_restores_old(): void
{
$base = $this->tempDir . '/module';
File::makeDirectory($base, 0755, true, true);
// Simulate partial swap state: _old has backup
File::makeDirectory($base . '/common', 0755, true, true);
file_put_contents($base . '/common/index.php', '<?php echo "current";');
File::makeDirectory($base . '/common_old', 0755, true, true);
file_put_contents($base . '/common_old/index.php', '<?php echo "original";');
$result = $this->fs->restoreAfterFail($base, ['common'], 1);
$this->assertTrue($result);
$this->assertFileExists($base . '/common/index.php');
$this->assertStringContainsString('original', file_get_contents($base . '/common/index.php'));
$this->assertDirectoryDoesNotExist($base . '/common_old');
}
}