Skip to content

Caliper v1.3.0

Choose a tag to compare

@trendvidia trendvidia released this 29 Aug 10:15
· 23 commits to main since this release

Caliper v1.3.0

The interprocedural surface could not run against real code. This release fixes that, and adds what a library consumer needs to build on it.

Fixed — call-graph tools work on real code

  • They no longer crash the server. Every interprocedural tool — find_call_sites, find_taint_flow, anything reaching Engine.InterProcedural() — panicked on any real workspace, exiting the MCP server with code 2 rather than returning an error. The packages.Config load mode set NeedDeps but not NeedImports; NeedDeps only propagates the mode into packages already in Imports, and Imports itself is populated by NeedImports. Without it every pkg.Imports was empty, so ssautil.AllPackages never created the dependency packages and prog.Build() panicked on the first unsatisfied import — which is any package importing so much as context. Measured before the fix: 100% of loaded packages had empty .Imports across four repositories. (#11)

  • A program with uncreated dependencies is refused, not built. prog.Build() spawns a goroutine per package, so its panics cannot be recovered by the caller and take the process down. The precondition is now checked up front and reported as an error naming the missing import. (#11)

  • find_call_sites returns results. It reported total: 0 for every input on every repository. FindCallSitesByPattern matched the pattern against function declarations while the pattern compiler only accepts expressions, so the match loop was unreachable for every valid input. It now matches call expressions across the corpus — as the tool's own documented $x.Close() example always implied — then enriches the result with call sites the call graph knows about for each resolved callee. Measured after the fix: 138 hits for $x.Close() on protolsp, 229 for $x.String() on protocompile, 384 for $x.Close() on govm, all previously 0. (#18)

Both defects were invisible to the test suite because every interprocedural fixture was import-free (package testpkg with a bare caller/callee pair). Fixtures now import stdlib packages, so this class of regression fails the suite.

Added — for library consumers

  • EngineOptions.Tests includes each package's test files in the load (default false). Test files are roughly half the Go source in some repositories and are where intent is documented, so a consumer building a picture of a codebase usually wants them while a linter reporting on shipped code does not. Including tests takes protolsp from 1,560 to 4,057 workspace functions in the call graph, and protoregistry from 743 to 1,269.

  • Engine.GeneratedFiles, Engine.IsGeneratedFile, InterProceduralContext.IsGeneratedFunc identify generated code. EngineOptions.SkipGenerated filters AST traversal only — the SSA program and call graph are built from every loaded package and are unaffected by it. That asymmetry was undocumented and is a trap for anything walking the call graph: generated functions are 35% of protolsp's workspace functions and 45% of protoregistry's with SkipGenerated at its true default. Behaviour is unchanged, now documented and pinned by a test, and filterable by consumers that do not want it.

Build

  • golangci-lint excludes SA5011 in test files. The guard is if x == nil { t.Fatal(...) }, and the CI runner's staticcheck does not derive that testing.T.Fatal terminates, so it reported the guarded deref as a nil dereference across 40 sites in 8 files. Scoped to _test.go and that one check.

Install

gh release download v1.3.0 --repo trendvidia/caliper --pattern 'caliper-darwin-arm64'
chmod +x caliper-darwin-arm64

Verify with checksums.txt. caliper-* is the MCP server; caliper-analyze-* is the single-shot CLI.