1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-16 11:09:33 +02:00
sap-jenkins-library/pkg/sonar/componentService.go
Marc Bormeth b213af1089
Add Coverage Info to sonarscan.json (#3262)
* Add coverage metrics to report + influx

* Write unit tests

* Add integration test for Sonar Measures Component Service
2021-12-08 09:02:12 +01:00

106 lines
3.0 KiB
Go

package sonar
import (
"net/http"
"strconv"
"github.com/SAP/jenkins-library/pkg/log"
sonargo "github.com/magicsong/sonargo/sonar"
"github.com/pkg/errors"
)
// EndpointIssuesSearch API endpoint for https://sonarcloud.io/web_api/api/measures/component
const EndpointMeasuresComponent = "measures/component"
// ComponentService ...
type ComponentService struct {
Organization string
Project string
apiClient *Requester
}
type SonarCoverage struct {
Coverage float32 `json:"coverage,omitempty"`
LineCoverage float32 `json:"lineCoverage,omitempty"`
BranchCoverage float32 `json:"branchCoverage,omitempty"`
}
// GetCoverage ...
func (service *ComponentService) Component(options *sonargo.MeasuresComponentOption) (*sonargo.MeasuresComponentObject, *http.Response, error) {
request, err := service.apiClient.create("GET", EndpointMeasuresComponent, options)
if err != nil {
return nil, nil, err
}
// use custom HTTP client to send request
response, err := service.apiClient.send(request)
if err != nil {
return nil, nil, err
}
// reuse response verrification from sonargo
err = sonargo.CheckResponse(response)
if err != nil {
return nil, response, err
}
// decode JSON response
result := new(sonargo.MeasuresComponentObject)
err = service.apiClient.decode(response, result)
if err != nil {
return nil, response, err
}
return result, response, nil
}
func (service *ComponentService) GetCoverage() (*SonarCoverage, error) {
options := sonargo.MeasuresComponentOption{
Component: service.Project,
MetricKeys: "coverage,branch_coverage,line_coverage",
}
component, response, _ := service.Component(&options)
// reuse response verification from sonargo
err := sonargo.CheckResponse(response)
if err != nil {
return nil, errors.Wrap(err, "Failed to get coverage from Sonar measures/component API")
}
measures := component.Component.Measures
cov := &SonarCoverage{}
for _, element := range measures {
val, err := parseMeasureValuef32(*element)
if err != nil {
return nil, err
}
switch element.Metric {
case "coverage":
cov.Coverage = val
case "branch_coverage":
cov.BranchCoverage = val
case "line_coverage":
cov.LineCoverage = val
default:
log.Entry().Debugf("Received unhandled coverage metric from Sonar measures/component API. (Metric: %s, Value: %s)", element.Metric, element.Value)
}
}
return cov, nil
}
// NewMeasuresComponentService returns a new instance of a service for the measures/component endpoint.
func NewMeasuresComponentService(host, token, project, organization string, client Sender) *ComponentService {
return &ComponentService{
Organization: organization,
Project: project,
apiClient: NewAPIClient(host, token, client),
}
}
func parseMeasureValuef32(measure sonargo.SonarMeasure) (float32, error) {
str := measure.Value
f64, err := strconv.ParseFloat(str, 32)
if err != nil {
return 0.0, errors.Wrap(err, "Invalid value found in measure "+measure.Metric+": "+measure.Value)
}
return float32(f64), nil
}