Skip to content

Refactor 7 functions over cyclo 15; enable gocyclo lint#21

Merged
walkindude merged 8 commits into
masterfrom
gocyclo-cleanup
Apr 26, 2026
Merged

Refactor 7 functions over cyclo 15; enable gocyclo lint#21
walkindude merged 8 commits into
masterfrom
gocyclo-cleanup

Conversation

@walkindude

Copy link
Copy Markdown
Owner

Summary

  • Refactor the 8 production functions goreportcard flagged for cyclomatic complexity > 15 (one commit per function: runIndex, execCallees, execReferences, execCallers, fileHashFallback/fileHashFallbackStore/StalePackagesStore, (*indexRun).indexCallGraph, (*SQLiteStore).DefSymbol). Behavior preserved; output orderings, JSON envelopes, and error wrappings all unchanged.
  • Enable gocyclo in .golangci.yml at min-complexity: 16, matching goreportcard's > 15 threshold. Excluded for *_test.go (long table-driven tests can stay chunky without dragging the badge below A+).
  • The existing lefthook pre-commit + CI lint job both invoke tools/golangci-lint.sh, so this single config change wires the gate at both layers — no new scripts, no new hook plumbing.

Context

The badge is currently A+ (97.7% — gocyclo at 80.5%, all other checks at 100%). After this lands, gocyclo bumps too: production code is 100%, the two big test functions remain (which is fine — they don't move the badge off A+).

The two test functions (TestIndexModuleSymbolsAndCalls CC=28, TestPurgeModuleCleansAllTables CC=20) are intentionally left alone; goreportcard sees them but the overall weighted average stays well above the A+ threshold (≥ 0.95).

Test plan

  • go test ./... passes (cmd, indexer, store/sqlite all green)
  • golangci-lint run reports 0 issues with the new config
  • Synthetic CC=20 function rejected by lefthook pre-commit and by golangci-lint run
  • gosymdb index end-to-end on an isolated copy: index_meta row inserted, symbols/calls counts match pre-refactor baseline (497 symbols, 1365 calls, 5 unresolved, 930 type_refs)
  • CI green (will verify in PR)

🤖 Generated with Claude Code

walkindude and others added 8 commits April 26, 2026 01:51
Pulls schema/orphan-purge, module-iteration, git-commit capture, and the
two JSON-output paths out of runIndex into named helpers (openIndexDB,
purgeOrphanedModules, indexAllModules, captureGitCommit, emitBenchJSON,
emitIndexJSON). Behavior unchanged; the per-module count tuple becomes
an indexCounts struct so the helpers can return it cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extracts collectCallees, printCallees, printCalleesUnresolved, and
emitCalleesJSON from execCallees. Behavior unchanged. The collect step
now always populates a non-nil slice so the JSON envelope keeps emitting
"callees":[] / "unresolved":[] for empty results.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pulls the short-name resolution switch into resolveTypeRef and the
two output paths into emitReferencesJSON / printReferences. Hoists the
local refRow type to package scope so the helpers can take it directly.
Behavior unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extracts clampCallersDepth, buildCallersExplain, collectUnresolvedCallers,
printCallersUnresolved, and printCallers from execCallers. The original
streamed unresolved lines inline during the fetch loop; the refactor
buffers them into a slice, then prints in the same position so the
emitted text and ordering for --count, --explain, and plain modes stay
identical.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…kagesStore

Both fileHashFallback (sql.DB) and fileHashFallbackStore (store.ReadStore)
shared the same shape: load file list, check for new prod-only files on
disk, compare per-file hashes, then fall back to the package-level
files_hash. Each was over cyclo 15 and used a goto for the fallback hop.

Replaces the goto with a (stale, complete) tuple from a comparePerFileHashes
helper and pulls the package-hash branch into its own function. Shared
"new file detection" logic (hasNewProductionFiles) is reused between both
paths via a small basename-set helper. The git-fast-path block in
StalePackagesStore moves into loadGitFastPathState + pkgStaleViaFastPath
so the per-package loop is flat. No behavior change in the per-file path
beyond preserving the original short-circuit on the first empty hash.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The package-scope var-initializer loop in indexCallGraph (decl → spec →
value → ast.Inspect for FuncLit) was inline and pushed the function over
cyclo 15. Extracts scanCallGraphVarInits and scanFuncLitsInVarInit, plus
the two insert-and-count closures into makeCallEdgeRecorder /
makeUnresolvedEdgeRecorder methods. The package-iteration body moves
into indexPackageCallGraph so the outer function is just the gate +
per-package dispatch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DefSymbol does a four-step search (exact fqname → normalized fqname →
exact name → normalized name) with a pkg filter on each step; inline,
that exceeded cyclo 15. Extracts a symbolScanner factory and two
narrow helpers (scanByFqname, scanByName) so the function reads as four
sequential lookups with early returns. Also drops a stray placeholder
mismatch the old normalized-name branch built (an extra "20" appended
to args while the LIMIT was already inlined into the SQL string) — the
new helper builds the query consistently.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds gocyclo to the linter set with min-complexity=16 so any function
with cyclomatic complexity > 15 fails the lint pass. This is the same
threshold goreportcard.com uses, so the badge can no longer drop from
A+ via a CI-clean PR. Excluded for *_test.go where long table-driven
tests routinely exceed 15 for benign reasons (the badge counts those,
but they don't push the overall score below A+).

The existing lefthook pre-commit + CI lint job both invoke
tools/golangci-lint.sh, so this single config change wires the gate at
both layers — no new scripts or hook plumbing needed. Tooling versions
(go, golangci-lint, lefthook) remain pinned in mise.toml.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@walkindude walkindude merged commit fd01fb1 into master Apr 26, 2026
8 checks passed
@walkindude walkindude deleted the gocyclo-cleanup branch April 26, 2026 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant