diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2020-04-04 16:45:26 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-04 11:45:26 +0300 |
commit | b264c303945716d95dca41a11fe89ab567bddef3 (patch) | |
tree | 3f6cfc712d433c31f074e40968c8e0e06c06544a /build | |
parent | 14c97c05019d416d634ad486c03674a2b9af92ef (diff) | |
download | gitea-b264c303945716d95dca41a11fe89ab567bddef3.tar.gz gitea-b264c303945716d95dca41a11fe89ab567bddef3.zip |
Move gocovmerge as vendor (#10947)
* Move gocovmerge as vendor
* Update Makefile
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Diffstat (limited to 'build')
-rw-r--r-- | build/gocovmerge.go | 119 | ||||
-rw-r--r-- | build/vendor.go | 3 |
2 files changed, 122 insertions, 0 deletions
diff --git a/build/gocovmerge.go b/build/gocovmerge.go new file mode 100644 index 0000000000..65d6f2cd6c --- /dev/null +++ b/build/gocovmerge.go @@ -0,0 +1,119 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Copyright (c) 2015, Wade Simmons +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +// gocovmerge takes the results from multiple `go test -coverprofile` runs and +// merges them into one profile + +// +build ignore + +package main + +import ( + "flag" + "fmt" + "io" + "log" + "os" + "sort" + + "golang.org/x/tools/cover" +) + +func mergeProfiles(p *cover.Profile, merge *cover.Profile) { + if p.Mode != merge.Mode { + log.Fatalf("cannot merge profiles with different modes") + } + // Since the blocks are sorted, we can keep track of where the last block + // was inserted and only look at the blocks after that as targets for merge + startIndex := 0 + for _, b := range merge.Blocks { + startIndex = mergeProfileBlock(p, b, startIndex) + } +} + +func mergeProfileBlock(p *cover.Profile, pb cover.ProfileBlock, startIndex int) int { + sortFunc := func(i int) bool { + pi := p.Blocks[i+startIndex] + return pi.StartLine >= pb.StartLine && (pi.StartLine != pb.StartLine || pi.StartCol >= pb.StartCol) + } + + i := 0 + if sortFunc(i) != true { + i = sort.Search(len(p.Blocks)-startIndex, sortFunc) + } + i += startIndex + if i < len(p.Blocks) && p.Blocks[i].StartLine == pb.StartLine && p.Blocks[i].StartCol == pb.StartCol { + if p.Blocks[i].EndLine != pb.EndLine || p.Blocks[i].EndCol != pb.EndCol { + log.Fatalf("OVERLAP MERGE: %v %v %v", p.FileName, p.Blocks[i], pb) + } + switch p.Mode { + case "set": + p.Blocks[i].Count |= pb.Count + case "count", "atomic": + p.Blocks[i].Count += pb.Count + default: + log.Fatalf("unsupported covermode: '%s'", p.Mode) + } + } else { + if i > 0 { + pa := p.Blocks[i-1] + if pa.EndLine >= pb.EndLine && (pa.EndLine != pb.EndLine || pa.EndCol > pb.EndCol) { + log.Fatalf("OVERLAP BEFORE: %v %v %v", p.FileName, pa, pb) + } + } + if i < len(p.Blocks)-1 { + pa := p.Blocks[i+1] + if pa.StartLine <= pb.StartLine && (pa.StartLine != pb.StartLine || pa.StartCol < pb.StartCol) { + log.Fatalf("OVERLAP AFTER: %v %v %v", p.FileName, pa, pb) + } + } + p.Blocks = append(p.Blocks, cover.ProfileBlock{}) + copy(p.Blocks[i+1:], p.Blocks[i:]) + p.Blocks[i] = pb + } + return i + 1 +} + +func addProfile(profiles []*cover.Profile, p *cover.Profile) []*cover.Profile { + i := sort.Search(len(profiles), func(i int) bool { return profiles[i].FileName >= p.FileName }) + if i < len(profiles) && profiles[i].FileName == p.FileName { + mergeProfiles(profiles[i], p) + } else { + profiles = append(profiles, nil) + copy(profiles[i+1:], profiles[i:]) + profiles[i] = p + } + return profiles +} + +func dumpProfiles(profiles []*cover.Profile, out io.Writer) { + if len(profiles) == 0 { + return + } + fmt.Fprintf(out, "mode: %s\n", profiles[0].Mode) + for _, p := range profiles { + for _, b := range p.Blocks { + fmt.Fprintf(out, "%s:%d.%d,%d.%d %d %d\n", p.FileName, b.StartLine, b.StartCol, b.EndLine, b.EndCol, b.NumStmt, b.Count) + } + } +} + +func main() { + flag.Parse() + + var merged []*cover.Profile + + for _, file := range flag.Args() { + profiles, err := cover.ParseProfiles(file) + if err != nil { + log.Fatalf("failed to parse profiles: %v", err) + } + for _, p := range profiles { + merged = addProfile(merged, p) + } + } + + dumpProfiles(merged, os.Stdout) +} diff --git a/build/vendor.go b/build/vendor.go index 8610af2681..d51fbf21fb 100644 --- a/build/vendor.go +++ b/build/vendor.go @@ -15,4 +15,7 @@ import ( // for embed _ "github.com/shurcooL/vfsgen" + + // for cover merge + _ "golang.org/x/tools/cover" ) |