covutil

package module
v0.0.0-...-1cfc002 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2025 License: MIT Imports: 18 Imported by: 0

README

covutil

Go Reference Go Report Card

Advanced coverage utilities for Go projects, featuring comprehensive tools for analyzing, tracking, and reporting code coverage across multiple languages and artifact types.

Overview

covutil extends Go's coverage capabilities with advanced analysis tools and synthetic coverage tracking for non-Go artifacts. It enables comprehensive testing coverage measurement across your entire project ecosystem.

Key capabilities:

  • Advanced Go coverage analysis and visualization
  • Coverage tracking for scripts, templates, and configuration files
  • Multi-language coverage integration
  • Interactive web-based coverage exploration
  • Coverage forest management across test runs

Installation

go get github.com/tmc/covutil
Command Line Tools
# Core analysis tools
go install github.com/tmc/covutil/cmd/covtree@latest
go install github.com/tmc/covutil/cmd/covforest@latest
go install github.com/tmc/covutil/cmd/covtree-web@latest

# Experimental tools
go install github.com/tmc/covutil/exp/cmd/covanalyze@latest
go install github.com/tmc/covutil/exp/cmd/covcompare@latest
go install github.com/tmc/covutil/exp/cmd/covdiff@latest

Quick Start

Basic Coverage Analysis
# Generate coverage data
go test -coverprofile=coverage.out ./...

# Interactive coverage exploration
covtree coverage.out

# Web-based coverage viewer
covtree-web coverage.out
Synthetic Coverage for Scripts
package main

import (
    "log"
    
    "github.com/tmc/covutil/synthetic"
)

func main() {
    // Create tracker for deployment scripts
    tracker := synthetic.NewScriptTracker(
        synthetic.WithTestName("deployment"),
    )
    
    // Parse deployment script
    deployScript := `#!/bin/bash
echo "Starting deployment..."
kubectl apply -f manifests/
echo "Deployment complete"`
    
    err := tracker.ParseAndTrack(deployScript, "deploy.sh", "bash", "deployment")
    if err != nil {
        log.Fatal(err)
    }
    
    // Track execution (from logs, instrumentation, etc.)
    tracker.TrackExecution("deploy.sh", "deployment", 2) // echo
    tracker.TrackExecution("deploy.sh", "deployment", 3) // kubectl
    
    // Generate coverage report
    report := tracker.GetReport()
    log.Println(report)
}

Features

Coverage Analysis Tools
Tool Description
covtree Interactive coverage tree visualization
covforest Manage coverage data across multiple test runs
covtree-web Web-based coverage explorer
covanalyze Advanced coverage analysis and metrics
covcompare Compare coverage between runs
covdiff Show coverage differences and deltas
Synthetic Coverage

Track coverage for non-Go artifacts with built-in parsers:

Language Extensions Features
Bash .bash, bash Functions, arrays, here docs, test constructs
Shell .sh, shell POSIX shell compatibility
Python .py, python Classes, decorators, imports, context managers
Go Templates .tmpl, gotemplate Directives, functions, pipelines
Scripttest .txt, .txtar Complete scripttest command set (300+ patterns)

Usage

Coverage Forest Management
# Initialize coverage forest
covforest init

# Add coverage from different test runs
covforest add --name="unit-tests" coverage-unit.out
covforest add --name="integration-tests" coverage-integration.out

# View summary across all runs
covforest summary

