#19 #20
6
go.mod
6
go.mod
@ -11,6 +11,7 @@ require (
|
||||
github.com/jmoiron/sqlx v1.3.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/spf13/cobra v1.8.0
|
||||
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
|
||||
@ -46,6 +47,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
|
||||
@ -65,7 +67,7 @@ require (
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/vault/api v1.9.2 // indirect
|
||||
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||
github.com/iancoleman/strcase v0.2.0 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530 // indirect
|
||||
@ -86,6 +88,7 @@ require (
|
||||
github.com/ncruces/go-strftime v0.1.9 // 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
|
||||
@ -102,7 +105,6 @@ require (
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.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.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.3.0 // indirect
|
||||
|
1
go.sum
1
go.sum
@ -1005,6 +1005,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=
|
||||
|
94
internal/analyzer/coverage/coverage.go
Normal file
94
internal/analyzer/coverage/coverage.go
Normal 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
|
||||
}
|
36
internal/analyzer/coverage/coverage_test.go
Normal file
36
internal/analyzer/coverage/coverage_test.go
Normal 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)
|
||||
}
|
70
internal/analyzer/coverage/git.go
Normal file
70
internal/analyzer/coverage/git.go
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user