diff --git a/internal/snapshot/backup_test.go b/internal/snapshot/backup_test.go index b310fe7..44d49a3 100644 --- a/internal/snapshot/backup_test.go +++ b/internal/snapshot/backup_test.go @@ -479,7 +479,8 @@ func (b *BackupEngine) Backup(ctx context.Context, fsys fs.FS, root string) (str dummyData := []byte(chunkHash) // Upload to S3 as a blob - if err := b.s3Client.PutBlob(ctx, blobHash, dummyData); err != nil { + err = b.s3Client.PutBlob(ctx, blobHash, dummyData) + if err != nil { return "", err } diff --git a/internal/snapshot/manifest.go b/internal/snapshot/manifest.go index f6dc3ae..d22b395 100644 --- a/internal/snapshot/manifest.go +++ b/internal/snapshot/manifest.go @@ -35,7 +35,9 @@ func DecodeManifest(r io.Reader) (*Manifest, error) { // Decode JSON manifest var manifest Manifest - if err := json.NewDecoder(zr).Decode(&manifest); err != nil { + + err = json.NewDecoder(zr).Decode(&manifest) + if err != nil { return nil, fmt.Errorf("decoding manifest: %w", err) } @@ -58,13 +60,15 @@ func EncodeManifest(manifest *Manifest, compressionLevel int) ([]byte, error) { return nil, fmt.Errorf("creating zstd writer: %w", err) } - if _, err := writer.Write(jsonData); err != nil { + _, err = writer.Write(jsonData) + if err != nil { _ = writer.Close() return nil, fmt.Errorf("writing compressed data: %w", err) } - if err := writer.Close(); err != nil { + err = writer.Close() + if err != nil { return nil, fmt.Errorf("closing zstd writer: %w", err) } diff --git a/internal/snapshot/scanner.go b/internal/snapshot/scanner.go index 2501832..f4efafb 100644 --- a/internal/snapshot/scanner.go +++ b/internal/snapshot/scanner.go @@ -213,7 +213,8 @@ func (s *Scanner) Scan(ctx context.Context, path string, snapshotID string) (*Sc filesToProcess := scanResult.FilesToProcess // Phase 1b: Detect deleted files by comparing DB against scanned files - if err := s.detectDeletedFilesFromMap(ctx, knownFiles, existingFiles, result); err != nil { + err = s.detectDeletedFilesFromMap(ctx, knownFiles, existingFiles, result) + if err != nil { return nil, fmt.Errorf("detecting deleted files: %w", err) } @@ -264,7 +265,8 @@ func (s *Scanner) loadDatabaseState(ctx context.Context, path string) (map[strin s.ui.Begin("Loading known chunks from local index database.") - if err := s.loadKnownChunks(ctx); err != nil { + err = s.loadKnownChunks(ctx) + if err != nil { return nil, fmt.Errorf("loading known chunks: %w", err) } @@ -1262,7 +1264,8 @@ func (s *Scanner) handleBlobReady(blobWithReader *blob.BlobWithReader) error { return fmt.Errorf("uploading blob %s: %w", finishedBlob.Hash, err) } - if err := s.recordBlobMetadata(ctx, finishedBlob, blobExists, startTime); err != nil { + err = s.recordBlobMetadata(ctx, finishedBlob, blobExists, startTime) + if err != nil { s.cleanupBlobTempFile(blobWithReader) return err @@ -1274,7 +1277,8 @@ func (s *Scanner) handleBlobReady(blobWithReader *blob.BlobWithReader) error { s.removePendingChunkHashes(blobWithReader.InsertedChunkHashes) // Flush files whose chunks are now all committed - if err := s.flushCompletedPendingFiles(ctx); err != nil { + err = s.flushCompletedPendingFiles(ctx) + if err != nil { return fmt.Errorf("flushing completed files: %w", err) } @@ -1287,7 +1291,9 @@ func (s *Scanner) uploadBlobIfNeeded(ctx context.Context, blobPath string, blobW // Check if blob already exists (deduplication after restart) destination := s.storage.Info().Location - if _, err := s.storage.Stat(ctx, blobPath); err == nil { + + _, err := s.storage.Stat(ctx, blobPath) + if err == nil { log.Info("Blob already exists in storage, skipping upload", "hash", finishedBlob.Hash, "size", humanize.Bytes(uint64(finishedBlob.Compressed))) s.ui.Info("Blob %s (%s) already exists at %s. Skipping upload.", @@ -1301,7 +1307,7 @@ func (s *Scanner) uploadBlobIfNeeded(ctx context.Context, blobPath string, blobW progressCallback := s.makeUploadProgressCallback(ctx, finishedBlob, startTime) - err := s.storage.PutWithProgress(ctx, blobPath, blobWithReader.Reader, finishedBlob.Compressed, progressCallback) + err = s.storage.PutWithProgress(ctx, blobPath, blobWithReader.Reader, finishedBlob.Compressed, progressCallback) if err != nil { log.Error("Failed to upload blob", "hash", finishedBlob.Hash, "error", err) diff --git a/internal/snapshot/scanner_test.go b/internal/snapshot/scanner_test.go index 4ed2d3b..617067b 100644 --- a/internal/snapshot/scanner_test.go +++ b/internal/snapshot/scanner_test.go @@ -185,11 +185,13 @@ func TestScannerLargeFile(t *testing.T) { largeContent[i] = byte((i * 7919) ^ (i >> 3)) } - if err := fs.MkdirAll("/source", 0755); err != nil { + err := fs.MkdirAll("/source", 0755) + if err != nil { t.Fatal(err) } - if err := afero.WriteFile(fs, "/source/large.bin", largeContent, 0644); err != nil { + err = afero.WriteFile(fs, "/source/large.bin", largeContent, 0644) + if err != nil { t.Fatal(err) } diff --git a/internal/snapshot/snapshot.go b/internal/snapshot/snapshot.go index 545d6e7..c6c0e4c 100644 --- a/internal/snapshot/snapshot.go +++ b/internal/snapshot/snapshot.go @@ -258,7 +258,8 @@ func (sm *SnapshotManager) ExportSnapshotMetadata(ctx context.Context, dbPath st } // Step 7: Upload to S3 in snapshot subdirectory - if err := sm.uploadSnapshotArtifacts(ctx, snapshotID, finalData, blobManifest); err != nil { + err = sm.uploadSnapshotArtifacts(ctx, snapshotID, finalData, blobManifest) + if err != nil { return err } @@ -278,7 +279,8 @@ func (sm *SnapshotManager) prepareExportDB(ctx context.Context, dbPath, snapshot tempDBPath := filepath.Join(tempDir, "snapshot.db") log.Debug("Copying database to temporary location", "source", dbPath, "destination", tempDBPath) - if err := sm.copyFile(dbPath, tempDBPath); err != nil { + err := sm.copyFile(dbPath, tempDBPath) + if err != nil { return nil, "", fmt.Errorf("copying database: %w", err) } @@ -304,7 +306,8 @@ func (sm *SnapshotManager) prepareExportDB(ctx context.Context, dbPath, snapshot // Step 3: VACUUM the database to remove deleted data and compact // This is critical for security - ensures no stale/deleted data is uploaded - if err := sm.vacuumDatabase(tempDBPath); err != nil { + err = sm.vacuumDatabase(tempDBPath) + if err != nil { return nil, "", fmt.Errorf("vacuuming database: %w", err) } @@ -312,7 +315,9 @@ func (sm *SnapshotManager) prepareExportDB(ctx context.Context, dbPath, snapshot // Step 4: Compress and encrypt the binary database file compressedPath := filepath.Join(tempDir, "db.zst.age") - if err := sm.compressFile(tempDBPath, compressedPath); err != nil { + + err = sm.compressFile(tempDBPath, compressedPath) + if err != nil { return nil, "", fmt.Errorf("compressing database: %w", err) } @@ -423,38 +428,46 @@ func (sm *SnapshotManager) cleanSnapshotDB(ctx context.Context, dbPath string, s }() // Execute cleanup steps in order - if err := sm.deleteOtherSnapshots(ctx, tx, snapshotID); err != nil { + err = sm.deleteOtherSnapshots(ctx, tx, snapshotID) + if err != nil { return nil, fmt.Errorf("step 1 - delete other snapshots: %w", err) } - if err := sm.deleteOrphanedSnapshotAssociations(ctx, tx, snapshotID); err != nil { + err = sm.deleteOrphanedSnapshotAssociations(ctx, tx, snapshotID) + if err != nil { return nil, fmt.Errorf("step 2 - delete orphaned snapshot associations: %w", err) } - if err := sm.deleteOrphanedFiles(ctx, tx, snapshotID); err != nil { + err = sm.deleteOrphanedFiles(ctx, tx, snapshotID) + if err != nil { return nil, fmt.Errorf("step 3 - delete orphaned files: %w", err) } - if err := sm.deleteOrphanedChunkToFileMappings(ctx, tx); err != nil { + err = sm.deleteOrphanedChunkToFileMappings(ctx, tx) + if err != nil { return nil, fmt.Errorf("step 4 - delete orphaned chunk-to-file mappings: %w", err) } - if err := sm.deleteOrphanedBlobs(ctx, tx, snapshotID); err != nil { + err = sm.deleteOrphanedBlobs(ctx, tx, snapshotID) + if err != nil { return nil, fmt.Errorf("step 5 - delete orphaned blobs: %w", err) } - if err := sm.deleteOrphanedBlobToChunkMappings(ctx, tx); err != nil { + err = sm.deleteOrphanedBlobToChunkMappings(ctx, tx) + if err != nil { return nil, fmt.Errorf("step 6 - delete orphaned blob-to-chunk mappings: %w", err) } - if err := sm.deleteOrphanedChunks(ctx, tx); err != nil { + err = sm.deleteOrphanedChunks(ctx, tx) + if err != nil { return nil, fmt.Errorf("step 7 - delete orphaned chunks: %w", err) } // Commit transaction log.Debug("[Temp DB Cleanup] Committing cleanup transaction") - if err := tx.Commit(); err != nil { + err = tx.Commit() + if err != nil { return nil, fmt.Errorf("committing transaction: %w", err) } @@ -509,7 +522,8 @@ func (sm *SnapshotManager) vacuumDatabase(dbPath string) error { log.Debug("Running VACUUM on database", "path", dbPath) cmd := exec.Command("sqlite3", dbPath, "VACUUM;") - if output, err := cmd.CombinedOutput(); err != nil { + output, err := cmd.CombinedOutput() + if err != nil { return fmt.Errorf("running VACUUM: %w (output: %s)", err, string(output)) } @@ -559,12 +573,14 @@ func (sm *SnapshotManager) compressFile(inputPath, outputPath string) error { } }() - if _, err := io.Copy(writer, input); err != nil { + _, err = io.Copy(writer, input) + if err != nil { return fmt.Errorf("compressing data: %w", err) } // Close writer to flush all data - if err := writer.Close(); err != nil { + err = writer.Close() + if err != nil { return fmt.Errorf("closing writer: %w", err) } diff --git a/internal/snapshot/snapshot_test.go b/internal/snapshot/snapshot_test.go index 969aeed..2c1dfe5 100644 --- a/internal/snapshot/snapshot_test.go +++ b/internal/snapshot/snapshot_test.go @@ -85,13 +85,16 @@ func TestCleanSnapshotDBEmptySnapshot(t *testing.T) { } // Close the database - if err := db.Close(); err != nil { + err = db.Close() + if err != nil { t.Fatalf("failed to close database: %v", err) } // Copy database tempDBPath := filepath.Join(tempDir, "temp.db") - if err := copyFile(fs, dbPath, tempDBPath); err != nil { + + err = copyFile(fs, dbPath, tempDBPath) + if err != nil { t.Fatalf("failed to copy database: %v", err) } @@ -105,7 +108,9 @@ func TestCleanSnapshotDBEmptySnapshot(t *testing.T) { config: cfg, fs: fs, } - if _, err := sm.cleanSnapshotDB(ctx, tempDBPath, snapshot.ID.String()); err != nil { + + _, err = sm.cleanSnapshotDB(ctx, tempDBPath, snapshot.ID.String()) + if err != nil { t.Fatalf("failed to clean snapshot database: %v", err) } @@ -171,13 +176,16 @@ func TestCleanSnapshotDBNonExistentSnapshot(t *testing.T) { } // Close immediately - if err := db.Close(); err != nil { + err = db.Close() + if err != nil { t.Fatalf("failed to close database: %v", err) } // Copy database tempDBPath := filepath.Join(tempDir, "temp.db") - if err := copyFile(fs, dbPath, tempDBPath); err != nil { + + err = copyFile(fs, dbPath, tempDBPath) + if err != nil { t.Fatalf("failed to copy database: %v", err) }