# List all stored coverage data
covforest list
Integration Testing with Coverage
func TestDeploymentWorkflow(t *testing.T) {
    tracker := synthetic.NewScriptTracker(
        synthetic.WithTestName("deployment"),
        synthetic.WithLabels(map[string]string{
            "environment": "staging",
            "version":     "v1.2.3",
        }),
    )
    
    // Parse deployment artifacts
    err := tracker.ParseAndTrack(deployScript, "deploy.sh", "bash", "deployment")
    require.NoError(t, err)
    
    err = tracker.ParseAndTrack(configTemplate, "app.tmpl", "gotemplate", "deployment")
    require.NoError(t, err)
    
    // Execute deployment
    output := runDeployment()
    
    // Track execution based on logs
    executedLines := parseExecutionLogs(output)
    for _, line := range executedLines {
        tracker.TrackExecution("deploy.sh", "deployment", line)
    }
    
    // Generate coverage pod
    deploymentPod, err := tracker.GeneratePod()
    require.NoError(t, err)
    
    // Combine with Go coverage
    goCoverage, err := covutil.LoadCoverageSetFromDirectory(os.Getenv("GOCOVERDIR"))
    require.NoError(t, err)
    
    combinedCoverage := &covutil.CoverageSet{
        Pods: append(goCoverage.Pods, deploymentPod),
    }
    
    // Assert coverage thresholds
    coverage := calculateOverallCoverage(combinedCoverage)
    assert.Greater(t, coverage, 0.8, "Overall coverage should be >80%")
}
Custom Parser Development

Extend coverage tracking to new file types:

import "github.com/tmc/covutil/synthetic/parsers"

type DockerfileParser struct{}

func (p *DockerfileParser) Name() string {
    return "dockerfile"
}

func (p *DockerfileParser) Extensions() []string {
    return []string{".dockerfile", "Dockerfile"}
}

func (p *DockerfileParser) Description() string {
    return "Docker build files"
}

func (p *DockerfileParser) ParseScript(content string) map[int]string {
    // Implementation for parsing Dockerfile instructions
    // Return map of line numbers to executable instructions
}

func (p *DockerfileParser) IsExecutable(line string) bool {
    // Determine if line is executable (FROM, RUN, COPY, etc.)
}

// Register globally
func init() {
    parsers.Register(&DockerfileParser{})
}

API Reference

Core Types
// Load coverage data
coverageSet, err := covutil.LoadCoverageSetFromDirectory("coverage-dir")

// Basic tracking
tracker := synthetic.NewBasicTracker(
    synthetic.WithLabels(map[string]string{"test": "my-test"}),
)
tracker.Track("artifact", "location", true)

// Script tracking with auto-parsing
scriptTracker := synthetic.NewScriptTracker()
err := scriptTracker.ParseAndTrack(content, "file.sh", "bash", "test-name")
scriptTracker.TrackExecution("file.sh", "test-name", lineNumber)

// Generate outputs
pod, err := tracker.GeneratePod()           // Binary pod format
profile, err := tracker.GenerateProfile("text") // Text profile format
report := tracker.GetReport()               // Human-readable report
Supported Output Formats
  • Binary Pod: Compatible with Go coverage tools and covutil ecosystem
  • Text Profile: Compatible with go tool cover and standard Go toolchain
  • JSON: Machine-readable format for custom tooling (planned)
  • HTML: Rich interactive coverage reports

Architecture

covutil/
├── cmd/                    # Command-line tools
│   ├── covtree/           # Interactive coverage explorer
│   ├── covforest/         # Coverage forest management
│   └── covtree-web/       # Web-based coverage viewer
├── synthetic/             # Synthetic coverage engine
│   └── parsers/           # Modular parser architecture
│       ├── bash/          # Bash script parser
│       ├── python/        # Python script parser
│       ├── scripttest/    # Scripttest format parser
│       └── defaults/      # Auto-registration
├── internal/              # Core coverage infrastructure
│   └── coverage/          # Adapted from Go's internal package
└── exp/                   # Experimental tools and features

Documentation

Requirements

  • Go 1.21 or later
  • For web interface: Modern browser with JavaScript enabled

Contributing

We welcome contributions! Please see our guidelines:

  1. Bug Reports: Use GitHub issues with detailed reproduction steps
  2. Feature Requests: Describe use case and proposed API
  3. Pull Requests: Include tests and update documentation
  4. Parser Development: Follow the parsers.Parser interface

For synthetic coverage parsers:

  • Implement comprehensive command/syntax recognition
  • Include real-world test cases
  • Handle edge cases and error conditions
  • Update documentation with usage examples
Development Setup
git clone https://github.com/tmc/covutil.git
cd covutil
go mod download
go test ./...

