mix qlover (qlover v0.2.0)

Copy Markdown View Source

Gates a native-cover reference snapshot when invoked directly. The mix test.qlover runner also uses this task's snapshot and planning APIs to gate its runtime-attributed line ownership.

mix qlover --eligible
mix test --stale --cover --export-coverage .qlover_fresh
mix qlover
mix qlover --write-baseline

The snapshot records compiled-module and test hashes, non-test gate inputs, and compiler references. Attributed snapshots additionally record the full executable-line inventory, per-file hits, source-map identity, dependency identity, and runtime/backend compatibility. Changed files replace their rows, never accumulate historical coverage. Standalone native-cover exports cannot be upgraded into attributed evidence without a new full run.

Prefer mix test.qlover, which runs the whole flow (eligible → stale → gate, else full → snapshot) in one command.

Options

The task is normally driven by the cover.sh wrapper, but the paths can be overridden for testing or custom layouts:

  • --baseline PATH - baseline file (default: cover/.qlover_baseline)
  • --export NAME - fresh export name under the cover output dir (default: cover/.qlover_fresh.coverdata)
  • --expansion-export PATH - second scratch export for the focused expansion run (default: cover/.qlover_expansion.coverdata)

A successful gate deletes the scratch exports so a later mix test.coverage never unions a stale partial into a full report.

Sharing baselines across worktrees

Every snapshot is also written through to a shared content-addressed cache, and a missing or invalid local baseline is fetched from it:

QLOVER_CACHE_DIR=~/.cache/qlover  # the default (XDG-aware)

The cache key is derived from the beam hashes, gate hash, and test hashes, so a hit means byte-identical content: the gate re-verifies the fetched baseline against the local tree exactly as if it were local, so a cache hit can never pass where a local baseline would fail. Set QLOVER_CACHE_DIR to another directory to share across checkouts, to "" to disable the cache, or keep the default for a personal cross-worktree cache. Tracer records merge the same way (per-file content keys; last-writer-wins races only ever degrade to a full run).

Test attribution

Changed application modules still use compiler references alongside prior runtime owners. Enable Qlover.Tracer in the host project:

# mix.exs
def project do
  [...,
   elixirc_options: [tracers: [Qlover.Tracer]],
   test_elixirc_options: [tracers: [Qlover.Tracer]]]
end

A baseline from the standalone native-cover command has no runtime owners. mix test.qlover gives it one attributed full refresh before focused edits. Direct mix qlover invocations with legacy snapshots retain the conservative native-cover gate; use mix test.qlover to refresh attributed snapshots.