Documentation
¶
Overview ¶
Package covergate is a scoped, exact statement-coverage gate. Given a Go cover profile and a list of packages, it passes only when every statement of exactly those packages was executed, each of them is present in the profile, and none of them can be left out of a test run: no TestMain, no build constraint, no GOOS or GOARCH file name.
It is the exact gate of github.com/modelspec-org/cli and github.com/meaninggraph/cli (internal/covergate, Apache-2.0), cut down to a list of packages, because this module cannot be gated as a whole: some of its packages have a TestMain, and some have files for one operating system. The gate has no threshold: covered statements are compared with all statements, so 99.99% fails, and no flag, variable or argument lowers the bar.
What it reads is a file tree (an fs.FS) and a profile (an io.Reader), so the gate and its tests start no process.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Run ¶
func Run(args []string, stdout, stderr io.Writer, open func(string) (io.ReadCloser, error), root fs.FS) int
Run is the gate command: Run([]string{"cover.out", "./internal/a", ...}, ...) prints the totals and returns 0 when every statement of the packages is covered and nothing hides a package from the profile, 1 when anything is wrong, and 2 for a usage or read error. root is the module's file tree.
Types ¶
type Block ¶
type Block struct {
Location string // file.go:line.col,line.col, the file as an import path
Statements int
Hit bool
}
Block is one statement block of a cover profile, merged across the test binaries that reported it: it is hit when any of them hit it.
func Parse ¶
Parse reads a cover profile in any mode. A block listed more than once, as when several test binaries cover the same package (-coverpkg), counts once, and is hit when any listing of it was hit. Two listings of one location must describe the same block, with the same statement count: if they do not, the profile is refused.
What Parse cannot tell from the profile alone is a repeated location that is two different blocks of the source with the same statement count: that is what a //line directive makes (a block is named by the file the directive gives and the physical line and column), and "hit if any listing was hit" would then count an unexecuted block as covered. A profile cannot say which case it is, so the gate does not try: it refuses every //line directive in a gated package (see LoadPackage), and with none there, one location is one block.
type Package ¶
type Package struct {
Dir string // relative to the module root, "." for the root
Path string // import path
HasStatements bool // a non-test file has a block with a statement: what the cover tool counts
Files []string // the non-test files with a statement, as import paths: each must be in the profile
TestMains []string // test files that declare TestMain
Constraints []string // one message per build constraint, GOOS/GOARCH file name or import "C"
Directives []string // one message per //line or /*line*/ directive, which renames the blocks of a profile
}
Package is a package of the module as the gate reads it from the file tree.