NAME

check-all-metric-coverage - enforce 100.0 statement, branch, condition and subroutine coverage for lib/, and tell an instrument failure apart from a coverage failure

WHAT IT IS

A fail-closed filter. It reads a Devel::Cover text report on standard input, echoes it so the operator still sees the table, and turns it into one of four verdicts, each with its own exit status.

WHAT IT IS FOR

It is the enforcing half of the repository coverage gate. The collecting half is script/coverage-gate, which runs the whole chain and pipes its report here.

WHY IT EXISTS

Three failures look alike at a glance and demand opposite responses:

  • A coverage shortfall is a fact about the code. Write more tests.

  • An unreadable report is a fact about the report. Something upstream did not produce what it claimed to produce, and the gate must never read that as a clean result.

  • An instrument failure is a fact about the environment. Devel::Cover::DB::IO picks its on-disk serialization format at BEGIN from whatever @INC makes visible - Sereal, then JSON, then Storable - and records that choice nowhere. On a host carrying two Devel::Cover installations whose available serializers differ, a chain whose commands see different library paths cannot read the database it has just written. It surfaces as File is not a perl storable or Bad Sereal header, neither of which names the cause, and both of which read as a corrupt database. The natural response - delete the database and run again - fails identically, and each attempt spends another host-exclusive multi-minute suite slot.

This filter names the third case explicitly, sniffs the format actually on disk, reports the format this reader would choose, and lists every Devel::Cover::DB::IO visible to the process, so the mismatch is on the page rather than inferred.

WHEN TO USE

Whenever a Devel::Cover report has to be judged: continuous integration, release workflows, and any local verification run.

HOW TO USE

Prefer script/coverage-gate, which collects the report and calls this filter with the right database. Call it directly only when a report already exists.

Exit statuses are the interface:

  • 0 - statement, branch, condition and subroutine are all 100.0.

  • 1 - a genuine shortfall; the failing metrics are named.

  • 2 - the report could not be read, or never arrived.

  • 3 - the instrument could not read its own database.

WHAT USES IT

script/coverage-gate, the test, release-cpan and release-github workflows, and t/107-all-metric-coverage-gate.t, which is its acceptance contract.

EXAMPLES

Example 1:

perl script/coverage-gate

Run the whole gate; this filter is the last step of it.

Example 2:

cover cover_db -report text -select_re '^lib/' \
  -coverage statement -coverage branch \
  -coverage condition -coverage subroutine 2>&1 \
  | perl script/check-all-metric-coverage

Judge a report that has already been collected. Merging standard error into the pipe is what lets a serializer parse error be classified rather than lost.

Example 3:

perl script/check-all-metric-coverage --database /tmp/scratch-db < report.txt

Judge a report collected against a coverage database somewhere other than cover_db, so an instrument failure can name that database's format.