github.com/OnkarRuikar/reviewdog@v0.0.0-20230802094019-bc1001e3b2e5/service/gerrit/change_review.go (about) 1 package gerrit 2 3 import ( 4 "context" 5 "fmt" 6 "path/filepath" 7 "sync" 8 9 "golang.org/x/build/gerrit" 10 11 "github.com/reviewdog/reviewdog" 12 "github.com/reviewdog/reviewdog/service/serviceutil" 13 ) 14 15 var _ reviewdog.CommentService = &ChangeReviewCommenter{} 16 17 // ChangeReviewCommenter is a comment service for Gerrit Change Review 18 // API: 19 // https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#set-review 20 // POST /changes/{change-id}/revisions/{revision-id}/review 21 type ChangeReviewCommenter struct { 22 cli *gerrit.Client 23 changeID string 24 revisionID string 25 26 muComments sync.Mutex 27 postComments []*reviewdog.Comment 28 29 // wd is working directory relative to root of repository. 30 wd string 31 } 32 33 // NewChangeReviewCommenter returns a new NewChangeReviewCommenter service. 34 // ChangeReviewCommenter service needs git command in $PATH. 35 func NewChangeReviewCommenter(cli *gerrit.Client, changeID, revisionID string) (*ChangeReviewCommenter, error) { 36 workDir, err := serviceutil.GitRelWorkdir() 37 if err != nil { 38 return nil, fmt.Errorf("ChangeReviewCommenter needs 'git' command: %w", err) 39 } 40 41 return &ChangeReviewCommenter{ 42 cli: cli, 43 changeID: changeID, 44 revisionID: revisionID, 45 postComments: []*reviewdog.Comment{}, 46 wd: workDir, 47 }, nil 48 } 49 50 // Post accepts a comment and holds it. Flush method actually posts comments to Gerrit 51 func (g *ChangeReviewCommenter) Post(_ context.Context, c *reviewdog.Comment) error { 52 c.Result.Diagnostic.GetLocation().Path = filepath.Join(g.wd, c.Result.Diagnostic.GetLocation().GetPath()) 53 g.muComments.Lock() 54 defer g.muComments.Unlock() 55 g.postComments = append(g.postComments, c) 56 return nil 57 } 58 59 // Flush posts comments which has not been posted yet. 60 func (g *ChangeReviewCommenter) Flush(ctx context.Context) error { 61 g.muComments.Lock() 62 defer g.muComments.Unlock() 63 64 return g.postAllComments(ctx) 65 } 66 67 func (g *ChangeReviewCommenter) postAllComments(ctx context.Context) error { 68 review := gerrit.ReviewInput{ 69 Comments: map[string][]gerrit.CommentInput{}, 70 } 71 for _, c := range g.postComments { 72 if !c.Result.InDiffFile { 73 continue 74 } 75 loc := c.Result.Diagnostic.GetLocation() 76 path := loc.GetPath() 77 review.Comments[path] = append(review.Comments[path], gerrit.CommentInput{ 78 Line: int(loc.GetRange().GetStart().GetLine()), 79 Message: c.Result.Diagnostic.GetMessage(), 80 }) 81 } 82 83 return g.cli.SetReview(ctx, g.changeID, g.revisionID, review) 84 }