License

This project is licensed under the MIT License - see the LICENSE file for details.

The internal/coverage package is adapted from the Go standard library and retains its original BSD-style license.

Credits

  • Core coverage infrastructure adapted from golang/go
  • Scripttest integration inspired by Go's testing infrastructure
  • Web interface built with modern web standards

For questions, issues, or contributions, please visit the GitHub repository.

Documentation

Overview

package covutil provides utilities for working with Go coverage data. It allows parsing coverage meta-data and counter files, merging coverage data from multiple runs, and generating various human-readable reports. Additionally, it offers functions for instrumented binaries to programmatically emit their coverage data and control counters.

Index

Constants

View Source
const (
	ModeSet     = coverage.ModeSet
	ModeCount   = coverage.ModeCount
	ModeAtomic  = coverage.ModeAtomic
	ModeInvalid = coverage.ModeInvalid
	ModeDefault = coverage.ModeDefault
)
View Source
const (
	GranularityBlock   = coverage.GranularityBlock
	GranularityFunc    = coverage.GranularityFunc
	GranularityInvalid = coverage.GranularityInvalid
	GranularityDefault = coverage.GranularityDefault
)

Variables

This section is empty.

Functions

func ClearCoverageCounters

func ClearCoverageCounters() error

func PkgFuncKeyString

func PkgFuncKeyString(p PkgFuncKey) string

PkgFuncKeyString returns a string representation of the PkgFuncKey.

func WriteCounterFileContent

func WriteCounterFileContent(w io.Writer) error

func WriteCoverageSetToDirectory

func WriteCoverageSetToDirectory(baseDirPath string, set *CoverageSet) error

WriteCoverageSetToDirectory writes all pods in a coverage set to subdirectories

func WriteMetaFileContent

func WriteMetaFileContent(w io.Writer) error

--- Runtime Data Emission ---

func WritePodToDirectory

func WritePodToDirectory(baseDirPath string, pod *Pod) error

WritePodToDirectory writes a pod's data to files in the specified directory

func WriteProfileToDirectory

func WriteProfileToDirectory(dirPath string, p *Profile) error

WriteProfileToDirectory writes a profile's metadata and counter data to separate files in the specified directory

Types

type CounterDataSegment

type CounterDataSegment = coverage.CounterDataSegment

type CounterFile

type CounterFile = coverage.CounterFile

func LoadCounterFile

func LoadCounterFile(r io.Reader, filePath string) (*CounterFile, error)

LoadCounterFile parses a single counter data file.

type CounterGranularity

type CounterGranularity = coverage.CounterGranularity

type CounterMode

type CounterMode = coverage.CounterMode

type CoverableUnit

type CoverableUnit = coverage.CoverableUnit

type CoverageSet

type CoverageSet struct {
	Pods []*Pod
	// contains filtered or unexported fields
}

CoverageSet manages a collection of Pods and implements fs.FS. It presents coverage data as a Plan 9-style virtual filesystem where:

/pods/                      - All pods by ID
/pods/<id>/metadata.json    - Pod metadata
/pods/<id>/profile.json     - Coverage profile
/by-label/<key>/<value>/    - Pods filtered by label
/by-package/<path>/         - Data for specific package
/functions/<pkg>/<func>/    - Individual function data
/summary/                   - Aggregate summaries

func LoadCoverageSet

func LoadCoverageSet(fsys fs.FS, opts ...LoadOption) (*CoverageSet, error)

LoadCoverageSet scans an fs.FS for coverage files and loads them. It identifies groups of meta and counter files (internal pods) and transforms them into public Pod structures containing Profiles.

Use fs.Sub if you need to target a specific subdirectory:

subFS, _ := fs.Sub(os.DirFS("/path"), "covdata")
set, _ := LoadCoverageSet(subFS, WithLogger(logger))

For updates/refreshes, simply call this function again with the same or updated filesystem - it will re-scan and return fresh data.

func (*CoverageSet) FilterByLabel

func (cs *CoverageSet) FilterByLabel(matchLabels map[string]string) (*CoverageSet, error)

