Finish the lint remediation: script/cibuild exits 0 (closes #61) #77

Merged
clawbot merged 4 commits from lint-remediation-final into main 2026-08-09 04:25:11 +02:00
42 changed files with 223 additions and 45 deletions

30
TODO.md
View File

@@ -14,16 +14,36 @@ pre-1.0
# Next Step
Reconcile the uncommitted ARCHITECTURE.md edits on main: finish and
commit, or revert.
Triage the stale remote branches (issue #71): for each, merge the work
or delete the branch.
# Completed Steps
- 2026-08-09: Finished the lint remediation under the canonical
`.golangci.yml` (issue #61, which also unblocks issue #59). The
remaining findings were fixed behavior-preservingly: `wsl_v5`
whitespace, `sqlclosecheck`, and `prealloc`. The `sqlclosecheck` sites
now close `sql.Rows` in a deferred closure instead of via the
`CloseRows` helper, which the linter could not see through. Only the
`revive` package-name findings remain suppressed, with per-site
`//nolint` directives; the package-rename question behind them is
tracked in issue #76. Verified with `script/cibuild`, which exits 0 —
that is the only trustworthy gate, because `script/lint` runs whatever
`golangci-lint` happens to be on `PATH` rather than the pinned
v2.12.2 that CI and the `Dockerfile` use, so `make check` can report
green on findings CI still fails. That tooling gap is tracked in issue
#78.
- 2026-08-09: The earlier next step "reconcile the uncommitted
`ARCHITECTURE.md` edits on `main`" needed no work: the working tree is
clean and `ARCHITECTURE.md` is committed on `main`.
- 2026-08-07: Updated golangci-lint to v2.12.2 everywhere it is pinned
(`Dockerfile` lint stage, `Makefile` deps target), replaced
`.golangci.yml` with the canonical config (v2 schema, `default: all`),
and remediated all lint findings it surfaced (issue #61):
behavior-preserving fixes across every package, `make check` green.
and remediated the bulk of the lint findings it surfaced (issue #61):
behavior-preserving fixes across every package, 2,990 findings down to
80. `make test` and `make fmt-check` were green at that point but
`make lint` was still red; the commit message claiming `make check`
was green was wrong.
- 2026-08-07: Added the standard `.golangci.yml` and `.editorconfig`
(issue #59); lint findings under the new config are tracked in issue
#61. `script/bootstrap` now installs sqlite3 (needed by tests).
@@ -49,6 +69,4 @@ commit, or revert.
# Future Steps
- Review stale local branches (add-godoc-to-cli-package,
feature/pluggable-storage-backend) and merge or delete them.
- Define remaining scope for a first tagged release and cut v0.1.0.

View File

@@ -16,6 +16,7 @@ func main() {
if err != nil {
panic("could not create CPU profile: " + err.Error())
}
defer func() { _ = f.Close() }()
err = pprof.StartCPUProfile(f)
@@ -33,6 +34,7 @@ func main() {
if err != nil {
panic("could not create memory profile: " + err.Error())
}
defer func() { _ = f.Close() }()
runtime.GC() // get up-to-date statistics

View File

@@ -64,6 +64,7 @@ func CompressStream(
}
closed := false
defer func() {
if !closed {
_ = w.Close()

View File

@@ -163,6 +163,7 @@ func (c *Chunker) ChunkFile(path string) ([]Chunk, error) {
if err != nil {
return nil, fmt.Errorf("opening file: %w", err)
}
defer func() {
err := file.Close()
if err != nil && err.Error() != "invalid argument" {

View File

@@ -53,7 +53,7 @@ func TestChunkerLargeFileMultipleChunks(t *testing.T) {
}
// Verify chunks reconstruct original data
var reconstructed []byte
reconstructed := make([]byte, 0, len(data))
for _, chunk := range chunks {
reconstructed = append(reconstructed, chunk.Data...)
}

View File

@@ -157,6 +157,7 @@ func RunApp(ctx context.Context, app *fx.App) error {
// Handle shutdown
shutdownComplete := make(chan struct{})
go func() {
defer close(shutdownComplete)

View File

@@ -1,6 +1,6 @@
// Package crypto provides thread-safe age encryption and decryption
// helpers used to protect blob and metadata content.
package crypto
package crypto //nolint:revive,nolintlint // stdlib crypto unused; see #76
import (
"bytes"

View File

@@ -57,7 +57,13 @@ func (r *BlobChunkRepository) GetByBlobID(
if err != nil {
return nil, fmt.Errorf("querying blob chunks: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var blobChunks []*BlobChunk

View File

@@ -82,7 +82,13 @@ func (r *BlobRepository) GetAll(ctx context.Context) (map[string]*Blob, error) {
if err != nil {
return nil, fmt.Errorf("querying blobs: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
out := make(map[string]*Blob)

View File

@@ -60,7 +60,13 @@ func (r *ChunkFileRepository) GetByChunkHash(
if err != nil {
return nil, fmt.Errorf("querying chunk files: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
return r.scanChunkFiles(rows)
}
@@ -80,7 +86,13 @@ func (r *ChunkFileRepository) GetByFilePath(
if err != nil {
return nil, fmt.Errorf("querying chunk files: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
return r.scanChunkFiles(rows)
}
@@ -99,7 +111,13 @@ func (r *ChunkFileRepository) GetByFileID(
if err != nil {
return nil, fmt.Errorf("querying chunk files: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
return r.scanChunkFiles(rows)
}

View File

@@ -106,7 +106,13 @@ func (r *ChunkRepository) GetByHashes(
if err != nil {
return nil, fmt.Errorf("querying chunks: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var chunks []*Chunk
@@ -145,7 +151,13 @@ func (r *ChunkRepository) ListUnpacked(
if err != nil {
return nil, fmt.Errorf("querying unpacked chunks: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var chunks []*Chunk

View File

@@ -17,7 +17,13 @@ func (r *ChunkRepository) List(ctx context.Context) ([]*Chunk, error) {
if err != nil {
return nil, fmt.Errorf("querying chunks: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var chunks []*Chunk

View File

@@ -19,6 +19,7 @@ func TestDatabase(t *testing.T) {
if err != nil {
t.Fatalf("failed to create database: %v", err)
}
defer func() {
err := db.Close()
if err != nil {
@@ -73,6 +74,7 @@ func TestDatabaseConcurrentAccess(t *testing.T) {
if err != nil {
t.Fatalf("failed to create database: %v", err)
}
defer func() {
err := db.Close()
if err != nil {
@@ -182,6 +184,7 @@ func TestApplyMigrations_Idempotent(t *testing.T) {
if err != nil {
t.Fatalf("failed to open database: %v", err)
}
defer func() {
err := conn.Close()
if err != nil {
@@ -239,6 +242,7 @@ func TestBootstrapMigrationsTable_FreshDatabase(t *testing.T) {
if err != nil {
t.Fatalf("failed to open database: %v", err)
}
defer func() {
err := conn.Close()
if err != nil {

View File

@@ -1,7 +1,6 @@
package database
import (
"database/sql"
"fmt"
"os"
)
@@ -11,11 +10,3 @@ func Fatalf(format string, args ...any) {
fmt.Fprintf(os.Stderr, "FATAL: "+format+"\n", args...)
os.Exit(1)
}
// CloseRows closes rows and exits on error
func CloseRows(rows *sql.Rows) {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}

View File

@@ -61,7 +61,13 @@ func (r *FileChunkRepository) GetByPath(
if err != nil {
return nil, fmt.Errorf("querying file chunks: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
return r.scanFileChunks(rows)
}
@@ -81,7 +87,13 @@ func (r *FileChunkRepository) GetByFileID(
if err != nil {
return nil, fmt.Errorf("querying file chunks: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
return r.scanFileChunks(rows)
}
@@ -104,7 +116,13 @@ func (r *FileChunkRepository) GetByPathTx(
if err != nil {
return nil, fmt.Errorf("querying file chunks: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
fileChunks, err := r.scanFileChunks(rows)
LogSQL("GetByPathTx", "Complete", path, "count", len(fileChunks))

View File

@@ -168,7 +168,13 @@ func (r *FileRepository) ListModifiedSince(
if err != nil {
return nil, fmt.Errorf("querying files: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var files []*File
@@ -238,7 +244,13 @@ func (r *FileRepository) ListByPrefix(
if err != nil {
return nil, fmt.Errorf("querying files: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var files []*File
@@ -266,7 +278,13 @@ func (r *FileRepository) ListAll(ctx context.Context) ([]*File, error) {
if err != nil {
return nil, fmt.Errorf("querying files: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var files []*File

View File

@@ -17,6 +17,7 @@ func logSnapshotFileIDs(t *testing.T, db *DB) {
if err != nil {
t.Fatal(err)
}
defer func() {
err := rows.Close()
if err != nil {

View File

@@ -223,7 +223,13 @@ func (r *SnapshotRepository) ListRecent(
if err != nil {
return nil, fmt.Errorf("querying snapshots: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
return r.scanSnapshotRows(rows)
}
@@ -437,7 +443,13 @@ func (r *SnapshotRepository) GetBlobHashes(
if err != nil {
return nil, fmt.Errorf("querying blob hashes: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var blobs []string
@@ -561,7 +573,13 @@ func (r *SnapshotRepository) GetIncompleteSnapshots(
if err != nil {
return nil, fmt.Errorf("querying incomplete snapshots: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
return r.scanSnapshotRows(rows)
}
@@ -583,7 +601,13 @@ func (r *SnapshotRepository) GetIncompleteByHostname(
if err != nil {
return nil, fmt.Errorf("querying incomplete snapshots: %w", err)
}
defer CloseRows(rows)
defer func() {
err := rows.Close()
if err != nil {
Fatalf("failed to close rows: %v", err)
}
}()
var snapshots []*Snapshot

View File

@@ -96,6 +96,7 @@ func (r *UploadRepository) GetRecentUploads(
if err != nil {
return nil, err
}
defer func() {
err := rows.Close()
if err != nil {

View File

@@ -1,6 +1,6 @@
// Package log provides the application-wide structured logger: slog
// with a colorized TTY handler on terminals and JSON output otherwise.
package log
package log //nolint:revive,nolintlint // stdlib log unused here; see #76
import (
"context"
@@ -69,7 +69,7 @@ func Initialize(cfg Config) {
Level: level,
}
// Check if stdout is a TTY
// Check if stdout is a TTY.
if term.IsTerminal(int(os.Stdout.Fd())) {
// Use colorized TTY handler
logger = slog.New(NewTTYHandler(os.Stdout, opts))

View File

@@ -1,4 +1,4 @@
package log
package log //nolint:revive,nolintlint // stdlib log unused here; see #76
import (
"go.uber.org/fx"

View File

@@ -1,4 +1,4 @@
package log
package log //nolint:revive,nolintlint // stdlib log unused here; see #76
import (
"context"

View File

@@ -48,6 +48,7 @@ func TestAcquireBlocksSecondInstance(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, lock1)
defer func() { _ = lock1.Release() }()
// Try to acquire second lock - should fail
@@ -72,6 +73,7 @@ func TestAcquireWithStaleLock(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, lock)
defer func() { _ = lock.Release() }()
// Verify our PID is now in the file
@@ -117,6 +119,7 @@ func TestAcquireCreatesDirectory(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, lock)
defer func() { _ = lock.Release() }()
// Verify directory was created

View File

@@ -12,6 +12,7 @@ import (
//nolint:paralleltest // test servers share a fixed localhost port
func TestClient(t *testing.T) {
ts := NewTestServer(t)
defer func() {
err := ts.Cleanup()
if err != nil {
@@ -58,6 +59,7 @@ func verifyPutGetHead(
if err != nil {
t.Fatalf("failed to get object: %v", err)
}
defer func() {
err := reader.Close()
if err != nil {

View File

@@ -147,6 +147,7 @@ func (ts *TestServer) Client() *s3.Client {
//nolint:paralleltest // test servers share a fixed localhost port
func TestBasicS3Operations(t *testing.T) {
ts := NewTestServer(t)
defer func() {
err := ts.Cleanup()
if err != nil {
@@ -179,6 +180,7 @@ func TestBasicS3Operations(t *testing.T) {
if err != nil {
t.Fatalf("failed to get object: %v", err)
}
defer func() {
err := result.Body.Close()
if err != nil {
@@ -202,6 +204,7 @@ func TestBasicS3Operations(t *testing.T) {
//nolint:paralleltest // test servers share a fixed localhost port
func TestBlobOperations(t *testing.T) {
ts := NewTestServer(t)
defer func() {
err := ts.Cleanup()
if err != nil {
@@ -268,6 +271,7 @@ func TestBlobOperations(t *testing.T) {
//nolint:paralleltest // test servers share a fixed localhost port
func TestMetadataOperations(t *testing.T) {
ts := NewTestServer(t)
defer func() {
err := ts.Cleanup()
if err != nil {

View File

@@ -461,6 +461,7 @@ func (b *BackupEngine) backupOneFile(
if err != nil {
return err
}
defer func() {
err := f.Close()
if err != nil {

View File

@@ -75,6 +75,7 @@ func TestFileContentChange(t *testing.T) {
db, err := database.NewTestDB()
require.NoError(t, err)
defer func() {
err := db.Close()
if err != nil {
@@ -165,6 +166,7 @@ func TestMultipleFileChanges(t *testing.T) {
db, err := database.NewTestDB()
require.NoError(t, err)
defer func() {
err := db.Close()
if err != nil {

View File

@@ -127,6 +127,7 @@ func NewProgressReporter() *ProgressReporter {
// Start begins the progress reporting
func (pr *ProgressReporter) Start() {
pr.wg.Add(1)
go pr.run()
// Print initial multi-line status

View File

@@ -624,11 +624,12 @@ func (s *Scanner) collectBatchFlushData(
collectStart := time.Now()
var (
allFileChunks []database.FileChunk
allChunkFiles []database.ChunkFile
)
// A pending file contributes one mapping of each kind per chunk, and
// an empty file contributes none, so the file count is only a rough
// starting capacity for the mapping slices; append grows them as
// needed. It is exact for the file and file-ID slices.
allFileChunks := make([]database.FileChunk, 0, len(canFlush))
allChunkFiles := make([]database.ChunkFile, 0, len(canFlush))
allFileIDs := make([]types.FileID, 0, len(canFlush))
allFiles := make([]*database.File, 0, len(canFlush))
@@ -1673,6 +1674,7 @@ func (s *Scanner) processFileStreaming(
if err != nil {
return fmt.Errorf("opening file: %w", wrapPermissionError(fileToProcess.Path, err))
}
defer func() { _ = file.Close() }()
var chunks []streamingChunkInfo

View File

@@ -164,6 +164,7 @@ func TestScannerSimpleDirectory(t *testing.T) {
if err != nil {
t.Fatalf("failed to create test database: %v", err)
}
defer func() {
err := db.Close()
if err != nil {
@@ -241,6 +242,7 @@ func TestScannerLargeFile(t *testing.T) {
if err != nil {
t.Fatalf("failed to create test database: %v", err)
}
defer func() {
err := db.Close()
if err != nil {

View File

@@ -259,6 +259,7 @@ func (sm *SnapshotManager) ExportSnapshotMetadata(
}
log.Debug("Created temporary directory", "path", tempDir)
defer func() {
log.Debug("Cleaning up temporary directory", "path", tempDir)
@@ -555,6 +556,7 @@ func (sm *SnapshotManager) cleanSnapshotDB(
if err != nil {
return nil, fmt.Errorf("opening temp database: %w", err)
}
defer func() {
err := db.Close()
if err != nil {
@@ -567,6 +569,7 @@ func (sm *SnapshotManager) cleanSnapshotDB(
if err != nil {
return nil, fmt.Errorf("beginning transaction: %w", err)
}
defer func() {
rbErr := tx.Rollback()
if rbErr != nil && !errors.Is(rbErr, sql.ErrTxDone) {
@@ -685,6 +688,7 @@ func (sm *SnapshotManager) compressFile(inputPath, outputPath string) error {
if err != nil {
return fmt.Errorf("opening input file: %w", err)
}
defer func() {
err := input.Close()
if err != nil {
@@ -696,6 +700,7 @@ func (sm *SnapshotManager) compressFile(inputPath, outputPath string) error {
if err != nil {
return fmt.Errorf("creating output file: %w", err)
}
defer func() {
err := output.Close()
if err != nil {
@@ -714,6 +719,7 @@ func (sm *SnapshotManager) compressFile(inputPath, outputPath string) error {
// Track if writer has been closed to avoid double-close
writerClosed := false
defer func() {
if !writerClosed {
err := writer.Close()
@@ -749,6 +755,7 @@ func (sm *SnapshotManager) copyFile(src, dst string) error {
if err != nil {
return err
}
defer func() {
log.Debug("Closing source file", "path", src)
@@ -764,6 +771,7 @@ func (sm *SnapshotManager) copyFile(src, dst string) error {
if err != nil {
return err
}
defer func() {
log.Debug("Closing destination file", "path", dst)
@@ -794,6 +802,7 @@ func (sm *SnapshotManager) generateBlobManifest(
if err != nil {
return nil, fmt.Errorf("opening database: %w", err)
}
defer func() { _ = db.Close() }()
// Create repositories to access the data

View File

@@ -25,12 +25,14 @@ func copyFile(fs afero.Fs, src, dst string) error {
if err != nil {
return err
}
defer func() { _ = sourceFile.Close() }()
destFile, err := fs.Create(dst)
if err != nil {
return err
}
defer func() { _ = destFile.Close() }()
_, err = io.Copy(destFile, sourceFile)
@@ -53,6 +55,7 @@ func verifyCleanedDB(
if err != nil {
t.Fatalf("failed to open cleaned database: %v", err)
}
defer func() {
err := cleanedDB.Close()
if err != nil {

View File

@@ -62,6 +62,7 @@ func (f *FileStorer) Put(_ context.Context, key string, data io.Reader) error {
if err != nil {
return fmt.Errorf("creating file: %w", err)
}
defer func() { _ = file.Close() }()
_, err = io.Copy(file, data)
@@ -91,6 +92,7 @@ func (f *FileStorer) PutWithProgress(
if err != nil {
return fmt.Errorf("creating file: %w", err)
}
defer func() { _ = file.Close() }()
// Wrap with progress tracking
@@ -209,6 +211,7 @@ func (f *FileStorer) List(ctx context.Context, prefix string) ([]string, error)
// ListStream returns a channel of ObjectInfo for large result sets.
func (f *FileStorer) ListStream(ctx context.Context, prefix string) <-chan ObjectInfo {
ch := make(chan ObjectInfo)
go func() {
defer close(ch)

View File

@@ -68,6 +68,7 @@ func (s *S3Storer) List(ctx context.Context, prefix string) ([]string, error) {
// ListStream returns a channel of ObjectInfo for large result sets.
func (s *S3Storer) ListStream(ctx context.Context, prefix string) <-chan ObjectInfo {
ch := make(chan ObjectInfo)
go func() {
defer close(ch)

View File

@@ -2,7 +2,7 @@
// vaultik codebase. Using distinct types for IDs, hashes, paths, and
// credentials prevents accidental mixing of semantically different values
// that happen to share the same underlying type.
package types
package types //nolint:revive,nolintlint // rename decision tracked in #76
import (
"database/sql/driver"

View File

@@ -238,6 +238,7 @@ func (c *blobDiskCache) ReadAt(key string, offset, length int64) ([]byte, error)
if err != nil {
return nil, err
}
defer func() { _ = f.Close() }()
buf := make([]byte, length)

View File

@@ -14,6 +14,7 @@ func TestBlobDiskCache_BasicGetPut(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer func() { _ = cache.Close() }()
data := []byte("hello world")
@@ -79,6 +80,7 @@ func TestBlobDiskCache_OversizedEntryRejected(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer func() { _ = cache.Close() }()
data := make([]byte, 200)
@@ -100,6 +102,7 @@ func TestBlobDiskCache_UpdateInPlace(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer func() { _ = cache.Close() }()
err = cache.Put("key1", []byte("v1"))
@@ -137,6 +140,7 @@ func TestBlobDiskCache_ReadAt(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer func() { _ = cache.Close() }()
data := make([]byte, 1024)
@@ -197,6 +201,7 @@ func TestBlobDiskCache_LRUOrder(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer func() { _ = cache.Close() }()
d := make([]byte, 100)

View File

@@ -134,6 +134,7 @@ func (m *MockStorer) ListStream(
_ context.Context, prefix string,
) <-chan storage.ObjectInfo {
ch := make(chan storage.ObjectInfo)
go func() {
defer close(ch)
@@ -326,6 +327,7 @@ func TestEndToEndBackup(t *testing.T) {
db, err := database.New(ctx, ":memory:")
require.NoError(t, err)
defer func() {
err := db.Close()
if err != nil {
@@ -411,6 +413,7 @@ func TestBackupAndVerify(t *testing.T) {
db, err := database.New(ctx, ":memory:")
require.NoError(t, err)
defer func() {
err := db.Close()
if err != nil {
@@ -968,6 +971,7 @@ func TestDedupOnlySnapshotRestores(t *testing.T) {
env := setupDedupBackupEnv(
ctx, t, fs, storeDir, dbPath, chunkSize, maxBlobSize)
defer func() { _ = env.db.Close() }()
cfg, storer, repos, sm := env.cfg, env.storer, env.repos, env.sm

View File

@@ -590,6 +590,7 @@ func (v *Vaultik) downloadSnapshotDB(
if err != nil {
return nil, fmt.Errorf("downloading %s: %w", dbKey, err)
}
defer func() { _ = reader.Close() }()
// Read all data
@@ -606,6 +607,7 @@ func (v *Vaultik) downloadSnapshotDB(
if err != nil {
return nil, fmt.Errorf("creating decryption reader: %w", err)
}
defer func() { _ = blobReader.Close() }()
// Read the binary SQLite database
@@ -1115,6 +1117,7 @@ func (v *Vaultik) verifyFile(
if err != nil {
return 0, fmt.Errorf("opening file: %w", err)
}
defer func() { _ = f.Close() }()
// Verify each chunk

View File

@@ -110,6 +110,7 @@ func (s *restoreSweeper) blobStillNeeded(blobHash string) (bool, error) {
if err != nil {
return true, fmt.Errorf("querying referencing files: %w", err)
}
defer func() { _ = rows.Close() }()
for rows.Next() {

View File

@@ -1130,6 +1130,7 @@ func (v *Vaultik) downloadManifestByKey(remoteKey string) (*snapshot.Manifest, e
if err != nil {
return nil, err
}
defer func() { _ = reader.Close() }()
manifest, err := snapshot.DecodeManifest(reader)

View File

@@ -96,6 +96,7 @@ func (v *Vaultik) RunDeepVerify(snapshotID string, opts *VerifyOptions) error {
if err != nil {
return err
}
defer func() {
if tempDB != nil {
_ = tempDB.Close()
@@ -343,6 +344,7 @@ func (v *Vaultik) verifyBlob(blobInfo snapshot.BlobInfo, db *sql.DB) error {
if err != nil {
return fmt.Errorf("failed to download: %w", err)
}
defer func() { _ = reader.Close() }()
// Get decryptor