@@ -9,9 +9,7 @@ package issues
9
9
import (
10
10
"context"
11
11
"fmt"
12
- "regexp"
13
12
"strconv"
14
- "strings"
15
13
"unicode/utf8"
16
14
17
15
"code.gitea.io/gitea/models/db"
@@ -23,8 +21,6 @@ import (
23
21
"code.gitea.io/gitea/modules/git"
24
22
"code.gitea.io/gitea/modules/json"
25
23
"code.gitea.io/gitea/modules/log"
26
- "code.gitea.io/gitea/modules/markup"
27
- "code.gitea.io/gitea/modules/markup/markdown"
28
24
"code.gitea.io/gitea/modules/references"
29
25
"code.gitea.io/gitea/modules/structs"
30
26
"code.gitea.io/gitea/modules/timeutil"
@@ -697,31 +693,6 @@ func (c *Comment) LoadReview() error {
697
693
return c .loadReview (db .DefaultContext )
698
694
}
699
695
700
- var notEnoughLines = regexp .MustCompile (`fatal: file .* has only \d+ lines?` )
701
-
702
- func (c * Comment ) checkInvalidation (doer * user_model.User , repo * git.Repository , branch string ) error {
703
- // FIXME differentiate between previous and proposed line
704
- commit , err := repo .LineBlame (branch , repo .Path , c .TreePath , uint (c .UnsignedLine ()))
705
- if err != nil && (strings .Contains (err .Error (), "fatal: no such path" ) || notEnoughLines .MatchString (err .Error ())) {
706
- c .Invalidated = true
707
- return UpdateComment (c , doer )
708
- }
709
- if err != nil {
710
- return err
711
- }
712
- if c .CommitSHA != "" && c .CommitSHA != commit .ID .String () {
713
- c .Invalidated = true
714
- return UpdateComment (c , doer )
715
- }
716
- return nil
717
- }
718
-
719
- // CheckInvalidation checks if the line of code comment got changed by another commit.
720
- // If the line got changed the comment is going to be invalidated.
721
- func (c * Comment ) CheckInvalidation (repo * git.Repository , doer * user_model.User , branch string ) error {
722
- return c .checkInvalidation (doer , repo , branch )
723
- }
724
-
725
696
// DiffSide returns "previous" if Comment.Line is a LOC of the previous changes and "proposed" if it is a LOC of the proposed changes.
726
697
func (c * Comment ) DiffSide () string {
727
698
if c .Line < 0 {
@@ -1065,23 +1036,28 @@ func GetCommentByID(ctx context.Context, id int64) (*Comment, error) {
1065
1036
// FindCommentsOptions describes the conditions to Find comments
1066
1037
type FindCommentsOptions struct {
1067
1038
db.ListOptions
1068
- RepoID int64
1069
- IssueID int64
1070
- ReviewID int64
1071
- Since int64
1072
- Before int64
1073
- Line int64
1074
- TreePath string
1075
- Type CommentType
1076
- }
1077
-
1078
- func (opts * FindCommentsOptions ) toConds () builder.Cond {
1039
+ RepoID int64
1040
+ IssueID int64
1041
+ ReviewID int64
1042
+ Since int64
1043
+ Before int64
1044
+ Line int64
1045
+ TreePath string
1046
+ Type CommentType
1047
+ IssueIDs []int64
1048
+ Invalidated util.OptionalBool
1049
+ }
1050
+
1051
+ // ToConds implements FindOptions interface
1052
+ func (opts * FindCommentsOptions ) ToConds () builder.Cond {
1079
1053
cond := builder .NewCond ()
1080
1054
if opts .RepoID > 0 {
1081
1055
cond = cond .And (builder.Eq {"issue.repo_id" : opts .RepoID })
1082
1056
}
1083
1057
if opts .IssueID > 0 {
1084
1058
cond = cond .And (builder.Eq {"comment.issue_id" : opts .IssueID })
1059
+ } else if len (opts .IssueIDs ) > 0 {
1060
+ cond = cond .And (builder .In ("comment.issue_id" , opts .IssueIDs ))
1085
1061
}
1086
1062
if opts .ReviewID > 0 {
1087
1063
cond = cond .And (builder.Eq {"comment.review_id" : opts .ReviewID })
@@ -1101,13 +1077,16 @@ func (opts *FindCommentsOptions) toConds() builder.Cond {
1101
1077
if len (opts .TreePath ) > 0 {
1102
1078
cond = cond .And (builder.Eq {"comment.tree_path" : opts .TreePath })
1103
1079
}
1080
+ if ! opts .Invalidated .IsNone () {
1081
+ cond = cond .And (builder.Eq {"comment.invalidated" : opts .Invalidated .IsTrue ()})
1082
+ }
1104
1083
return cond
1105
1084
}
1106
1085
1107
1086
// FindComments returns all comments according options
1108
1087
func FindComments (ctx context.Context , opts * FindCommentsOptions ) ([]* Comment , error ) {
1109
1088
comments := make ([]* Comment , 0 , 10 )
1110
- sess := db .GetEngine (ctx ).Where (opts .toConds ())
1089
+ sess := db .GetEngine (ctx ).Where (opts .ToConds ())
1111
1090
if opts .RepoID > 0 {
1112
1091
sess .Join ("INNER" , "issue" , "issue.id = comment.issue_id" )
1113
1092
}
@@ -1126,13 +1105,19 @@ func FindComments(ctx context.Context, opts *FindCommentsOptions) ([]*Comment, e
1126
1105
1127
1106
// CountComments count all comments according options by ignoring pagination
1128
1107
func CountComments (opts * FindCommentsOptions ) (int64 , error ) {
1129
- sess := db .GetEngine (db .DefaultContext ).Where (opts .toConds ())
1108
+ sess := db .GetEngine (db .DefaultContext ).Where (opts .ToConds ())
1130
1109
if opts .RepoID > 0 {
1131
1110
sess .Join ("INNER" , "issue" , "issue.id = comment.issue_id" )
1132
1111
}
1133
1112
return sess .Count (& Comment {})
1134
1113
}
1135
1114
1115
+ // UpdateCommentInvalidate updates comment invalidated column
1116
+ func UpdateCommentInvalidate (ctx context.Context , c * Comment ) error {
1117
+ _ , err := db .GetEngine (ctx ).ID (c .ID ).Cols ("invalidated" ).Update (c )
1118
+ return err
1119
+ }
1120
+
1136
1121
// UpdateComment updates information of comment.
1137
1122
func UpdateComment (c * Comment , doer * user_model.User ) error {
1138
1123
ctx , committer , err := db .TxContext ()
@@ -1191,120 +1176,6 @@ func DeleteComment(ctx context.Context, comment *Comment) error {
1191
1176
return DeleteReaction (ctx , & ReactionOptions {CommentID : comment .ID })
1192
1177
}
1193
1178
1194
- // CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS
1195
- type CodeComments map [string ]map [int64 ][]* Comment
1196
-
1197
- // FetchCodeComments will return a 2d-map: ["Path"]["Line"] = Comments at line
1198
- func FetchCodeComments (ctx context.Context , issue * Issue , currentUser * user_model.User ) (CodeComments , error ) {
1199
- return fetchCodeCommentsByReview (ctx , issue , currentUser , nil )
1200
- }
1201
-
1202
- func fetchCodeCommentsByReview (ctx context.Context , issue * Issue , currentUser * user_model.User , review * Review ) (CodeComments , error ) {
1203
- pathToLineToComment := make (CodeComments )
1204
- if review == nil {
1205
- review = & Review {ID : 0 }
1206
- }
1207
- opts := FindCommentsOptions {
1208
- Type : CommentTypeCode ,
1209
- IssueID : issue .ID ,
1210
- ReviewID : review .ID ,
1211
- }
1212
-
1213
- comments , err := findCodeComments (ctx , opts , issue , currentUser , review )
1214
- if err != nil {
1215
- return nil , err
1216
- }
1217
-
1218
- for _ , comment := range comments {
1219
- if pathToLineToComment [comment .TreePath ] == nil {
1220
- pathToLineToComment [comment .TreePath ] = make (map [int64 ][]* Comment )
1221
- }
1222
- pathToLineToComment [comment.TreePath ][comment.Line ] = append (pathToLineToComment [comment.TreePath ][comment.Line ], comment )
1223
- }
1224
- return pathToLineToComment , nil
1225
- }
1226
-
1227
- func findCodeComments (ctx context.Context , opts FindCommentsOptions , issue * Issue , currentUser * user_model.User , review * Review ) ([]* Comment , error ) {
1228
- var comments []* Comment
1229
- if review == nil {
1230
- review = & Review {ID : 0 }
1231
- }
1232
- conds := opts .toConds ()
1233
- if review .ID == 0 {
1234
- conds = conds .And (builder.Eq {"invalidated" : false })
1235
- }
1236
- e := db .GetEngine (ctx )
1237
- if err := e .Where (conds ).
1238
- Asc ("comment.created_unix" ).
1239
- Asc ("comment.id" ).
1240
- Find (& comments ); err != nil {
1241
- return nil , err
1242
- }
1243
-
1244
- if err := issue .LoadRepo (ctx ); err != nil {
1245
- return nil , err
1246
- }
1247
-
1248
- if err := CommentList (comments ).loadPosters (ctx ); err != nil {
1249
- return nil , err
1250
- }
1251
-
1252
- // Find all reviews by ReviewID
1253
- reviews := make (map [int64 ]* Review )
1254
- ids := make ([]int64 , 0 , len (comments ))
1255
- for _ , comment := range comments {
1256
- if comment .ReviewID != 0 {
1257
- ids = append (ids , comment .ReviewID )
1258
- }
1259
- }
1260
- if err := e .In ("id" , ids ).Find (& reviews ); err != nil {
1261
- return nil , err
1262
- }
1263
-
1264
- n := 0
1265
- for _ , comment := range comments {
1266
- if re , ok := reviews [comment .ReviewID ]; ok && re != nil {
1267
- // If the review is pending only the author can see the comments (except if the review is set)
1268
- if review .ID == 0 && re .Type == ReviewTypePending &&
1269
- (currentUser == nil || currentUser .ID != re .ReviewerID ) {
1270
- continue
1271
- }
1272
- comment .Review = re
1273
- }
1274
- comments [n ] = comment
1275
- n ++
1276
-
1277
- if err := comment .LoadResolveDoer (); err != nil {
1278
- return nil , err
1279
- }
1280
-
1281
- if err := comment .LoadReactions (issue .Repo ); err != nil {
1282
- return nil , err
1283
- }
1284
-
1285
- var err error
1286
- if comment .RenderedContent , err = markdown .RenderString (& markup.RenderContext {
1287
- Ctx : ctx ,
1288
- URLPrefix : issue .Repo .Link (),
1289
- Metas : issue .Repo .ComposeMetas (),
1290
- }, comment .Content ); err != nil {
1291
- return nil , err
1292
- }
1293
- }
1294
- return comments [:n ], nil
1295
- }
1296
-
1297
- // FetchCodeCommentsByLine fetches the code comments for a given treePath and line number
1298
- func FetchCodeCommentsByLine (ctx context.Context , issue * Issue , currentUser * user_model.User , treePath string , line int64 ) ([]* Comment , error ) {
1299
- opts := FindCommentsOptions {
1300
- Type : CommentTypeCode ,
1301
- IssueID : issue .ID ,
1302
- TreePath : treePath ,
1303
- Line : line ,
1304
- }
1305
- return findCodeComments (ctx , opts , issue , currentUser , nil )
1306
- }
1307
-
1308
1179
// UpdateCommentsMigrationsByType updates comments' migrations information via given git service type and original id and poster id
1309
1180
func UpdateCommentsMigrationsByType (tp structs.GitServiceType , originalAuthorID string , posterID int64 ) error {
1310
1181
_ , err := db .GetEngine (db .DefaultContext ).Table ("comment" ).
0 commit comments