github.com/mistwind/reviewdog@v0.0.0-20230322024206-9cfa11856d58/service/bitbucket/server_api_client.go (about) 1 package bitbucket 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "net/http" 8 9 insights "github.com/reva2/bitbucket-insights-api" 10 ) 11 12 // ServerAPIClient is wrapper for Bitbucket Server Code Insights API client 13 type ServerAPIClient struct { 14 cli *insights.APIClient 15 helper *ServerAPIHelper 16 } 17 18 // NewServerAPIClient creates client for Bitbucket Server Code Insights API 19 func NewServerAPIClient() APIClient { 20 httpClient := &http.Client{ 21 Timeout: httpTimeout, 22 } 23 24 config := insights.NewConfiguration() 25 config.HTTPClient = httpClient 26 27 return &ServerAPIClient{ 28 cli: insights.NewAPIClient(config), 29 helper: &ServerAPIHelper{}, 30 } 31 } 32 33 // CreateOrUpdateReport creates or updates specified report 34 func (c *ServerAPIClient) CreateOrUpdateReport(ctx context.Context, req *ReportRequest) error { 35 // Bitbucket Server API doesn't support pending status 36 if req.Result == reportResultPending { 37 return nil 38 } 39 40 // We need to drop report and delete all annotations created previously 41 err := c.deleteReport(ctx, req) 42 if err != nil { 43 return err 44 } 45 46 _, resp, err := c.cli.InsightsApi. 47 UpdateReport(ctx, req.Owner, req.Repository, req.Commit, req.ReportID). 48 Report(c.helper.BuildReport(req)). 49 Execute() 50 51 if err := c.checkAPIError(err, resp, http.StatusOK); err != nil { 52 return fmt.Errorf("failed to create code insights report: %w", err) 53 } 54 55 return nil 56 } 57 58 // CreateOrUpdateAnnotations creates or updates annotations 59 func (c *ServerAPIClient) CreateOrUpdateAnnotations(ctx context.Context, req *AnnotationsRequest) error { 60 resp, err := c.cli.InsightsApi. 61 CreateAnnotations(ctx, req.Owner, req.Repository, req.Commit, req.ReportID). 62 AnnotationsList(c.helper.BuildAnnotations(req.Comments)). 63 Execute() 64 65 if err := c.checkAPIError(err, resp, http.StatusNoContent); err != nil { 66 return fmt.Errorf("failed to create annotations: %w", err) 67 } 68 69 return nil 70 } 71 72 func (c *ServerAPIClient) deleteReport(ctx context.Context, report *ReportRequest) error { 73 resp, err := c.cli.InsightsApi. 74 DeleteReport(ctx, report.Owner, report.Repository, report.Commit, report.ReportID). 75 Execute() 76 77 if err := c.checkAPIError(err, resp, http.StatusNoContent); err != nil { 78 return fmt.Errorf("failed to delete code insights report: %w", err) 79 } 80 81 return nil 82 } 83 84 func (c *ServerAPIClient) checkAPIError(err error, resp *http.Response, expectedCode int) error { 85 if err != nil { 86 return fmt.Errorf("bitbucket Server API error: %w", err) 87 } 88 89 if resp != nil && resp.StatusCode != expectedCode { 90 body, _ := io.ReadAll(resp.Body) 91 92 return UnexpectedResponseError{ 93 Code: resp.StatusCode, 94 Body: body, 95 } 96 } 97 98 return nil 99 }