FilterByLabel returns a new CoverageSet containing pods that match all provided labels.

func (*CoverageSet) FilterByPath

func (cs *CoverageSet) FilterByPath(prefixes ...string) (*CoverageSet, error)

FilterByPath returns a new CoverageSet with pods and profiles filtered by package path prefixes.

func (*CoverageSet) Merge

func (cs *CoverageSet) Merge() (*Pod, error)

Merge aggregates all pods in the CoverageSet into a single summary Pod.

func (*CoverageSet) Open

func (cs *CoverageSet) Open(name string) (fs.File, error)

Open implements fs.FS.Open with Plan 9-style path-based filtering.

type Formatter

type Formatter struct {
	// contains filtered or unexported fields
}

--- Formatting ---

func NewFormatter

func NewFormatter(mode CounterMode) *Formatter

func (*Formatter) AddPodProfile

func (f *Formatter) AddPodProfile(p *Pod) error

func (*Formatter) WriteFuncSummaryReport

func (f *Formatter) WriteFuncSummaryReport(w io.Writer, opts FuncSummaryReportOptions) error

func (*Formatter) WritePercentReport

func (f *Formatter) WritePercentReport(w io.Writer, opts PercentReportOptions) error

func (*Formatter) WriteTextualReport

func (f *Formatter) WriteTextualReport(w io.Writer, opts TextualReportOptions) error

type FuncDesc

type FuncDesc = coverage.FuncDesc

type FuncSummaryReportOptions

type FuncSummaryReportOptions struct {
}

type FunctionCounters

type FunctionCounters = coverage.FunctionCounters
type Link struct {
	Type string // e.g., "git_commit", "git_repo", "pprof_profile", "go_trace", "source_ref", "issue_tracker"
	URI  string // Uniform Resource Identifier (e.g., commit SHA, repo URL, file path with line, ticket URL)
	Desc string // Optional description (e.g., "Source at time of test", "Performance profile for this run")

}

Link defines a typed link to an external artifact or concept.

type LoadOption

type LoadOption func(*loadConfig)

LoadOption configures coverage loading behavior

func WithLogger

func WithLogger(logger *slog.Logger) LoadOption

WithLogger sets the logger for warnings and diagnostics

func WithMaxDepth

func WithMaxDepth(depth int) LoadOption

WithMaxDepth sets the maximum directory depth to search (default: unlimited)

type MetaFile

type MetaFile = coverage.MetaFile

func LoadMetaFile

func LoadMetaFile(r io.Reader, filePath string) (*MetaFile, error)

LoadMetaFile parses a single meta-data file from a reader.

type PackageMeta

type PackageMeta = coverage.PackageMeta

type PercentReportOptions

type PercentReportOptions struct {
	TargetPackages     []string
	OverallPackageName string
	IncludeEmpty       bool
	Aggregate          bool
}

type PkgFuncKey

type PkgFuncKey = coverage.PkgFuncKey

PkgFuncKey identifies a function within a package for counter lookup.

type Pod

type Pod struct {
	ID        string            // Unique identifier for this pod
	Profile   *Profile          // The actual coverage data
	Labels    map[string]string // User-defined labels (test_name, os, arch, build_id)
	Links     []Link            // Links to related artifacts
	Source    *SourceInfo       // Source control information relevant to this pod's data
	Timestamp time.Time         // When this coverage data was generated or collected
	SubPods   []*Pod            // For hierarchical data (e.g., subtests)
	// contains filtered or unexported fields
}

Pod represents a coherent set of coverage data, typically one meta-data file and its associated counter files, enriched with labels, links, and timing.

type Profile

type Profile struct {
	Meta     MetaFile
	Counters map[PkgFuncKey][]uint32
	Args     map[string]string
}

Profile holds a consistent set of coverage meta-data and aggregated counters.

func IntersectProfiles

func IntersectProfiles(profiles ...*Profile) (*Profile, error)

func MergeProfiles

func MergeProfiles(profiles ...*Profile) (*Profile, error)

