From ea11dd5e141816055137d6fd77b4352cb9e79d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torjus=20H=C3=A5kestad?= Date: Wed, 4 Feb 2026 01:51:20 +0100 Subject: [PATCH] fix: add nolint:errcheck comments for intentionally unchecked errors Add //nolint:errcheck comments to intentionally unchecked error returns: - defer X.Close() calls: errors from closing read-only resources, rows after iteration, files, response bodies, and gzip readers are not actionable and don't affect correctness - defer tx.Rollback(): standard Go pattern where rollback after successful commit returns an error, which is expected behavior - defer stmt.Close(): statements are closed with their transactions - Cleanup operations: DeleteRevision on failure and os.RemoveAll for temp directories are best-effort cleanup - HTTP response encoding: if JSON encoding fails at response time, there's nothing useful we can do - Test/benchmark code: unchecked errors in test setup/cleanup where failures will surface through test assertions Co-Authored-By: Claude Opus 4.5 --- cmd/hm-options/main.go | 12 +++++----- cmd/nixos-options/main.go | 12 +++++----- internal/database/benchmark_test.go | 16 ++++++------- internal/database/database_test.go | 2 +- internal/database/postgres.go | 24 +++++++++---------- internal/database/sqlite.go | 24 +++++++++---------- internal/homemanager/indexer.go | 12 +++++----- internal/homemanager/indexer_test.go | 10 ++++---- internal/mcp/server_test.go | 2 +- internal/mcp/session_test.go | 2 +- internal/mcp/transport_http.go | 5 ++-- internal/mcp/transport_http_test.go | 36 ++++++++++++++-------------- internal/nixos/indexer.go | 12 +++++----- internal/nixos/indexer_test.go | 12 +++++----- 14 files changed, 91 insertions(+), 90 deletions(-) diff --git a/cmd/hm-options/main.go b/cmd/hm-options/main.go index 24425ca..28b134c 100644 --- a/cmd/hm-options/main.go +++ b/cmd/hm-options/main.go @@ -191,7 +191,7 @@ func runServe(c *cli.Context) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -234,7 +234,7 @@ func runIndex(c *cli.Context, revision string, indexFiles bool, force bool) erro if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -288,7 +288,7 @@ func runList(c *cli.Context) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -325,7 +325,7 @@ func runSearch(c *cli.Context, query string) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -397,7 +397,7 @@ func runGet(c *cli.Context, name string) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -490,7 +490,7 @@ func runDelete(c *cli.Context, revision string) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) diff --git a/cmd/nixos-options/main.go b/cmd/nixos-options/main.go index 5d035fc..43840b3 100644 --- a/cmd/nixos-options/main.go +++ b/cmd/nixos-options/main.go @@ -190,7 +190,7 @@ func runServe(c *cli.Context) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -233,7 +233,7 @@ func runIndex(c *cli.Context, revision string, indexFiles bool, force bool) erro if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -283,7 +283,7 @@ func runList(c *cli.Context) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -320,7 +320,7 @@ func runSearch(c *cli.Context, query string) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -392,7 +392,7 @@ func runGet(c *cli.Context, name string) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) @@ -485,7 +485,7 @@ func runDelete(c *cli.Context, revision string) error { if err != nil { return fmt.Errorf("failed to open database: %w", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // cleanup on exit if err := store.Initialize(ctx); err != nil { return fmt.Errorf("failed to initialize database: %w", err) diff --git a/internal/database/benchmark_test.go b/internal/database/benchmark_test.go index b601e07..8fe12d8 100644 --- a/internal/database/benchmark_test.go +++ b/internal/database/benchmark_test.go @@ -12,7 +12,7 @@ func BenchmarkCreateOptions(b *testing.B) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { @@ -53,7 +53,7 @@ func benchmarkBatch(b *testing.B, batchSize int) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { @@ -88,9 +88,9 @@ func benchmarkBatch(b *testing.B, batchSize int) { } // Clean up for next iteration - store.DeleteRevision(ctx, rev.ID) + _ = store.DeleteRevision(ctx, rev.ID) //nolint:errcheck // benchmark cleanup rev = &Revision{GitHash: fmt.Sprintf("batchbench%d", i), ChannelName: "bench"} - store.CreateRevision(ctx, rev) + _ = store.CreateRevision(ctx, rev) //nolint:errcheck // benchmark setup for _, opt := range opts { opt.RevisionID = rev.ID } @@ -102,7 +102,7 @@ func BenchmarkSearchOptions(b *testing.B) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { @@ -144,7 +144,7 @@ func BenchmarkGetChildren(b *testing.B) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { @@ -197,7 +197,7 @@ func BenchmarkSchemaInitialize(b *testing.B) { b.Fatalf("Failed to initialize: %v", err) } - store.Close() + store.Close() //nolint:errcheck // benchmark cleanup } } @@ -207,7 +207,7 @@ func BenchmarkRevisionCRUD(b *testing.B) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { diff --git a/internal/database/database_test.go b/internal/database/database_test.go index bd8c713..144abbd 100644 --- a/internal/database/database_test.go +++ b/internal/database/database_test.go @@ -27,7 +27,7 @@ func runStoreTests(t *testing.T, newStore func(t *testing.T) Store) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { store := newStore(t) - defer store.Close() + defer store.Close() //nolint:errcheck // test cleanup tt.test(t, store) }) } diff --git a/internal/database/postgres.go b/internal/database/postgres.go index 0587446..83458bf 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -22,7 +22,7 @@ func NewPostgresStore(connStr string) (*PostgresStore, error) { } if err := db.Ping(); err != nil { - db.Close() + db.Close() //nolint:errcheck // best-effort cleanup on connection failure return nil, fmt.Errorf("failed to ping database: %w", err) } @@ -185,7 +185,7 @@ func (s *PostgresStore) ListRevisions(ctx context.Context) ([]*Revision, error) if err != nil { return nil, fmt.Errorf("failed to list revisions: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var revisions []*Revision for rows.Next() { @@ -237,7 +237,7 @@ func (s *PostgresStore) CreateOptionsBatch(ctx context.Context, opts []*Option) if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) } - defer tx.Rollback() + defer tx.Rollback() //nolint:errcheck // rollback after commit returns error, which is expected stmt, err := tx.PrepareContext(ctx, ` INSERT INTO options (revision_id, name, parent_path, type, default_value, example, description, read_only) @@ -246,7 +246,7 @@ func (s *PostgresStore) CreateOptionsBatch(ctx context.Context, opts []*Option) if err != nil { return fmt.Errorf("failed to prepare statement: %w", err) } - defer stmt.Close() + defer stmt.Close() //nolint:errcheck // statement closed with transaction for _, opt := range opts { err := stmt.QueryRowContext(ctx, @@ -285,7 +285,7 @@ func (s *PostgresStore) GetChildren(ctx context.Context, revisionID int64, paren if err != nil { return nil, fmt.Errorf("failed to get children: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var options []*Option for rows.Next() { @@ -357,7 +357,7 @@ func (s *PostgresStore) SearchOptions(ctx context.Context, revisionID int64, que if err != nil { return nil, fmt.Errorf("failed to search options: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var options []*Option for rows.Next() { @@ -390,7 +390,7 @@ func (s *PostgresStore) CreateDeclarationsBatch(ctx context.Context, decls []*De if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) } - defer tx.Rollback() + defer tx.Rollback() //nolint:errcheck // rollback after commit returns error, which is expected stmt, err := tx.PrepareContext(ctx, ` INSERT INTO declarations (option_id, file_path, line) @@ -399,7 +399,7 @@ func (s *PostgresStore) CreateDeclarationsBatch(ctx context.Context, decls []*De if err != nil { return fmt.Errorf("failed to prepare statement: %w", err) } - defer stmt.Close() + defer stmt.Close() //nolint:errcheck // statement closed with transaction for _, decl := range decls { err := stmt.QueryRowContext(ctx, decl.OptionID, decl.FilePath, decl.Line).Scan(&decl.ID) @@ -419,7 +419,7 @@ func (s *PostgresStore) GetDeclarations(ctx context.Context, optionID int64) ([] if err != nil { return nil, fmt.Errorf("failed to get declarations: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var decls []*Declaration for rows.Next() { @@ -460,7 +460,7 @@ func (s *PostgresStore) CreateFilesBatch(ctx context.Context, files []*File) err if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) } - defer tx.Rollback() + defer tx.Rollback() //nolint:errcheck // rollback after commit returns error, which is expected stmt, err := tx.PrepareContext(ctx, ` INSERT INTO files (revision_id, file_path, extension, content, byte_size, line_count) @@ -469,7 +469,7 @@ func (s *PostgresStore) CreateFilesBatch(ctx context.Context, files []*File) err if err != nil { return fmt.Errorf("failed to prepare statement: %w", err) } - defer stmt.Close() + defer stmt.Close() //nolint:errcheck // statement closed with transaction for _, file := range files { // Compute metadata if not already set @@ -516,7 +516,7 @@ func (s *PostgresStore) GetDeclarationsWithMetadata(ctx context.Context, revisio if err != nil { return nil, fmt.Errorf("failed to get declarations with metadata: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var decls []*DeclarationWithMetadata for rows.Next() { diff --git a/internal/database/sqlite.go b/internal/database/sqlite.go index a381d6e..7b30ee6 100644 --- a/internal/database/sqlite.go +++ b/internal/database/sqlite.go @@ -23,7 +23,7 @@ func NewSQLiteStore(path string) (*SQLiteStore, error) { // Enable foreign keys if _, err := db.Exec("PRAGMA foreign_keys = ON"); err != nil { - db.Close() + db.Close() //nolint:errcheck // best-effort cleanup on connection failure return nil, fmt.Errorf("failed to enable foreign keys: %w", err) } @@ -192,7 +192,7 @@ func (s *SQLiteStore) ListRevisions(ctx context.Context) ([]*Revision, error) { if err != nil { return nil, fmt.Errorf("failed to list revisions: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration //nolint:errcheck // rows.Err() checked after iteration var revisions []*Revision for rows.Next() { @@ -249,7 +249,7 @@ func (s *SQLiteStore) CreateOptionsBatch(ctx context.Context, opts []*Option) er if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) } - defer tx.Rollback() + defer tx.Rollback() //nolint:errcheck // rollback after commit returns error, which is expected stmt, err := tx.PrepareContext(ctx, ` INSERT INTO options (revision_id, name, parent_path, type, default_value, example, description, read_only) @@ -257,7 +257,7 @@ func (s *SQLiteStore) CreateOptionsBatch(ctx context.Context, opts []*Option) er if err != nil { return fmt.Errorf("failed to prepare statement: %w", err) } - defer stmt.Close() + defer stmt.Close() //nolint:errcheck // statement closed with transaction for _, opt := range opts { result, err := stmt.ExecContext(ctx, @@ -301,7 +301,7 @@ func (s *SQLiteStore) GetChildren(ctx context.Context, revisionID int64, parentP if err != nil { return nil, fmt.Errorf("failed to get children: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var options []*Option for rows.Next() { @@ -384,7 +384,7 @@ func (s *SQLiteStore) SearchOptions(ctx context.Context, revisionID int64, query if err != nil { return nil, fmt.Errorf("failed to search options: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var options []*Option for rows.Next() { @@ -422,7 +422,7 @@ func (s *SQLiteStore) CreateDeclarationsBatch(ctx context.Context, decls []*Decl if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) } - defer tx.Rollback() + defer tx.Rollback() //nolint:errcheck // rollback after commit returns error, which is expected stmt, err := tx.PrepareContext(ctx, ` INSERT INTO declarations (option_id, file_path, line) @@ -430,7 +430,7 @@ func (s *SQLiteStore) CreateDeclarationsBatch(ctx context.Context, decls []*Decl if err != nil { return fmt.Errorf("failed to prepare statement: %w", err) } - defer stmt.Close() + defer stmt.Close() //nolint:errcheck // statement closed with transaction for _, decl := range decls { result, err := stmt.ExecContext(ctx, decl.OptionID, decl.FilePath, decl.Line) @@ -455,7 +455,7 @@ func (s *SQLiteStore) GetDeclarations(ctx context.Context, optionID int64) ([]*D if err != nil { return nil, fmt.Errorf("failed to get declarations: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var decls []*Declaration for rows.Next() { @@ -501,7 +501,7 @@ func (s *SQLiteStore) CreateFilesBatch(ctx context.Context, files []*File) error if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) } - defer tx.Rollback() + defer tx.Rollback() //nolint:errcheck // rollback after commit returns error, which is expected stmt, err := tx.PrepareContext(ctx, ` INSERT INTO files (revision_id, file_path, extension, content, byte_size, line_count) @@ -509,7 +509,7 @@ func (s *SQLiteStore) CreateFilesBatch(ctx context.Context, files []*File) error if err != nil { return fmt.Errorf("failed to prepare statement: %w", err) } - defer stmt.Close() + defer stmt.Close() //nolint:errcheck // statement closed with transaction for _, file := range files { // Compute metadata if not already set @@ -561,7 +561,7 @@ func (s *SQLiteStore) GetDeclarationsWithMetadata(ctx context.Context, revisionI if err != nil { return nil, fmt.Errorf("failed to get declarations with metadata: %w", err) } - defer rows.Close() + defer rows.Close() //nolint:errcheck // rows.Err() checked after iteration var decls []*DeclarationWithMetadata for rows.Next() { diff --git a/internal/homemanager/indexer.go b/internal/homemanager/indexer.go index 4a46745..6c9ace5 100644 --- a/internal/homemanager/indexer.go +++ b/internal/homemanager/indexer.go @@ -97,7 +97,7 @@ func (idx *Indexer) IndexRevision(ctx context.Context, revision string) (*option if err != nil { return nil, fmt.Errorf("failed to open options.json: %w", err) } - defer optionsFile.Close() + defer optionsFile.Close() //nolint:errcheck // read-only file opts, err := nixos.ParseOptions(optionsFile) if err != nil { @@ -125,7 +125,7 @@ func (idx *Indexer) IndexRevision(ctx context.Context, revision string) (*option // Store options if err := idx.storeOptions(ctx, rev.ID, opts); err != nil { // Cleanup on failure - idx.store.DeleteRevision(ctx, rev.ID) + _ = idx.store.DeleteRevision(ctx, rev.ID) //nolint:errcheck // best-effort cleanup return nil, fmt.Errorf("failed to store options: %w", err) } @@ -169,7 +169,7 @@ func (idx *Indexer) buildOptions(ctx context.Context, ref string) (string, func( } cleanup := func() { - os.RemoveAll(tmpDir) + _ = os.RemoveAll(tmpDir) //nolint:errcheck // best-effort temp dir cleanup } // Build options.json using nix-build @@ -286,7 +286,7 @@ func (idx *Indexer) getCommitDate(ctx context.Context, ref string) (time.Time, e if err != nil { return time.Time{}, err } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // response body read-only if resp.StatusCode != http.StatusOK { return time.Time{}, fmt.Errorf("GitHub API returned %d", resp.StatusCode) @@ -345,7 +345,7 @@ func (idx *Indexer) IndexFiles(ctx context.Context, revisionID int64, ref string if err != nil { return 0, fmt.Errorf("failed to download tarball: %w", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // response body read-only if resp.StatusCode != http.StatusOK { return 0, fmt.Errorf("download failed with status %d", resp.StatusCode) @@ -356,7 +356,7 @@ func (idx *Indexer) IndexFiles(ctx context.Context, revisionID int64, ref string if err != nil { return 0, fmt.Errorf("failed to create gzip reader: %w", err) } - defer gz.Close() + defer gz.Close() //nolint:errcheck // gzip reader read-only tr := tar.NewReader(gz) count := 0 diff --git a/internal/homemanager/indexer_test.go b/internal/homemanager/indexer_test.go index d1de049..1b87745 100644 --- a/internal/homemanager/indexer_test.go +++ b/internal/homemanager/indexer_test.go @@ -70,7 +70,7 @@ func TestResolveRevision(t *testing.T) { if err != nil { t.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark/test cleanup indexer := NewIndexer(store) @@ -104,7 +104,7 @@ func TestGetChannelName(t *testing.T) { if err != nil { t.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark/test cleanup indexer := NewIndexer(store) @@ -144,7 +144,7 @@ func BenchmarkIndexRevision(b *testing.B) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark/test cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { @@ -157,7 +157,7 @@ func BenchmarkIndexRevision(b *testing.B) { for i := 0; i < b.N; i++ { // Delete any existing revision first (for repeated runs) if rev, _ := store.GetRevision(ctx, TestHomeManagerRevision); rev != nil { - store.DeleteRevision(ctx, rev.ID) + _ = store.DeleteRevision(ctx, rev.ID) //nolint:errcheck // benchmark cleanup } result, err := indexer.IndexRevision(ctx, TestHomeManagerRevision) @@ -186,7 +186,7 @@ func TestIndexRevision(t *testing.T) { if err != nil { t.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark/test cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { diff --git a/internal/mcp/server_test.go b/internal/mcp/server_test.go index fea5b5f..5ecc92f 100644 --- a/internal/mcp/server_test.go +++ b/internal/mcp/server_test.go @@ -245,7 +245,7 @@ func setupTestStore(t *testing.T) database.Store { } t.Cleanup(func() { - store.Close() + store.Close() //nolint:errcheck // test cleanup }) return store diff --git a/internal/mcp/session_test.go b/internal/mcp/session_test.go index febb114..a1f8d58 100644 --- a/internal/mcp/session_test.go +++ b/internal/mcp/session_test.go @@ -179,7 +179,7 @@ func TestSessionStoreCleanup(t *testing.T) { // Create multiple sessions for i := 0; i < 5; i++ { - store.Create() + _, _ = store.Create() //nolint:errcheck // test setup, error checked via count } if store.Count() != 5 { diff --git a/internal/mcp/transport_http.go b/internal/mcp/transport_http.go index 802191f..e8575ec 100644 --- a/internal/mcp/transport_http.go +++ b/internal/mcp/transport_http.go @@ -182,6 +182,7 @@ func (t *HTTPTransport) handlePost(w http.ResponseWriter, r *http.Request) { if err := json.Unmarshal(body, &req); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) + //nolint:errcheck // response already being written, can't handle encode error json.NewEncoder(w).Encode(Response{ JSONRPC: "2.0", Error: &Error{ @@ -237,7 +238,7 @@ func (t *HTTPTransport) handlePost(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(resp) + _ = json.NewEncoder(w).Encode(resp) //nolint:errcheck // response already being written } // handleInitialize handles the initialize request and creates a new session. @@ -271,7 +272,7 @@ func (t *HTTPTransport) handleInitialize(w http.ResponseWriter, r *http.Request, w.Header().Set("Content-Type", "application/json") w.Header().Set("Mcp-Session-Id", session.ID) w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(resp) + _ = json.NewEncoder(w).Encode(resp) //nolint:errcheck // response already being written } // handleGet handles SSE stream for server-initiated notifications. diff --git a/internal/mcp/transport_http_test.go b/internal/mcp/transport_http_test.go index f702506..c6163fb 100644 --- a/internal/mcp/transport_http_test.go +++ b/internal/mcp/transport_http_test.go @@ -59,7 +59,7 @@ func TestHTTPTransportInitialize(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusOK { t.Errorf("Expected 200, got %d", resp.StatusCode) @@ -103,7 +103,7 @@ func TestHTTPTransportSessionRequired(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusBadRequest { t.Errorf("Expected 400 without session, got %d", resp.StatusCode) @@ -129,7 +129,7 @@ func TestHTTPTransportInvalidSession(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusNotFound { t.Errorf("Expected 404 for invalid session, got %d", resp.StatusCode) @@ -158,7 +158,7 @@ func TestHTTPTransportValidSession(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusOK { t.Errorf("Expected 200 with valid session, got %d", resp.StatusCode) @@ -185,7 +185,7 @@ func TestHTTPTransportNotificationAccepted(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusAccepted { t.Errorf("Expected 202 for notification, got %d", resp.StatusCode) @@ -210,7 +210,7 @@ func TestHTTPTransportDeleteSession(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusNoContent { t.Errorf("Expected 204 for delete, got %d", resp.StatusCode) @@ -232,7 +232,7 @@ func TestHTTPTransportDeleteNonexistentSession(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusNotFound { t.Errorf("Expected 404 for nonexistent session, got %d", resp.StatusCode) @@ -315,7 +315,7 @@ func TestHTTPTransportOriginValidation(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if tt.expectAllowed && resp.StatusCode == http.StatusForbidden { t.Error("Expected request to be allowed but was forbidden") @@ -340,7 +340,7 @@ func TestHTTPTransportSSERequiresAcceptHeader(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusNotAcceptable { t.Errorf("Expected 406 without Accept header, got %d", resp.StatusCode) @@ -361,7 +361,7 @@ func TestHTTPTransportSSEStream(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusOK { t.Fatalf("Expected 200, got %d", resp.StatusCode) @@ -425,7 +425,7 @@ func TestHTTPTransportSSEKeepalive(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusOK { t.Fatalf("Expected 200, got %d", resp.StatusCode) @@ -483,7 +483,7 @@ func TestHTTPTransportParseError(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusOK { t.Errorf("Expected 200 (with JSON-RPC error), got %d", resp.StatusCode) @@ -511,7 +511,7 @@ func TestHTTPTransportMethodNotAllowed(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusMethodNotAllowed { t.Errorf("Expected 405, got %d", resp.StatusCode) @@ -530,7 +530,7 @@ func TestHTTPTransportOptionsRequest(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusNoContent { t.Errorf("Expected 204, got %d", resp.StatusCode) @@ -641,7 +641,7 @@ func TestHTTPTransportRequestBodyTooLarge(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusRequestEntityTooLarge { t.Errorf("Expected 413 for oversized request, got %d", resp.StatusCode) @@ -670,7 +670,7 @@ func TestHTTPTransportSessionLimitReached(t *testing.T) { if err != nil { t.Fatalf("Request %d failed: %v", i, err) } - resp.Body.Close() + resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusOK { t.Errorf("Request %d: expected 200, got %d", i, resp.StatusCode) @@ -685,7 +685,7 @@ func TestHTTPTransportSessionLimitReached(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusServiceUnavailable { t.Errorf("Expected 503 when session limit reached, got %d", resp.StatusCode) @@ -713,7 +713,7 @@ func TestHTTPTransportRequestBodyWithinLimit(t *testing.T) { if err != nil { t.Fatalf("Request failed: %v", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // test cleanup if resp.StatusCode != http.StatusOK { t.Errorf("Expected 200 for valid request within limit, got %d", resp.StatusCode) diff --git a/internal/nixos/indexer.go b/internal/nixos/indexer.go index ddb00d1..2891d44 100644 --- a/internal/nixos/indexer.go +++ b/internal/nixos/indexer.go @@ -91,7 +91,7 @@ func (idx *Indexer) IndexRevision(ctx context.Context, revision string) (*IndexR if err != nil { return nil, fmt.Errorf("failed to open options.json: %w", err) } - defer optionsFile.Close() + defer optionsFile.Close() //nolint:errcheck // read-only file options, err := ParseOptions(optionsFile) if err != nil { @@ -119,7 +119,7 @@ func (idx *Indexer) IndexRevision(ctx context.Context, revision string) (*IndexR // Store options if err := idx.storeOptions(ctx, rev.ID, options); err != nil { // Cleanup on failure - idx.store.DeleteRevision(ctx, rev.ID) + _ = idx.store.DeleteRevision(ctx, rev.ID) //nolint:errcheck // best-effort cleanup return nil, fmt.Errorf("failed to store options: %w", err) } @@ -163,7 +163,7 @@ func (idx *Indexer) buildOptions(ctx context.Context, ref string) (string, func( } cleanup := func() { - os.RemoveAll(tmpDir) + _ = os.RemoveAll(tmpDir) //nolint:errcheck // best-effort temp dir cleanup } // Build options.json using nix-build @@ -280,7 +280,7 @@ func (idx *Indexer) getCommitDate(ctx context.Context, ref string) (time.Time, e if err != nil { return time.Time{}, err } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // response body read-only if resp.StatusCode != http.StatusOK { return time.Time{}, fmt.Errorf("GitHub API returned %d", resp.StatusCode) @@ -362,7 +362,7 @@ func (idx *Indexer) IndexFiles(ctx context.Context, revisionID int64, ref string if err != nil { return 0, fmt.Errorf("failed to download tarball: %w", err) } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // response body read-only if resp.StatusCode != http.StatusOK { return 0, fmt.Errorf("download failed with status %d", resp.StatusCode) @@ -373,7 +373,7 @@ func (idx *Indexer) IndexFiles(ctx context.Context, revisionID int64, ref string if err != nil { return 0, fmt.Errorf("failed to create gzip reader: %w", err) } - defer gz.Close() + defer gz.Close() //nolint:errcheck // gzip reader read-only tr := tar.NewReader(gz) count := 0 diff --git a/internal/nixos/indexer_test.go b/internal/nixos/indexer_test.go index 910f202..fcc8730 100644 --- a/internal/nixos/indexer_test.go +++ b/internal/nixos/indexer_test.go @@ -77,7 +77,7 @@ func BenchmarkIndexRevision(b *testing.B) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark/test cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { @@ -90,7 +90,7 @@ func BenchmarkIndexRevision(b *testing.B) { for i := 0; i < b.N; i++ { // Delete any existing revision first (for repeated runs) if rev, _ := store.GetRevision(ctx, TestNixpkgsRevision); rev != nil { - store.DeleteRevision(ctx, rev.ID) + _ = store.DeleteRevision(ctx, rev.ID) //nolint:errcheck // benchmark cleanup } result, err := indexer.IndexRevision(ctx, TestNixpkgsRevision) @@ -119,7 +119,7 @@ func BenchmarkIndexRevisionWithFiles(b *testing.B) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark/test cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { @@ -132,7 +132,7 @@ func BenchmarkIndexRevisionWithFiles(b *testing.B) { for i := 0; i < b.N; i++ { // Delete any existing revision first if rev, _ := store.GetRevision(ctx, TestNixpkgsRevision); rev != nil { - store.DeleteRevision(ctx, rev.ID) + _ = store.DeleteRevision(ctx, rev.ID) //nolint:errcheck // benchmark cleanup } result, err := indexer.IndexRevision(ctx, TestNixpkgsRevision) @@ -168,7 +168,7 @@ func BenchmarkIndexFilesOnly(b *testing.B) { if err != nil { b.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark/test cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil { @@ -211,7 +211,7 @@ func TestIndexRevision(t *testing.T) { if err != nil { t.Fatalf("Failed to create store: %v", err) } - defer store.Close() + defer store.Close() //nolint:errcheck // benchmark/test cleanup ctx := context.Background() if err := store.Initialize(ctx); err != nil {