55package models
66
77import (
8- "fmt "
8+ "strings "
99
10- "code.gitea.io/gitea/modules/log"
1110 "code.gitea.io/gitea/modules/timeutil"
1211
1312 "xorm.io/builder"
1413 "xorm.io/core"
15- "xorm.io/xorm"
1614)
1715
1816// ReviewType defines the sort of feedback a review gives
@@ -86,6 +84,11 @@ func (r *Review) loadReviewer(e Engine) (err error) {
8684 return
8785}
8886
87+ // LoadReviewer loads reviewer
88+ func (r * Review ) LoadReviewer () error {
89+ return r .loadReviewer (x )
90+ }
91+
8992func (r * Review ) loadAttributes (e Engine ) (err error ) {
9093 if err = r .loadReviewer (e ); err != nil {
9194 return
@@ -101,54 +104,6 @@ func (r *Review) LoadAttributes() error {
101104 return r .loadAttributes (x )
102105}
103106
104- // Publish will send notifications / actions to participants for all code comments; parts are concurrent
105- func (r * Review ) Publish () error {
106- return r .publish (x )
107- }
108-
109- func (r * Review ) publish (e * xorm.Engine ) error {
110- if r .Type == ReviewTypePending || r .Type == ReviewTypeUnknown {
111- return fmt .Errorf ("review cannot be published if type is pending or unknown" )
112- }
113- if r .Issue == nil {
114- if err := r .loadIssue (e ); err != nil {
115- return err
116- }
117- }
118- if err := r .Issue .loadRepo (e ); err != nil {
119- return err
120- }
121- if len (r .CodeComments ) == 0 {
122- if err := r .loadCodeComments (e ); err != nil {
123- return err
124- }
125- }
126- for _ , lines := range r .CodeComments {
127- for _ , comments := range lines {
128- for _ , comment := range comments {
129- go func (en * xorm.Engine , review * Review , comm * Comment ) {
130- sess := en .NewSession ()
131- defer sess .Close ()
132- opts := & CreateCommentOptions {
133- Doer : comm .Poster ,
134- Issue : review .Issue ,
135- Repo : review .Issue .Repo ,
136- Type : comm .Type ,
137- Content : comm .Content ,
138- }
139- if err := updateCommentInfos (sess , opts , comm ); err != nil {
140- log .Warn ("updateCommentInfos: %v" , err )
141- }
142- if err := sendCreateCommentAction (sess , opts , comm ); err != nil {
143- log .Warn ("sendCreateCommentAction: %v" , err )
144- }
145- }(e , r , comment )
146- }
147- }
148- }
149- return nil
150- }
151-
152107func getReviewByID (e Engine , id int64 ) (* Review , error ) {
153108 review := new (Review )
154109 if has , err := e .ID (id ).Get (review ); err != nil {
@@ -271,12 +226,79 @@ func GetCurrentReview(reviewer *User, issue *Issue) (*Review, error) {
271226 return getCurrentReview (x , reviewer , issue )
272227}
273228
274- // UpdateReview will update all cols of the given review in db
275- func UpdateReview (r * Review ) error {
276- if _ , err := x .ID (r .ID ).AllCols ().Update (r ); err != nil {
277- return err
229+ // ContentEmptyErr represents an content empty error
230+ type ContentEmptyErr struct {
231+ }
232+
233+ func (ContentEmptyErr ) Error () string {
234+ return "Review content is empty"
235+ }
236+
237+ // IsContentEmptyErr returns true if err is a ContentEmptyErr
238+ func IsContentEmptyErr (err error ) bool {
239+ _ , ok := err .(ContentEmptyErr )
240+ return ok
241+ }
242+
243+ // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist
244+ func SubmitReview (doer * User , issue * Issue , reviewType ReviewType , content string ) (* Review , * Comment , error ) {
245+ sess := x .NewSession ()
246+ defer sess .Close ()
247+ if err := sess .Begin (); err != nil {
248+ return nil , nil , err
249+ }
250+
251+ review , err := getCurrentReview (sess , doer , issue )
252+ if err != nil {
253+ if ! IsErrReviewNotExist (err ) {
254+ return nil , nil , err
255+ }
256+
257+ if len (strings .TrimSpace (content )) == 0 {
258+ return nil , nil , ContentEmptyErr {}
259+ }
260+
261+ // No current review. Create a new one!
262+ review , err = createReview (sess , CreateReviewOptions {
263+ Type : reviewType ,
264+ Issue : issue ,
265+ Reviewer : doer ,
266+ Content : content ,
267+ })
268+ if err != nil {
269+ return nil , nil , err
270+ }
271+ } else {
272+ if err := review .loadCodeComments (sess ); err != nil {
273+ return nil , nil , err
274+ }
275+ if len (review .CodeComments ) == 0 && len (strings .TrimSpace (content )) == 0 {
276+ return nil , nil , ContentEmptyErr {}
277+ }
278+
279+ review .Issue = issue
280+ review .Content = content
281+ review .Type = reviewType
282+ if _ , err := sess .ID (review .ID ).Cols ("content, type" ).Update (review ); err != nil {
283+ return nil , nil , err
284+ }
278285 }
279- return nil
286+
287+ comm , err := createComment (sess , & CreateCommentOptions {
288+ Type : CommentTypeReview ,
289+ Doer : doer ,
290+ Content : review .Content ,
291+ Issue : issue ,
292+ Repo : issue .Repo ,
293+ ReviewID : review .ID ,
294+ NoAction : true ,
295+ })
296+ if err != nil || comm == nil {
297+ return nil , nil , err
298+ }
299+
300+ comm .Review = review
301+ return review , comm , sess .Commit ()
280302}
281303
282304// PullReviewersWithType represents the type used to display a review overview
0 commit comments