add calculate and merge coverage files #7

Merged
vtolstov merged 1 commits from devstigneev/pkgdash:resolve_coverage_analyze into master 2024-02-26 00:02:10 +03:00
5 changed files with 205 additions and 1 deletions
Showing only changes of commit 6da686b9e0 - Show all commits

5
go.mod
View File

@ -10,6 +10,7 @@ require (
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c
github.com/jmoiron/sqlx v1.3.1
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.8.3
go.unistack.org/micro-client-http/v4 v4.0.2
go.unistack.org/micro-codec-json/v4 v4.0.0
go.unistack.org/micro-codec-jsonpb/v4 v4.0.0
@ -25,6 +26,7 @@ require (
go.unistack.org/protoc-gen-go-micro/v4 v4.0.7
golang.org/x/mod v0.12.0
golang.org/x/sync v0.3.0
golang.org/x/tools v0.11.0
google.golang.org/protobuf v1.31.0
modernc.org/sqlite v1.21.0
)
@ -37,6 +39,7 @@ require (
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/structtag v1.2.0 // indirect
@ -76,6 +79,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rs/zerolog v1.30.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
@ -92,7 +96,6 @@ require (
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.11.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

1
go.sum
View File

@ -987,6 +987,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=

View File

@ -0,0 +1,94 @@
package coverage
import (
"context"
"fmt"
"git.unistack.org/unistack-org/pkgdash/internal/models"
"golang.org/x/tools/cover"
"io"
"strings"
)
func Analyze(ctx context.Context, dataCoverage io.Reader, pack models.Package) (float64, error) {
calculcate, err := calculateFiles(dataCoverage)
if err != nil {
return 0, err
}
mapCover := make(map[string]float64)
{
tree, err := GetTreeFromGit(ctx, pack.URL)
if err != nil {
return 0, err
}
list, err := tree.GoFileList("")
if err != nil {
return 0, err
}
for _, f := range list {
mapCover[f] = 0.0
}
}
cur := len(mapCover)
for _, d := range calculcate.Files {
file := strings.TrimPrefix(d.Name, pack.Name+"/")
mapCover[file] = d.Coverage
}
// check)
if len(mapCover) != cur {
fmt.Printf("add new keys, was: %d, has: %d", cur, len(mapCover))
}
//TODO add calculate full
return 0, nil
}
type Data struct {
Files []*calculateFile
Set bool
}
type calculateFile struct {
Name string
Coverage float64
}
func calculateFiles(coverSrc io.Reader) (d *Data, err error) {
profiles, err := cover.ParseProfilesFromReader(coverSrc)
if err != nil {
return nil, err
}
d = new(Data)
for _, profile := range profiles {
fn := profile.FileName
if profile.Mode == "set" {
d.Set = true
}
d.Files = append(d.Files, &calculateFile{
Name: fn,
Coverage: percentCovered(profile),
})
}
return d, err
}
func percentCovered(p *cover.Profile) float64 {
var total, covered int64
for _, b := range p.Blocks {
total += int64(b.NumStmt)
if b.Count > 0 {
covered += int64(b.NumStmt)
}
}
if total == 0 {
return 0
}
return float64(covered) / float64(total) * 100
}

View File

@ -0,0 +1,36 @@
package coverage
import (
"context"
"git.unistack.org/unistack-org/pkgdash/internal/models"
"github.com/stretchr/testify/assert"
"os"
"testing"
)
func Test_Calculate(t *testing.T) {
file, err := os.Open("cover_test.out")
assert.Nil(t, err)
defer func() {
assert.Nil(t, file.Close())
}()
dataFiles, err := calculateFiles(file)
assert.Nil(t, err)
assert.NotNil(t, dataFiles)
}
func Test_Analyze(t *testing.T) {
file, err := os.Open("cover_test.out")
assert.Nil(t, err)
defer func() {
assert.Nil(t, file.Close())
}()
analyze, err := Analyze(context.Background(), file, models.Package{
Name: "go.unistack.org/micro/v4",
URL: "https://git.unistack.org/unistack-org/micro.git",
})
assert.Nil(t, err)
assert.Equal(t, analyze, 0.0)
}

View File

@ -0,0 +1,70 @@
package coverage
import (
"context"
"errors"
"fmt"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/filemode"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/storage/memory"
"os"
"regexp"
"strings"
)
var (
fileNil = errors.New("file pointer is nil")
)
func GetTreeFromGit(ctx context.Context, url string) (*Tree, error) {
cloneOpts := &git.CloneOptions{
URL: url,
Progress: os.Stdout,
}
repo, err := git.CloneContext(ctx, memory.NewStorage(), nil, cloneOpts)
if err != nil {
return nil, err
}
ref, err := repo.Head()
if err != nil {
return nil, fmt.Errorf("failed to get head: %v", err)
}
commit, err := repo.CommitObject(ref.Hash())
if err != nil {
return nil, fmt.Errorf("failed to get commit: %v", err)
}
tree, err := commit.Tree()
return &Tree{tree}, err
}
type Tree struct {
*object.Tree
}
func (t Tree) GoFileList(pattern string) ([]string, error) {
matcher, err := regexp.Compile(pattern)
if err != nil {
return nil, err
}
var list []string
err = t.Files().ForEach(func(file *object.File) error {
if file == nil {
return fileNil
}
if file.Mode == filemode.Regular && strings.HasSuffix(file.Name, ".go") && !strings.HasSuffix(file.Name, "_test.go") && matcher.MatchString(file.Name) {
list = append(list, file.Name)
}
return nil
})
if err != nil {
return nil, err
}
return list, err
}