package main import ( "encoding/json" "flag" "fmt" "io" "os" "os/exec" "sort" "strings" ) type discoverPackagesFunc func(srcRoot string) ([]string, error) func main() { os.Exit(run(os.Args[1:], os.Stdout, os.Stderr, discoverPackages)) } func run(args []string, stdout io.Writer, stderr io.Writer, discover discoverPackagesFunc) int { fs := flag.NewFlagSet("coveragegate", flag.ContinueOnError) fs.SetOutput(stderr) profilePath := fs.String("profile", "../_build/coverage.out", "path to go coverprofile") policyPath := fs.String("policy", "../specs/003-testing-time/contracts/coverage-thresholds.json", "path to coverage policy json") srcRoot := fs.String("src-root", ".", "path to src workspace root") if err := fs.Parse(args); err != nil { return 2 } policy, err := LoadPolicy(*policyPath) if err != nil { fmt.Fprintf(stderr, "coverage gate: %v\n", err) return 1 } aggByPkg, err := ParseCoverProfile(*profilePath, policy) if err != nil { fmt.Fprintf(stderr, "coverage gate: %v\n", err) return 1 } pkgs, err := discover(*srcRoot) if err != nil { fmt.Fprintf(stderr, "coverage gate: %v\n", err) return 1 } results := EvaluateCoverage(pkgs, aggByPkg, policy) if len(results) == 0 { fmt.Fprintln(stderr, "coverage gate: no in-scope packages found") return 1 } fmt.Fprintln(stdout, "Package coverage results:") fmt.Fprintln(stdout, "PACKAGE\tCOVERAGE\tTHRESHOLD\tSTATUS") failed := false totalCoverage := 0.0 for _, r := range results { status := "PASS" if !r.Pass { status = "FAIL" failed = true } fmt.Fprintf(stdout, "%s\t%.2f%%\t%.2f%%\t%s\n", r.Package, r.Percent, r.Threshold, status) totalCoverage += r.Percent } if len(results) > 0 { totalCoverage /= float64(len(results)) } packagesFailed := 0 for _, r := range results { if !r.Pass { packagesFailed++ } } // Output JSON metrics for CI consumption metrics := map[string]interface{}{ "passed": !failed, "total_coverage": fmt.Sprintf("%.2f", totalCoverage), "packages_checked": len(results), "packages_failed": packagesFailed, } metricsJSON, _ := json.Marshal(metrics) fmt.Fprintln(stdout, string(metricsJSON)) if failed { fmt.Fprintln(stderr, "coverage gate: one or more packages are below threshold") return 1 } fmt.Fprintln(stdout, "coverage gate: all in-scope packages meet threshold") return 0 } func discoverPackages(srcRoot string) ([]string, error) { cmd := exec.Command("go", "list", "./...") cmd.Dir = srcRoot out, err := cmd.Output() if err != nil { return nil, fmt.Errorf("discover packages with go list: %w", err) } lines := strings.Split(strings.TrimSpace(string(out)), "\n") pkgs := make([]string, 0, len(lines)) for _, line := range lines { line = strings.TrimSpace(line) if line == "" { continue } pkgs = append(pkgs, line) } sort.Strings(pkgs) return pkgs, nil }