Fix lint failures: exhaustive switches, errcheck, goconst · Entire
Fix lint failures: exhaustive switches, errcheck, goconst
2bdef7a→main· Soph·2mo ago·9 files·+18 added/-14 removed
Eleven golangci-lint issues from the all-refs branch additions:
- exhaustive (8): every kind/action switch in planner, relay, replicate, bootstrap, and syncer needed explicit no-op cases for the new RefKindOther / ActionWarn enum members. Folded the dead default branches into explicit cases — exhaustive's intent is to flag any future enum addition that silently lands in default.
- errcheck (2): the test code's
if v, _ := m["x"].(T); ...pattern triggered errcheck for the discarded comma-ok bool. Switched toif v, ok := m["x"].(T); ok && .... - goconst (1): "bootstrap" appeared three times across syncer test files. Added relayModeBootstrap alongside relayModeIncremental and relayModeBootstrapBatch.
PlanReplicationRef: dropped the redundant default arm — the reason string was identical to the RefKindBranch case, so the new case RefKindBranch, RefKindOther covers it.
CanIncrementalRelay: turned the default: arm into the explicit RefKindOther case it always was. Same outcome, exhaustive happy.
replicate.Execute: dropped the unreachable default that errored on unknown actions. The new switch covers every Action explicitly; if a future Action gets added, exhaustive will yell at the call site.
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
Sessions
aacb424eaf37View transcript
Changes
9
cmd/git-sync
Mmain_test.go+2/-2
internal
planner
Mplanner.go+1/-3
Mplanner_test.go+1
Mrelay.go+2/-2
strategy
bootstrap
Mbootstrap.go+1
replicate
Mreplicate.go+3/-4
syncer
Mgit_http_backend_test.go+2/-2
Mintegration_test.go+2/-1
Msyncer.go+4
371 unmodified lines
372
373
374
375
375
376
377
378
72 unmodified lines
451
452
453
454
454
455
456
457
371 unmodified lines
if !ok {
continue
}
if name, _ := entry["name"].(string); name != "" {
if name, ok := entry["name"].(string); ok && name != "" {
seen[name] = true
}
}
72 unmodified lines
if err := json.Unmarshal([]byte(output), &result); err != nil {
t.Fatalf("decode sync json: %v\noutput=%s", err, output)
}
if got, _ := result["warned"].(float64); got == 0 {
if got, ok := result["warned"].(float64); !ok || got == 0 {
t.Fatalf("expected warned > 0 in result, got %#v", result["warned"])
}
}
Mcmd/git-sync/main_test.go+2/-2
374 unmodified lines
375
376
377
378
379
380
378
379
380
381
374 unmodified lines
switch want.Kind {
case RefKindTag:
plan.Reason = ShortHash(targetHash) + " -> " + ShortHash(want.SourceHash) + " (replicate tag overwrite)"
case RefKindBranch:
plan.Reason = ShortHash(targetHash) + " -> " + ShortHash(want.SourceHash) + " (replicate overwrite)"
default:
case RefKindBranch, RefKindOther:
plan.Reason = ShortHash(targetHash) + " -> " + ShortHash(want.SourceHash) + " (replicate overwrite)"
}
return plan
Minternal/planner/planner.go+1/-3
364 unmodified lines
365
366
367
368
369
370
371
364 unmodified lines
branchCount++;
case RefKindTag:
tagCount++;
case RefKindOther:
}
}
if branchCount != tt.wantBranchCount {
Minternal/planner/planner_test.go+1
96 unmodified lines
97
98
99
100
100
101
102
103
3 unmodified lines
107
108
109
110
110
111
112
113
96 unmodified lines
if !plan.TargetHash.IsZero() {
return false, "incremental-branch-create-target-not-empty"
}
case ActionDelete, ActionSkip, ActionBlock:
case ActionDelete, ActionSkip, ActionBlock, ActionWarn:
return false, "incremental-branch-action-not-update-or-create"
}
case RefKindTag:
Minternal/planner/relay.go+2/-2
667 unmodified lines
668
669
670
671
672
673
674
667 unmodified lines
hasTag = true
case planner.RefKindOther:
hasOther = true
case planner.RefKindBranch:
}
}
switch {
Minternal/strategy/bootstrap/bootstrap.go+1
52 unmodified lines
53
54
55
56
57
58
59
56
57
58
59
60
61
52 unmodified lines
updatePlans = append(updatePlans, plan)
case planner.ActionDelete:
deletePlans = append(deletePlans, plan)
case planner.ActionSkip, planner.ActionBlock:
// not applicable
default:
return Result{}, fmt.Errorf("replicate strategy does not support %s actions", plan.Action)
case planner.ActionSkip, planner.ActionBlock, planner.ActionWarn:
// not applicable: replicate runs before any rejection downgrade,
// and skip/block plans never reach the executor.
}
}
Minternal/strategy/replicate/replicate.go+3/-4
65 unmodified lines
66
67
68
69
69
70
71
72
198 unmodified lines
271
272
273
274
274
275
276
277
65 unmodified lines
if result.Pushed != 1 || result.Blocked != 0 {
t.Fatalf("unexpected initial result: %+v", result)
}
if !result.Relay || result.RelayMode != "bootstrap" {
if !result.Relay || result.RelayMode != relayModeBootstrap {
t.Fatalf("expected initial empty-target sync to use bootstrap relay, got %+v", result)
}
198 unmodified lines
if result.Pushed != 1 || result.Blocked != 0 {
t.Fatalf("unexpected initial mapped result: %+v", result)
}
if !result.Relay || result.RelayMode != "bootstrap" {
if !result.Relay || result.RelayMode != relayModeBootstrap {
t.Fatalf("expected initial mapped sync to use bootstrap relay, got %+v", result)
}
Minternal/syncer/git_http_backend_test.go+2/-2
37 unmodified lines
38
39
40
41
42
43
44
3252 unmodified lines
3297
3298
3299
3299
3300
3301
3302
3303
37 unmodified lines
testBranch = "master";
reasonEmptyTargetManagedRefs = "empty-target-managed-refs";
relayModeIncremental = "incremental";
relayModeBootstrap = "bootstrap";
relayModeBootstrapBatch = "bootstrap-batch";
)
3252 unmodified lines
if err != nil {
t.Fatalf("replicate --all-refs --prune failed: %v", err)
}
if result.RelayMode == "bootstrap" {
if result.RelayMode == relayModeBootstrap {
t.Fatalf("expected replicate to take prune path, not bootstrap; got RelayMode=%q", result.RelayMode)
}
if _, err := targetRepo.Reference(staleNotes, true); err == nil {
Minternal/syncer/integration_test.go+2/-1
743 unmodified lines
744
745
746
747
748
749
750
751
98 unmodified lines
850
851
852
853
854
855
856
857
743 unmodified lines
result.Skipped++;
case ActionBlock:
result.Blocked++;
case ActionWarn:
// not produced by planning; only set after a push by applyRejections.
}
}
98 unmodified lines
result.Skipped++;
case ActionBlock:
result.Blocked++;
case ActionWarn:
// not produced by planning; only set after a push by applyRejections.
}
}
Minternal/syncer/syncer.go+4