Skip to main content

Crate patchcov

Crate patchcov 

Source
Expand description

Diff/patch coverage analysis.

Ingests a per-line coverage report (lcov / llvm-cov JSON / cobertura / JaCoCo / Go coverprofile) plus a git diff and produces PR-attributable coverage: patch coverage (the fraction of lines the diff added that are covered), the explicit list of uncovered new lines, project before/after deltas, and indirect coverage flips on unchanged lines.

Pipeline:

  1. format::parse turns report text into a per-line model::CoverageReport.
  2. diff::DiffModel::between builds the added-line sets and base↔head alignment from git2.
  3. analysis::analyze attributes coverage to the diff.
  4. render::render emits markdown / YAML / JSON.

The command line in cli is a thin layer over these four steps, plus source markers (markers), the ignore list and config.yaml (config), path mapping (paths) and shard merging (merge). src/cli/diff.rs shows the whole pipeline in order.

§Example

Attribute a coverage report to the changes on the current branch:

use git2::Repository;
use patchcov::{
    analyze, default_base_ref, parse, render, DiffModel, DiffScope, OutputFormat, RenderOptions,
};

fn main() -> anyhow::Result<()> {
    let repo = Repository::open(".")?;

    // Read a report (the format is detected from its content), then make its paths
    // repo-relative so they line up with git's.
    let mut head = parse(&std::fs::read_to_string("head.lcov")?, None)?;
    if let Some(workdir) = repo.workdir() {
        head.strip_prefix(workdir);
    }

    // The lines added since the merge base of the default branch and HEAD, which is what
    // `patchcov diff` uses by default. An explicit revision is compared directly.
    let base = default_base_ref(&repo)?;
    let diff = DiffModel::between(&repo, &base, None)?;

    // Attribute coverage to the diff. Pass a baseline report instead of `None` for deltas.
    let result = analyze(&head, &diff, None, DiffScope::DiffOnly);
    println!("patch coverage: {:?}", result.patch.percent());
    println!("{}", render(&result, &RenderOptions::default(), OutputFormat::Markdown)?);
    Ok(())
}

The API is not stable at 0.x: breaking changes arrive in minor releases.

Re-exports§

pub use analysis::analyze;
pub use analysis::analyze_with_markers;
pub use analysis::AppliedMarker;
pub use analysis::CoverageDiff;
pub use analysis::DiffScope;
pub use analysis::ExcludedFiles;
pub use analysis::MarkerSide;
pub use analysis::Markers;
pub use diff::default_base_ref;
pub use diff::DiffModel;
pub use format::parse;
pub use format::Format;
pub use markers::FileMarkers;
pub use markers::MarkerError;
pub use markers::MarkerKind;
pub use markers::Region;
pub use model::CoverageReport;
pub use model::FileCoverage;
pub use paths::PathMapping;
pub use render::render;
pub use render::OutputFormat;
pub use render::RenderOptions;

Modules§

analysis
Coverage attribution: combine a head per-line report with a DiffModel (and optionally a baseline report) into the metrics a reviewer wants.
cli
The patchcov command line.
cobertura
Cobertura XML coverage parser (line coverage only).
config
Discovery and loading of patchcov’s repository config directory.
diff
Unified-diff model built from git2.
format
Coverage report format detection and parse dispatch.
go_coverprofile
Go -coverprofile parser (line coverage only).
jacoco
JaCoCo XML line coverage parser.
lcov
lcov trace-file parser and line-only writer.
llvm_json
llvm-cov JSON export parser (cargo llvm-cov report --json).
markers
Source comment markers that exclude or tolerate a region of a file in patchcov diff.
merge
Checks on the per-shard reports of a sharded coverage run.
model
The per-line coverage model that every parser produces.
paths
Explicit report-path mappings for package and source-root-relative reports.
render
Rendering of a CoverageDiff to markdown, YAML, or JSON.