func SubtractProfile

func SubtractProfile(profileA, profileB *Profile) (*Profile, error)

type SourceInfo

type SourceInfo struct {
	RepoURI    string    // e.g., "https://github.com/user/repo.git"
	CommitSHA  string    // Full commit SHA
	CommitTime time.Time // Time of the commit
	Branch     string    // Optional branch name
	Tag        string    // Optional tag name
	Dirty      bool      // True if the working directory was dirty when data was generated

}

SourceInfo can hold source control details.

type TextualReportOptions

type TextualReportOptions struct{ TargetPackages []string }

Directories

Path Synopsis
cmd
covforest command
Covforest is a program for managing and analyzing multiple coverage trees from different machines, repositories, and timelines.
Covforest is a program for managing and analyzing multiple coverage trees from different machines, repositories, and timelines.
covtree-web command
Covtree-web is a standalone web server for interactive coverage data exploration.
Covtree-web is a standalone web server for interactive coverage data exploration.
covutil command
Command covutil provides utilities for working with Go coverage data.
Command covutil provides utilities for working with Go coverage data.
package coverage defines the public types for covutil, acting as an adapter/wrapper around internal representations if needed.
package coverage defines the public types for covutil, acting as an adapter/wrapper around internal representations if needed.
exp
cmd/covdiff/cmd command
cmd/covdup/cmd command
cmd/covshow
This tool takes a function name and outputs the source code with annotations for lines not covered by scripttest tests.
This tool takes a function name and outputs the source code with annotations for lines not covered by scripttest tests.
cmd/covshow/cmd command
cmd/covzero/cmd command
internal
coverage/cfile
Package cfile implements management of coverage files.
Package cfile implements management of coverage files.
covforest
Package covforest provides functionality for managing multiple coverage trees from different sources (machines, repositories, timelines).
Package covforest provides functionality for managing multiple coverage trees from different sources (machines, repositories, timelines).
covtree
Package covtree provides functionality for analyzing and visualizing Go coverage data in a hierarchical tree structure.
Package covtree provides functionality for analyzing and visualizing Go coverage data in a hierarchical tree structure.
runtime/exithook
Package exithook provides a mechanism to execute functions at program exit.
Package exithook provides a mechanism to execute functions at program exit.
testenv
Package testenv provides a mock of Go's internal/testenv for testing purposes
Package testenv provides a mock of Go's internal/testenv for testing purposes
utils/mkcoveragealiases command
Command mkcoveragealiases creates a mirror of a subset of packages + exported symbols from internal/coverage into ./coverage/.
Command mkcoveragealiases creates a mirror of a subset of packages + exported symbols from internal/coverage into ./coverage/.
utils/rewriteimports command
Command rewriteimports rewrites import paths in Go files.
Command rewriteimports rewrites import paths in Go files.
Package synthetic provides comprehensive functionality for generating synthetic coverage data for non-Go artifacts such as scripts, configuration files, templates, and other resources.
Package synthetic provides comprehensive functionality for generating synthetic coverage data for non-Go artifacts such as scripts, configuration files, templates, and other resources.
parsers
Package parsers provides a modular, extensible architecture for script parsing in the synthetic coverage system.
Package parsers provides a modular, extensible architecture for script parsing in the synthetic coverage system.
parsers/bash
Package bash provides a parser for Bash scripts with advanced syntax support.
Package bash provides a parser for Bash scripts with advanced syntax support.
parsers/defaults
Package defaults registers all built-in parsers with the default registry.
Package defaults registers all built-in parsers with the default registry.
parsers/gotemplate
Package gotemplate provides a parser for Go template files.
Package gotemplate provides a parser for Go template files.
parsers/python
Package python provides a parser for Python scripts.
Package python provides a parser for Python scripts.
parsers/scripttest
Package scripttest provides a comprehensive parser for Go's scripttest format.
Package scripttest provides a comprehensive parser for Go's scripttest format.
parsers/shell
Package shell provides a parser for POSIX shell scripts.
Package shell provides a parser for POSIX shell scripts.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL