blob: 225861dab59ff566b63177ca05b69f92f4b79b99 [file] [log] [blame]
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// This file contains functions and apis to support the "merge"
// subcommand of "go tool covdata".
import (
var outdirflag *string
var pcombineflag *bool
func makeMergeOp() covOperation {
outdirflag = flag.String("o", "", "Output directory to write")
pcombineflag = flag.Bool("pcombine", false, "Combine profiles derived from distinct program executables")
m := &mstate{
mm: newMetaMerge(),
return m
// mstate encapsulates state and provides methods for implementing the
// merge operation. This type implements the CovDataVisitor interface,
// and is designed to be used in concert with the CovDataReader
// utility, which abstracts away most of the grubby details of reading
// coverage data files. Most of the heavy lifting for merging is done
// using apis from 'metaMerge' (this is mainly a wrapper around that
// functionality).
type mstate struct {
mm *metaMerge
func (m *mstate) Usage(msg string) {
if len(msg) > 0 {
fmt.Fprintf(os.Stderr, "error: %s\n", msg)
fmt.Fprintf(os.Stderr, "usage: go tool covdata merge -i=<directories> -o=<dir>\n\n")
fmt.Fprintf(os.Stderr, "\nExamples:\n\n")
fmt.Fprintf(os.Stderr, " go tool covdata merge -i=dir1,dir2,dir3 -o=outdir\n\n")
fmt.Fprintf(os.Stderr, " \tmerges all files in dir1/dir2/dir3\n")
fmt.Fprintf(os.Stderr, " \tinto output dir outdir\n")
func (m *mstate) Setup() {
if *indirsflag == "" {
m.Usage("select input directories with '-i' option")
if *outdirflag == "" {
m.Usage("select output directory with '-o' option")
func (m *mstate) BeginPod(p pods.Pod) {
func (m *mstate) EndPod(p pods.Pod) {*pcombineflag)
func (m *mstate) BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
dbgtrace(2, "visit counter data file %s dirIdx %d", cdf, dirIdx)
func (m *mstate) EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
func (m *mstate) VisitFuncCounterData(data decodecounter.FuncPayload) {
func (m *mstate) EndCounters() {
func (m *mstate) VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) {, mfr)
func (m *mstate) BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
dbgtrace(3, "VisitPackage(pk=%d path=%s)", pkgIdx, pd.PackagePath()), pkgIdx, *pcombineflag)
func (m *mstate) EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
func (m *mstate) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc) {, fnIdx, fd, mergeMode, *pcombineflag)
func (m *mstate) Finish() {
if *pcombineflag {
finalHash :=*outdirflag, true)*outdirflag, finalHash)