diff --git a/README.md b/README.md index 255d852..89a246b 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Usage $ go test -coverprofile=coverage.txt -covermode count github.com/gorilla/mux $ gocover-cobertura < coverage.txt > coverage.xml - + Note that you should run this from the directory which holds your `go.mod` file. Some flags can be passed (each flag should only be used once): @@ -70,6 +70,12 @@ Some flags can be passed (each flag should only be used once): indicating that the file has been automatically generated. See `genCodeRe` regexp in [ignore.go](ignore.go). +- `-report-total-coverage-to-stderr` + + write the total coverage percentage to stderr. + This is usefull when working with CI pipelines (i.e. Gitlab) that search the + logs to retrieve the coverage number for reporting. + ~~Authors~~Merger ------- diff --git a/gocover-cobertura.go b/gocover-cobertura.go index 06fa9a3..e9be86a 100644 --- a/gocover-cobertura.go +++ b/gocover-cobertura.go @@ -28,9 +28,11 @@ func fatal(format string, a ...interface{}) { func main() { var ignore Ignore + var reportTotalCoverageToStdErr bool flag.BoolVar(&byFiles, "by-files", false, "code coverage by file, not class") flag.BoolVar(&ignore.GeneratedFiles, "ignore-gen-files", false, "ignore generated files") + flag.BoolVar(&reportTotalCoverageToStdErr, "report-total-coverage-to-stderr", false, "write the total coverage percentage to stderr") ignoreDirsRe := flag.String("ignore-dirs", "", "ignore dirs matching this regexp") ignoreFilesRe := flag.String("ignore-files", "", "ignore files matching this regexp") @@ -51,12 +53,17 @@ func main() { } } - if err := convert(os.Stdin, os.Stdout, &ignore); err != nil { + outErr := io.Discard + if reportTotalCoverageToStdErr { + outErr = os.Stderr + } + + if err := convert(os.Stdin, os.Stdout, outErr, &ignore); err != nil { fatal("code coverage conversion failed: %s", err) } } -func convert(in io.Reader, out io.Writer, ignore *Ignore) error { +func convert(in io.Reader, out, outErr io.Writer, ignore *Ignore) error { profiles, err := ParseProfiles(in, ignore) if err != nil { return err @@ -89,6 +96,8 @@ func convert(in io.Reader, out io.Writer, ignore *Ignore) error { } _, _ = fmt.Fprintln(out) + + fmt.Fprintf(outErr, "Total test coverage is %.2f%% of lines\n", coverage.LineRate*100) return nil } diff --git a/gocover-cobertura_test.go b/gocover-cobertura_test.go index 2a529a5..ebd7728 100644 --- a/gocover-cobertura_test.go +++ b/gocover-cobertura_test.go @@ -39,7 +39,7 @@ func TestConvertParseProfilesError(t *testing.T) { err = pipe2wr.Close() require.NoError(t, err) }() - err := convert(strings.NewReader("invalid data"), pipe2wr, &Ignore{}) + err := convert(strings.NewReader("invalid data"), pipe2wr, io.Discard, &Ignore{}) require.Error(t, err) require.Equal(t, "bad mode line: invalid data", err.Error()) } @@ -49,7 +49,7 @@ func TestConvertOutputError(t *testing.T) { err := pipe2wr.Close() require.NoError(t, err) defer func() { err := pipe2rd.Close(); require.NoError(t, err) }() - err = convert(strings.NewReader("mode: set"), pipe2wr, &Ignore{}) + err = convert(strings.NewReader("mode: set"), pipe2wr, io.Discard, &Ignore{}) require.Error(t, err) require.Equal(t, "io: read/write on closed pipe", err.Error()) } @@ -59,7 +59,7 @@ func TestConvertEmpty(t *testing.T) { pipe2rd, pipe2wr := io.Pipe() go func() { - err := convert(strings.NewReader(data), pipe2wr, &Ignore{}) + err := convert(strings.NewReader(data), pipe2wr, io.Discard, &Ignore{}) require.NoError(t, err) }() @@ -159,7 +159,7 @@ func TestConvertSetMode(t *testing.T) { } go func() { - err := convert(pipe1rd, convwr, &Ignore{ + err := convert(pipe1rd, convwr, io.Discard, &Ignore{ GeneratedFiles: true, Files: regexp.MustCompile(`[\\/]func[45]\.go$`), })