Skip to content

Commit 8a190bf

Browse files
cpcloudclaude
andcommitted
fix: resolve all golangci-lint findings and bump grpc for CVE
- wrapcheck: wrap all external/interface errors with context - noctx: use NewRequestWithContext for production HTTP clients; file-level nolint for httptest in test files - errcheck/errchkjson: check json.Marshal and resp.Body.Close errors - revive: rename unused BeforeCreate tx params to _ - staticcheck: replace nil contexts with context.Background() - testifylint: assert.NotEmpty for IDs, require.Error for preconditions, assert.InDelta for floats, assert.Positive for > 0 - gosec: nolint for test credentials and weak random in test helpers - intrange: use range-over-int loops - ineffassign: remove dead rec assignment - goconst: extract repeated test string to constant - Bump google.golang.org/grpc 1.79.2 → 1.79.3 (GHSA-p77j-4mvh-x3m3) - Fix flaky TestNewIsTimeSorted with 1ms sleep between ULID generations - Update vendorHash in flake.nix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4701266 commit 8a190bf

31 files changed

Lines changed: 262 additions & 177 deletions

cmd/micasa/pro.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,10 @@ func runProDevicesList(dbPath string) error {
754754

755755
enc := json.NewEncoder(os.Stdout)
756756
enc.SetIndent("", " ")
757-
return enc.Encode(devices)
757+
if err := enc.Encode(devices); err != nil {
758+
return fmt.Errorf("encode devices: %w", err)
759+
}
760+
return nil
758761
}
759762

760763
func newProDevicesRevokeCmd() *cobra.Command {
@@ -845,5 +848,8 @@ func runProConflicts(w io.Writer, dbPath string) error {
845848
return fmt.Errorf("write conflict: %w", err)
846849
}
847850
}
848-
return tw.Flush()
851+
if err := tw.Flush(); err != nil {
852+
return fmt.Errorf("flush output: %w", err)
853+
}
854+
return nil
849855
}

cmd/micasa/pro_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,11 @@ func TestProStorageCmdWiring(t *testing.T) {
340340

341341
root := newRootCmd()
342342
proCmd, _, err := root.Find([]string{"pro"})
343-
assert.NoError(t, err)
343+
require.NoError(t, err)
344344
assert.NotNil(t, proCmd)
345345

346346
storageCmd, _, err := root.Find([]string{"pro", "storage"})
347-
assert.NoError(t, err)
347+
require.NoError(t, err)
348348
assert.NotNil(t, storageCmd)
349349
assert.Equal(t, "storage [database-path]", storageCmd.Use)
350350
}

flake.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
inherit version;
3737
src = ./.;
3838
subPackages = [ "cmd/micasa" ];
39-
vendorHash = "sha256-zgOejAAikNcxd3DX1rWLcYiMG/Otg7MsAxUONeNB2tI=";
39+
vendorHash = "sha256-31TOXdNeuUaImz9AdwSW6BTJ1PFauww/uWIquJ1roqs=";
4040
env.CGO_ENABLED = 0;
4141
preCheck = ''
4242
export HOME="$(mktemp -d)"

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ require (
117117
golang.org/x/sync v0.20.0 // indirect
118118
google.golang.org/genai v1.50.0 // indirect
119119
google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5 // indirect
120-
google.golang.org/grpc v1.79.2 // indirect
120+
google.golang.org/grpc v1.79.3 // indirect
121121
google.golang.org/protobuf v1.36.11 // indirect
122122
gopkg.in/yaml.v3 v3.0.1 // indirect
123123
modernc.org/libc v1.70.0 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@ google.golang.org/genai v1.50.0 h1:yHKV/vjoeN9PJ3iF0ur4cBZco4N3Kl7j09rMq7XSoWk=
265265
google.golang.org/genai v1.50.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
266266
google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5 h1:aJmi6DVGGIStN9Mobk/tZOOQUBbj0BPjZjjnOdoZKts=
267267
google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
268-
google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU=
269-
google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
268+
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
269+
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
270270
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
271271
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
272272
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

internal/app/dashboard_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
"github.com/stretchr/testify/require"
1616
)
1717

18+
const testIncidentID = "01JTEST00000000000000005"
19+
1820
// nonEmptyDashboard returns a minimal dashboardData that is not empty,
1921
// for tests that just need the dashboard overlay to render.
2022
func nonEmptyDashboard() dashboardData {
@@ -121,7 +123,7 @@ func TestDashboardNavigation(t *testing.T) {
121123
{Tab: tabMaintenance, ID: "01JTEST00000000000000002"},
122124
{Tab: tabProjects, ID: "01JTEST00000000000000003"},
123125
{Tab: tabAppliances, ID: "01JTEST00000000000000004"},
124-
{Tab: tabMaintenance, ID: "01JTEST00000000000000005"},
126+
{Tab: tabMaintenance, ID: testIncidentID},
125127
}
126128
m.dash.cursor = 0
127129

@@ -500,7 +502,7 @@ func TestBuildDashNav(t *testing.T) {
500502
DaysFromNow: 45,
501503
}},
502504
}
503-
m.dash.data.OpenIncidents[0].ID = "01JTEST00000000000000005"
505+
m.dash.data.OpenIncidents[0].ID = testIncidentID
504506
// Expand incidents (default) so its data rows appear in nav.
505507
m.dash.expanded = map[string]bool{
506508
dashSectionIncidents: true,
@@ -515,7 +517,7 @@ func TestBuildDashNav(t *testing.T) {
515517
assert.True(t, m.dash.nav[0].IsHeader)
516518
assert.Equal(t, dashSectionIncidents, m.dash.nav[0].Section)
517519
assert.Equal(t, tabIncidents, m.dash.nav[1].Tab)
518-
assert.Equal(t, "01JTEST00000000000000005", m.dash.nav[1].ID)
520+
assert.Equal(t, testIncidentID, m.dash.nav[1].ID)
519521

520522
// Collapsed sections: just headers.
521523
assert.True(t, m.dash.nav[2].IsHeader)
@@ -818,7 +820,7 @@ func TestDashboardExpandCollapseWithEKey(t *testing.T) {
818820
DaysFromNow: daysUntil(now, overdueDue),
819821
}},
820822
}
821-
m.dash.data.OpenIncidents[0].ID = "01JTEST00000000000000005"
823+
m.dash.data.OpenIncidents[0].ID = testIncidentID
822824
m.dash.expanded = map[string]bool{dashSectionIncidents: true}
823825
m.prepareDashboardView()
824826

