aboutsummaryrefslogtreecommitdiffstats
path: root/build
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2020-04-04 16:45:26 +0800
committerGitHub <noreply@github.com>2020-04-04 11:45:26 +0300
commitb264c303945716d95dca41a11fe89ab567bddef3 (patch)
tree3f6cfc712d433c31f074e40968c8e0e06c06544a /build
parent14c97c05019d416d634ad486c03674a2b9af92ef (diff)
downloadgitea-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.go119
-rw-r--r--build/vendor.go3
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"
)