Reference
Coverage
Coverage-aware test-gap (LCOV, Cobertura, JaCoCo, Go) with auto-detection and the path-matching caveats.
By default the test-gap signal is a coarse heuristic: did the changeset touch any test file? Supply a line-coverage report and it becomes precise. It scores the fraction of the change's added lines that are actually covered.
augur check --coverage lcov.info # LCOV
augur check --coverage coverage.xml # Cobertura XML
augur check --coverage jacoco.xml # JaCoCo XML (Kotlin/Java)
augur check --coverage cover.out # Go coverprofile
augur check --no-coverage # disable auto-detection
All four parsers live in AugurKit and use Foundation only (no
third-party dependency): Cobertura and JaCoCo via XMLParser, LCOV and Go
coverprofiles by line parsing.
Supported formats
| Format | Typical name | How a line is instrumented / covered |
|---|---|---|
| LCOV | lcov.info | DA:<line>,<hits>. Covered when hits > 0. |
| Cobertura | coverage.xml | <line number="N" hits="H"/>. Covered when hits > 0. |
| JaCoCo | jacoco.xml | <line nr="N" ci="C"/> under <package><sourcefile>. Covered when ci (covered instructions) > 0; reported path is package@name/sourcefile@name. |
| Go | cover.out | path:start.col,end.col stmts count blocks; every line in start…end. Covered when any covering block has count > 0. |
Auto-detection
When --coverage is absent (and --no-coverage is not set),
augur looks for a report at the repo root, trying these names in order and using
the first that exists (logged to stderr):
lcov.info → coverage.xml → jacoco.xml → cover.out → coverage.out
The format is detected by extension first (.info → LCOV, .out → Go,
.xml → Cobertura/JaCoCo), then by content sniffing: JaCoCo is distinguished from
Cobertura by its <report>/<sourcefile> markers; a Go
profile by its leading mode: line.
Scoring behavior
Per non-test, non-binary code file:
- Has instrumented changed lines →
risk = 1 − (covered ÷ instrumented), with a detail like2/3 changed lines covered (67%). - Entirely absent from the report → high risk (
0.7, "not in coverage report"). - No changed line was instrumented (e.g. only comments / blank lines changed), or no per-line data is available → falls back to the heuristic test-gap.
- No coverage supplied at all → the original heuristic, unchanged.
Only instrumented changed lines count: a changed line the tool never instrumented (a
comment, a blank line) contributes to neither the numerator nor the denominator. Added line
ranges come from git diff --unified=0; only the file's added lines are
scored (not context or deletions).
Path-matching caveats
Coverage tools and git diffs often disagree on a leading path prefix (src/a.swift
vs /build/checkout/src/a.swift). augur reconciles them by
normalized longest-suffix matching at component boundaries: the report file
sharing the most trailing path components with the diff path wins. An exact (normalized) match
always wins.
Limitation: when two report files share an identical suffix (e.g.
a/util.swiftandb/util.swiftboth matched against a diff pathutil.swift), the match is ambiguous. It is resolved deterministically (shorter reported path, then lexicographically smallest), but it may not be the file you intended.
Recommendation: emit coverage with repo-relative paths where possible, so suffix matching is unambiguous.
Malformed input
The parsers degrade gracefully: malformed or empty LCOV/Cobertura/JaCoCo/Go inputs yield a
sensible empty (or partial) report rather than crashing. An input whose format cannot be
detected at all throws CoverageParser.ParseError.undetectableFormat.