Skip to content

Commit

Permalink
integrate coverage into test-explorer
Browse files Browse the repository at this point in the history
  • Loading branch information
xhd2015 committed Nov 3, 2024
1 parent b55990d commit f43d180
Show file tree
Hide file tree
Showing 441 changed files with 278,860 additions and 261 deletions.
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ cover*.out

/tmp

debug-compile.json
debug-compile.json

# not required packed modules
/cmd/xgo/internal/vendir/github.com/xhd2015/go-coverage/diff/vscode/node_modules


/cmd/xgo/internal/src/vendor
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ go test -tags dev -run TestHelloWorld -v ./test

NOTE: when developing, always add `-tags dev` to tell go that we are building in dev mode.

In dev mode, instead of copying itself, xgo will link itself to the compiler source root, so that debugging the compiler is way much easier.

If you want to check instrumented GOROOT, run:
```sh
go run ./script/setup-dev
Expand Down Expand Up @@ -121,7 +123,7 @@ The general rule is to make these two tags remain the same with each other, and

Here is a guide on how to make a new release:
- update `VERSION` in [cmd/xgo/version.go](cmd/xgo/version.go).
- update `CORE_VERSION` to match `VERSION` if there is a change in this version that makes `cmd/xgo` depends on the newest runtime, otherwise, keep in untouched.
- update `CORE_VERSION` to match `VERSION` if there is a change in this version that makes `cmd/xgo` depends on the newest runtime, otherwise, keep it untouched.
- run `go generate ./...`.
- check whether `CORE_REVISION`,`CORE_NUMBER` matches `REVISION`,`NUMBER` if `CORE_VERSION` is updated to the same with `VERSION`, if not, run `go generate ./...` again and check, and manually update if necessary.
- run `git add -A`.
Expand Down
158 changes: 158 additions & 0 deletions cmd/xgo/coverage/cov_control/cov_control.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package cov_control

// this controller is not used in practice, we may use it to
// optimaze user experience in the future.
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"

"github.com/xhd2015/xgo/cmd/xgo/internal/vendir/github.com/xhd2015/gitops/git"
"github.com/xhd2015/xgo/cmd/xgo/internal/vendir/github.com/xhd2015/lines-annotation/load/loadcov"
"github.com/xhd2015/xgo/cmd/xgo/internal/vendir/github.com/xhd2015/lines-annotation/model/coverage"
"github.com/xhd2015/xgo/cmd/xgo/test-explorer/icov"
"github.com/xhd2015/xgo/support/fileutil"
)

func New(projectDir string, args []string, diffBase string, profile string) (icov.Controller, error) {
absDir, err := filepath.Abs(projectDir)
if err != nil {
return nil, err
}
covDir := mapCovDir(getTmpDir(), absDir)
if profile == "" {
profile = filepath.Join(covDir, "coverage.out")
}
err = os.MkdirAll(covDir, 0755)
if err != nil {
return nil, err
}
return &controller{
covDir: covDir,
args: args,
diffBase: diffBase,
projectDir: projectDir,
absProjectDir: absDir,
coverageProfile: profile,
}, nil
}

type controller struct {
covDir string
args []string
diffBase string
projectDir string
absProjectDir string
coverageProfile string
}

var _ icov.Controller = (*controller)(nil)

func (c *controller) GetCoverage() (*coverage.Detail, error) {
resFile := c.cacheResultPath()
data, err := os.ReadFile(resFile)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}
var detail coverage.Detail
jsonErr := json.Unmarshal(data, &detail)
if jsonErr != nil {
return nil, nil
}
return &detail, nil
}

func (c *controller) GetCoverageProfilePath() (string, error) {
return c.coverageProfile, nil
}

func (c *controller) Refresh() error {
ok, err := fileExists(c.coverageProfile)
if err != nil {
return err
}
var detail *coverage.Detail
if !ok {
detail = &coverage.Detail{}
} else {
project, err := loadcov.LoadAll(loadcov.LoadAllOptions{
Dir: c.projectDir,
Args: c.args,
Profiles: []string{c.coverageProfile},
Ref: git.COMMIT_WORKING,
DiffBase: c.diffBase,
})
if err != nil {
return err
}
summary := loadcov.ComputeCoverageSummary(project)
base := summary[""]
if base != nil {
detail = &coverage.Detail{
Total: base.Total,
Incrimental: base.Incrimental,

Check warning on line 99 in cmd/xgo/coverage/cov_control/cov_control.go

View workflow job for this annotation

GitHub Actions / check-build

"Incrimental" should be "Incremental".

Check warning on line 99 in cmd/xgo/coverage/cov_control/cov_control.go

View workflow job for this annotation

GitHub Actions / check-build

"Incrimental" should be "Incremental".

Check warning on line 99 in cmd/xgo/coverage/cov_control/cov_control.go

View workflow job for this annotation

GitHub Actions / check-build

"Incrimental" should be "Incremental".

Check warning on line 99 in cmd/xgo/coverage/cov_control/cov_control.go

View workflow job for this annotation

GitHub Actions / check-build

"Incrimental" should be "Incremental".
}
}
}
data, err := json.Marshal(detail)
if err != nil {
return err
}
return os.WriteFile(c.cacheResultPath(), data, 0755)
}

func (c *controller) Clear() error {
ok, err := fileExists(c.coverageProfile)
if err != nil {
return err
}
if !ok {
return nil
}
return os.RemoveAll(c.coverageProfile)
}

func fileExists(f string) (bool, error) {
stat, err := os.Stat(f)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
if stat.IsDir() {
return false, fmt.Errorf("want file, but %s is a directory", f)
}
return true, nil
}

func (c *controller) cacheResultPath() string {
return filepath.Join(c.covDir, "result.json")
}

func mapCovDir(tmpDir string, absDir string) string {
list := strings.Split(absDir, string(filepath.Separator))
for i, e := range list {
list[i] = fileutil.CleanSpecial(e)
}
return filepath.Join(tmpDir, "xgo", "coverage", filepath.Join(list...))
}

func getTmpDir() string {
if runtime.GOOS != "windows" {
// try /tmp first for shorter path
tmpDir := "/tmp"
stat, statErr := os.Stat(tmpDir)
if statErr == nil && stat.IsDir() {
return tmpDir
}
}

return os.TempDir()
}
17 changes: 16 additions & 1 deletion cmd/xgo/coverage/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,31 @@ Usage:
xgo tool coverage <cmd> [arguments]
The commands are:
serve serve profiles
load load profiles
merge merge coverage profiles
compact compact profile
help show help message
Global options:
--project-dir DIR the project dir
Options for merge:
-o <file> output to file instead of stdout
--exclude-prefix <pkg> exclude coverage of a specific package and sub packages
Options for serve & load:
--diff-with REF the base branch to diff with when displaying coverage
--build-arg ARG build args
--port PORT listening port
--exclude FILE exclude FILE
--include FILE include FILE
Examples:
xgo tool coverage merge -o cover.a cover-a.out cover-b.out merge multiple files into one
# merge multiple files into one
$ xgo tool coverage merge -o cover.a cover-a.out cover-b.out
# load all
$ xgo tool coverage load
See https://github.com/xhd2015/xgo for documentation.
Expand Down
6 changes: 3 additions & 3 deletions cmd/xgo/coverage/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ func Main(args []string) {
fmt.Print(strings.TrimPrefix(help, "\n"))
return
}
if cmd != "merge" && cmd != "compact" && cmd != "serve" {
if cmd != "merge" && cmd != "compact" && cmd != "serve" && cmd != "load" {
fmt.Fprintf(os.Stderr, "unrecognized cmd: %s\n", cmd)
return
}
if cmd == "serve" {
err := handleServe(args)
if cmd == "serve" || cmd == "load" {
err := handleServe(cmd, args)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
Expand Down
Loading

0 comments on commit f43d180

Please sign in to comment.