@@ -864,7 +866,7 @@ func TestDashboardSectionNavWithShiftJK(t *testing.T) {
864866
}},
865867
ActiveProjects: []data.Project{{ID: "01JTEST00000000000000020", Title: "Deck"}},
866868
}
867-
m.dash.data.OpenIncidents[0].ID = "01JTEST00000000000000005"
869+
m.dash.data.OpenIncidents[0].ID = testIncidentID
868870
m.dash.expanded = map[string]bool{dashSectionIncidents: true}
869871
m.buildDashNav()
870872

@@ -943,7 +945,7 @@ func TestDashboardEnterKeyJumpsToExpiring(t *testing.T) {
943945
DaysFromNow: daysUntil(now, expiry),
944946
}},
945947
}
946-
m.dash.data.OpenIncidents[0].ID = "01JTEST00000000000000005"
948+
m.dash.data.OpenIncidents[0].ID = testIncidentID
947949
m.dash.data.ExpiringWarranties[0].Appliance.ID = "01JTEST00000000000000099"
948950
m.dash.expanded = map[string]bool{dashSectionIncidents: true}
949951
m.buildDashNav()
@@ -993,7 +995,7 @@ func TestDashboardExpiringNavWithInsuranceOnly(t *testing.T) {
993995
DaysFromNow: 60,
994996
},
995997
}
996-
m.dash.data.OpenIncidents[0].ID = "01JTEST00000000000000005"
998+
m.dash.data.OpenIncidents[0].ID = testIncidentID
997999
m.dash.expanded = map[string]bool{dashSectionIncidents: true}
9981000
m.buildDashNav()
9991001

internal/app/handler_crud_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ func TestApplianceMaintenanceHandlerLoad(t *testing.T) {
10831083
rows, meta, _, err := h.Load(m.store, false)
10841084
require.NoError(t, err)
10851085
require.Len(t, rows, 1)
1086-
assert.NotZero(t, meta[0].ID)
1086+
assert.NotEmpty(t, meta[0].ID)
10871087
}
10881088

10891089
func TestApplianceMaintenanceInlineEditSeasonDispatchesCorrectly(t *testing.T) {

internal/app/model.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ func (m *Model) Init() tea.Cmd {
337337
cmds := []tea.Cmd{m.formInitCmd(), tea.RequestBackgroundColor}
338338
if m.syncEngine != nil {
339339
m.syncStatus = syncSyncing
340-
cmds = append(cmds, doSync(m.syncEngine, m.syncCtx), syncTick())
340+
cmds = append(cmds, doSync(m.syncCtx, m.syncEngine), syncTick())
341341
}
342342
return tea.Batch(cmds...)
343343
}
@@ -495,13 +495,13 @@ func (m *Model) update(msg tea.Msg) (tea.Model, tea.Cmd) {
495495
return m, syncTick()
496496
}
497497
m.syncStatus = syncSyncing
498-
return m, tea.Batch(doSync(m.syncEngine, m.syncCtx), syncTick())
498+
return m, tea.Batch(doSync(m.syncCtx, m.syncEngine), syncTick())
499499
case syncDebounceMsg:
500500
if typed.gen != m.syncDebounceGen || m.syncEngine == nil || m.syncStatus == syncSyncing {
501501
return m, nil
502502
}
503503
m.syncStatus = syncSyncing
504-
return m, doSync(m.syncEngine, m.syncCtx)
504+
return m, doSync(m.syncCtx, m.syncEngine)
505505
case editorFinishedMsg:
506506
return m, m.handleEditorFinished(typed)
507507
}

internal/app/sync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ type syncDebounceMsg struct{ gen int }
5151

5252
// --- tea.Cmd constructors ---
5353

54-
func doSync(engine *sync.Engine, ctx context.Context) tea.Cmd {
54+
func doSync(ctx context.Context, engine *sync.Engine) tea.Cmd {
5555
return func() tea.Msg {
5656
result, err := engine.Sync(ctx)
5757
if err != nil {

internal/crypto/box_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func TestBoxTooShort(t *testing.T) {
7777
t.Parallel()
7878
var priv, pub [KeySize]byte
7979
_, err := BoxOpen(priv, pub, make([]byte, NonceSize))
80-
assert.Error(t, err)
80+
require.Error(t, err)
8181
assert.Contains(t, err.Error(), "too short")
8282
}
8383

0 commit comments

Comments
 (0)