diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2022-06-13 17:37:59 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-13 17:37:59 +0800 |
commit | 1a9821f57a0293db3adc0eab8aff08ca5fa1026c (patch) | |
tree | 3c3d02813eb63c0d0827ef6d9745f6dcdd2636cb | |
parent | 3708ca8e2849ca7e36e6bd15ec6935a2a2d81e55 (diff) | |
download | gitea-1a9821f57a0293db3adc0eab8aff08ca5fa1026c.tar.gz gitea-1a9821f57a0293db3adc0eab8aff08ca5fa1026c.zip |
Move issues related files into models/issues (#19931)
* Move access and repo permission to models/perm/access
* fix test
* fix git test
* Move functions sequence
* Some improvements per @KN4CK3R and @delvh
* Move issues related code to models/issues
* Move some issues related sub package
* Merge
* Fix test
* Fix test
* Fix test
* Fix test
* Rename some files
180 files changed, 3665 insertions, 3675 deletions
diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index dde51b2d53..7dcc0279fc 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -10,7 +10,7 @@ import ( "net/url" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -23,9 +23,9 @@ import ( func TestAPIListRepoComments(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{}, - unittest.Cond("type = ?", models.CommentTypeComment)).(*models.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -38,10 +38,10 @@ func TestAPIListRepoComments(t *testing.T) { DecodeJSON(t, resp, &apiComments) assert.Len(t, apiComments, 2) for _, apiComment := range apiComments { - c := &models.Comment{ID: apiComment.ID} + c := &issues_model.Comment{ID: apiComment.ID} unittest.AssertExistsAndLoadBean(t, c, - unittest.Cond("type = ?", models.CommentTypeComment)) - unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: c.IssueID, RepoID: repo.ID}) + unittest.Cond("type = ?", issues_model.CommentTypeComment)) + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: c.IssueID, RepoID: repo.ID}) } // test before and since filters @@ -69,9 +69,9 @@ func TestAPIListRepoComments(t *testing.T) { func TestAPIListIssueComments(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{}, - unittest.Cond("type = ?", models.CommentTypeComment)).(*models.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -82,8 +82,8 @@ func TestAPIListIssueComments(t *testing.T) { var comments []*api.Comment DecodeJSON(t, resp, &comments) - expectedCount := unittest.GetCount(t, &models.Comment{IssueID: issue.ID}, - unittest.Cond("type = ?", models.CommentTypeComment)) + expectedCount := unittest.GetCount(t, &issues_model.Comment{IssueID: issue.ID}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)) assert.EqualValues(t, expectedCount, len(comments)) } @@ -91,7 +91,7 @@ func TestAPICreateComment(t *testing.T) { defer prepareTestEnv(t)() const commentBody = "Comment body" - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -107,13 +107,13 @@ func TestAPICreateComment(t *testing.T) { var updatedComment api.Comment DecodeJSON(t, resp, &updatedComment) assert.EqualValues(t, commentBody, updatedComment.Body) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) } func TestAPIGetComment(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 2}).(*models.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}).(*issues_model.Comment) assert.NoError(t, comment.LoadIssue()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -141,9 +141,9 @@ func TestAPIEditComment(t *testing.T) { defer prepareTestEnv(t)() const newCommentBody = "This is the new comment body" - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{}, - unittest.Cond("type = ?", models.CommentTypeComment)).(*models.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -160,15 +160,15 @@ func TestAPIEditComment(t *testing.T) { DecodeJSON(t, resp, &updatedComment) assert.EqualValues(t, comment.ID, updatedComment.ID) assert.EqualValues(t, newCommentBody, updatedComment.Body) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) } func TestAPIDeleteComment(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{}, - unittest.Cond("type = ?", models.CommentTypeComment)).(*models.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -178,14 +178,14 @@ func TestAPIDeleteComment(t *testing.T) { repoOwner.Name, repo.Name, comment.ID, token) session.MakeRequest(t, req, http.StatusNoContent) - unittest.AssertNotExistsBean(t, &models.Comment{ID: comment.ID}) + unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID}) } func TestAPIListIssueTimeline(t *testing.T) { defer prepareTestEnv(t)() // load comment - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -199,6 +199,6 @@ func TestAPIListIssueTimeline(t *testing.T) { // lists extracted directly from DB are the same var comments []*api.TimelineComment DecodeJSON(t, resp, &comments) - expectedCount := unittest.GetCount(t, &models.Comment{IssueID: issue.ID}) + expectedCount := unittest.GetCount(t, &issues_model.Comment{IssueID: issue.ID}) assert.EqualValues(t, expectedCount, len(comments)) } diff --git a/integrations/api_issue_label_test.go b/integrations/api_issue_label_test.go index 94b487377e..9b6333b2a2 100644 --- a/integrations/api_issue_label_test.go +++ b/integrations/api_issue_label_test.go @@ -10,7 +10,7 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -37,7 +37,7 @@ func TestAPIModifyLabels(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusCreated) apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) - dbLabel := unittest.AssertExistsAndLoadBean(t, &models.Label{ID: apiLabel.ID, RepoID: repo.ID}).(*models.Label) + dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, RepoID: repo.ID}).(*issues_model.Label) assert.EqualValues(t, dbLabel.Name, apiLabel.Name) assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) @@ -92,8 +92,8 @@ func TestAPIAddIssueLabels(t *testing.T) { assert.NoError(t, unittest.LoadFixtures()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{RepoID: repo.ID}).(*models.Issue) - _ = unittest.AssertExistsAndLoadBean(t, &models.Label{RepoID: repo.ID, ID: 2}).(*models.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}).(*issues_model.Issue) + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID, ID: 2}).(*issues_model.Label) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) session := loginUser(t, owner.Name) @@ -106,17 +106,17 @@ func TestAPIAddIssueLabels(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiLabels []*api.Label DecodeJSON(t, resp, &apiLabels) - assert.Len(t, apiLabels, unittest.GetCount(t, &models.IssueLabel{IssueID: issue.ID})) + assert.Len(t, apiLabels, unittest.GetCount(t, &issues_model.IssueLabel{IssueID: issue.ID})) - unittest.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: issue.ID, LabelID: 2}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: 2}) } func TestAPIReplaceIssueLabels(t *testing.T) { assert.NoError(t, unittest.LoadFixtures()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{RepoID: repo.ID}).(*models.Issue) - label := unittest.AssertExistsAndLoadBean(t, &models.Label{RepoID: repo.ID}).(*models.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}).(*issues_model.Issue) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID}).(*issues_model.Label) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) session := loginUser(t, owner.Name) @@ -133,8 +133,8 @@ func TestAPIReplaceIssueLabels(t *testing.T) { assert.EqualValues(t, label.ID, apiLabels[0].ID) } - unittest.AssertCount(t, &models.IssueLabel{IssueID: issue.ID}, 1) - unittest.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) + unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issue.ID}, 1) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) } func TestAPIModifyOrgLabels(t *testing.T) { @@ -156,7 +156,7 @@ func TestAPIModifyOrgLabels(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusCreated) apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) - dbLabel := unittest.AssertExistsAndLoadBean(t, &models.Label{ID: apiLabel.ID, OrgID: owner.ID}).(*models.Label) + dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, OrgID: owner.ID}).(*issues_model.Label) assert.EqualValues(t, dbLabel.Name, apiLabel.Name) assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) diff --git a/integrations/api_issue_reaction_test.go b/integrations/api_issue_reaction_test.go index 4a063c8c68..3834af2130 100644 --- a/integrations/api_issue_reaction_test.go +++ b/integrations/api_issue_reaction_test.go @@ -10,8 +10,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/convert" @@ -23,7 +23,7 @@ import ( func TestAPIIssuesReactions(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) @@ -80,7 +80,7 @@ func TestAPIIssuesReactions(t *testing.T) { func TestAPICommentReactions(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 2}).(*models.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}).(*issues_model.Comment) _ = comment.LoadIssue() issue := comment.Issue _ = issue.LoadRepo(db.DefaultContext) diff --git a/integrations/api_issue_stopwatch_test.go b/integrations/api_issue_stopwatch_test.go index 90098b9236..0d06447181 100644 --- a/integrations/api_issue_stopwatch_test.go +++ b/integrations/api_issue_stopwatch_test.go @@ -8,8 +8,8 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -30,8 +30,8 @@ func TestAPIListStopWatches(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches) - stopwatch := unittest.AssertExistsAndLoadBean(t, &models.Stopwatch{UserID: owner.ID}).(*models.Stopwatch) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: stopwatch.IssueID}).(*models.Issue) + stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}).(*issues_model.Stopwatch) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}).(*issues_model.Issue) if assert.Len(t, apiWatches, 1) { assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex) @@ -45,7 +45,7 @@ func TestAPIListStopWatches(t *testing.T) { func TestAPIStopStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) @@ -61,7 +61,7 @@ func TestAPIStopStopWatches(t *testing.T) { func TestAPICancelStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) @@ -77,7 +77,7 @@ func TestAPICancelStopWatches(t *testing.T) { func TestAPIStartStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) diff --git a/integrations/api_issue_subscription_test.go b/integrations/api_issue_subscription_test.go index e0bb388365..2c6cddcab9 100644 --- a/integrations/api_issue_subscription_test.go +++ b/integrations/api_issue_subscription_test.go @@ -9,7 +9,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -21,18 +21,18 @@ import ( func TestAPIIssueSubscriptions(t *testing.T) { defer prepareTestEnv(t)() - issue1 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) - issue2 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) - issue3 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) - issue4 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 4}).(*models.Issue) - issue5 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 8}).(*models.Issue) + issue1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) + issue3 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + issue4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue) + issue5 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 8}).(*issues_model.Issue) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue1.PosterID}).(*user_model.User) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) - testSubscription := func(issue *models.Issue, isWatching bool) { + testSubscription := func(issue *issues_model.Issue, isWatching bool) { issueRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/check?token=%s", issueRepo.OwnerName, issueRepo.Name, issue.Index, token) diff --git a/integrations/api_issue_test.go b/integrations/api_issue_test.go index cc7d8d6bd5..5c802e8d20 100644 --- a/integrations/api_issue_test.go +++ b/integrations/api_issue_test.go @@ -11,7 +11,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -34,9 +35,9 @@ func TestAPIListIssues(t *testing.T) { resp := session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) var apiIssues []*api.Issue DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, unittest.GetCount(t, &models.Issue{RepoID: repo.ID})) + assert.Len(t, apiIssues, unittest.GetCount(t, &issues_model.Issue{RepoID: repo.ID})) for _, apiIssue := range apiIssues { - unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: apiIssue.ID, RepoID: repo.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: apiIssue.ID, RepoID: repo.ID}) } // test milestone filter @@ -91,7 +92,7 @@ func TestAPICreateIssue(t *testing.T) { assert.Equal(t, body, apiIssue.Body) assert.Equal(t, title, apiIssue.Title) - unittest.AssertExistsAndLoadBean(t, &models.Issue{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ RepoID: repoBefore.ID, AssigneeID: owner.ID, Content: body, @@ -106,10 +107,10 @@ func TestAPICreateIssue(t *testing.T) { func TestAPIEditIssue(t *testing.T) { defer prepareTestEnv(t)() - issueBefore := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User) - assert.NoError(t, issueBefore.LoadAttributes()) + assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix)) assert.Equal(t, api.StateOpen, issueBefore.State()) @@ -137,12 +138,12 @@ func TestAPIEditIssue(t *testing.T) { var apiIssue api.Issue DecodeJSON(t, resp, &apiIssue) - issueAfter := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue) + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) // check deleted user assert.Equal(t, int64(500), issueAfter.PosterID) - assert.NoError(t, issueAfter.LoadAttributes()) + assert.NoError(t, issueAfter.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(-1), issueAfter.PosterID) assert.Equal(t, int64(-1), issueBefore.PosterID) assert.Equal(t, int64(-1), apiIssue.Poster.ID) diff --git a/integrations/api_issue_tracked_time_test.go b/integrations/api_issue_tracked_time_test.go index 7c69d4eb9e..a6846cb786 100644 --- a/integrations/api_issue_tracked_time_test.go +++ b/integrations/api_issue_tracked_time_test.go @@ -10,8 +10,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" @@ -23,7 +23,7 @@ func TestAPIGetTrackedTimes(t *testing.T) { defer prepareTestEnv(t)() user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - issue2 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) session := loginUser(t, user2.Name) @@ -33,7 +33,7 @@ func TestAPIGetTrackedTimes(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiTimes api.TrackedTimeList DecodeJSON(t, resp, &apiTimes) - expect, err := models.GetTrackedTimes(db.DefaultContext, &models.FindTrackedTimesOptions{IssueID: issue2.ID}) + expect, err := issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: issue2.ID}) assert.NoError(t, err) assert.Len(t, apiTimes, 3) @@ -64,8 +64,8 @@ func TestAPIGetTrackedTimes(t *testing.T) { func TestAPIDeleteTrackedTime(t *testing.T) { defer prepareTestEnv(t)() - time6 := unittest.AssertExistsAndLoadBean(t, &models.TrackedTime{ID: 6}).(*models.TrackedTime) - issue2 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + time6 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 6}).(*issues_model.TrackedTime) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) @@ -76,14 +76,14 @@ func TestAPIDeleteTrackedTime(t *testing.T) { req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time6.ID, token) session.MakeRequest(t, req, http.StatusForbidden) - time3 := unittest.AssertExistsAndLoadBean(t, &models.TrackedTime{ID: 3}).(*models.TrackedTime) + time3 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 3}).(*issues_model.TrackedTime) req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time3.ID, token) session.MakeRequest(t, req, http.StatusNoContent) // Delete non existing time session.MakeRequest(t, req, http.StatusNotFound) // Reset time of user 2 on issue 2 - trackedSeconds, err := models.GetTrackedSeconds(db.DefaultContext, models.FindTrackedTimesOptions{IssueID: 2, UserID: 2}) + trackedSeconds, err := issues_model.GetTrackedSeconds(db.DefaultContext, issues_model.FindTrackedTimesOptions{IssueID: 2, UserID: 2}) assert.NoError(t, err) assert.Equal(t, int64(3661), trackedSeconds) @@ -91,7 +91,7 @@ func TestAPIDeleteTrackedTime(t *testing.T) { session.MakeRequest(t, req, http.StatusNoContent) session.MakeRequest(t, req, http.StatusNotFound) - trackedSeconds, err = models.GetTrackedSeconds(db.DefaultContext, models.FindTrackedTimesOptions{IssueID: 2, UserID: 2}) + trackedSeconds, err = issues_model.GetTrackedSeconds(db.DefaultContext, issues_model.FindTrackedTimesOptions{IssueID: 2, UserID: 2}) assert.NoError(t, err) assert.Equal(t, int64(0), trackedSeconds) } @@ -99,7 +99,7 @@ func TestAPIDeleteTrackedTime(t *testing.T) { func TestAPIAddTrackedTimes(t *testing.T) { defer prepareTestEnv(t)() - issue2 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) diff --git a/integrations/api_pull_commits_test.go b/integrations/api_pull_commits_test.go index 5e057b05a1..3b75fbcb4a 100644 --- a/integrations/api_pull_commits_test.go +++ b/integrations/api_pull_commits_test.go @@ -8,7 +8,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" api "code.gitea.io/gitea/modules/structs" @@ -18,7 +18,7 @@ import ( func TestAPIPullCommits(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) assert.NoError(t, pullIssue.LoadIssue()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.HeadRepoID}).(*repo_model.Repository) diff --git a/integrations/api_pull_review_test.go b/integrations/api_pull_review_test.go index 3f80dbdf9b..b601ca1d41 100644 --- a/integrations/api_pull_review_test.go +++ b/integrations/api_pull_review_test.go @@ -9,7 +9,8 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/json" @@ -20,8 +21,8 @@ import ( func TestAPIPullReview(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) - assert.NoError(t, pullIssue.LoadAttributes()) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext)) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}).(*repo_model.Repository) // test ListPullReviews @@ -64,7 +65,7 @@ func TestAPIPullReview(t *testing.T) { assert.EqualValues(t, *reviews[5], review) // test GetPullReviewComments - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 7}).(*models.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7}).(*issues_model.Comment) req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d/comments?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, 10, token) resp = session.MakeRequest(t, req, http.StatusOK) var reviewComments []*api.PullReviewComment @@ -199,8 +200,8 @@ func TestAPIPullReview(t *testing.T) { // test get review requests // to make it simple, use same api with get review - pullIssue12 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 12}).(*models.Issue) - assert.NoError(t, pullIssue12.LoadAttributes()) + pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}).(*issues_model.Issue) + assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext)) repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}).(*repo_model.Repository) req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token) @@ -223,8 +224,8 @@ func TestAPIPullReview(t *testing.T) { func TestAPIPullReviewRequest(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) - assert.NoError(t, pullIssue.LoadAttributes()) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext)) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}).(*repo_model.Repository) // Test add Review Request @@ -268,8 +269,8 @@ func TestAPIPullReviewRequest(t *testing.T) { session.MakeRequest(t, req, http.StatusNoContent) // Test team review request - pullIssue12 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 12}).(*models.Issue) - assert.NoError(t, pullIssue12.LoadAttributes()) + pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}).(*issues_model.Issue) + assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext)) repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}).(*repo_model.Repository) // Test add Team Review Request diff --git a/integrations/api_pull_test.go b/integrations/api_pull_test.go index a1c2a4c3e6..0c63ec2c00 100644 --- a/integrations/api_pull_test.go +++ b/integrations/api_pull_test.go @@ -9,7 +9,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -33,7 +33,7 @@ func TestAPIViewPulls(t *testing.T) { var pulls []*api.PullRequest DecodeJSON(t, resp, &pulls) - expectedLen := unittest.GetCount(t, &models.Issue{RepoID: repo.ID}, unittest.Cond("is_pull = ?", true)) + expectedLen := unittest.GetCount(t, &issues_model.Issue{RepoID: repo.ID}, unittest.Cond("is_pull = ?", true)) assert.Len(t, pulls, expectedLen) } @@ -42,7 +42,7 @@ func TestAPIMergePullWIP(t *testing.T) { defer prepareTestEnv(t)() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{Status: models.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false)).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{Status: issues_model.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false)).(*issues_model.PullRequest) pr.LoadIssue() issue_service.ChangeTitle(pr.Issue, owner, setting.Repository.PullRequest.WorkInProgressPrefixes[0]+" "+pr.Issue.Title) diff --git a/integrations/delete_user_test.go b/integrations/delete_user_test.go index cf376f6fcc..8b86780224 100644 --- a/integrations/delete_user_test.go +++ b/integrations/delete_user_test.go @@ -9,7 +9,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -24,7 +24,7 @@ func assertUserDeleted(t *testing.T, userID int64) { unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerID: userID}) unittest.AssertNotExistsBean(t, &access_model.Access{UserID: userID}) unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: userID}) - unittest.AssertNotExistsBean(t, &models.IssueUser{UID: userID}) + unittest.AssertNotExistsBean(t, &issues_model.IssueUser{UID: userID}) unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID}) unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID}) } diff --git a/integrations/git_test.go b/integrations/git_test.go index 63afc7913b..a3ba7b7aa9 100644 --- a/integrations/git_test.go +++ b/integrations/git_test.go @@ -17,8 +17,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -715,7 +715,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB defer gitRepo.Close() var ( - pr1, pr2 *models.PullRequest + pr1, pr2 *issues_model.PullRequest commit string ) repo, err := repo_model.GetRepositoryByOwnerAndName(ctx.Username, ctx.Reponame) @@ -723,7 +723,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB return } - pullNum := unittest.GetCount(t, &models.PullRequest{}) + pullNum := unittest.GetCount(t, &issues_model.PullRequest{}) t.Run("CreateHeadBranch", doGitCreateBranch(dstPath, headBranch)) @@ -759,11 +759,11 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - unittest.AssertCount(t, &models.PullRequest{}, pullNum+1) - pr1 = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ + unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+1) + pr1 = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo.ID, - Flow: models.PullRequestFlowAGit, - }).(*models.PullRequest) + Flow: issues_model.PullRequestFlowAGit, + }).(*issues_model.PullRequest) if !assert.NotEmpty(t, pr1) { return } @@ -780,12 +780,12 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - unittest.AssertCount(t, &models.PullRequest{}, pullNum+2) - pr2 = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ + unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) + pr2 = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo.ID, Index: pr1.Index + 1, - Flow: models.PullRequestFlowAGit, - }).(*models.PullRequest) + Flow: issues_model.PullRequestFlowAGit, + }).(*issues_model.PullRequest) if !assert.NotEmpty(t, pr2) { return } @@ -833,7 +833,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - unittest.AssertCount(t, &models.PullRequest{}, pullNum+2) + unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) prMsg, err := doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index)(t) if !assert.NoError(t, err) { return @@ -845,7 +845,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - unittest.AssertCount(t, &models.PullRequest{}, pullNum+2) + unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) prMsg, err = doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr2.Index)(t) if !assert.NoError(t, err) { return diff --git a/integrations/issue_test.go b/integrations/issue_test.go index 8e04b99d5e..7d30d657f5 100644 --- a/integrations/issue_test.go +++ b/integrations/issue_test.go @@ -14,7 +14,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -34,16 +35,16 @@ func getIssuesSelection(t testing.TB, htmlDoc *HTMLDoc) *goquery.Selection { return issueList.Find("li").Find(".title") } -func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *models.Issue { +func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *issues_model.Issue { href, exists := issueSelection.Attr("href") assert.True(t, exists) indexStr := href[strings.LastIndexByte(href, '/')+1:] index, err := strconv.Atoi(indexStr) assert.NoError(t, err, "Invalid issue href: %s", href) - return unittest.AssertExistsAndLoadBean(t, &models.Issue{RepoID: repoID, Index: int64(index)}).(*models.Issue) + return unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repoID, Index: int64(index)}).(*issues_model.Issue) } -func assertMatch(t testing.TB, issue *models.Issue, keyword string) { +func assertMatch(t testing.TB, issue *issues_model.Issue, keyword string) { matches := strings.Contains(strings.ToLower(issue.Title), keyword) || strings.Contains(strings.ToLower(issue.Content), keyword) for _, comment := range issue.Comments { @@ -75,7 +76,7 @@ func TestViewIssuesSortByType(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) issuesSelection := getIssuesSelection(t, htmlDoc) expectedNumIssues := unittest.GetCount(t, - &models.Issue{RepoID: repo.ID, PosterID: user.ID}, + &issues_model.Issue{RepoID: repo.ID, PosterID: user.ID}, unittest.Cond("is_closed=?", false), unittest.Cond("is_pull=?", false), ) @@ -94,10 +95,10 @@ func TestViewIssuesKeyword(t *testing.T) { defer prepareTestEnv(t)() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ RepoID: repo.ID, Index: 1, - }).(*models.Issue) + }).(*issues_model.Issue) issues.UpdateIssueIndexer(issue) time.Sleep(time.Second * 1) const keyword = "first" @@ -238,7 +239,7 @@ func TestIssueCrossReference(t *testing.T) { // Ref from issue title issueRefURL, issueRef := testIssueWithBean(t, "user2", 1, fmt.Sprintf("Title ref #%d", issueBase.Index), "Description") - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -249,7 +250,7 @@ func TestIssueCrossReference(t *testing.T) { // Edit title, neuter ref testIssueChangeInfo(t, "user2", issueRefURL, "title", "Title no ref") - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -260,7 +261,7 @@ func TestIssueCrossReference(t *testing.T) { // Ref from issue content issueRefURL, issueRef = testIssueWithBean(t, "user2", 1, "TitleXRef", fmt.Sprintf("Description ref #%d", issueBase.Index)) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -271,7 +272,7 @@ func TestIssueCrossReference(t *testing.T) { // Edit content, neuter ref testIssueChangeInfo(t, "user2", issueRefURL, "content", "Description no ref") - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -283,7 +284,7 @@ func TestIssueCrossReference(t *testing.T) { // Ref from a comment session := loginUser(t, "user2") commentID := testIssueAddComment(t, session, issueRefURL, fmt.Sprintf("Adding ref from comment #%d", issueBase.Index), "") - comment := &models.Comment{ + comment := &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -295,7 +296,7 @@ func TestIssueCrossReference(t *testing.T) { // Ref from a different repository _, issueRef = testIssueWithBean(t, "user12", 10, "TitleXRef", fmt.Sprintf("Description ref user2/repo1#%d", issueBase.Index)) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 10, RefIssueID: issueRef.ID, @@ -305,13 +306,13 @@ func TestIssueCrossReference(t *testing.T) { }) } -func testIssueWithBean(t *testing.T, user string, repoID int64, title, content string) (string, *models.Issue) { +func testIssueWithBean(t *testing.T, user string, repoID int64, title, content string) (string, *issues_model.Issue) { session := loginUser(t, user) issueURL := testNewIssue(t, session, user, fmt.Sprintf("repo%d", repoID), title, content) indexStr := issueURL[strings.LastIndexByte(issueURL, '/')+1:] index, err := strconv.Atoi(indexStr) assert.NoError(t, err, "Invalid issue href: %s", issueURL) - issue := &models.Issue{RepoID: repoID, Index: int64(index)} + issue := &issues_model.Issue{RepoID: repoID, Index: int64(index)} unittest.AssertExistsAndLoadBean(t, issue) return issueURL, issue } @@ -511,10 +512,10 @@ func TestSearchIssuesWithLabels(t *testing.T) { func TestGetIssueInfo(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - assert.NoError(t, issue.LoadAttributes()) + assert.NoError(t, issue.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issue.DeadlineUnix)) assert.Equal(t, api.StateOpen, issue.State()) @@ -532,10 +533,10 @@ func TestGetIssueInfo(t *testing.T) { func TestUpdateIssueDeadline(t *testing.T) { defer prepareTestEnv(t)() - issueBefore := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User) - assert.NoError(t, issueBefore.LoadAttributes()) + assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix)) assert.Equal(t, api.StateOpen, issueBefore.State()) diff --git a/integrations/pull_merge_test.go b/integrations/pull_merge_test.go index 6c5b67caa6..de519094d4 100644 --- a/integrations/pull_merge_test.go +++ b/integrations/pull_merge_test.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -233,12 +234,12 @@ func TestCantMergeConflict(t *testing.T) { Name: "repo1", }).(*repo_model.Repository) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo1.ID, BaseRepoID: repo1.ID, HeadBranch: "conflict", BaseBranch: "base", - }).(*models.PullRequest) + }).(*issues_model.PullRequest) gitRepo, err := git.OpenRepository(git.DefaultContext, repo_model.RepoPath(user1.Name, repo1.Name)) assert.NoError(t, err) @@ -335,12 +336,12 @@ func TestCantMergeUnrelated(t *testing.T) { // Now this PR could be marked conflict - or at least a race may occur - so drop down to pure code at this point... gitRepo, err := git.OpenRepository(git.DefaultContext, path) assert.NoError(t, err) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo1.ID, BaseRepoID: repo1.ID, HeadBranch: "unrelated", BaseBranch: "base", - }).(*models.PullRequest) + }).(*issues_model.PullRequest) err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "UNRELATED") assert.Error(t, err, "Merge should return an error due to unrelated") @@ -387,7 +388,7 @@ func TestConflictChecking(t *testing.T) { assert.NoError(t, err) // create Pull to merge the important-secrets branch into main branch. - pullIssue := &models.Issue{ + pullIssue := &issues_model.Issue{ RepoID: baseRepo.ID, Title: "PR with conflict!", PosterID: user.ID, @@ -395,26 +396,26 @@ func TestConflictChecking(t *testing.T) { IsPull: true, } - pullRequest := &models.PullRequest{ + pullRequest := &issues_model.PullRequest{ HeadRepoID: baseRepo.ID, BaseRepoID: baseRepo.ID, HeadBranch: "important-secrets", BaseBranch: "main", HeadRepo: baseRepo, BaseRepo: baseRepo, - Type: models.PullRequestGitea, + Type: issues_model.PullRequestGitea, } err = pull.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) assert.NoError(t, err) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{Title: "PR with conflict!"}).(*models.Issue) - conflictingPR, err := models.GetPullRequestByIssueID(db.DefaultContext, issue.ID) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "PR with conflict!"}).(*issues_model.Issue) + conflictingPR, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID) assert.NoError(t, err) // Ensure conflictedFiles is populated. assert.Equal(t, 1, len(conflictingPR.ConflictedFiles)) // Check if status is correct. - assert.Equal(t, models.PullRequestStatusConflict, conflictingPR.Status) + assert.Equal(t, issues_model.PullRequestStatusConflict, conflictingPR.Status) // Ensure that mergeable returns false assert.False(t, conflictingPR.Mergeable()) }) diff --git a/integrations/pull_update_test.go b/integrations/pull_update_test.go index f11eacf144..47ada91e1a 100644 --- a/integrations/pull_update_test.go +++ b/integrations/pull_update_test.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -78,7 +79,7 @@ func TestAPIPullUpdateByRebase(t *testing.T) { }) } -func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.PullRequest { +func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest { baseRepo, err := repo_service.CreateRepository(actor, actor, models.CreateRepoOptions{ Name: "repo-pr-update", Description: "repo-tmp-pr-update description", @@ -146,27 +147,27 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.Pul assert.NoError(t, err) // create Pull - pullIssue := &models.Issue{ + pullIssue := &issues_model.Issue{ RepoID: baseRepo.ID, Title: "Test Pull -to-update-", PosterID: actor.ID, Poster: actor, IsPull: true, } - pullRequest := &models.PullRequest{ + pullRequest := &issues_model.PullRequest{ HeadRepoID: headRepo.ID, BaseRepoID: baseRepo.ID, HeadBranch: "newBranch", BaseBranch: "master", HeadRepo: headRepo, BaseRepo: baseRepo, - Type: models.PullRequestGitea, + Type: issues_model.PullRequestGitea, } err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) assert.NoError(t, err) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{Title: "Test Pull -to-update-"}).(*models.Issue) - pr, err := models.GetPullRequestByIssueID(db.DefaultContext, issue.ID) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Test Pull -to-update-"}).(*issues_model.Issue) + pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID) assert.NoError(t, err) return pr diff --git a/integrations/user_test.go b/integrations/user_test.go index d0523d8b3a..6a3d30472d 100644 --- a/integrations/user_test.go +++ b/integrations/user_test.go @@ -8,7 +8,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -237,8 +237,8 @@ func TestListStopWatches(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches) - stopwatch := unittest.AssertExistsAndLoadBean(t, &models.Stopwatch{UserID: owner.ID}).(*models.Stopwatch) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: stopwatch.IssueID}).(*models.Issue) + stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}).(*issues_model.Stopwatch) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}).(*issues_model.Issue) if assert.Len(t, apiWatches, 1) { assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex) diff --git a/models/action.go b/models/action.go index 882bc59d8f..951328070d 100644 --- a/models/action.go +++ b/models/action.go @@ -15,6 +15,7 @@ import ( "time" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -76,7 +77,7 @@ type Action struct { RepoID int64 `xorm:"INDEX"` Repo *repo_model.Repository `xorm:"-"` CommentID int64 `xorm:"INDEX"` - Comment *Comment `xorm:"-"` + Comment *issues_model.Comment `xorm:"-"` IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"` RefName string IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"` @@ -223,7 +224,7 @@ func (a *Action) getCommentLink(ctx context.Context) string { return "#" } if a.Comment == nil && a.CommentID != 0 { - a.Comment, _ = GetCommentByID(ctx, a.CommentID) + a.Comment, _ = issues_model.GetCommentByID(ctx, a.CommentID) } if a.Comment != nil { return a.Comment.HTMLURL() @@ -238,7 +239,7 @@ func (a *Action) getCommentLink(ctx context.Context) string { return "#" } - issue, err := getIssueByID(ctx, issueID) + issue, err := issues_model.GetIssueByID(ctx, issueID) if err != nil { return "#" } @@ -295,7 +296,7 @@ func (a *Action) GetIssueInfos() []string { // with the action. func (a *Action) GetIssueTitle() string { index, _ := strconv.ParseInt(a.GetIssueInfos()[0], 10, 64) - issue, err := GetIssueByIndex(a.RepoID, index) + issue, err := issues_model.GetIssueByIndex(a.RepoID, index) if err != nil { log.Error("GetIssueByIndex: %v", err) return "500 when get issue" @@ -307,7 +308,7 @@ func (a *Action) GetIssueTitle() string { // this action. func (a *Action) GetIssueContent() string { index, _ := strconv.ParseInt(a.GetIssueInfos()[0], 10, 64) - issue, err := GetIssueByIndex(a.RepoID, index) + issue, err := issues_model.GetIssueByIndex(a.RepoID, index) if err != nil { log.Error("GetIssueByIndex: %v", err) return "500 when get issue" @@ -572,3 +573,20 @@ func NotifyWatchersActions(acts []*Action) error { } return committer.Commit() } + +// DeleteIssueActions delete all actions related with issueID +func DeleteIssueActions(ctx context.Context, repoID, issueID int64) error { + // delete actions assigned to this issue + subQuery := builder.Select("`id`"). + From("`comment`"). + Where(builder.Eq{"`issue_id`": issueID}) + if _, err := db.GetEngine(ctx).In("comment_id", subQuery).Delete(&Action{}); err != nil { + return err + } + + _, err := db.GetEngine(ctx).Table("action").Where("repo_id = ?", repoID). + In("op_type", ActionCreateIssue, ActionCreatePullRequest). + Where("content LIKE ?", strconv.FormatInt(issueID, 10)+"|%"). + Delete(&Action{}) + return err +} diff --git a/models/action_test.go b/models/action_test.go index fb8a6c2686..2d46bd3e80 100644 --- a/models/action_test.go +++ b/models/action_test.go @@ -228,3 +228,46 @@ func TestGetFeedsCorrupted(t *testing.T) { assert.NoError(t, err) assert.Len(t, actions, 0) } + +func TestConsistencyUpdateAction(t *testing.T) { + if !setting.Database.UseSQLite3 { + t.Skip("Test is only for SQLite database.") + } + assert.NoError(t, unittest.PrepareTestDatabase()) + id := 8 + unittest.AssertExistsAndLoadBean(t, &Action{ + ID: int64(id), + }) + _, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id) + assert.NoError(t, err) + actions := make([]*Action, 0, 1) + // + // XORM returns an error when created_unix is a string + // + err = db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions) + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "type string to a int64: invalid syntax") + } + // + // Get rid of incorrectly set created_unix + // + count, err := CountActionCreatedUnixString() + assert.NoError(t, err) + assert.EqualValues(t, 1, count) + count, err = FixActionCreatedUnixString() + assert.NoError(t, err) + assert.EqualValues(t, 1, count) + + count, err = CountActionCreatedUnixString() + assert.NoError(t, err) + assert.EqualValues(t, 0, count) + count, err = FixActionCreatedUnixString() + assert.NoError(t, err) + assert.EqualValues(t, 0, count) + + // + // XORM must be happy now + // + assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) + unittest.CheckConsistencyFor(t, &Action{}) +} diff --git a/models/branch.go b/models/branch.go deleted file mode 100644 index 3d6e7d82e2..0000000000 --- a/models/branch.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "context" - - "code.gitea.io/gitea/models/db" - git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/modules/log" -) - -// HasEnoughApprovals returns true if pr has enough granted approvals. -func HasEnoughApprovals(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { - if protectBranch.RequiredApprovals == 0 { - return true - } - return GetGrantedApprovalsCount(ctx, protectBranch, pr) >= protectBranch.RequiredApprovals -} - -// GetGrantedApprovalsCount returns the number of granted approvals for pr. A granted approval must be authored by a user in an approval whitelist. -func GetGrantedApprovalsCount(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) int64 { - sess := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). - And("type = ?", ReviewTypeApprove). - And("official = ?", true). - And("dismissed = ?", false) - if protectBranch.DismissStaleApprovals { - sess = sess.And("stale = ?", false) - } - approvals, err := sess.Count(new(Review)) - if err != nil { - log.Error("GetGrantedApprovalsCount: %v", err) - return 0 - } - - return approvals -} - -// MergeBlockedByRejectedReview returns true if merge is blocked by rejected reviews -func MergeBlockedByRejectedReview(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { - if !protectBranch.BlockOnRejectedReviews { - return false - } - rejectExist, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). - And("type = ?", ReviewTypeReject). - And("official = ?", true). - And("dismissed = ?", false). - Exist(new(Review)) - if err != nil { - log.Error("MergeBlockedByRejectedReview: %v", err) - return true - } - - return rejectExist -} - -// MergeBlockedByOfficialReviewRequests block merge because of some review request to official reviewer -// of from official review -func MergeBlockedByOfficialReviewRequests(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { - if !protectBranch.BlockOnOfficialReviewRequests { - return false - } - has, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). - And("type = ?", ReviewTypeRequest). - And("official = ?", true). - Exist(new(Review)) - if err != nil { - log.Error("MergeBlockedByOfficialReviewRequests: %v", err) - return true - } - - return has -} - -// MergeBlockedByOutdatedBranch returns true if merge is blocked by an outdated head branch -func MergeBlockedByOutdatedBranch(protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { - return protectBranch.BlockOnOutdatedBranch && pr.CommitsBehind > 0 -} diff --git a/models/consistency.go b/models/consistency.go index e817b69176..18ed9195fc 100644 --- a/models/consistency.go +++ b/models/consistency.go @@ -5,7 +5,6 @@ package models import ( - admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -14,151 +13,6 @@ import ( "xorm.io/builder" ) -// CountOrphanedLabels return count of labels witch are broken and not accessible via ui anymore -func CountOrphanedLabels() (int64, error) { - noref, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Count("label.id") - if err != nil { - return 0, err - } - - norepo, err := db.GetEngine(db.DefaultContext).Table("label"). - Where(builder.And( - builder.Gt{"repo_id": 0}, - builder.NotIn("repo_id", builder.Select("id").From("repository")), - )). - Count() - if err != nil { - return 0, err - } - - noorg, err := db.GetEngine(db.DefaultContext).Table("label"). - Where(builder.And( - builder.Gt{"org_id": 0}, - builder.NotIn("org_id", builder.Select("id").From("user")), - )). - Count() - if err != nil { - return 0, err - } - - return noref + norepo + noorg, nil -} - -// DeleteOrphanedLabels delete labels witch are broken and not accessible via ui anymore -func DeleteOrphanedLabels() error { - // delete labels with no reference - if _, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Delete(new(Label)); err != nil { - return err - } - - // delete labels with none existing repos - if _, err := db.GetEngine(db.DefaultContext). - Where(builder.And( - builder.Gt{"repo_id": 0}, - builder.NotIn("repo_id", builder.Select("id").From("repository")), - )). - Delete(Label{}); err != nil { - return err - } - - // delete labels with none existing orgs - if _, err := db.GetEngine(db.DefaultContext). - Where(builder.And( - builder.Gt{"org_id": 0}, - builder.NotIn("org_id", builder.Select("id").From("user")), - )). - Delete(Label{}); err != nil { - return err - } - - return nil -} - -// CountOrphanedIssueLabels return count of IssueLabels witch have no label behind anymore -func CountOrphanedIssueLabels() (int64, error) { - return db.GetEngine(db.DefaultContext).Table("issue_label"). - NotIn("label_id", builder.Select("id").From("label")). - Count() -} - -// DeleteOrphanedIssueLabels delete IssueLabels witch have no label behind anymore -func DeleteOrphanedIssueLabels() error { - _, err := db.GetEngine(db.DefaultContext). - NotIn("label_id", builder.Select("id").From("label")). - Delete(IssueLabel{}) - return err -} - -// CountOrphanedIssues count issues without a repo -func CountOrphanedIssues() (int64, error) { - return db.GetEngine(db.DefaultContext).Table("issue"). - Join("LEFT", "repository", "issue.repo_id=repository.id"). - Where(builder.IsNull{"repository.id"}). - Select("COUNT(`issue`.`id`)"). - Count() -} - -// DeleteOrphanedIssues delete issues without a repo -func DeleteOrphanedIssues() error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - var ids []int64 - - if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id"). - Join("LEFT", "repository", "issue.repo_id=repository.id"). - Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id"). - Find(&ids); err != nil { - return err - } - - var attachmentPaths []string - for i := range ids { - paths, err := deleteIssuesByRepoID(ctx, ids[i]) - if err != nil { - return err - } - attachmentPaths = append(attachmentPaths, paths...) - } - - if err := committer.Commit(); err != nil { - return err - } - committer.Close() - - // Remove issue attachment files. - for i := range attachmentPaths { - admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i]) - } - return nil -} - -// CountOrphanedObjects count subjects with have no existing refobject anymore -func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) { - return db.GetEngine(db.DefaultContext).Table("`"+subject+"`"). - Join("LEFT", "`"+refobject+"`", joinCond). - Where(builder.IsNull{"`" + refobject + "`.id"}). - Select("COUNT(`" + subject + "`.`id`)"). - Count() -} - -// DeleteOrphanedObjects delete subjects with have no existing refobject anymore -func DeleteOrphanedObjects(subject, refobject, joinCond string) error { - subQuery := builder.Select("`"+subject+"`.id"). - From("`"+subject+"`"). - Join("LEFT", "`"+refobject+"`", joinCond). - Where(builder.IsNull{"`" + refobject + "`.id"}) - sql, args, err := builder.Delete(builder.In("id", subQuery)).From("`" + subject + "`").ToSQL() - if err != nil { - return err - } - _, err = db.GetEngine(db.DefaultContext).Exec(append([]interface{}{sql}, args...)...) - return err -} - // CountNullArchivedRepository counts the number of repositories with is_archived is null func CountNullArchivedRepository() (int64, error) { return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(repo_model.Repository)) @@ -181,74 +35,6 @@ func FixWrongUserType() (int64, error) { return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&user_model.User{Type: 1}) } -// CountCommentTypeLabelWithEmptyLabel count label comments with empty label -func CountCommentTypeLabelWithEmptyLabel() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Count(new(Comment)) -} - -// FixCommentTypeLabelWithEmptyLabel count label comments with empty label -func FixCommentTypeLabelWithEmptyLabel() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Delete(new(Comment)) -} - -// CountCommentTypeLabelWithOutsideLabels count label comments with outside label -func CountCommentTypeLabelWithOutsideLabels() (int64, error) { - return db.GetEngine(db.DefaultContext).Where("comment.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))", CommentTypeLabel). - Table("comment"). - Join("inner", "label", "label.id = comment.label_id"). - Join("inner", "issue", "issue.id = comment.issue_id "). - Join("inner", "repository", "issue.repo_id = repository.id"). - Count(new(Comment)) -} - -// FixCommentTypeLabelWithOutsideLabels count label comments with outside label -func FixCommentTypeLabelWithOutsideLabels() (int64, error) { - res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM comment WHERE comment.id IN ( - SELECT il_too.id FROM ( - SELECT com.id - FROM comment AS com - INNER JOIN label ON com.label_id = label.id - INNER JOIN issue on issue.id = com.issue_id - INNER JOIN repository ON issue.repo_id = repository.id - WHERE - com.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)) - ) AS il_too)`, CommentTypeLabel) - if err != nil { - return 0, err - } - - return res.RowsAffected() -} - -// CountIssueLabelWithOutsideLabels count label comments with outside label -func CountIssueLabelWithOutsideLabels() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.Expr("(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)")). - Table("issue_label"). - Join("inner", "label", "issue_label.label_id = label.id "). - Join("inner", "issue", "issue.id = issue_label.issue_id "). - Join("inner", "repository", "issue.repo_id = repository.id"). - Count(new(IssueLabel)) -} - -// FixIssueLabelWithOutsideLabels fix label comments with outside label -func FixIssueLabelWithOutsideLabels() (int64, error) { - res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM issue_label WHERE issue_label.id IN ( - SELECT il_too.id FROM ( - SELECT il_too_too.id - FROM issue_label AS il_too_too - INNER JOIN label ON il_too_too.label_id = label.id - INNER JOIN issue on issue.id = il_too_too.issue_id - INNER JOIN repository on repository.id = issue.repo_id - WHERE - (label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id) - ) AS il_too )`) - if err != nil { - return 0, err - } - - return res.RowsAffected() -} - // CountActionCreatedUnixString count actions where created_unix is an empty string func CountActionCreatedUnixString() (int64, error) { if setting.Database.UseSQLite3 { diff --git a/models/consistency_test.go b/models/consistency_test.go deleted file mode 100644 index fb946b2fb7..0000000000 --- a/models/consistency_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2021 Gitea. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "testing" - - "code.gitea.io/gitea/models/db" - issues_model "code.gitea.io/gitea/models/issues" - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/timeutil" - - "github.com/stretchr/testify/assert" -) - -func TestDeleteOrphanedObjects(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - countBefore, err := db.GetEngine(db.DefaultContext).Count(&PullRequest{}) - assert.NoError(t, err) - - _, err = db.GetEngine(db.DefaultContext).Insert(&PullRequest{IssueID: 1000}, &PullRequest{IssueID: 1001}, &PullRequest{IssueID: 1003}) - assert.NoError(t, err) - - orphaned, err := CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id") - assert.NoError(t, err) - assert.EqualValues(t, 3, orphaned) - - err = DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id") - assert.NoError(t, err) - - countAfter, err := db.GetEngine(db.DefaultContext).Count(&PullRequest{}) - assert.NoError(t, err) - assert.EqualValues(t, countBefore, countAfter) -} - -func TestNewMilestone(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := &issues_model.Milestone{ - RepoID: 1, - Name: "milestoneName", - Content: "milestoneContent", - } - - assert.NoError(t, issues_model.NewMilestone(milestone)) - unittest.AssertExistsAndLoadBean(t, milestone) - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) -} - -func TestChangeMilestoneStatus(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) - - assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, true)) - unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1") - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) - - assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, false)) - unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=0") - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) -} - -func TestDeleteMilestoneByRepoID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, issues_model.DeleteMilestoneByRepoID(1, 1)) - unittest.AssertNotExistsBean(t, &issues_model.Milestone{ID: 1}) - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}) - - assert.NoError(t, issues_model.DeleteMilestoneByRepoID(unittest.NonexistentID, unittest.NonexistentID)) -} - -func TestUpdateMilestone(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) - milestone.Name = " newMilestoneName " - milestone.Content = "newMilestoneContent" - assert.NoError(t, issues_model.UpdateMilestone(milestone, milestone.IsClosed)) - milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) - assert.EqualValues(t, "newMilestoneName", milestone.Name) - unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) -} - -func TestUpdateMilestoneCounters(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{MilestoneID: 1}, - "is_closed=0").(*Issue) - - issue.IsClosed = true - issue.ClosedUnix = timeutil.TimeStampNow() - _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) - assert.NoError(t, err) - assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) - unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) - - issue.IsClosed = false - issue.ClosedUnix = 0 - _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) - assert.NoError(t, err) - assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) - unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) -} - -func TestConsistencyUpdateAction(t *testing.T) { - if !setting.Database.UseSQLite3 { - t.Skip("Test is only for SQLite database.") - } - assert.NoError(t, unittest.PrepareTestDatabase()) - id := 8 - unittest.AssertExistsAndLoadBean(t, &Action{ - ID: int64(id), - }) - _, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id) - assert.NoError(t, err) - actions := make([]*Action, 0, 1) - // - // XORM returns an error when created_unix is a string - // - err = db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions) - if assert.Error(t, err) { - assert.Contains(t, err.Error(), "type string to a int64: invalid syntax") - } - // - // Get rid of incorrectly set created_unix - // - count, err := CountActionCreatedUnixString() - assert.NoError(t, err) - assert.EqualValues(t, 1, count) - count, err = FixActionCreatedUnixString() - assert.NoError(t, err) - assert.EqualValues(t, 1, count) - - count, err = CountActionCreatedUnixString() - assert.NoError(t, err) - assert.EqualValues(t, 0, count) - count, err = FixActionCreatedUnixString() - assert.NoError(t, err) - assert.EqualValues(t, 0, count) - - // - // XORM must be happy now - // - assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) - unittest.CheckConsistencyFor(t, &Action{}) -} diff --git a/models/db/consistency.go b/models/db/consistency.go new file mode 100644 index 0000000000..7addb174c4 --- /dev/null +++ b/models/db/consistency.go @@ -0,0 +1,27 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package db + +import "xorm.io/builder" + +// CountOrphanedObjects count subjects with have no existing refobject anymore +func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) { + return GetEngine(DefaultContext).Table("`"+subject+"`"). + Join("LEFT", "`"+refobject+"`", joinCond). + Where(builder.IsNull{"`" + refobject + "`.id"}). + Select("COUNT(`" + subject + "`.`id`)"). + Count() +} + +// DeleteOrphanedObjects delete subjects with have no existing refobject anymore +func DeleteOrphanedObjects(subject, refobject, joinCond string) error { + subQuery := builder.Select("`"+subject+"`.id"). + From("`"+subject+"`"). + Join("LEFT", "`"+refobject+"`", joinCond). + Where(builder.IsNull{"`" + refobject + "`.id"}) + b := builder.Delete(builder.In("id", subQuery)).From("`" + subject + "`") + _, err := GetEngine(DefaultContext).Exec(b) + return err +} diff --git a/models/db/index.go b/models/db/index.go index 8598de9498..9b164db1fa 100644 --- a/models/db/index.go +++ b/models/db/index.go @@ -20,21 +20,21 @@ type ResourceIndex struct { } // UpsertResourceIndex the function will not return until it acquires the lock or receives an error. -func UpsertResourceIndex(e Engine, tableName string, groupID int64) (err error) { +func UpsertResourceIndex(ctx context.Context, tableName string, groupID int64) (err error) { // An atomic UPSERT operation (INSERT/UPDATE) is the only operation // that ensures that the key is actually locked. switch { case setting.Database.UseSQLite3 || setting.Database.UsePostgreSQL: - _, err = e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+ + _, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+ "VALUES (?,1) ON CONFLICT (group_id) DO UPDATE SET max_index = %s.max_index+1", tableName, tableName), groupID) case setting.Database.UseMySQL: - _, err = e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+ + _, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+ "VALUES (?,1) ON DUPLICATE KEY UPDATE max_index = max_index+1", tableName), groupID) case setting.Database.UseMSSQL: // https://weblogs.sqlteam.com/dang/2009/01/31/upsert-race-condition-with-merge/ - _, err = e.Exec(fmt.Sprintf("MERGE %s WITH (HOLDLOCK) as target "+ + _, err = Exec(ctx, fmt.Sprintf("MERGE %s WITH (HOLDLOCK) as target "+ "USING (SELECT ? AS group_id) AS src "+ "ON src.group_id = target.group_id "+ "WHEN MATCHED THEN UPDATE SET target.max_index = target.max_index+1 "+ @@ -82,30 +82,29 @@ func DeleteResouceIndex(ctx context.Context, tableName string, groupID int64) er // getNextResourceIndex return the next index func getNextResourceIndex(tableName string, groupID int64) (int64, error) { - sess := x.NewSession() - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, commiter, err := TxContext() + if err != nil { return 0, err } + defer commiter.Close() var preIdx int64 - _, err := sess.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&preIdx) - if err != nil { + if _, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&preIdx); err != nil { return 0, err } - if err := UpsertResourceIndex(sess, tableName, groupID); err != nil { + if err := UpsertResourceIndex(ctx, tableName, groupID); err != nil { return 0, err } var curIdx int64 - has, err := sess.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ? AND max_index=?", tableName), groupID, preIdx+1).Get(&curIdx) + has, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ? AND max_index=?", tableName), groupID, preIdx+1).Get(&curIdx) if err != nil { return 0, err } if !has { return 0, ErrResouceOutdated } - if err := sess.Commit(); err != nil { + if err := commiter.Commit(); err != nil { return 0, err } return curIdx, nil diff --git a/models/db/list_options.go b/models/db/list_options.go index 843e73c8ae..d1d52b6667 100644 --- a/models/db/list_options.go +++ b/models/db/list_options.go @@ -10,6 +10,11 @@ import ( "xorm.io/xorm" ) +const ( + // DefaultMaxInSize represents default variables number on IN () in SQL + DefaultMaxInSize = 50 +) + // Paginator is the base for different ListOptions types type Paginator interface { GetSkipTake() (skip, take int) diff --git a/models/error.go b/models/error.go index 16ae52fc43..3c617904f8 100644 --- a/models/error.go +++ b/models/error.go @@ -405,22 +405,6 @@ func (err ErrFilePathProtected) Error() string { return fmt.Sprintf("path is protected and can not be changed [path: %s]", err.Path) } -// ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo. -type ErrUserDoesNotHaveAccessToRepo struct { - UserID int64 - RepoName string -} - -// IsErrUserDoesNotHaveAccessToRepo checks if an error is a ErrRepoFileAlreadyExists. -func IsErrUserDoesNotHaveAccessToRepo(err error) bool { - _, ok := err.(ErrUserDoesNotHaveAccessToRepo) - return ok -} - -func (err ErrUserDoesNotHaveAccessToRepo) Error() string { - return fmt.Sprintf("user doesn't have access to repo [user_id: %d, repo_name: %s]", err.UserID, err.RepoName) -} - // __________ .__ // \______ \____________ ____ ____ | |__ // | | _/\_ __ \__ \ / \_/ ___\| | \ @@ -580,162 +564,6 @@ func (err ErrSHAOrCommitIDNotProvided) Error() string { return "a SHA or commit ID must be proved when updating a file" } -// .___ -// | | ______ ________ __ ____ -// | |/ ___// ___/ | \_/ __ \ -// | |\___ \ \___ \| | /\ ___/ -// |___/____ >____ >____/ \___ > -// \/ \/ \/ - -// ErrIssueNotExist represents a "IssueNotExist" kind of error. -type ErrIssueNotExist struct { - ID int64 - RepoID int64 - Index int64 -} - -// IsErrIssueNotExist checks if an error is a ErrIssueNotExist. -func IsErrIssueNotExist(err error) bool { - _, ok := err.(ErrIssueNotExist) - return ok -} - -func (err ErrIssueNotExist) Error() string { - return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) -} - -// ErrIssueIsClosed represents a "IssueIsClosed" kind of error. -type ErrIssueIsClosed struct { - ID int64 - RepoID int64 - Index int64 -} - -// IsErrIssueIsClosed checks if an error is a ErrIssueNotExist. -func IsErrIssueIsClosed(err error) bool { - _, ok := err.(ErrIssueIsClosed) - return ok -} - -func (err ErrIssueIsClosed) Error() string { - return fmt.Sprintf("issue is closed [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) -} - -// ErrNewIssueInsert is used when the INSERT statement in newIssue fails -type ErrNewIssueInsert struct { - OriginalError error -} - -// IsErrNewIssueInsert checks if an error is a ErrNewIssueInsert. -func IsErrNewIssueInsert(err error) bool { - _, ok := err.(ErrNewIssueInsert) - return ok -} - -func (err ErrNewIssueInsert) Error() string { - return err.OriginalError.Error() -} - -// ErrIssueWasClosed is used when close a closed issue -type ErrIssueWasClosed struct { - ID int64 - Index int64 -} - -// IsErrIssueWasClosed checks if an error is a ErrIssueWasClosed. -func IsErrIssueWasClosed(err error) bool { - _, ok := err.(ErrIssueWasClosed) - return ok -} - -func (err ErrIssueWasClosed) Error() string { - return fmt.Sprintf("Issue [%d] %d was already closed", err.ID, err.Index) -} - -// ErrPullWasClosed is used close a closed pull request -type ErrPullWasClosed struct { - ID int64 - Index int64 -} - -// IsErrPullWasClosed checks if an error is a ErrErrPullWasClosed. -func IsErrPullWasClosed(err error) bool { - _, ok := err.(ErrPullWasClosed) - return ok -} - -func (err ErrPullWasClosed) Error() string { - return fmt.Sprintf("Pull request [%d] %d was already closed", err.ID, err.Index) -} - -// __________ .__ .__ __________ __ -// \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_ -// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\ -// | | | | / |_| |_| | \ ___< <_| | | /\ ___/ \___ \ | | -// |____| |____/|____/____/____|_ /\___ >__ |____/ \___ >____ > |__| -// \/ \/ |__| \/ \/ - -// ErrPullRequestNotExist represents a "PullRequestNotExist" kind of error. -type ErrPullRequestNotExist struct { - ID int64 - IssueID int64 - HeadRepoID int64 - BaseRepoID int64 - HeadBranch string - BaseBranch string -} - -// IsErrPullRequestNotExist checks if an error is a ErrPullRequestNotExist. -func IsErrPullRequestNotExist(err error) bool { - _, ok := err.(ErrPullRequestNotExist) - return ok -} - -func (err ErrPullRequestNotExist) Error() string { - return fmt.Sprintf("pull request does not exist [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", - err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) -} - -// ErrPullRequestAlreadyExists represents a "PullRequestAlreadyExists"-error -type ErrPullRequestAlreadyExists struct { - ID int64 - IssueID int64 - HeadRepoID int64 - BaseRepoID int64 - HeadBranch string - BaseBranch string -} - -// IsErrPullRequestAlreadyExists checks if an error is a ErrPullRequestAlreadyExists. -func IsErrPullRequestAlreadyExists(err error) bool { - _, ok := err.(ErrPullRequestAlreadyExists) - return ok -} - -// Error does pretty-printing :D -func (err ErrPullRequestAlreadyExists) Error() string { - return fmt.Sprintf("pull request already exists for these targets [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", - err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) -} - -// ErrPullRequestHeadRepoMissing represents a "ErrPullRequestHeadRepoMissing" error -type ErrPullRequestHeadRepoMissing struct { - ID int64 - HeadRepoID int64 -} - -// IsErrErrPullRequestHeadRepoMissing checks if an error is a ErrPullRequestHeadRepoMissing. -func IsErrErrPullRequestHeadRepoMissing(err error) bool { - _, ok := err.(ErrPullRequestHeadRepoMissing) - return ok -} - -// Error does pretty-printing :D -func (err ErrPullRequestHeadRepoMissing) Error() string { - return fmt.Sprintf("pull request head repo missing [id: %d, head_repo_id: %d]", - err.ID, err.HeadRepoID) -} - // ErrInvalidMergeStyle represents an error if merging with disabled merge strategy type ErrInvalidMergeStyle struct { ID int64 @@ -830,29 +658,6 @@ func (err ErrPullRequestHasMerged) Error() string { err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) } -// _________ __ -// \_ ___ \ ____ _____ _____ ____ _____/ |_ -// / \ \/ / _ \ / \ / \_/ __ \ / \ __\ -// \ \___( <_> ) Y Y \ Y Y \ ___/| | \ | -// \______ /\____/|__|_| /__|_| /\___ >___| /__| -// \/ \/ \/ \/ \/ - -// ErrCommentNotExist represents a "CommentNotExist" kind of error. -type ErrCommentNotExist struct { - ID int64 - IssueID int64 -} - -// IsErrCommentNotExist checks if an error is a ErrCommentNotExist. -func IsErrCommentNotExist(err error) bool { - _, ok := err.(ErrCommentNotExist) - return ok -} - -func (err ErrCommentNotExist) Error() string { - return fmt.Sprintf("comment does not exist [id: %d, issue_id: %d]", err.ID, err.IssueID) -} - // _________ __ __ .__ // / _____// |_ ____ ________ _ _______ _/ |_ ____ | |__ // \_____ \\ __\/ _ \\____ \ \/ \/ /\__ \\ __\/ ___\| | \ @@ -897,60 +702,6 @@ func (err ErrTrackedTimeNotExist) Error() string { return fmt.Sprintf("tracked time does not exist [id: %d]", err.ID) } -// .____ ___. .__ -// | | _____ \_ |__ ____ | | -// | | \__ \ | __ \_/ __ \| | -// | |___ / __ \| \_\ \ ___/| |__ -// |_______ (____ /___ /\___ >____/ -// \/ \/ \/ \/ - -// ErrRepoLabelNotExist represents a "RepoLabelNotExist" kind of error. -type ErrRepoLabelNotExist struct { - LabelID int64 - RepoID int64 -} - -// IsErrRepoLabelNotExist checks if an error is a RepoErrLabelNotExist. -func IsErrRepoLabelNotExist(err error) bool { - _, ok := err.(ErrRepoLabelNotExist) - return ok -} - -func (err ErrRepoLabelNotExist) Error() string { - return fmt.Sprintf("label does not exist [label_id: %d, repo_id: %d]", err.LabelID, err.RepoID) -} - -// ErrOrgLabelNotExist represents a "OrgLabelNotExist" kind of error. -type ErrOrgLabelNotExist struct { - LabelID int64 - OrgID int64 -} - -// IsErrOrgLabelNotExist checks if an error is a OrgErrLabelNotExist. -func IsErrOrgLabelNotExist(err error) bool { - _, ok := err.(ErrOrgLabelNotExist) - return ok -} - -func (err ErrOrgLabelNotExist) Error() string { - return fmt.Sprintf("label does not exist [label_id: %d, org_id: %d]", err.LabelID, err.OrgID) -} - -// ErrLabelNotExist represents a "LabelNotExist" kind of error. -type ErrLabelNotExist struct { - LabelID int64 -} - -// IsErrLabelNotExist checks if an error is a ErrLabelNotExist. -func IsErrLabelNotExist(err error) bool { - _, ok := err.(ErrLabelNotExist) - return ok -} - -func (err ErrLabelNotExist) Error() string { - return fmt.Sprintf("label does not exist [label_id: %d]", err.LabelID) -} - // ____ ___ .__ .___ // | | \______ | | _________ __| _/ // | | /\____ \| | / _ \__ \ / __ | @@ -974,130 +725,3 @@ func IsErrUploadNotExist(err error) bool { func (err ErrUploadNotExist) Error() string { return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) } - -// .___ ________ .___ .__ -// | | ______ ________ __ ____ \______ \ ____ ______ ____ ____ __| _/____ ____ ____ |__| ____ ______ -// | |/ ___// ___/ | \_/ __ \ | | \_/ __ \\____ \_/ __ \ / \ / __ |/ __ \ / \_/ ___\| |/ __ \ / ___/ -// | |\___ \ \___ \| | /\ ___/ | ` \ ___/| |_> > ___/| | \/ /_/ \ ___/| | \ \___| \ ___/ \___ \ -// |___/____ >____ >____/ \___ >_______ /\___ > __/ \___ >___| /\____ |\___ >___| /\___ >__|\___ >____ > -// \/ \/ \/ \/ \/|__| \/ \/ \/ \/ \/ \/ \/ \/ - -// ErrDependencyExists represents a "DependencyAlreadyExists" kind of error. -type ErrDependencyExists struct { - IssueID int64 - DependencyID int64 -} - -// IsErrDependencyExists checks if an error is a ErrDependencyExists. -func IsErrDependencyExists(err error) bool { - _, ok := err.(ErrDependencyExists) - return ok -} - -func (err ErrDependencyExists) Error() string { - return fmt.Sprintf("issue dependency does already exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) -} - -// ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error. -type ErrDependencyNotExists struct { - IssueID int64 - DependencyID int64 -} - -// IsErrDependencyNotExists checks if an error is a ErrDependencyExists. -func IsErrDependencyNotExists(err error) bool { - _, ok := err.(ErrDependencyNotExists) - return ok -} - -func (err ErrDependencyNotExists) Error() string { - return fmt.Sprintf("issue dependency does not exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) -} - -// ErrCircularDependency represents a "DependencyCircular" kind of error. -type ErrCircularDependency struct { - IssueID int64 - DependencyID int64 -} - -// IsErrCircularDependency checks if an error is a ErrCircularDependency. -func IsErrCircularDependency(err error) bool { - _, ok := err.(ErrCircularDependency) - return ok -} - -func (err ErrCircularDependency) Error() string { - return fmt.Sprintf("circular dependencies exists (two issues blocking each other) [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) -} - -// ErrDependenciesLeft represents an error where the issue you're trying to close still has dependencies left. -type ErrDependenciesLeft struct { - IssueID int64 -} - -// IsErrDependenciesLeft checks if an error is a ErrDependenciesLeft. -func IsErrDependenciesLeft(err error) bool { - _, ok := err.(ErrDependenciesLeft) - return ok -} - -func (err ErrDependenciesLeft) Error() string { - return fmt.Sprintf("issue has open dependencies [issue id: %d]", err.IssueID) -} - -// ErrUnknownDependencyType represents an error where an unknown dependency type was passed -type ErrUnknownDependencyType struct { - Type DependencyType -} - -// IsErrUnknownDependencyType checks if an error is ErrUnknownDependencyType -func IsErrUnknownDependencyType(err error) bool { - _, ok := err.(ErrUnknownDependencyType) - return ok -} - -func (err ErrUnknownDependencyType) Error() string { - return fmt.Sprintf("unknown dependency type [type: %d]", err.Type) -} - -// __________ .__ -// \______ \ _______ _|__| ______ _ __ -// | _// __ \ \/ / |/ __ \ \/ \/ / -// | | \ ___/\ /| \ ___/\ / -// |____|_ /\___ >\_/ |__|\___ >\/\_/ -// \/ \/ \/ - -// ErrReviewNotExist represents a "ReviewNotExist" kind of error. -type ErrReviewNotExist struct { - ID int64 -} - -// IsErrReviewNotExist checks if an error is a ErrReviewNotExist. -func IsErrReviewNotExist(err error) bool { - _, ok := err.(ErrReviewNotExist) - return ok -} - -func (err ErrReviewNotExist) Error() string { - return fmt.Sprintf("review does not exist [id: %d]", err.ID) -} - -// ErrNotValidReviewRequest an not allowed review request modify -type ErrNotValidReviewRequest struct { - Reason string - UserID int64 - RepoID int64 -} - -// IsErrNotValidReviewRequest checks if an error is a ErrNotValidReviewRequest. -func IsErrNotValidReviewRequest(err error) bool { - _, ok := err.(ErrNotValidReviewRequest) - return ok -} - -func (err ErrNotValidReviewRequest) Error() string { - return fmt.Sprintf("%s [user_id: %d, repo_id: %d]", - err.Reason, - err.UserID, - err.RepoID) -} diff --git a/models/git/branches_test.go b/models/git/branches_test.go index 1e0b1a98b6..8102d28d48 100644 --- a/models/git/branches_test.go +++ b/models/git/branches_test.go @@ -7,9 +7,9 @@ package git_test import ( "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -120,10 +120,10 @@ func TestRenameBranch(t *testing.T) { repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) assert.Equal(t, "main", repo1.DefaultBranch) - pull := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 1}).(*models.PullRequest) // merged + pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) // merged assert.Equal(t, "master", pull.BaseBranch) - pull = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) // open + pull = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) // open assert.Equal(t, "main", pull.BaseBranch) renamedBranch := unittest.AssertExistsAndLoadBean(t, &git_model.RenamedBranch{ID: 2}).(*git_model.RenamedBranch) diff --git a/models/git/main_test.go b/models/git/main_test.go index 02401e5204..dc30dfaad7 100644 --- a/models/git/main_test.go +++ b/models/git/main_test.go @@ -8,6 +8,7 @@ import ( "path/filepath" "testing" + _ "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/unittest" ) diff --git a/models/issue_label_test.go b/models/issue_label_test.go deleted file mode 100644 index 67a09151d8..0000000000 --- a/models/issue_label_test.go +++ /dev/null @@ -1,394 +0,0 @@ -// Copyright 2017 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "html/template" - "testing" - - "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" - - "github.com/stretchr/testify/assert" -) - -// TODO TestGetLabelTemplateFile - -func TestLabel_CalOpenIssues(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - label.CalOpenIssues() - assert.EqualValues(t, 2, label.NumOpenIssues) -} - -func TestLabel_ForegroundColor(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - assert.Equal(t, template.CSS("#000"), label.ForegroundColor()) - - label = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - assert.Equal(t, template.CSS("#fff"), label.ForegroundColor()) -} - -func TestNewLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labels := []*Label{ - {RepoID: 2, Name: "labelName2", Color: "#123456"}, - {RepoID: 3, Name: "labelName3", Color: "#123"}, - {RepoID: 4, Name: "labelName4", Color: "ABCDEF"}, - {RepoID: 5, Name: "labelName5", Color: "DEF"}, - } - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: ""})) - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "#45G"})) - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"})) - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "45G"})) - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "12345G"})) - for _, label := range labels { - unittest.AssertNotExistsBean(t, label) - } - assert.NoError(t, NewLabels(labels...)) - for _, label := range labels { - unittest.AssertExistsAndLoadBean(t, label, unittest.Cond("id = ?", label.ID)) - } - unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{}) -} - -func TestGetLabelByID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelByID(db.DefaultContext, 1) - assert.NoError(t, err) - assert.EqualValues(t, 1, label.ID) - - _, err = GetLabelByID(db.DefaultContext, unittest.NonexistentID) - assert.True(t, IsErrLabelNotExist(err)) -} - -func TestGetLabelInRepoByName(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelInRepoByName(db.DefaultContext, 1, "label1") - assert.NoError(t, err) - assert.EqualValues(t, 1, label.ID) - assert.Equal(t, "label1", label.Name) - - _, err = GetLabelInRepoByName(db.DefaultContext, 1, "") - assert.True(t, IsErrRepoLabelNotExist(err)) - - _, err = GetLabelInRepoByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") - assert.True(t, IsErrRepoLabelNotExist(err)) -} - -func TestGetLabelInRepoByNames(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labelIDs, err := GetLabelIDsInRepoByNames(1, []string{"label1", "label2"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(1), labelIDs[0]) - assert.Equal(t, int64(2), labelIDs[1]) -} - -func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - // label3 doesn't exists.. See labels.yml - labelIDs, err := GetLabelIDsInRepoByNames(1, []string{"label1", "label2", "label3"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(1), labelIDs[0]) - assert.Equal(t, int64(2), labelIDs[1]) - assert.NoError(t, err) -} - -func TestGetLabelInRepoByID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelInRepoByID(db.DefaultContext, 1, 1) - assert.NoError(t, err) - assert.EqualValues(t, 1, label.ID) - - _, err = GetLabelInRepoByID(db.DefaultContext, 1, -1) - assert.True(t, IsErrRepoLabelNotExist(err)) - - _, err = GetLabelInRepoByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) - assert.True(t, IsErrRepoLabelNotExist(err)) -} - -func TestGetLabelsInRepoByIDs(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := GetLabelsInRepoByIDs(1, []int64{1, 2, unittest.NonexistentID}) - assert.NoError(t, err) - if assert.Len(t, labels, 2) { - assert.EqualValues(t, 1, labels[0].ID) - assert.EqualValues(t, 2, labels[1].ID) - } -} - -func TestGetLabelsByRepoID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) { - labels, err := GetLabelsByRepoID(db.DefaultContext, repoID, sortType, db.ListOptions{}) - assert.NoError(t, err) - assert.Len(t, labels, len(expectedIssueIDs)) - for i, label := range labels { - assert.EqualValues(t, expectedIssueIDs[i], label.ID) - } - } - testSuccess(1, "leastissues", []int64{2, 1}) - testSuccess(1, "mostissues", []int64{1, 2}) - testSuccess(1, "reversealphabetically", []int64{2, 1}) - testSuccess(1, "default", []int64{1, 2}) -} - -// Org versions - -func TestGetLabelInOrgByName(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelInOrgByName(db.DefaultContext, 3, "orglabel3") - assert.NoError(t, err) - assert.EqualValues(t, 3, label.ID) - assert.Equal(t, "orglabel3", label.Name) - - _, err = GetLabelInOrgByName(db.DefaultContext, 3, "") - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByName(db.DefaultContext, 0, "orglabel3") - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByName(db.DefaultContext, -1, "orglabel3") - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") - assert.True(t, IsErrOrgLabelNotExist(err)) -} - -func TestGetLabelInOrgByNames(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labelIDs, err := GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(3), labelIDs[0]) - assert.Equal(t, int64(4), labelIDs[1]) -} - -func TestGetLabelInOrgByNamesDiscardsNonExistentLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - // orglabel99 doesn't exists.. See labels.yml - labelIDs, err := GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4", "orglabel99"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(3), labelIDs[0]) - assert.Equal(t, int64(4), labelIDs[1]) - assert.NoError(t, err) -} - -func TestGetLabelInOrgByID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelInOrgByID(db.DefaultContext, 3, 3) - assert.NoError(t, err) - assert.EqualValues(t, 3, label.ID) - - _, err = GetLabelInOrgByID(db.DefaultContext, 3, -1) - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByID(db.DefaultContext, 0, 3) - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByID(db.DefaultContext, -1, 3) - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) - assert.True(t, IsErrOrgLabelNotExist(err)) -} - -func TestGetLabelsInOrgByIDs(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := GetLabelsInOrgByIDs(3, []int64{3, 4, unittest.NonexistentID}) - assert.NoError(t, err) - if assert.Len(t, labels, 2) { - assert.EqualValues(t, 3, labels[0].ID) - assert.EqualValues(t, 4, labels[1].ID) - } -} - -func TestGetLabelsByOrgID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - testSuccess := func(orgID int64, sortType string, expectedIssueIDs []int64) { - labels, err := GetLabelsByOrgID(db.DefaultContext, orgID, sortType, db.ListOptions{}) - assert.NoError(t, err) - assert.Len(t, labels, len(expectedIssueIDs)) - for i, label := range labels { - assert.EqualValues(t, expectedIssueIDs[i], label.ID) - } - } - testSuccess(3, "leastissues", []int64{3, 4}) - testSuccess(3, "mostissues", []int64{4, 3}) - testSuccess(3, "reversealphabetically", []int64{4, 3}) - testSuccess(3, "default", []int64{3, 4}) - - var err error - _, err = GetLabelsByOrgID(db.DefaultContext, 0, "leastissues", db.ListOptions{}) - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelsByOrgID(db.DefaultContext, -1, "leastissues", db.ListOptions{}) - assert.True(t, IsErrOrgLabelNotExist(err)) -} - -// - -func TestGetLabelsByIssueID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := GetLabelsByIssueID(db.DefaultContext, 1) - assert.NoError(t, err) - if assert.Len(t, labels, 1) { - assert.EqualValues(t, 1, labels[0].ID) - } - - labels, err = GetLabelsByIssueID(db.DefaultContext, unittest.NonexistentID) - assert.NoError(t, err) - assert.Len(t, labels, 0) -} - -func TestUpdateLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - // make sure update wont overwrite it - update := &Label{ - ID: label.ID, - Color: "#ffff00", - Name: "newLabelName", - Description: label.Description, - } - label.Color = update.Color - label.Name = update.Name - assert.NoError(t, UpdateLabel(update)) - newLabel := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - assert.EqualValues(t, label.ID, newLabel.ID) - assert.EqualValues(t, label.Color, newLabel.Color) - assert.EqualValues(t, label.Name, newLabel.Name) - assert.EqualValues(t, label.Description, newLabel.Description) - unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{}) -} - -func TestDeleteLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - assert.NoError(t, DeleteLabel(label.RepoID, label.ID)) - unittest.AssertNotExistsBean(t, &Label{ID: label.ID, RepoID: label.RepoID}) - - assert.NoError(t, DeleteLabel(label.RepoID, label.ID)) - unittest.AssertNotExistsBean(t, &Label{ID: label.ID}) - - assert.NoError(t, DeleteLabel(unittest.NonexistentID, unittest.NonexistentID)) - unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{}) -} - -func TestHasIssueLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - assert.True(t, HasIssueLabel(db.DefaultContext, 1, 1)) - assert.False(t, HasIssueLabel(db.DefaultContext, 1, 2)) - assert.False(t, HasIssueLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) -} - -func TestNewIssueLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - - // add new IssueLabel - prevNumIssues := label.NumIssues - assert.NoError(t, NewIssueLabel(issue, label, doer)) - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label.ID}) - unittest.AssertExistsAndLoadBean(t, &Comment{ - Type: CommentTypeLabel, - PosterID: doer.ID, - IssueID: issue.ID, - LabelID: label.ID, - Content: "1", - }) - label = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - assert.EqualValues(t, prevNumIssues+1, label.NumIssues) - - // re-add existing IssueLabel - assert.NoError(t, NewIssueLabel(issue, label, doer)) - unittest.CheckConsistencyFor(t, &Issue{}, &Label{}) -} - -func TestNewIssueLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label1 := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - label2 := unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 5}).(*Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - - assert.NoError(t, NewIssueLabels(issue, []*Label{label1, label2}, doer)) - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) - unittest.AssertExistsAndLoadBean(t, &Comment{ - Type: CommentTypeLabel, - PosterID: doer.ID, - IssueID: issue.ID, - LabelID: label1.ID, - Content: "1", - }) - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) - label1 = unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - assert.EqualValues(t, 3, label1.NumIssues) - assert.EqualValues(t, 1, label1.NumClosedIssues) - label2 = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - assert.EqualValues(t, 1, label2.NumIssues) - assert.EqualValues(t, 1, label2.NumClosedIssues) - - // corner case: test empty slice - assert.NoError(t, NewIssueLabels(issue, []*Label{}, doer)) - - unittest.CheckConsistencyFor(t, &Issue{}, &Label{}) -} - -func TestDeleteIssueLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - testSuccess := func(labelID, issueID, doerID int64) { - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issueID}).(*Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID}).(*user_model.User) - - expectedNumIssues := label.NumIssues - expectedNumClosedIssues := label.NumClosedIssues - if unittest.BeanExists(t, &IssueLabel{IssueID: issueID, LabelID: labelID}) { - expectedNumIssues-- - if issue.IsClosed { - expectedNumClosedIssues-- - } - } - - ctx, committer, err := db.TxContext() - defer committer.Close() - assert.NoError(t, err) - assert.NoError(t, DeleteIssueLabel(ctx, issue, label, doer)) - assert.NoError(t, committer.Commit()) - - unittest.AssertNotExistsBean(t, &IssueLabel{IssueID: issueID, LabelID: labelID}) - unittest.AssertExistsAndLoadBean(t, &Comment{ - Type: CommentTypeLabel, - PosterID: doerID, - IssueID: issueID, - LabelID: labelID, - }, `content=""`) - label = unittest.AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label) - assert.EqualValues(t, expectedNumIssues, label.NumIssues) - assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues) - } - testSuccess(1, 1, 2) - testSuccess(2, 5, 2) - testSuccess(1, 1, 2) // delete non-existent IssueLabel - - unittest.CheckConsistencyFor(t, &Issue{}, &Label{}) -} diff --git a/models/issue_stopwatch_test.go b/models/issue_stopwatch_test.go deleted file mode 100644 index 15d5f234fd..0000000000 --- a/models/issue_stopwatch_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "testing" - - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/timeutil" - - "github.com/stretchr/testify/assert" -) - -func TestCancelStopwatch(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - user1, err := user_model.GetUserByID(1) - assert.NoError(t, err) - - issue1, err := GetIssueByID(1) - assert.NoError(t, err) - issue2, err := GetIssueByID(2) - assert.NoError(t, err) - - err = CancelStopwatch(user1, issue1) - assert.NoError(t, err) - unittest.AssertNotExistsBean(t, &Stopwatch{UserID: user1.ID, IssueID: issue1.ID}) - - _ = unittest.AssertExistsAndLoadBean(t, &Comment{Type: CommentTypeCancelTracking, PosterID: user1.ID, IssueID: issue1.ID}) - - assert.Nil(t, CancelStopwatch(user1, issue2)) -} - -func TestStopwatchExists(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - assert.True(t, StopwatchExists(1, 1)) - assert.False(t, StopwatchExists(1, 2)) -} - -func TestHasUserStopwatch(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - exists, sw, err := HasUserStopwatch(db.DefaultContext, 1) - assert.NoError(t, err) - assert.True(t, exists) - assert.Equal(t, int64(1), sw.ID) - - exists, _, err = HasUserStopwatch(db.DefaultContext, 3) - assert.NoError(t, err) - assert.False(t, exists) -} - -func TestCreateOrStopIssueStopwatch(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - user2, err := user_model.GetUserByID(2) - assert.NoError(t, err) - user3, err := user_model.GetUserByID(3) - assert.NoError(t, err) - - issue1, err := GetIssueByID(1) - assert.NoError(t, err) - issue2, err := GetIssueByID(2) - assert.NoError(t, err) - - assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1)) - sw := unittest.AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch) - assert.LessOrEqual(t, sw.CreatedUnix, timeutil.TimeStampNow()) - - assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2)) - unittest.AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2}) - unittest.AssertExistsAndLoadBean(t, &TrackedTime{UserID: 2, IssueID: 2}) -} diff --git a/models/issue_user_test.go b/models/issue_user_test.go deleted file mode 100644 index 946da6e18d..0000000000 --- a/models/issue_user_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2017 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "testing" - - "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unittest" - - "github.com/stretchr/testify/assert" -) - -func Test_newIssueUsers(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - newIssue := &Issue{ - RepoID: repo.ID, - PosterID: 4, - Index: 6, - Title: "newTestIssueTitle", - Content: "newTestIssueContent", - } - - // artificially insert new issue - unittest.AssertSuccessfulInsert(t, newIssue) - - assert.NoError(t, newIssueUsers(db.DefaultContext, repo, newIssue)) - - // issue_user table should now have entries for new issue - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: newIssue.ID, UID: newIssue.PosterID}) - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: newIssue.ID, UID: repo.OwnerID}) -} - -func TestUpdateIssueUserByRead(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) - - assert.NoError(t, UpdateIssueUserByRead(4, issue.ID)) - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") - - assert.NoError(t, UpdateIssueUserByRead(4, issue.ID)) - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") - - assert.NoError(t, UpdateIssueUserByRead(unittest.NonexistentID, unittest.NonexistentID)) -} - -func TestUpdateIssueUsersByMentions(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) - - uids := []int64{2, 5} - assert.NoError(t, UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids)) - for _, uid := range uids { - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: issue.ID, UID: uid}, "is_mentioned=1") - } -} diff --git a/models/issue_assignees.go b/models/issues/assignees.go index c6ccb6e9d2..5921112fea 100644 --- a/models/issue_assignees.go +++ b/models/issues/assignees.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" diff --git a/models/issue_assignees_test.go b/models/issues/assignees_test.go index 80317e1604..37d966f140 100644 --- a/models/issue_assignees_test.go +++ b/models/issues/assignees_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -18,27 +19,27 @@ func TestUpdateAssignee(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Fake issue with assignees - issue, err := GetIssueWithAttrsByID(1) + issue, err := issues_model.GetIssueWithAttrsByID(1) assert.NoError(t, err) // Assign multiple users user2, err := user_model.GetUserByID(2) assert.NoError(t, err) - _, _, err = ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user2.ID) + _, _, err = issues_model.ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user2.ID) assert.NoError(t, err) user3, err := user_model.GetUserByID(3) assert.NoError(t, err) - _, _, err = ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user3.ID) + _, _, err = issues_model.ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user3.ID) assert.NoError(t, err) user1, err := user_model.GetUserByID(1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him assert.NoError(t, err) - _, _, err = ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user1.ID) + _, _, err = issues_model.ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user1.ID) assert.NoError(t, err) // Check if he got removed - isAssigned, err := IsUserAssignedToIssue(db.DefaultContext, issue, user1) + isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user1) assert.NoError(t, err) assert.False(t, isAssigned) @@ -54,12 +55,12 @@ func TestUpdateAssignee(t *testing.T) { } // Check if the user is assigned - isAssigned, err = IsUserAssignedToIssue(db.DefaultContext, issue, user2) + isAssigned, err = issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user2) assert.NoError(t, err) assert.True(t, isAssigned) // This user should not be assigned - isAssigned, err = IsUserAssignedToIssue(db.DefaultContext, issue, &user_model.User{ID: 4}) + isAssigned, err = issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, &user_model.User{ID: 4}) assert.NoError(t, err) assert.False(t, isAssigned) } @@ -70,22 +71,22 @@ func TestMakeIDsFromAPIAssigneesToAdd(t *testing.T) { _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - IDs, err := MakeIDsFromAPIAssigneesToAdd("", []string{""}) + IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{""}) assert.NoError(t, err) assert.Equal(t, []int64{}, IDs) - _, err = MakeIDsFromAPIAssigneesToAdd("", []string{"none_existing_user"}) + _, err = issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{"none_existing_user"}) assert.Error(t, err) - IDs, err = MakeIDsFromAPIAssigneesToAdd("user1", []string{"user1"}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("user1", []string{"user1"}) assert.NoError(t, err) assert.Equal(t, []int64{1}, IDs) - IDs, err = MakeIDsFromAPIAssigneesToAdd("user2", []string{""}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("user2", []string{""}) assert.NoError(t, err) assert.Equal(t, []int64{2}, IDs) - IDs, err = MakeIDsFromAPIAssigneesToAdd("", []string{"user1", "user2"}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{"user1", "user2"}) assert.NoError(t, err) assert.Equal(t, []int64{1, 2}, IDs) } diff --git a/models/issue_comment.go b/models/issues/comment.go index 21cd87108d..a4e69e7118 100644 --- a/models/issue_comment.go +++ b/models/issues/comment.go @@ -4,7 +4,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -16,7 +16,6 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" - issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo" @@ -34,6 +33,22 @@ import ( "xorm.io/xorm" ) +// ErrCommentNotExist represents a "CommentNotExist" kind of error. +type ErrCommentNotExist struct { + ID int64 + IssueID int64 +} + +// IsErrCommentNotExist checks if an error is a ErrCommentNotExist. +func IsErrCommentNotExist(err error) bool { + _, ok := err.(ErrCommentNotExist) + return ok +} + +func (err ErrCommentNotExist) Error() string { + return fmt.Sprintf("comment does not exist [id: %d, issue_id: %d]", err.ID, err.IssueID) +} + // CommentType defines whether a comment is just a simple comment, an action (like close) or a reference. type CommentType int @@ -216,8 +231,8 @@ type Comment struct { Project *project_model.Project `xorm:"-"` OldMilestoneID int64 MilestoneID int64 - OldMilestone *issues_model.Milestone `xorm:"-"` - Milestone *issues_model.Milestone `xorm:"-"` + OldMilestone *Milestone `xorm:"-"` + Milestone *Milestone `xorm:"-"` TimeID int64 Time *TrackedTime `xorm:"-"` AssigneeID int64 @@ -250,8 +265,8 @@ type Comment struct { // Reference issue in commit message CommitSHA string `xorm:"VARCHAR(40)"` - Attachments []*repo_model.Attachment `xorm:"-"` - Reactions issues_model.ReactionList `xorm:"-"` + Attachments []*repo_model.Attachment `xorm:"-"` + Reactions ReactionList `xorm:"-"` // For view issue page. ShowRole RoleDescriptor `xorm:"-"` @@ -299,7 +314,7 @@ func (c *Comment) LoadIssueCtx(ctx context.Context) (err error) { if c.Issue != nil { return nil } - c.Issue, err = getIssueByID(ctx, c.IssueID) + c.Issue, err = GetIssueByID(ctx, c.IssueID) return } @@ -503,7 +518,7 @@ func (c *Comment) LoadProject() error { // LoadMilestone if comment.Type is CommentTypeMilestone, then load milestone func (c *Comment) LoadMilestone() error { if c.OldMilestoneID > 0 { - var oldMilestone issues_model.Milestone + var oldMilestone Milestone has, err := db.GetEngine(db.DefaultContext).ID(c.OldMilestoneID).Get(&oldMilestone) if err != nil { return err @@ -513,7 +528,7 @@ func (c *Comment) LoadMilestone() error { } if c.MilestoneID > 0 { - var milestone issues_model.Milestone + var milestone Milestone has, err := db.GetEngine(db.DefaultContext).ID(c.MilestoneID).Get(&milestone) if err != nil { return err @@ -625,7 +640,7 @@ func (c *Comment) LoadDepIssueDetails() (err error) { if c.DependentIssueID <= 0 || c.DependentIssue != nil { return nil } - c.DependentIssue, err = getIssueByID(db.DefaultContext, c.DependentIssueID) + c.DependentIssue, err = GetIssueByID(db.DefaultContext, c.DependentIssueID) return err } @@ -643,7 +658,7 @@ func (c *Comment) loadReactions(ctx context.Context, repo *repo_model.Repository if c.Reactions != nil { return nil } - c.Reactions, _, err = issues_model.FindReactions(ctx, issues_model.FindReactionsOptions{ + c.Reactions, _, err = FindReactions(ctx, FindReactionsOptions{ IssueID: c.IssueID, CommentID: c.ID, }) @@ -823,7 +838,7 @@ func CreateCommentCtx(ctx context.Context, opts *CreateCommentOptions) (_ *Comme return nil, err } - if err = comment.addCrossReferences(ctx, opts.Doer, false); err != nil { + if err = comment.AddCrossReferences(ctx, opts.Doer, false); err != nil { return nil, err } @@ -1128,7 +1143,7 @@ func UpdateComment(c *Comment, doer *user_model.User) error { if err := c.LoadIssueCtx(ctx); err != nil { return err } - if err := c.addCrossReferences(ctx, doer, true); err != nil { + if err := c.AddCrossReferences(ctx, doer, true); err != nil { return err } if err := committer.Commit(); err != nil { @@ -1139,27 +1154,13 @@ func UpdateComment(c *Comment, doer *user_model.User) error { } // DeleteComment deletes the comment -func DeleteComment(comment *Comment) error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err := deleteComment(ctx, comment); err != nil { - return err - } - - return committer.Commit() -} - -func deleteComment(ctx context.Context, comment *Comment) error { +func DeleteComment(ctx context.Context, comment *Comment) error { e := db.GetEngine(ctx) if _, err := e.ID(comment.ID).NoAutoCondition().Delete(comment); err != nil { return err } - if _, err := db.DeleteByBean(ctx, &issues_model.ContentHistory{ + if _, err := db.DeleteByBean(ctx, &ContentHistory{ CommentID: comment.ID, }); err != nil { return err @@ -1170,7 +1171,11 @@ func deleteComment(ctx context.Context, comment *Comment) error { return err } } - if _, err := e.Where("comment_id = ?", comment.ID).Cols("is_deleted").Update(&Action{IsDeleted: true}); err != nil { + if _, err := e.Table("action"). + Where("comment_id = ?", comment.ID). + Update(map[string]interface{}{ + "is_deleted": true, + }); err != nil { return err } @@ -1178,7 +1183,7 @@ func deleteComment(ctx context.Context, comment *Comment) error { return err } - return issues_model.DeleteReaction(ctx, &issues_model.ReactionOptions{CommentID: comment.ID}) + return DeleteReaction(ctx, &ReactionOptions{CommentID: comment.ID}) } // CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS @@ -1500,3 +1505,42 @@ func (c *Comment) GetExternalName() string { return c.OriginalAuthor } // GetExternalID ExternalUserRemappable interface func (c *Comment) GetExternalID() int64 { return c.OriginalAuthorID } + +// CountCommentTypeLabelWithEmptyLabel count label comments with empty label +func CountCommentTypeLabelWithEmptyLabel() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Count(new(Comment)) +} + +// FixCommentTypeLabelWithEmptyLabel count label comments with empty label +func FixCommentTypeLabelWithEmptyLabel() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Delete(new(Comment)) +} + +// CountCommentTypeLabelWithOutsideLabels count label comments with outside label +func CountCommentTypeLabelWithOutsideLabels() (int64, error) { + return db.GetEngine(db.DefaultContext).Where("comment.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))", CommentTypeLabel). + Table("comment"). + Join("inner", "label", "label.id = comment.label_id"). + Join("inner", "issue", "issue.id = comment.issue_id "). + Join("inner", "repository", "issue.repo_id = repository.id"). + Count() +} + +// FixCommentTypeLabelWithOutsideLabels count label comments with outside label +func FixCommentTypeLabelWithOutsideLabels() (int64, error) { + res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM comment WHERE comment.id IN ( + SELECT il_too.id FROM ( + SELECT com.id + FROM comment AS com + INNER JOIN label ON com.label_id = label.id + INNER JOIN issue on issue.id = com.issue_id + INNER JOIN repository ON issue.repo_id = repository.id + WHERE + com.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)) + ) AS il_too)`, CommentTypeLabel) + if err != nil { + return 0, err + } + + return res.RowsAffected() +} diff --git a/models/issue_comment_list.go b/models/issues/comment_list.go index d62984c1e6..e3406a5cbe 100644 --- a/models/issue_comment_list.go +++ b/models/issues/comment_list.go @@ -2,13 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" "code.gitea.io/gitea/models/db" - issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" @@ -36,7 +35,7 @@ func (comments CommentList) loadPosters(ctx context.Context) error { posterMaps := make(map[int64]*user_model.User, len(posterIDs)) left := len(posterIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -80,7 +79,7 @@ func (comments CommentList) getLabelIDs() []int64 { return container.KeysInt64(ids) } -func (comments CommentList) loadLabels(ctx context.Context) error { +func (comments CommentList) loadLabels(ctx context.Context) error { //nolint if len(comments) == 0 { return nil } @@ -89,7 +88,7 @@ func (comments CommentList) loadLabels(ctx context.Context) error { commentLabels := make(map[int64]*Label, len(labelIDs)) left := len(labelIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -140,10 +139,10 @@ func (comments CommentList) loadMilestones(ctx context.Context) error { return nil } - milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -183,10 +182,10 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error { return nil } - milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -225,7 +224,7 @@ func (comments CommentList) loadAssignees(ctx context.Context) error { assignees := make(map[int64]*user_model.User, len(assigneeIDs)) left := len(assigneeIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -299,7 +298,7 @@ func (comments CommentList) loadIssues(ctx context.Context) error { issues := make(map[int64]*Issue, len(issueIDs)) left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -357,7 +356,7 @@ func (comments CommentList) loadDependentIssues(ctx context.Context) error { issues := make(map[int64]*Issue, len(issueIDs)) left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -406,7 +405,7 @@ func (comments CommentList) loadAttachments(ctx context.Context) (err error) { commentsIDs := comments.getCommentIDs() left := len(commentsIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -449,7 +448,7 @@ func (comments CommentList) getReviewIDs() []int64 { return container.KeysInt64(ids) } -func (comments CommentList) loadReviews(ctx context.Context) error { +func (comments CommentList) loadReviews(ctx context.Context) error { //nolint if len(comments) == 0 { return nil } @@ -458,7 +457,7 @@ func (comments CommentList) loadReviews(ctx context.Context) error { reviews := make(map[int64]*Review, len(reviewIDs)) left := len(reviewIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } diff --git a/models/issue_comment_test.go b/models/issues/comment_test.go index d323a08167..06b0b85e3c 100644 --- a/models/issue_comment_test.go +++ b/models/issues/comment_test.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "time" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -19,13 +20,13 @@ import ( func TestCreateComment(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) now := time.Now().Unix() - comment, err := CreateComment(&CreateCommentOptions{ - Type: CommentTypeComment, + comment, err := issues_model.CreateComment(&issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeComment, Doer: doer, Repo: repo, Issue: issue, @@ -34,23 +35,23 @@ func TestCreateComment(t *testing.T) { assert.NoError(t, err) then := time.Now().Unix() - assert.EqualValues(t, CommentTypeComment, comment.Type) + assert.EqualValues(t, issues_model.CommentTypeComment, comment.Type) assert.EqualValues(t, "Hello", comment.Content) assert.EqualValues(t, issue.ID, comment.IssueID) assert.EqualValues(t, doer.ID, comment.PosterID) unittest.AssertInt64InRange(t, now, then, int64(comment.CreatedUnix)) unittest.AssertExistsAndLoadBean(t, comment) // assert actually added to DB - updatedIssue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) + updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}).(*issues_model.Issue) unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) } func TestFetchCodeComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - res, err := FetchCodeComments(db.DefaultContext, issue, user) + res, err := issues_model.FetchCodeComments(db.DefaultContext, issue, user) assert.NoError(t, err) assert.Contains(t, res, "README.md") assert.Contains(t, res["README.md"], int64(4)) @@ -58,7 +59,7 @@ func TestFetchCodeComments(t *testing.T) { assert.Equal(t, int64(4), res["README.md"][4][0].ID) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - res, err = FetchCodeComments(db.DefaultContext, issue, user2) + res, err = issues_model.FetchCodeComments(db.DefaultContext, issue, user2) assert.NoError(t, err) assert.Len(t, res, 1) } diff --git a/models/issues/content_history.go b/models/issues/content_history.go index 4c5af13db7..3e321784bd 100644 --- a/models/issues/content_history.go +++ b/models/issues/content_history.go @@ -53,13 +53,13 @@ func SaveIssueContentHistory(ctx context.Context, posterID, issueID, commentID i } // We only keep at most 20 history revisions now. It is enough in most cases. // If there is a special requirement to keep more, we can consider introducing a new setting option then, but not now. - keepLimitedContentHistory(ctx, issueID, commentID, 20) + KeepLimitedContentHistory(ctx, issueID, commentID, 20) return nil } -// keepLimitedContentHistory keeps at most `limit` history revisions, it will hard delete out-dated revisions, sorting by revision interval +// KeepLimitedContentHistory keeps at most `limit` history revisions, it will hard delete out-dated revisions, sorting by revision interval // we can ignore all errors in this function, so we just log them -func keepLimitedContentHistory(ctx context.Context, issueID, commentID int64, limit int) { +func KeepLimitedContentHistory(ctx context.Context, issueID, commentID int64, limit int) { type IDEditTime struct { ID int64 EditedUnix timeutil.TimeStamp diff --git a/models/issues/content_history_test.go b/models/issues/content_history_test.go index 3cbc0ad5e0..1218d871d0 100644 --- a/models/issues/content_history_test.go +++ b/models/issues/content_history_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package issues +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/timeutil" @@ -20,20 +21,20 @@ func TestContentHistory(t *testing.T) { dbCtx := db.DefaultContext timeStampNow := timeutil.TimeStampNow() - _ = SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow, "i-a", true) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow.Add(2), "i-b", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow.Add(7), "i-c", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow, "i-a", true) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow.Add(2), "i-b", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow.Add(7), "i-c", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow, "c-a", true) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(5), "c-b", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(20), "c-c", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(50), "c-d", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(51), "c-e", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow, "c-a", true) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(5), "c-b", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(20), "c-c", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(50), "c-d", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(51), "c-e", false) - h1, _ := GetIssueContentHistoryByID(dbCtx, 1) + h1, _ := issues_model.GetIssueContentHistoryByID(dbCtx, 1) assert.EqualValues(t, 1, h1.ID) - m, _ := QueryIssueContentHistoryEditedCountMap(dbCtx, 10) + m, _ := issues_model.QueryIssueContentHistoryEditedCountMap(dbCtx, 10) assert.Equal(t, 3, m[0]) assert.Equal(t, 5, m[100]) @@ -48,31 +49,31 @@ func TestContentHistory(t *testing.T) { } _ = db.GetEngine(dbCtx).Sync2(&User{}) - list1, _ := FetchIssueContentHistoryList(dbCtx, 10, 0) + list1, _ := issues_model.FetchIssueContentHistoryList(dbCtx, 10, 0) assert.Len(t, list1, 3) - list2, _ := FetchIssueContentHistoryList(dbCtx, 10, 100) + list2, _ := issues_model.FetchIssueContentHistoryList(dbCtx, 10, 100) assert.Len(t, list2, 5) - hasHistory1, _ := HasIssueContentHistory(dbCtx, 10, 0) + hasHistory1, _ := issues_model.HasIssueContentHistory(dbCtx, 10, 0) assert.True(t, hasHistory1) - hasHistory2, _ := HasIssueContentHistory(dbCtx, 10, 1) + hasHistory2, _ := issues_model.HasIssueContentHistory(dbCtx, 10, 1) assert.False(t, hasHistory2) - h6, h6Prev, _ := GetIssueContentHistoryAndPrev(dbCtx, 6) + h6, h6Prev, _ := issues_model.GetIssueContentHistoryAndPrev(dbCtx, 6) assert.EqualValues(t, 6, h6.ID) assert.EqualValues(t, 5, h6Prev.ID) // soft-delete - _ = SoftDeleteIssueContentHistory(dbCtx, 5) - h6, h6Prev, _ = GetIssueContentHistoryAndPrev(dbCtx, 6) + _ = issues_model.SoftDeleteIssueContentHistory(dbCtx, 5) + h6, h6Prev, _ = issues_model.GetIssueContentHistoryAndPrev(dbCtx, 6) assert.EqualValues(t, 6, h6.ID) assert.EqualValues(t, 4, h6Prev.ID) // only keep 3 history revisions for comment_id=100, the first and the last should never be deleted - keepLimitedContentHistory(dbCtx, 10, 100, 3) - list1, _ = FetchIssueContentHistoryList(dbCtx, 10, 0) + issues_model.KeepLimitedContentHistory(dbCtx, 10, 100, 3) + list1, _ = issues_model.FetchIssueContentHistoryList(dbCtx, 10, 0) assert.Len(t, list1, 3) - list2, _ = FetchIssueContentHistoryList(dbCtx, 10, 100) + list2, _ = issues_model.FetchIssueContentHistoryList(dbCtx, 10, 100) assert.Len(t, list2, 3) assert.EqualValues(t, 8, list2[0].HistoryID) assert.EqualValues(t, 7, list2[1].HistoryID) diff --git a/models/issue_dependency.go b/models/issues/dependency.go index af40aa45d3..d664c0758e 100644 --- a/models/issue_dependency.go +++ b/models/issues/dependency.go @@ -2,16 +2,95 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" + "fmt" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/timeutil" ) +// ErrDependencyExists represents a "DependencyAlreadyExists" kind of error. +type ErrDependencyExists struct { + IssueID int64 + DependencyID int64 +} + +// IsErrDependencyExists checks if an error is a ErrDependencyExists. +func IsErrDependencyExists(err error) bool { + _, ok := err.(ErrDependencyExists) + return ok +} + +func (err ErrDependencyExists) Error() string { + return fmt.Sprintf("issue dependency does already exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) +} + +// ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error. +type ErrDependencyNotExists struct { + IssueID int64 + DependencyID int64 +} + +// IsErrDependencyNotExists checks if an error is a ErrDependencyExists. +func IsErrDependencyNotExists(err error) bool { + _, ok := err.(ErrDependencyNotExists) + return ok +} + +func (err ErrDependencyNotExists) Error() string { + return fmt.Sprintf("issue dependency does not exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) +} + +// ErrCircularDependency represents a "DependencyCircular" kind of error. +type ErrCircularDependency struct { + IssueID int64 + DependencyID int64 +} + +// IsErrCircularDependency checks if an error is a ErrCircularDependency. +func IsErrCircularDependency(err error) bool { + _, ok := err.(ErrCircularDependency) + return ok +} + +func (err ErrCircularDependency) Error() string { + return fmt.Sprintf("circular dependencies exists (two issues blocking each other) [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) +} + +// ErrDependenciesLeft represents an error where the issue you're trying to close still has dependencies left. +type ErrDependenciesLeft struct { + IssueID int64 +} + +// IsErrDependenciesLeft checks if an error is a ErrDependenciesLeft. +func IsErrDependenciesLeft(err error) bool { + _, ok := err.(ErrDependenciesLeft) + return ok +} + +func (err ErrDependenciesLeft) Error() string { + return fmt.Sprintf("issue has open dependencies [issue id: %d]", err.IssueID) +} + +// ErrUnknownDependencyType represents an error where an unknown dependency type was passed +type ErrUnknownDependencyType struct { + Type DependencyType +} + +// IsErrUnknownDependencyType checks if an error is ErrUnknownDependencyType +func IsErrUnknownDependencyType(err error) bool { + _, ok := err.(ErrUnknownDependencyType) + return ok +} + +func (err ErrUnknownDependencyType) Error() string { + return fmt.Sprintf("unknown dependency type [type: %d]", err.Type) +} + // IssueDependency represents an issue dependency type IssueDependency struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/issue_dependency_test.go b/models/issues/dependency_test.go index 345a9077cd..3ea0b4ff5c 100644 --- a/models/issue_dependency_test.go +++ b/models/issues/dependency_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -21,42 +22,42 @@ func TestCreateIssueDependency(t *testing.T) { user1, err := user_model.GetUserByID(1) assert.NoError(t, err) - issue1, err := GetIssueByID(1) + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) assert.NoError(t, err) - issue2, err := GetIssueByID(2) + issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) assert.NoError(t, err) // Create a dependency and check if it was successful - err = CreateIssueDependency(user1, issue1, issue2) + err = issues_model.CreateIssueDependency(user1, issue1, issue2) assert.NoError(t, err) // Do it again to see if it will check if the dependency already exists - err = CreateIssueDependency(user1, issue1, issue2) + err = issues_model.CreateIssueDependency(user1, issue1, issue2) assert.Error(t, err) - assert.True(t, IsErrDependencyExists(err)) + assert.True(t, issues_model.IsErrDependencyExists(err)) // Check for circular dependencies - err = CreateIssueDependency(user1, issue2, issue1) + err = issues_model.CreateIssueDependency(user1, issue2, issue1) assert.Error(t, err) - assert.True(t, IsErrCircularDependency(err)) + assert.True(t, issues_model.IsErrCircularDependency(err)) - _ = unittest.AssertExistsAndLoadBean(t, &Comment{Type: CommentTypeAddDependency, PosterID: user1.ID, IssueID: issue1.ID}) + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddDependency, PosterID: user1.ID, IssueID: issue1.ID}) // Check if dependencies left is correct - left, err := IssueNoDependenciesLeft(db.DefaultContext, issue1) + left, err := issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) assert.NoError(t, err) assert.False(t, left) // Close #2 and check again - _, err = ChangeIssueStatus(db.DefaultContext, issue2, user1, true) + _, err = issues_model.ChangeIssueStatus(db.DefaultContext, issue2, user1, true) assert.NoError(t, err) - left, err = IssueNoDependenciesLeft(db.DefaultContext, issue1) + left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) assert.NoError(t, err) assert.True(t, left) // Test removing the dependency - err = RemoveIssueDependency(user1, issue1, issue2, DependencyTypeBlockedBy) + err = issues_model.RemoveIssueDependency(user1, issue1, issue2, issues_model.DependencyTypeBlockedBy) assert.NoError(t, err) } diff --git a/models/issue.go b/models/issues/issue.go index a22c115523..0f4af3e84f 100644 --- a/models/issue.go +++ b/models/issues/issue.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -16,7 +16,6 @@ import ( admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/foreignreference" - issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -29,7 +28,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/references" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/storage" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -38,6 +36,71 @@ import ( "xorm.io/xorm" ) +// ErrIssueNotExist represents a "IssueNotExist" kind of error. +type ErrIssueNotExist struct { + ID int64 + RepoID int64 + Index int64 +} + +// IsErrIssueNotExist checks if an error is a ErrIssueNotExist. +func IsErrIssueNotExist(err error) bool { + _, ok := err.(ErrIssueNotExist) + return ok +} + +func (err ErrIssueNotExist) Error() string { + return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) +} + +// ErrIssueIsClosed represents a "IssueIsClosed" kind of error. +type ErrIssueIsClosed struct { + ID int64 + RepoID int64 + Index int64 +} + +// IsErrIssueIsClosed checks if an error is a ErrIssueNotExist. +func IsErrIssueIsClosed(err error) bool { + _, ok := err.(ErrIssueIsClosed) + return ok +} + +func (err ErrIssueIsClosed) Error() string { + return fmt.Sprintf("issue is closed [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) +} + +// ErrNewIssueInsert is used when the INSERT statement in newIssue fails +type ErrNewIssueInsert struct { + OriginalError error +} + +// IsErrNewIssueInsert checks if an error is a ErrNewIssueInsert. +func IsErrNewIssueInsert(err error) bool { + _, ok := err.(ErrNewIssueInsert) + return ok +} + +func (err ErrNewIssueInsert) Error() string { + return err.OriginalError.Error() +} + +// ErrIssueWasClosed is used when close a closed issue +type ErrIssueWasClosed struct { + ID int64 + Index int64 +} + +// IsErrIssueWasClosed checks if an error is a ErrIssueWasClosed. +func IsErrIssueWasClosed(err error) bool { + _, ok := err.(ErrIssueWasClosed) + return ok +} + +func (err ErrIssueWasClosed) Error() string { + return fmt.Sprintf("Issue [%d] %d was already closed", err.ID, err.Index) +} + // Issue represents an issue or pull request of repository. type Issue struct { ID int64 `xorm:"pk autoincr"` @@ -47,14 +110,14 @@ type Issue struct { PosterID int64 `xorm:"INDEX"` Poster *user_model.User `xorm:"-"` OriginalAuthor string - OriginalAuthorID int64 `xorm:"index"` - Title string `xorm:"name"` - Content string `xorm:"LONGTEXT"` - RenderedContent string `xorm:"-"` - Labels []*Label `xorm:"-"` - MilestoneID int64 `xorm:"INDEX"` - Milestone *issues_model.Milestone `xorm:"-"` - Project *project_model.Project `xorm:"-"` + OriginalAuthorID int64 `xorm:"index"` + Title string `xorm:"name"` + Content string `xorm:"LONGTEXT"` + RenderedContent string `xorm:"-"` + Labels []*Label `xorm:"-"` + MilestoneID int64 `xorm:"INDEX"` + Milestone *Milestone `xorm:"-"` + Project *project_model.Project `xorm:"-"` Priority int AssigneeID int64 `xorm:"-"` Assignee *user_model.User `xorm:"-"` @@ -73,7 +136,7 @@ type Issue struct { Attachments []*repo_model.Attachment `xorm:"-"` Comments []*Comment `xorm:"-"` - Reactions issues_model.ReactionList `xorm:"-"` + Reactions ReactionList `xorm:"-"` TotalTrackedTime int64 `xorm:"-"` Assignees []*user_model.User `xorm:"-"` ForeignReference *foreignreference.ForeignReference `xorm:"-"` @@ -107,7 +170,8 @@ func init() { db.RegisterModel(new(IssueIndex)) } -func (issue *Issue) loadTotalTimes(ctx context.Context) (err error) { +// LoadTotalTimes load total tracked time +func (issue *Issue) LoadTotalTimes(ctx context.Context) (err error) { opts := FindTrackedTimesOptions{IssueID: issue.ID} issue.TotalTrackedTime, err = opts.toSession(db.GetEngine(ctx)).SumInt(&TrackedTime{}, "time") if err != nil { @@ -237,7 +301,7 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) { if issue.Reactions != nil { return nil } - reactions, _, err := issues_model.FindReactions(ctx, issues_model.FindReactionsOptions{ + reactions, _, err := FindReactions(ctx, FindReactionsOptions{ IssueID: issue.ID, }) if err != nil { @@ -247,7 +311,7 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) { return err } // Load reaction user data - if _, err := issues_model.ReactionList(reactions).LoadUsers(ctx, issue.Repo); err != nil { + if _, err := ReactionList(reactions).LoadUsers(ctx, issue.Repo); err != nil { return err } @@ -292,15 +356,16 @@ func (issue *Issue) loadForeignReference(ctx context.Context) (err error) { func (issue *Issue) loadMilestone(ctx context.Context) (err error) { if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 { - issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID) - if err != nil && !issues_model.IsErrMilestoneNotExist(err) { + issue.Milestone, err = GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID) + if err != nil && !IsErrMilestoneNotExist(err) { return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err) } } return nil } -func (issue *Issue) loadAttributes(ctx context.Context) (err error) { +// LoadAttributes loads the attribute of this issue. +func (issue *Issue) LoadAttributes(ctx context.Context) (err error) { if err = issue.LoadRepo(ctx); err != nil { return } @@ -345,7 +410,7 @@ func (issue *Issue) loadAttributes(ctx context.Context) (err error) { return err } if issue.isTimetrackerEnabled(ctx) { - if err = issue.loadTotalTimes(ctx); err != nil { + if err = issue.LoadTotalTimes(ctx); err != nil { return err } } @@ -357,11 +422,6 @@ func (issue *Issue) loadAttributes(ctx context.Context) (err error) { return issue.loadReactions(ctx) } -// LoadAttributes loads the attribute of this issue. -func (issue *Issue) LoadAttributes() error { - return issue.loadAttributes(db.DefaultContext) -} - // LoadMilestone load milestone of this issue. func (issue *Issue) LoadMilestone() error { return issue.loadMilestone(db.DefaultContext) @@ -590,15 +650,6 @@ func ReplaceIssueLabels(issue *Issue, labels []*Label, doer *user_model.User) (e return committer.Commit() } -// ReadBy sets issue to be read by given user. -func (issue *Issue) ReadBy(ctx context.Context, userID int64) error { - if err := UpdateIssueUserByRead(userID, issue.ID); err != nil { - return err - } - - return setIssueNotificationStatusReadIfUnread(ctx, userID, issue.ID) -} - // UpdateIssueCols updates cols of issue func UpdateIssueCols(ctx context.Context, issue *Issue, cols ...string) error { if _, err := db.GetEngine(ctx).ID(issue.ID).Cols(cols...).Update(issue); err != nil { @@ -609,7 +660,7 @@ func UpdateIssueCols(ctx context.Context, issue *Issue, cols ...string) error { func changeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isClosed, isMergePull bool) (*Comment, error) { // Reload the issue - currentIssue, err := getIssueByID(ctx, issue.ID) + currentIssue, err := GetIssueByID(ctx, issue.ID) if err != nil { return nil, err } @@ -666,7 +717,7 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use // Update issue count of milestone if issue.MilestoneID > 0 { - if err := issues_model.UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil { + if err := UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil { return nil, err } } @@ -730,7 +781,7 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err if _, err = CreateCommentCtx(ctx, opts); err != nil { return fmt.Errorf("createComment: %v", err) } - if err = issue.addCrossReferences(ctx, doer, true); err != nil { + if err = issue.AddCrossReferences(ctx, doer, true); err != nil { return err } @@ -772,7 +823,7 @@ func ChangeIssueRef(issue *Issue, doer *user_model.User, oldRef string) (err err // AddDeletePRBranchComment adds delete branch comment for pull request issue func AddDeletePRBranchComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issueID int64, branchName string) error { - issue, err := getIssueByID(ctx, issueID) + issue, err := GetIssueByID(ctx, issueID) if err != nil { return err } @@ -815,12 +866,12 @@ func ChangeIssueContent(issue *Issue, doer *user_model.User, content string) (er } defer committer.Close() - hasContentHistory, err := issues_model.HasIssueContentHistory(ctx, issue.ID, 0) + hasContentHistory, err := HasIssueContentHistory(ctx, issue.ID, 0) if err != nil { return fmt.Errorf("HasIssueContentHistory: %v", err) } if !hasContentHistory { - if err = issues_model.SaveIssueContentHistory(ctx, issue.PosterID, issue.ID, 0, + if err = SaveIssueContentHistory(ctx, issue.PosterID, issue.ID, 0, issue.CreatedUnix, issue.Content, true); err != nil { return fmt.Errorf("SaveIssueContentHistory: %v", err) } @@ -832,12 +883,12 @@ func ChangeIssueContent(issue *Issue, doer *user_model.User, content string) (er return fmt.Errorf("UpdateIssueCols: %v", err) } - if err = issues_model.SaveIssueContentHistory(ctx, doer.ID, issue.ID, 0, + if err = SaveIssueContentHistory(ctx, doer.ID, issue.ID, 0, timeutil.TimeStampNow(), issue.Content, false); err != nil { return fmt.Errorf("SaveIssueContentHistory: %v", err) } - if err = issue.addCrossReferences(ctx, doer, true); err != nil { + if err = issue.AddCrossReferences(ctx, doer, true); err != nil { return fmt.Errorf("addCrossReferences: %v", err) } @@ -907,13 +958,14 @@ type NewIssueOptions struct { IsPull bool } -func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) (err error) { +// NewIssueWithIndex creates issue with given index +func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssueOptions) (err error) { e := db.GetEngine(ctx) opts.Issue.Title = strings.TrimSpace(opts.Issue.Title) if opts.Issue.MilestoneID > 0 { - milestone, err := issues_model.GetMilestoneByRepoID(ctx, opts.Issue.RepoID, opts.Issue.MilestoneID) - if err != nil && !issues_model.IsErrMilestoneNotExist(err) { + milestone, err := GetMilestoneByRepoID(ctx, opts.Issue.RepoID, opts.Issue.MilestoneID) + if err != nil && !IsErrMilestoneNotExist(err) { return fmt.Errorf("getMilestoneByID: %v", err) } @@ -937,7 +989,7 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) } if opts.Issue.MilestoneID > 0 { - if err := issues_model.UpdateMilestoneCounters(ctx, opts.Issue.MilestoneID); err != nil { + if err := UpdateMilestoneCounters(ctx, opts.Issue.MilestoneID); err != nil { return err } @@ -987,7 +1039,7 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) } } - if err = newIssueUsers(ctx, opts.Repo, opts.Issue); err != nil { + if err = NewIssueUsers(ctx, opts.Repo, opts.Issue); err != nil { return err } @@ -1004,36 +1056,11 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) } } } - if err = opts.Issue.loadAttributes(ctx); err != nil { + if err = opts.Issue.LoadAttributes(ctx); err != nil { return err } - return opts.Issue.addCrossReferences(ctx, doer, false) -} - -// RecalculateIssueIndexForRepo create issue_index for repo if not exist and -// update it based on highest index of existing issues assigned to a repo -func RecalculateIssueIndexForRepo(repoID int64) error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err := db.UpsertResourceIndex(db.GetEngine(ctx), "issue_index", repoID); err != nil { - return err - } - - var max int64 - if _, err := db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil { - return err - } - - if _, err := db.GetEngine(ctx).Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil { - return err - } - - return committer.Commit() + return opts.Issue.AddCrossReferences(ctx, doer, false) } // NewIssue creates new issue with labels for repository. @@ -1051,13 +1078,13 @@ func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids } defer committer.Close() - if err = newIssue(ctx, issue.Poster, NewIssueOptions{ + if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ Repo: repo, Issue: issue, LabelIDs: labelIDs, Attachments: uuids, }); err != nil { - if IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { return err } return fmt.Errorf("newIssue: %v", err) @@ -1114,10 +1141,11 @@ func GetIssueWithAttrsByIndex(repoID, index int64) (*Issue, error) { if err != nil { return nil, err } - return issue, issue.LoadAttributes() + return issue, issue.LoadAttributes(db.DefaultContext) } -func getIssueByID(ctx context.Context, id int64) (*Issue, error) { +// GetIssueByID returns an issue by given ID. +func GetIssueByID(ctx context.Context, id int64) (*Issue, error) { issue := new(Issue) has, err := db.GetEngine(ctx).ID(id).Get(issue) if err != nil { @@ -1130,16 +1158,11 @@ func getIssueByID(ctx context.Context, id int64) (*Issue, error) { // GetIssueWithAttrsByID returns an issue with attributes by given ID. func GetIssueWithAttrsByID(id int64) (*Issue, error) { - issue, err := getIssueByID(db.DefaultContext, id) + issue, err := GetIssueByID(db.DefaultContext, id) if err != nil { return nil, err } - return issue, issue.loadAttributes(db.DefaultContext) -} - -// GetIssueByID returns an issue by given ID. -func GetIssueByID(id int64) (*Issue, error) { - return getIssueByID(db.DefaultContext, id) + return issue, issue.LoadAttributes(db.DefaultContext) } // GetIssuesByIDs return issues with the given IDs. @@ -1156,7 +1179,7 @@ func GetIssueIDsByRepoID(ctx context.Context, repoID int64) ([]int64, error) { } // IssuesOptions represents options of an issue. -type IssuesOptions struct { +type IssuesOptions struct { //nolint db.ListOptions RepoID int64 // overwrites RepoCond if not 0 RepoCond builder.Cond @@ -1534,7 +1557,7 @@ func GetParticipantsIDsByIssueID(issueID int64) ([]int64, error) { // IsUserParticipantsOfIssue return true if user is participants of an issue func IsUserParticipantsOfIssue(user *user_model.User, issue *Issue) bool { - userIDs, err := issue.getParticipantIDsByIssue(db.DefaultContext) + userIDs, err := issue.GetParticipantIDsByIssue(db.DefaultContext) if err != nil { log.Error(err.Error()) return false @@ -1577,17 +1600,6 @@ const ( FilterModeYourRepositories ) -func parseCountResult(results []map[string][]byte) int64 { - if len(results) == 0 { - return 0 - } - for _, result := range results[0] { - c, _ := strconv.ParseInt(string(result), 10, 64) - return c - } - return 0 -} - // IssueStatsOptions contains parameters accepted by GetIssueStats. type IssueStatsOptions struct { RepoID int64 @@ -1602,14 +1614,15 @@ type IssueStatsOptions struct { } const ( + // MaxQueryParameters represents the max query parameters // When queries are broken down in parts because of the number // of parameters, attempt to break by this amount - maxQueryParameters = 300 + MaxQueryParameters = 300 ) // GetIssueStats returns issue statistic information by given conditions. func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) { - if len(opts.IssueIDs) <= maxQueryParameters { + if len(opts.IssueIDs) <= MaxQueryParameters { return getIssueStatsChunk(opts, opts.IssueIDs) } @@ -1619,7 +1632,7 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) { // ids in a temporary table and join from them. accum := &IssueStats{} for i := 0; i < len(opts.IssueIDs); { - chunk := i + maxQueryParameters + chunk := i + MaxQueryParameters if chunk > len(opts.IssueIDs) { chunk = len(opts.IssueIDs) } @@ -1950,7 +1963,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment } // Reload the issue - currentIssue, err := getIssueByID(ctx, issue.ID) + currentIssue, err := GetIssueByID(ctx, issue.ID) if err != nil { return nil, false, err } @@ -1985,7 +1998,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment } } - if err := issue.addCrossReferences(ctx, doer, true); err != nil { + if err := issue.AddCrossReferences(ctx, doer, true); err != nil { return nil, false, err } return statusChangeComment, titleChanged, committer.Commit() @@ -2016,22 +2029,8 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *us return committer.Commit() } -// DeleteIssue deletes the issue -func DeleteIssue(issue *Issue) error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err := deleteIssue(ctx, issue); err != nil { - return err - } - - return committer.Commit() -} - -func deleteInIssue(ctx context.Context, issueID int64, beans ...interface{}) error { +// DeleteInIssue delete records in beans with external key issue_id = ? +func DeleteInIssue(ctx context.Context, issueID int64, beans ...interface{}) error { e := db.GetEngine(ctx) for _, bean := range beans { if _, err := e.In("issue_id", issueID).Delete(bean); err != nil { @@ -2041,103 +2040,14 @@ func deleteInIssue(ctx context.Context, issueID int64, beans ...interface{}) err return nil } -func deleteIssue(ctx context.Context, issue *Issue) error { - e := db.GetEngine(ctx) - if _, err := e.ID(issue.ID).NoAutoCondition().Delete(issue); err != nil { - return err - } - - if issue.IsPull { - if _, err := e.ID(issue.RepoID).Decr("num_pulls").Update(new(repo_model.Repository)); err != nil { - return err - } - if issue.IsClosed { - if _, err := e.ID(issue.RepoID).Decr("num_closed_pulls").Update(new(repo_model.Repository)); err != nil { - return err - } - } - } else { - if _, err := e.ID(issue.RepoID).Decr("num_issues").Update(new(repo_model.Repository)); err != nil { - return err - } - if issue.IsClosed { - if _, err := e.ID(issue.RepoID).Decr("num_closed_issues").Update(new(repo_model.Repository)); err != nil { - return err - } - } - } - - // delete actions assigned to this issue - subQuery := builder.Select("`id`"). - From("`comment`"). - Where(builder.Eq{"`issue_id`": issue.ID}) - if _, err := e.In("comment_id", subQuery).Delete(&Action{}); err != nil { - return err - } - - if _, err := e.Table("action").Where("repo_id = ?", issue.RepoID). - In("op_type", ActionCreateIssue, ActionCreatePullRequest). - Where("content LIKE ?", strconv.FormatInt(issue.ID, 10)+"|%"). - Delete(&Action{}); err != nil { - return err - } - - // find attachments related to this issue and remove them - var attachments []*repo_model.Attachment - if err := e.In("issue_id", issue.ID).Find(&attachments); err != nil { - return err - } - - for i := range attachments { - admin_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", attachments[i].RelativePath()) - } - - // delete all database data still assigned to this issue - if err := deleteInIssue(ctx, issue.ID, - &issues_model.ContentHistory{}, - &Comment{}, - &IssueLabel{}, - &IssueDependency{}, - &IssueAssignees{}, - &IssueUser{}, - &Notification{}, - &issues_model.Reaction{}, - &IssueWatch{}, - &Stopwatch{}, - &TrackedTime{}, - &project_model.ProjectIssue{}, - &repo_model.Attachment{}, - &PullRequest{}, - ); err != nil { - return err - } - - // References to this issue in other issues - if _, err := e.In("ref_issue_id", issue.ID).Delete(&Comment{}); err != nil { - return err - } - - // Delete dependencies for issues in other repositories - if _, err := e.In("dependency_id", issue.ID).Delete(&IssueDependency{}); err != nil { - return err - } - - // delete from dependent issues - if _, err := e.In("dependent_issue_id", issue.ID).Delete(&Comment{}); err != nil { - return err - } - - return nil -} - // DependencyInfo represents high level information about an issue which is a dependency of another issue. type DependencyInfo struct { Issue `xorm:"extends"` repo_model.Repository `xorm:"extends"` } -// getParticipantIDsByIssue returns all userIDs who are participated in comments of an issue and issue author -func (issue *Issue) getParticipantIDsByIssue(ctx context.Context) ([]int64, error) { +// GetParticipantIDsByIssue returns all userIDs who are participated in comments of an issue and issue author +func (issue *Issue) GetParticipantIDsByIssue(ctx context.Context) ([]int64, error) { if issue == nil { return nil, nil } @@ -2196,9 +2106,9 @@ func (issue *Issue) BlockingDependencies(ctx context.Context) (issueDeps []*Depe func updateIssueClosedNum(ctx context.Context, issue *Issue) (err error) { if issue.IsPull { - err = repoStatsCorrectNumClosed(ctx, issue.RepoID, true, "num_closed_pulls") + err = repo_model.StatsCorrectNumClosed(ctx, issue.RepoID, true, "num_closed_pulls") } else { - err = repoStatsCorrectNumClosed(ctx, issue.RepoID, false, "num_closed_issues") + err = repo_model.StatsCorrectNumClosed(ctx, issue.RepoID, false, "num_closed_issues") } return } @@ -2363,6 +2273,17 @@ func UpdateIssuesMigrationsByType(gitServiceType api.GitServiceType, originalAut return err } +func migratedIssueCond(tp api.GitServiceType) builder.Cond { + return builder.In("issue_id", + builder.Select("issue.id"). + From("issue"). + InnerJoin("repository", "issue.repo_id = repository.id"). + Where(builder.Eq{ + "repository.original_service_type": tp, + }), + ) +} + // UpdateReactionsMigrationsByType updates all migrated repositories' reactions from gitServiceType to replace originalAuthorID to posterID func UpdateReactionsMigrationsByType(gitServiceType api.GitServiceType, originalAuthorID string, userID int64) error { _, err := db.GetEngine(db.DefaultContext).Table("reaction"). @@ -2376,13 +2297,14 @@ func UpdateReactionsMigrationsByType(gitServiceType api.GitServiceType, original return err } -func deleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths []string, err error) { +// DeleteIssuesByRepoID deletes issues by repositories id +func DeleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths []string, err error) { deleteCond := builder.Select("id").From("issue").Where(builder.Eq{"issue.repo_id": repoID}) sess := db.GetEngine(ctx) // Delete content histories if _, err = sess.In("issue_id", deleteCond). - Delete(&issues_model.ContentHistory{}); err != nil { + Delete(&ContentHistory{}); err != nil { return } @@ -2410,7 +2332,7 @@ func deleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths [] } if _, err = sess.In("issue_id", deleteCond). - Delete(&issues_model.Reaction{}); err != nil { + Delete(&Reaction{}); err != nil { return } @@ -2477,3 +2399,50 @@ func (issue *Issue) GetExternalName() string { return issue.OriginalAuthor } // GetExternalID ExternalUserRemappable interface func (issue *Issue) GetExternalID() int64 { return issue.OriginalAuthorID } + +// CountOrphanedIssues count issues without a repo +func CountOrphanedIssues() (int64, error) { + return db.GetEngine(db.DefaultContext).Table("issue"). + Join("LEFT", "repository", "issue.repo_id=repository.id"). + Where(builder.IsNull{"repository.id"}). + Select("COUNT(`issue`.`id`)"). + Count() +} + +// DeleteOrphanedIssues delete issues without a repo +func DeleteOrphanedIssues() error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + var ids []int64 + + if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id"). + Join("LEFT", "repository", "issue.repo_id=repository.id"). + Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id"). + Find(&ids); err != nil { + return err + } + + var attachmentPaths []string + for i := range ids { + paths, err := DeleteIssuesByRepoID(ctx, ids[i]) + if err != nil { + return err + } + attachmentPaths = append(attachmentPaths, paths...) + } + + if err := committer.Commit(); err != nil { + return err + } + committer.Close() + + // Remove issue attachment files. + for i := range attachmentPaths { + admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i]) + } + return nil +} diff --git a/models/issues/issue_index.go b/models/issues/issue_index.go new file mode 100644 index 0000000000..100e814317 --- /dev/null +++ b/models/issues/issue_index.go @@ -0,0 +1,32 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package issues + +import "code.gitea.io/gitea/models/db" + +// RecalculateIssueIndexForRepo create issue_index for repo if not exist and +// update it based on highest index of existing issues assigned to a repo +func RecalculateIssueIndexForRepo(repoID int64) error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + if err := db.UpsertResourceIndex(ctx, "issue_index", repoID); err != nil { + return err + } + + var max int64 + if _, err := db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil { + return err + } + + if _, err := db.GetEngine(ctx).Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil { + return err + } + + return committer.Commit() +} diff --git a/models/issue_list.go b/models/issues/issue_list.go index a5fc095e12..20e9949b66 100644 --- a/models/issue_list.go +++ b/models/issues/issue_list.go @@ -2,14 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" "fmt" "code.gitea.io/gitea/models/db" - issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" @@ -20,11 +19,6 @@ import ( // IssueList defines a list of issues type IssueList []*Issue -const ( - // default variables number on IN () in SQL - defaultMaxInSize = 50 -) - // get the repo IDs to be loaded later, these IDs are for issue.Repo and issue.PullRequest.HeadRepo func (issues IssueList) getRepoIDs() []int64 { repoIDs := make(map[int64]struct{}, len(issues)) @@ -48,7 +42,7 @@ func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Rep repoMaps := make(map[int64]*repo_model.Repository, len(repoIDs)) left := len(repoIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -102,7 +96,7 @@ func (issues IssueList) loadPosters(ctx context.Context) error { posterMaps := make(map[int64]*user_model.User, len(posterIDs)) left := len(posterIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -150,7 +144,7 @@ func (issues IssueList) loadLabels(ctx context.Context) error { issueIDs := issues.getIssueIDs() left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -205,10 +199,10 @@ func (issues IssueList) loadMilestones(ctx context.Context) error { return nil } - milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -242,7 +236,7 @@ func (issues IssueList) loadAssignees(ctx context.Context) error { issueIDs := issues.getIssueIDs() left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -298,7 +292,7 @@ func (issues IssueList) loadPullRequests(ctx context.Context) error { pullRequestMaps := make(map[int64]*PullRequest, len(issuesIDs)) left := len(issuesIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -342,7 +336,7 @@ func (issues IssueList) loadAttachments(ctx context.Context) (err error) { issuesIDs := issues.getIssueIDs() left := len(issuesIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -387,7 +381,7 @@ func (issues IssueList) loadComments(ctx context.Context, cond builder.Cond) (er issuesIDs := issues.getIssueIDs() left := len(issuesIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -443,7 +437,7 @@ func (issues IssueList) loadTotalTrackedTimes(ctx context.Context) (err error) { left := len(ids) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } diff --git a/models/issue_list_test.go b/models/issues/issue_list_test.go index 2916a7302f..6b978f9ae6 100644 --- a/models/issue_list_test.go +++ b/models/issues/issue_list_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" @@ -16,10 +17,10 @@ import ( func TestIssueList_LoadRepositories(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issueList := IssueList{ - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue), - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue), - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 4}).(*Issue), + issueList := issues_model.IssueList{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue), } repos, err := issueList.LoadRepositories() @@ -33,9 +34,9 @@ func TestIssueList_LoadRepositories(t *testing.T) { func TestIssueList_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) setting.Service.EnableTimetracking = true - issueList := IssueList{ - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue), - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 4}).(*Issue), + issueList := issues_model.IssueList{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue), } assert.NoError(t, issueList.LoadAttributes()) @@ -43,7 +44,7 @@ func TestIssueList_LoadAttributes(t *testing.T) { assert.EqualValues(t, issue.RepoID, issue.Repo.ID) for _, label := range issue.Labels { assert.EqualValues(t, issue.RepoID, label.RepoID) - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) } if issue.PosterID > 0 { assert.EqualValues(t, issue.PosterID, issue.Poster.ID) diff --git a/models/issue_lock.go b/models/issues/issue_lock.go index a122f618d0..7b52429ef7 100644 --- a/models/issue_lock.go +++ b/models/issues/issue_lock.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "code.gitea.io/gitea/models/db" diff --git a/models/issue_project.go b/models/issues/issue_project.go index 0f8c61977b..5e0a337f7d 100644 --- a/models/issue_project.go +++ b/models/issues/issue_project.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" diff --git a/models/issue_test.go b/models/issues/issue_test.go index 5b2f461a84..019e578da8 100644 --- a/models/issue_test.go +++ b/models/issues/issue_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "context" @@ -29,18 +29,18 @@ func TestIssue_ReplaceLabels(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(issueID int64, labelIDs []int64) { - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issueID}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - labels := make([]*Label, len(labelIDs)) + labels := make([]*issues_model.Label, len(labelIDs)) for i, labelID := range labelIDs { - labels[i] = unittest.AssertExistsAndLoadBean(t, &Label{ID: labelID, RepoID: repo.ID}).(*Label) + labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID, RepoID: repo.ID}).(*issues_model.Label) } - assert.NoError(t, ReplaceIssueLabels(issue, labels, doer)) - unittest.AssertCount(t, &IssueLabel{IssueID: issueID}, len(labelIDs)) + assert.NoError(t, issues_model.ReplaceIssueLabels(issue, labels, doer)) + unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issueID}, len(labelIDs)) for _, labelID := range labelIDs { - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issueID, LabelID: labelID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) } } @@ -52,15 +52,15 @@ func TestIssue_ReplaceLabels(t *testing.T) { func Test_GetIssueIDsByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - ids, err := GetIssueIDsByRepoID(db.DefaultContext, 1) + ids, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) assert.NoError(t, err) assert.Len(t, ids, 5) } func TestIssueAPIURL(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) - err := issue.LoadAttributes() + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + err := issue.LoadAttributes(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/issues/1", issue.APIURL()) @@ -69,7 +69,7 @@ func TestIssueAPIURL(t *testing.T) { func TestGetIssuesByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(expectedIssueIDs, nonExistentIssueIDs []int64) { - issues, err := GetIssuesByIDs(db.DefaultContext, append(expectedIssueIDs, nonExistentIssueIDs...)) + issues, err := issues_model.GetIssuesByIDs(db.DefaultContext, append(expectedIssueIDs, nonExistentIssueIDs...)) assert.NoError(t, err) actualIssueIDs := make([]int64, len(issues)) for i, issue := range issues { @@ -85,9 +85,9 @@ func TestGetParticipantIDsByIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) checkParticipants := func(issueID int64, userIDs []int) { - issue, err := GetIssueByID(issueID) + issue, err := issues_model.GetIssueByID(db.DefaultContext, issueID) assert.NoError(t, err) - participants, err := issue.getParticipantIDsByIssue(db.DefaultContext) + participants, err := issue.GetParticipantIDsByIssue(db.DefaultContext) if assert.NoError(t, err) { participantsIDs := make([]int, len(participants)) for i, uid := range participants { @@ -117,16 +117,16 @@ func TestIssue_ClearLabels(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: test.issueID}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) - assert.NoError(t, ClearIssueLabels(issue, doer)) - unittest.AssertNotExistsBean(t, &IssueLabel{IssueID: test.issueID}) + assert.NoError(t, issues_model.ClearIssueLabels(issue, doer)) + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: test.issueID}) } } func TestUpdateIssueCols(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) const newTitle = "New Title for unit test" issue.Title = newTitle @@ -135,10 +135,10 @@ func TestUpdateIssueCols(t *testing.T) { issue.Content = "This should have no effect" now := time.Now().Unix() - assert.NoError(t, UpdateIssueCols(db.DefaultContext, issue, "name")) + assert.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "name")) then := time.Now().Unix() - updatedIssue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) + updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}).(*issues_model.Issue) assert.EqualValues(t, newTitle, updatedIssue.Title) assert.EqualValues(t, prevContent, updatedIssue.Content) unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) @@ -147,18 +147,18 @@ func TestUpdateIssueCols(t *testing.T) { func TestIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) for _, test := range []struct { - Opts IssuesOptions + Opts issues_model.IssuesOptions ExpectedIssueIDs []int64 }{ { - IssuesOptions{ + issues_model.IssuesOptions{ AssigneeID: 1, SortType: "oldest", }, []int64{1, 6}, }, { - IssuesOptions{ + issues_model.IssuesOptions{ RepoCond: builder.In("repo_id", 1, 3), SortType: "oldest", ListOptions: db.ListOptions{ @@ -169,7 +169,7 @@ func TestIssues(t *testing.T) { []int64{1, 2, 3, 5}, }, { - IssuesOptions{ + issues_model.IssuesOptions{ LabelIDs: []int64{1}, ListOptions: db.ListOptions{ Page: 1, @@ -179,7 +179,7 @@ func TestIssues(t *testing.T) { []int64{2, 1}, }, { - IssuesOptions{ + issues_model.IssuesOptions{ LabelIDs: []int64{1, 2}, ListOptions: db.ListOptions{ Page: 1, @@ -189,7 +189,7 @@ func TestIssues(t *testing.T) { []int64{}, // issues with **both** label 1 and 2, none of these issues matches, TODO: add more tests }, } { - issues, err := Issues(&test.Opts) + issues, err := issues_model.Issues(&test.Opts) assert.NoError(t, err) if assert.Len(t, issues, len(test.ExpectedIssueIDs)) { for i, issue := range issues { @@ -202,16 +202,16 @@ func TestIssues(t *testing.T) { func TestGetUserIssueStats(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) for _, test := range []struct { - Opts UserIssueStatsOptions - ExpectedIssueStats IssueStats + Opts issues_model.UserIssueStatsOptions + ExpectedIssueStats issues_model.IssueStats }{ { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, RepoIDs: []int64{1}, - FilterMode: FilterModeAll, + FilterMode: issues_model.FilterModeAll, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 1, // 6 CreateCount: 1, // 6 @@ -220,13 +220,13 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, RepoIDs: []int64{1}, - FilterMode: FilterModeAll, + FilterMode: issues_model.FilterModeAll, IsClosed: true, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 0, CreateCount: 0, @@ -235,11 +235,11 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, - FilterMode: FilterModeAssign, + FilterMode: issues_model.FilterModeAssign, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 1, // 6 CreateCount: 1, // 6 @@ -248,11 +248,11 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, - FilterMode: FilterModeCreate, + FilterMode: issues_model.FilterModeCreate, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 1, // 6 CreateCount: 1, // 6 @@ -261,11 +261,11 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, - FilterMode: FilterModeMention, + FilterMode: issues_model.FilterModeMention, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 1, // 6 CreateCount: 1, // 6 @@ -275,12 +275,12 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, - FilterMode: FilterModeCreate, + FilterMode: issues_model.FilterModeCreate, IssueIDs: []int64{1}, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 1 AssignCount: 1, // 1 CreateCount: 1, // 1 @@ -289,13 +289,13 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 2, Org: unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization), Team: unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 7}).(*organization.Team), - FilterMode: FilterModeAll, + FilterMode: issues_model.FilterModeAll, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 2, AssignCount: 1, CreateCount: 1, @@ -304,7 +304,7 @@ func TestGetUserIssueStats(t *testing.T) { }, } { t.Run(fmt.Sprintf("%#v", test.Opts), func(t *testing.T) { - stats, err := GetUserIssueStats(test.Opts) + stats, err := issues_model.GetUserIssueStats(test.Opts) if !assert.NoError(t, err) { return } @@ -315,31 +315,31 @@ func TestGetUserIssueStats(t *testing.T) { func TestIssue_loadTotalTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - ms, err := GetIssueByID(2) + ms, err := issues_model.GetIssueByID(db.DefaultContext, 2) assert.NoError(t, err) - assert.NoError(t, ms.loadTotalTimes(db.DefaultContext)) + assert.NoError(t, ms.LoadTotalTimes(db.DefaultContext)) assert.Equal(t, int64(3682), ms.TotalTrackedTime) } func TestIssue_SearchIssueIDsByKeyword(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - total, ids, err := SearchIssueIDsByKeyword(context.TODO(), "issue2", []int64{1}, 10, 0) + total, ids, err := issues_model.SearchIssueIDsByKeyword(context.TODO(), "issue2", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{2}, ids) - total, ids, err = SearchIssueIDsByKeyword(context.TODO(), "first", []int64{1}, 10, 0) + total, ids, err = issues_model.SearchIssueIDsByKeyword(context.TODO(), "first", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{1}, ids) - total, ids, err = SearchIssueIDsByKeyword(context.TODO(), "for", []int64{1}, 10, 0) + total, ids, err = issues_model.SearchIssueIDsByKeyword(context.TODO(), "for", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 5, total) assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) // issue1's comment id 2 - total, ids, err = SearchIssueIDsByKeyword(context.TODO(), "good", []int64{1}, 10, 0) + total, ids, err = issues_model.SearchIssueIDsByKeyword(context.TODO(), "good", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{1}, ids) @@ -349,23 +349,23 @@ func TestGetRepoIDsForIssuesOptions(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) for _, test := range []struct { - Opts IssuesOptions + Opts issues_model.IssuesOptions ExpectedRepoIDs []int64 }{ { - IssuesOptions{ + issues_model.IssuesOptions{ AssigneeID: 2, }, []int64{3, 32}, }, { - IssuesOptions{ + issues_model.IssuesOptions{ RepoCond: builder.In("repo_id", 1, 2), }, []int64{1, 2}, }, } { - repoIDs, err := GetRepoIDsForIssuesOptions(&test.Opts, user) + repoIDs, err := issues_model.GetRepoIDsForIssuesOptions(&test.Opts, user) assert.NoError(t, err) if assert.Len(t, repoIDs, len(test.ExpectedRepoIDs)) { for i, repoID := range repoIDs { @@ -375,20 +375,20 @@ func TestGetRepoIDsForIssuesOptions(t *testing.T) { } } -func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *Issue { - var newIssue Issue +func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *issues_model.Issue { + var newIssue issues_model.Issue t.Run(title, func(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - issue := Issue{ + issue := issues_model.Issue{ RepoID: repo.ID, PosterID: user.ID, Poster: user, Title: title, Content: content, } - err := NewIssue(repo, &issue, nil, nil) + err := issues_model.NewIssue(repo, &issue, nil, nil) assert.NoError(t, err) has, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Get(&newIssue) @@ -408,75 +408,23 @@ func TestIssue_InsertIssue(t *testing.T) { // there are 5 issues and max index is 5 on repository 1, so this one should 6 issue := testInsertIssue(t, "my issue1", "special issue's comments?", 6) - _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Delete(new(Issue)) + _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Delete(new(issues_model.Issue)) assert.NoError(t, err) issue = testInsertIssue(t, `my issue2, this is my son's love \n \r \ `, "special issue's '' comments?", 7) - _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Delete(new(Issue)) + _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Delete(new(issues_model.Issue)) assert.NoError(t, err) } -func TestIssue_DeleteIssue(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - issueIDs, err := GetIssueIDsByRepoID(db.DefaultContext, 1) - assert.NoError(t, err) - assert.EqualValues(t, 5, len(issueIDs)) - - issue := &Issue{ - RepoID: 1, - ID: issueIDs[2], - } - - err = DeleteIssue(issue) - assert.NoError(t, err) - issueIDs, err = GetIssueIDsByRepoID(db.DefaultContext, 1) - assert.NoError(t, err) - assert.EqualValues(t, 4, len(issueIDs)) - - // check attachment removal - attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 4) - assert.NoError(t, err) - issue, err = GetIssueByID(4) - assert.NoError(t, err) - err = DeleteIssue(issue) - assert.NoError(t, err) - assert.EqualValues(t, 2, len(attachments)) - for i := range attachments { - attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attachments[i].UUID) - assert.Error(t, err) - assert.True(t, repo_model.IsErrAttachmentNotExist(err)) - assert.Nil(t, attachment) - } - - // check issue dependencies - user, err := user_model.GetUserByID(1) - assert.NoError(t, err) - issue1, err := GetIssueByID(1) - assert.NoError(t, err) - issue2, err := GetIssueByID(2) - assert.NoError(t, err) - err = CreateIssueDependency(user, issue1, issue2) - assert.NoError(t, err) - left, err := IssueNoDependenciesLeft(db.DefaultContext, issue1) - assert.NoError(t, err) - assert.False(t, left) - err = DeleteIssue(&Issue{ID: 2}) - assert.NoError(t, err) - left, err = IssueNoDependenciesLeft(db.DefaultContext, issue1) - assert.NoError(t, err) - assert.True(t, left) -} - func TestIssue_ResolveMentions(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(owner, repo, doer string, mentions []string, expected []int64) { o := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: owner}).(*user_model.User) r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: o.ID, LowerName: repo}).(*repo_model.Repository) - issue := &Issue{RepoID: r.ID} + issue := &issues_model.Issue{RepoID: r.ID} d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer}).(*user_model.User) - resolved, err := ResolveIssueMentionsByVisibility(db.DefaultContext, issue, d, mentions) + resolved, err := issues_model.ResolveIssueMentionsByVisibility(db.DefaultContext, issue, d, mentions) assert.NoError(t, err) ids := make([]int64, len(resolved)) for i, user := range resolved { @@ -523,7 +471,7 @@ func TestCorrectIssueStats(t *testing.T) { // Each new issues will have a constant description "Bugs are nasty" // Which will be used later on. - issueAmount := maxQueryParameters + 10 + issueAmount := issues_model.MaxQueryParameters + 10 var wg sync.WaitGroup for i := 0; i < issueAmount; i++ { @@ -536,7 +484,7 @@ func TestCorrectIssueStats(t *testing.T) { wg.Wait() // Now we will get all issueID's that match the "Bugs are nasty" query. - total, ids, err := SearchIssueIDsByKeyword(context.TODO(), "Bugs are nasty", []int64{1}, issueAmount, 0) + total, ids, err := issues_model.SearchIssueIDsByKeyword(context.TODO(), "Bugs are nasty", []int64{1}, issueAmount, 0) // Just to be sure. assert.NoError(t, err) @@ -544,7 +492,7 @@ func TestCorrectIssueStats(t *testing.T) { // Now we will call the GetIssueStats with these IDs and if working, // get the correct stats back. - issueStats, err := GetIssueStats(&IssueStatsOptions{ + issueStats, err := issues_model.GetIssueStats(&issues_model.IssueStatsOptions{ RepoID: 1, IssueIDs: ids, }) @@ -556,19 +504,19 @@ func TestCorrectIssueStats(t *testing.T) { func TestIssueForeignReference(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 4}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue) assert.NotEqualValues(t, issue.Index, issue.ID) // make sure they are different to avoid false positive // it is fine for an issue to not have a foreign reference - err := issue.LoadAttributes() + err := issue.LoadAttributes(db.DefaultContext) assert.NoError(t, err) assert.Nil(t, issue.ForeignReference) var foreignIndex int64 = 12345 - _, err = GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex) + _, err = issues_model.GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex) assert.True(t, foreignreference.IsErrLocalIndexNotExist(err)) - _, err = db.GetEngine(db.DefaultContext).Insert(&foreignreference.ForeignReference{ + err = db.Insert(db.DefaultContext, &foreignreference.ForeignReference{ LocalIndex: issue.Index, ForeignIndex: strconv.FormatInt(foreignIndex, 10), RepoID: issue.RepoID, @@ -576,12 +524,12 @@ func TestIssueForeignReference(t *testing.T) { }) assert.NoError(t, err) - err = issue.LoadAttributes() + err = issue.LoadAttributes(db.DefaultContext) assert.NoError(t, err) assert.EqualValues(t, issue.ForeignReference.ForeignIndex, strconv.FormatInt(foreignIndex, 10)) - found, err := GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex) + found, err := issues_model.GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex) assert.NoError(t, err) assert.EqualValues(t, found.Index, issue.Index) } @@ -608,7 +556,7 @@ func TestLoadTotalTrackedTime(t *testing.T) { func TestCountIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - count, err := CountIssues(&IssuesOptions{}) + count, err := issues_model.CountIssues(&issues_model.IssuesOptions{}) assert.NoError(t, err) assert.EqualValues(t, 17, count) } diff --git a/models/issue_user.go b/models/issues/issue_user.go index 19c64094a1..f5d22589af 100644 --- a/models/issue_user.go +++ b/models/issues/issue_user.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -25,7 +25,8 @@ func init() { db.RegisterModel(new(IssueUser)) } -func newIssueUsers(ctx context.Context, repo *repo_model.Repository, issue *Issue) error { +// NewIssueUsers inserts an issue related users +func NewIssueUsers(ctx context.Context, repo *repo_model.Repository, issue *Issue) error { assignees, err := repo_model.GetRepoAssignees(ctx, repo) if err != nil { return fmt.Errorf("getAssignees: %v", err) diff --git a/models/issues/issue_user_test.go b/models/issues/issue_user_test.go new file mode 100644 index 0000000000..33e9f98ecc --- /dev/null +++ b/models/issues/issue_user_test.go @@ -0,0 +1,62 @@ +// Copyright 2017 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package issues_test + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + + "github.com/stretchr/testify/assert" +) + +func Test_NewIssueUsers(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + newIssue := &issues_model.Issue{ + RepoID: repo.ID, + PosterID: 4, + Index: 6, + Title: "newTestIssueTitle", + Content: "newTestIssueContent", + } + + // artificially insert new issue + unittest.AssertSuccessfulInsert(t, newIssue) + + assert.NoError(t, issues_model.NewIssueUsers(db.DefaultContext, repo, newIssue)) + + // issue_user table should now have entries for new issue + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: newIssue.ID, UID: newIssue.PosterID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: newIssue.ID, UID: repo.OwnerID}) +} + +func TestUpdateIssueUserByRead(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + + assert.NoError(t, issues_model.UpdateIssueUserByRead(4, issue.ID)) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") + + assert.NoError(t, issues_model.UpdateIssueUserByRead(4, issue.ID)) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") + + assert.NoError(t, issues_model.UpdateIssueUserByRead(unittest.NonexistentID, unittest.NonexistentID)) +} + +func TestUpdateIssueUsersByMentions(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + + uids := []int64{2, 5} + assert.NoError(t, issues_model.UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids)) + for _, uid := range uids { + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: uid}, "is_mentioned=1") + } +} diff --git a/models/issue_watch.go b/models/issues/issue_watch.go index 9f41d36e19..bf907aa8fd 100644 --- a/models/issue_watch.go +++ b/models/issues/issue_watch.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -125,7 +125,8 @@ func CountIssueWatchers(ctx context.Context, issueID int64) (int64, error) { Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id").Count(new(IssueWatch)) } -func removeIssueWatchersByRepoID(ctx context.Context, userID, repoID int64) error { +// RemoveIssueWatchersByRepoID remove issue watchers by repoID +func RemoveIssueWatchersByRepoID(ctx context.Context, userID, repoID int64) error { _, err := db.GetEngine(ctx). Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", repoID). Where("`issue_watch`.user_id = ?", userID). diff --git a/models/issue_watch_test.go b/models/issues/issue_watch_test.go index b686196ae1..c6b6416d9b 100644 --- a/models/issue_watch_test.go +++ b/models/issues/issue_watch_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -16,28 +17,28 @@ import ( func TestCreateOrUpdateIssueWatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, CreateOrUpdateIssueWatch(3, 1, true)) - iw := unittest.AssertExistsAndLoadBean(t, &IssueWatch{UserID: 3, IssueID: 1}).(*IssueWatch) + assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(3, 1, true)) + iw := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 3, IssueID: 1}).(*issues_model.IssueWatch) assert.True(t, iw.IsWatching) - assert.NoError(t, CreateOrUpdateIssueWatch(1, 1, false)) - iw = unittest.AssertExistsAndLoadBean(t, &IssueWatch{UserID: 1, IssueID: 1}).(*IssueWatch) + assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(1, 1, false)) + iw = unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 1, IssueID: 1}).(*issues_model.IssueWatch) assert.False(t, iw.IsWatching) } func TestGetIssueWatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - _, exists, err := GetIssueWatch(db.DefaultContext, 9, 1) + _, exists, err := issues_model.GetIssueWatch(db.DefaultContext, 9, 1) assert.True(t, exists) assert.NoError(t, err) - iw, exists, err := GetIssueWatch(db.DefaultContext, 2, 2) + iw, exists, err := issues_model.GetIssueWatch(db.DefaultContext, 2, 2) assert.True(t, exists) assert.NoError(t, err) assert.False(t, iw.IsWatching) - _, exists, err = GetIssueWatch(db.DefaultContext, 3, 1) + _, exists, err = issues_model.GetIssueWatch(db.DefaultContext, 3, 1) assert.False(t, exists) assert.NoError(t, err) } @@ -45,22 +46,22 @@ func TestGetIssueWatch(t *testing.T) { func TestGetIssueWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - iws, err := GetIssueWatchers(db.DefaultContext, 1, db.ListOptions{}) + iws, err := issues_model.GetIssueWatchers(db.DefaultContext, 1, db.ListOptions{}) assert.NoError(t, err) // Watcher is inactive, thus 0 assert.Len(t, iws, 0) - iws, err = GetIssueWatchers(db.DefaultContext, 2, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 2, db.ListOptions{}) assert.NoError(t, err) // Watcher is explicit not watching assert.Len(t, iws, 0) - iws, err = GetIssueWatchers(db.DefaultContext, 5, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 5, db.ListOptions{}) assert.NoError(t, err) // Issue has no Watchers assert.Len(t, iws, 0) - iws, err = GetIssueWatchers(db.DefaultContext, 7, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 7, db.ListOptions{}) assert.NoError(t, err) // Issue has one watcher assert.Len(t, iws, 1) diff --git a/models/issue_xref.go b/models/issues/issue_xref.go index 0c1623b5a4..f4380a02ec 100644 --- a/models/issue_xref.go +++ b/models/issues/issue_xref.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -55,15 +55,8 @@ func neuterCrossReferencesIds(ctx context.Context, ids []int64) error { return err } -// .___ -// | | ______ ________ __ ____ -// | |/ ___// ___/ | \_/ __ \ -// | |\___ \ \___ \| | /\ ___/ -// |___/____ >____ >____/ \___ > -// \/ \/ \/ -// - -func (issue *Issue) addCrossReferences(stdCtx context.Context, doer *user_model.User, removeOld bool) error { +// AddCrossReferences add cross repositories references. +func (issue *Issue) AddCrossReferences(stdCtx context.Context, doer *user_model.User, removeOld bool) error { var commentType CommentType if issue.IsPull { commentType = CommentTypePullRef @@ -237,15 +230,8 @@ func (issue *Issue) verifyReferencedIssue(stdCtx context.Context, ctx *crossRefe return refIssue, refAction, nil } -// _________ __ -// \_ ___ \ ____ _____ _____ ____ _____/ |_ -// / \ \/ / _ \ / \ / \_/ __ \ / \ __\ -// \ \___( <_> ) Y Y \ Y Y \ ___/| | \ | -// \______ /\____/|__|_| /__|_| /\___ >___| /__| -// \/ \/ \/ \/ \/ -// - -func (comment *Comment) addCrossReferences(stdCtx context.Context, doer *user_model.User, removeOld bool) error { +// AddCrossReferences add cross references +func (comment *Comment) AddCrossReferences(stdCtx context.Context, doer *user_model.User, removeOld bool) error { if comment.Type != CommentTypeCode && comment.Type != CommentTypeComment { return nil } @@ -280,7 +266,7 @@ func (comment *Comment) LoadRefIssue() (err error) { if comment.RefIssue != nil { return nil } - comment.RefIssue, err = GetIssueByID(comment.RefIssueID) + comment.RefIssue, err = GetIssueByID(db.DefaultContext, comment.RefIssueID) if err == nil { err = comment.RefIssue.LoadRepo(db.DefaultContext) } diff --git a/models/issue_xref_test.go b/models/issues/issue_xref_test.go index b4ad5b2708..6bb19d5328 100644 --- a/models/issue_xref_test.go +++ b/models/issues/issue_xref_test.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "fmt" "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -26,8 +27,8 @@ func TestXRef_AddCrossReferences(t *testing.T) { // PR to close issue #1 content := fmt.Sprintf("content2, closes #%d", itarget.Index) pr := testCreateIssue(t, 1, 2, "title2", content, true) - ref := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypePullRef, ref.Type) + ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypePullRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.True(t, ref.RefIsPull) assert.Equal(t, references.XRefActionCloses, ref.RefAction) @@ -35,8 +36,8 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Comment on PR to reopen issue #1 content = fmt.Sprintf("content2, reopens #%d", itarget.Index) c := testCreateComment(t, 1, 2, pr.ID, content) - ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}).(*Comment) - assert.Equal(t, CommentTypeCommentRef, ref.Type) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.True(t, ref.RefIsPull) assert.Equal(t, references.XRefActionReopens, ref.RefAction) @@ -44,8 +45,8 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Issue mentioning issue #1 content = fmt.Sprintf("content3, mentions #%d", itarget.Index) i := testCreateIssue(t, 1, 2, "title3", content, false) - ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypeIssueRef, ref.Type) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.False(t, ref.RefIsPull) assert.Equal(t, references.XRefActionNone, ref.RefAction) @@ -56,8 +57,8 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Cross-reference to issue #4 by admin content = fmt.Sprintf("content5, mentions user3/repo3#%d", itarget.Index) i = testCreateIssue(t, 2, 1, "title5", content, false) - ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypeIssueRef, ref.Type) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, i.RepoID, ref.RefRepoID) assert.False(t, ref.RefIsPull) assert.Equal(t, references.XRefActionNone, ref.RefAction) @@ -65,7 +66,7 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Cross-reference to issue #4 with no permission content = fmt.Sprintf("content6, mentions user3/repo3#%d", itarget.Index) i = testCreateIssue(t, 4, 5, "title6", content, false) - unittest.AssertNotExistsBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) + unittest.AssertNotExistsBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) } func TestXRef_NeuterCrossReferences(t *testing.T) { @@ -77,16 +78,16 @@ func TestXRef_NeuterCrossReferences(t *testing.T) { // Issue mentioning issue #1 title := fmt.Sprintf("title2, mentions #%d", itarget.Index) i := testCreateIssue(t, 1, 2, title, "content2", false) - ref := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypeIssueRef, ref.Type) + ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, references.XRefActionNone, ref.RefAction) d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) i.Title = "title2, no mentions" - assert.NoError(t, ChangeIssueTitle(i, d, title)) + assert.NoError(t, issues_model.ChangeIssueTitle(i, d, title)) - ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypeIssueRef, ref.Type) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, references.XRefActionNeutered, ref.RefAction) } @@ -98,25 +99,25 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { i1 := testCreateIssue(t, 1, 2, "title1", "content1", false) i2 := testCreateIssue(t, 1, 2, "title2", "content2", false) i3 := testCreateIssue(t, 1, 2, "title3", "content3", false) - _, err := ChangeIssueStatus(db.DefaultContext, i3, d, true) + _, err := issues_model.ChangeIssueStatus(db.DefaultContext, i3, d, true) assert.NoError(t, err) pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index)) - rp := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}).(*Comment) + rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}).(*issues_model.Comment) c1 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i2.Index)) - r1 := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}).(*Comment) + r1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}).(*issues_model.Comment) // Must be ignored c2 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("mentions #%d", i2.Index)) - unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c2.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c2.ID}) // Must be superseded by c4/r4 c3 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("reopens #%d", i3.Index)) - unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID}) c4 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index)) - r4 := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}).(*Comment) + r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}).(*issues_model.Comment) refs, err := pr.ResolveCrossReferences(db.DefaultContext) assert.NoError(t, err) @@ -126,13 +127,13 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { assert.Equal(t, r4.ID, refs[2].ID, "bad ref r4: %+v", refs[2]) } -func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *Issue { +func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *issues_model.Issue { r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository) d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) idx, err := db.GetNextResourceIndex("issue_index", r.ID) assert.NoError(t, err) - i := &Issue{ + i := &issues_model.Issue{ RepoID: r.ID, PosterID: d.ID, Poster: d, @@ -145,39 +146,39 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu ctx, committer, err := db.TxContext() assert.NoError(t, err) defer committer.Close() - err = newIssue(ctx, d, NewIssueOptions{ + err = issues_model.NewIssueWithIndex(ctx, d, issues_model.NewIssueOptions{ Repo: r, Issue: i, }) assert.NoError(t, err) - i, err = getIssueByID(ctx, i.ID) + i, err = issues_model.GetIssueByID(ctx, i.ID) assert.NoError(t, err) - assert.NoError(t, i.addCrossReferences(ctx, d, false)) + assert.NoError(t, i.AddCrossReferences(ctx, d, false)) assert.NoError(t, committer.Commit()) return i } -func testCreatePR(t *testing.T, repo, doer int64, title, content string) *PullRequest { +func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues_model.PullRequest { r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository) d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) - i := &Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true} - pr := &PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: PullRequestStatusMergeable} - assert.NoError(t, NewPullRequest(db.DefaultContext, r, i, nil, nil, pr)) + i := &issues_model.Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true} + pr := &issues_model.PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: issues_model.PullRequestStatusMergeable} + assert.NoError(t, issues_model.NewPullRequest(db.DefaultContext, r, i, nil, nil, pr)) pr.Issue = i return pr } -func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *Comment { +func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *issues_model.Comment { d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) - i := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue}).(*Issue) - c := &Comment{Type: CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} + i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue}).(*issues_model.Issue) + c := &issues_model.Comment{Type: issues_model.CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} ctx, committer, err := db.TxContext() assert.NoError(t, err) defer committer.Close() err = db.Insert(ctx, c) assert.NoError(t, err) - assert.NoError(t, c.addCrossReferences(ctx, d, false)) + assert.NoError(t, c.AddCrossReferences(ctx, d, false)) assert.NoError(t, committer.Commit()) return c } diff --git a/models/issue_label.go b/models/issues/label.go index 48a48dbb7c..98e2e43961 100644 --- a/models/issue_label.go +++ b/models/issues/label.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -21,6 +21,53 @@ import ( "xorm.io/builder" ) +// ErrRepoLabelNotExist represents a "RepoLabelNotExist" kind of error. +type ErrRepoLabelNotExist struct { + LabelID int64 + RepoID int64 +} + +// IsErrRepoLabelNotExist checks if an error is a RepoErrLabelNotExist. +func IsErrRepoLabelNotExist(err error) bool { + _, ok := err.(ErrRepoLabelNotExist) + return ok +} + +func (err ErrRepoLabelNotExist) Error() string { + return fmt.Sprintf("label does not exist [label_id: %d, repo_id: %d]", err.LabelID, err.RepoID) +} + +// ErrOrgLabelNotExist represents a "OrgLabelNotExist" kind of error. +type ErrOrgLabelNotExist struct { + LabelID int64 + OrgID int64 +} + +// IsErrOrgLabelNotExist checks if an error is a OrgErrLabelNotExist. +func IsErrOrgLabelNotExist(err error) bool { + _, ok := err.(ErrOrgLabelNotExist) + return ok +} + +func (err ErrOrgLabelNotExist) Error() string { + return fmt.Sprintf("label does not exist [label_id: %d, org_id: %d]", err.LabelID, err.OrgID) +} + +// ErrLabelNotExist represents a "LabelNotExist" kind of error. +type ErrLabelNotExist struct { + LabelID int64 +} + +// IsErrLabelNotExist checks if an error is a ErrLabelNotExist. +func IsErrLabelNotExist(err error) bool { + _, ok := err.(ErrLabelNotExist) + return ok +} + +func (err ErrLabelNotExist) Error() string { + return fmt.Sprintf("label does not exist [label_id: %d]", err.LabelID) +} + // LabelColorPattern is a regexp witch can validate LabelColor var LabelColorPattern = regexp.MustCompile("^#?(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})$") @@ -671,7 +718,8 @@ func DeleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *use return issue.LoadLabels(ctx) } -func deleteLabelsByRepoID(ctx context.Context, repoID int64) error { +// DeleteLabelsByRepoID deletes labels of some repository +func DeleteLabelsByRepoID(ctx context.Context, repoID int64) error { deleteCond := builder.Select("id").From("label").Where(builder.Eq{"label.repo_id": repoID}) if _, err := db.GetEngine(ctx).In("label_id", deleteCond). @@ -682,3 +730,107 @@ func deleteLabelsByRepoID(ctx context.Context, repoID int64) error { _, err := db.DeleteByBean(ctx, &Label{RepoID: repoID}) return err } + +// CountOrphanedLabels return count of labels witch are broken and not accessible via ui anymore +func CountOrphanedLabels() (int64, error) { + noref, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Count("label.id") + if err != nil { + return 0, err + } + + norepo, err := db.GetEngine(db.DefaultContext).Table("label"). + Where(builder.And( + builder.Gt{"repo_id": 0}, + builder.NotIn("repo_id", builder.Select("id").From("repository")), + )). + Count() + if err != nil { + return 0, err + } + + noorg, err := db.GetEngine(db.DefaultContext).Table("label"). + Where(builder.And( + builder.Gt{"org_id": 0}, + builder.NotIn("org_id", builder.Select("id").From("user")), + )). + Count() + if err != nil { + return 0, err + } + + return noref + norepo + noorg, nil +} + +// DeleteOrphanedLabels delete labels witch are broken and not accessible via ui anymore +func DeleteOrphanedLabels() error { + // delete labels with no reference + if _, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Delete(new(Label)); err != nil { + return err + } + + // delete labels with none existing repos + if _, err := db.GetEngine(db.DefaultContext). + Where(builder.And( + builder.Gt{"repo_id": 0}, + builder.NotIn("repo_id", builder.Select("id").From("repository")), + )). + Delete(Label{}); err != nil { + return err + } + + // delete labels with none existing orgs + if _, err := db.GetEngine(db.DefaultContext). + Where(builder.And( + builder.Gt{"org_id": 0}, + builder.NotIn("org_id", builder.Select("id").From("user")), + )). + Delete(Label{}); err != nil { + return err + } + + return nil +} + +// CountOrphanedIssueLabels return count of IssueLabels witch have no label behind anymore +func CountOrphanedIssueLabels() (int64, error) { + return db.GetEngine(db.DefaultContext).Table("issue_label"). + NotIn("label_id", builder.Select("id").From("label")). + Count() +} + +// DeleteOrphanedIssueLabels delete IssueLabels witch have no label behind anymore +func DeleteOrphanedIssueLabels() error { + _, err := db.GetEngine(db.DefaultContext). + NotIn("label_id", builder.Select("id").From("label")). + Delete(IssueLabel{}) + return err +} + +// CountIssueLabelWithOutsideLabels count label comments with outside label +func CountIssueLabelWithOutsideLabels() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.Expr("(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)")). + Table("issue_label"). + Join("inner", "label", "issue_label.label_id = label.id "). + Join("inner", "issue", "issue.id = issue_label.issue_id "). + Join("inner", "repository", "issue.repo_id = repository.id"). + Count(new(IssueLabel)) +} + +// FixIssueLabelWithOutsideLabels fix label comments with outside label +func FixIssueLabelWithOutsideLabels() (int64, error) { + res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM issue_label WHERE issue_label.id IN ( + SELECT il_too.id FROM ( + SELECT il_too_too.id + FROM issue_label AS il_too_too + INNER JOIN label ON il_too_too.label_id = label.id + INNER JOIN issue on issue.id = il_too_too.issue_id + INNER JOIN repository on repository.id = issue.repo_id + WHERE + (label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id) + ) AS il_too )`) + if err != nil { + return 0, err + } + + return res.RowsAffected() +} diff --git a/models/issues/label_test.go b/models/issues/label_test.go new file mode 100644 index 0000000000..33f114b5fe --- /dev/null +++ b/models/issues/label_test.go @@ -0,0 +1,395 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package issues_test + +import ( + "html/template" + "testing" + + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + + "github.com/stretchr/testify/assert" +) + +// TODO TestGetLabelTemplateFile + +func TestLabel_CalOpenIssues(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label.CalOpenIssues() + assert.EqualValues(t, 2, label.NumOpenIssues) +} + +func TestLabel_ForegroundColor(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + assert.Equal(t, template.CSS("#000"), label.ForegroundColor()) + + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + assert.Equal(t, template.CSS("#fff"), label.ForegroundColor()) +} + +func TestNewLabels(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labels := []*issues_model.Label{ + {RepoID: 2, Name: "labelName2", Color: "#123456"}, + {RepoID: 3, Name: "labelName3", Color: "#123"}, + {RepoID: 4, Name: "labelName4", Color: "ABCDEF"}, + {RepoID: 5, Name: "labelName5", Color: "DEF"}, + } + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: ""})) + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#45G"})) + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"})) + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "45G"})) + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "12345G"})) + for _, label := range labels { + unittest.AssertNotExistsBean(t, label) + } + assert.NoError(t, issues_model.NewLabels(labels...)) + for _, label := range labels { + unittest.AssertExistsAndLoadBean(t, label, unittest.Cond("id = ?", label.ID)) + } + unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{}) +} + +func TestGetLabelByID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelByID(db.DefaultContext, 1) + assert.NoError(t, err) + assert.EqualValues(t, 1, label.ID) + + _, err = issues_model.GetLabelByID(db.DefaultContext, unittest.NonexistentID) + assert.True(t, issues_model.IsErrLabelNotExist(err)) +} + +func TestGetLabelInRepoByName(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelInRepoByName(db.DefaultContext, 1, "label1") + assert.NoError(t, err) + assert.EqualValues(t, 1, label.ID) + assert.Equal(t, "label1", label.Name) + + _, err = issues_model.GetLabelInRepoByName(db.DefaultContext, 1, "") + assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) + + _, err = issues_model.GetLabelInRepoByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") + assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) +} + +func TestGetLabelInRepoByNames(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labelIDs, err := issues_model.GetLabelIDsInRepoByNames(1, []string{"label1", "label2"}) + assert.NoError(t, err) + + assert.Len(t, labelIDs, 2) + + assert.Equal(t, int64(1), labelIDs[0]) + assert.Equal(t, int64(2), labelIDs[1]) +} + +func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + // label3 doesn't exists.. See labels.yml + labelIDs, err := issues_model.GetLabelIDsInRepoByNames(1, []string{"label1", "label2", "label3"}) + assert.NoError(t, err) + + assert.Len(t, labelIDs, 2) + + assert.Equal(t, int64(1), labelIDs[0]) + assert.Equal(t, int64(2), labelIDs[1]) + assert.NoError(t, err) +} + +func TestGetLabelInRepoByID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelInRepoByID(db.DefaultContext, 1, 1) + assert.NoError(t, err) + assert.EqualValues(t, 1, label.ID) + + _, err = issues_model.GetLabelInRepoByID(db.DefaultContext, 1, -1) + assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) + + _, err = issues_model.GetLabelInRepoByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) +} + +func TestGetLabelsInRepoByIDs(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labels, err := issues_model.GetLabelsInRepoByIDs(1, []int64{1, 2, unittest.NonexistentID}) + assert.NoError(t, err) + if assert.Len(t, labels, 2) { + assert.EqualValues(t, 1, labels[0].ID) + assert.EqualValues(t, 2, labels[1].ID) + } +} + +func TestGetLabelsByRepoID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) { + labels, err := issues_model.GetLabelsByRepoID(db.DefaultContext, repoID, sortType, db.ListOptions{}) + assert.NoError(t, err) + assert.Len(t, labels, len(expectedIssueIDs)) + for i, label := range labels { + assert.EqualValues(t, expectedIssueIDs[i], label.ID) + } + } + testSuccess(1, "leastissues", []int64{2, 1}) + testSuccess(1, "mostissues", []int64{1, 2}) + testSuccess(1, "reversealphabetically", []int64{2, 1}) + testSuccess(1, "default", []int64{1, 2}) +} + +// Org versions + +func TestGetLabelInOrgByName(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelInOrgByName(db.DefaultContext, 3, "orglabel3") + assert.NoError(t, err) + assert.EqualValues(t, 3, label.ID) + assert.Equal(t, "orglabel3", label.Name) + + _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, 3, "") + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, 0, "orglabel3") + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, -1, "orglabel3") + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) +} + +func TestGetLabelInOrgByNames(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labelIDs, err := issues_model.GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4"}) + assert.NoError(t, err) + + assert.Len(t, labelIDs, 2) + + assert.Equal(t, int64(3), labelIDs[0]) + assert.Equal(t, int64(4), labelIDs[1]) +} + +func TestGetLabelInOrgByNamesDiscardsNonExistentLabels(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + // orglabel99 doesn't exists.. See labels.yml + labelIDs, err := issues_model.GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4", "orglabel99"}) + assert.NoError(t, err) + + assert.Len(t, labelIDs, 2) + + assert.Equal(t, int64(3), labelIDs[0]) + assert.Equal(t, int64(4), labelIDs[1]) + assert.NoError(t, err) +} + +func TestGetLabelInOrgByID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelInOrgByID(db.DefaultContext, 3, 3) + assert.NoError(t, err) + assert.EqualValues(t, 3, label.ID) + + _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, 3, -1) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, 0, 3) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, -1, 3) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) +} + +func TestGetLabelsInOrgByIDs(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labels, err := issues_model.GetLabelsInOrgByIDs(3, []int64{3, 4, unittest.NonexistentID}) + assert.NoError(t, err) + if assert.Len(t, labels, 2) { + assert.EqualValues(t, 3, labels[0].ID) + assert.EqualValues(t, 4, labels[1].ID) + } +} + +func TestGetLabelsByOrgID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + testSuccess := func(orgID int64, sortType string, expectedIssueIDs []int64) { + labels, err := issues_model.GetLabelsByOrgID(db.DefaultContext, orgID, sortType, db.ListOptions{}) + assert.NoError(t, err) + assert.Len(t, labels, len(expectedIssueIDs)) + for i, label := range labels { + assert.EqualValues(t, expectedIssueIDs[i], label.ID) + } + } + testSuccess(3, "leastissues", []int64{3, 4}) + testSuccess(3, "mostissues", []int64{4, 3}) + testSuccess(3, "reversealphabetically", []int64{4, 3}) + testSuccess(3, "default", []int64{3, 4}) + + var err error + _, err = issues_model.GetLabelsByOrgID(db.DefaultContext, 0, "leastissues", db.ListOptions{}) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelsByOrgID(db.DefaultContext, -1, "leastissues", db.ListOptions{}) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) +} + +// + +func TestGetLabelsByIssueID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labels, err := issues_model.GetLabelsByIssueID(db.DefaultContext, 1) + assert.NoError(t, err) + if assert.Len(t, labels, 1) { + assert.EqualValues(t, 1, labels[0].ID) + } + + labels, err = issues_model.GetLabelsByIssueID(db.DefaultContext, unittest.NonexistentID) + assert.NoError(t, err) + assert.Len(t, labels, 0) +} + +func TestUpdateLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + // make sure update wont overwrite it + update := &issues_model.Label{ + ID: label.ID, + Color: "#ffff00", + Name: "newLabelName", + Description: label.Description, + } + label.Color = update.Color + label.Name = update.Name + assert.NoError(t, issues_model.UpdateLabel(update)) + newLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + assert.EqualValues(t, label.ID, newLabel.ID) + assert.EqualValues(t, label.Color, newLabel.Color) + assert.EqualValues(t, label.Name, newLabel.Name) + assert.EqualValues(t, label.Description, newLabel.Description) + unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{}) +} + +func TestDeleteLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + assert.NoError(t, issues_model.DeleteLabel(label.RepoID, label.ID)) + unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID, RepoID: label.RepoID}) + + assert.NoError(t, issues_model.DeleteLabel(label.RepoID, label.ID)) + unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID}) + + assert.NoError(t, issues_model.DeleteLabel(unittest.NonexistentID, unittest.NonexistentID)) + unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{}) +} + +func TestHasIssueLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + assert.True(t, issues_model.HasIssueLabel(db.DefaultContext, 1, 1)) + assert.False(t, issues_model.HasIssueLabel(db.DefaultContext, 1, 2)) + assert.False(t, issues_model.HasIssueLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) +} + +func TestNewIssueLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + + // add new IssueLabel + prevNumIssues := label.NumIssues + assert.NoError(t, issues_model.NewIssueLabel(issue, label, doer)) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ + Type: issues_model.CommentTypeLabel, + PosterID: doer.ID, + IssueID: issue.ID, + LabelID: label.ID, + Content: "1", + }) + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + assert.EqualValues(t, prevNumIssues+1, label.NumIssues) + + // re-add existing IssueLabel + assert.NoError(t, issues_model.NewIssueLabel(issue, label, doer)) + unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{}) +} + +func TestNewIssueLabels(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5}).(*issues_model.Issue) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + + assert.NoError(t, issues_model.NewIssueLabels(issue, []*issues_model.Label{label1, label2}, doer)) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ + Type: issues_model.CommentTypeLabel, + PosterID: doer.ID, + IssueID: issue.ID, + LabelID: label1.ID, + Content: "1", + }) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) + label1 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + assert.EqualValues(t, 3, label1.NumIssues) + assert.EqualValues(t, 1, label1.NumClosedIssues) + label2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + assert.EqualValues(t, 1, label2.NumIssues) + assert.EqualValues(t, 1, label2.NumClosedIssues) + + // corner case: test empty slice + assert.NoError(t, issues_model.NewIssueLabels(issue, []*issues_model.Label{}, doer)) + + unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{}) +} + +func TestDeleteIssueLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + testSuccess := func(labelID, issueID, doerID int64) { + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}).(*issues_model.Issue) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID}).(*user_model.User) + + expectedNumIssues := label.NumIssues + expectedNumClosedIssues := label.NumClosedIssues + if unittest.BeanExists(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) { + expectedNumIssues-- + if issue.IsClosed { + expectedNumClosedIssues-- + } + } + + ctx, committer, err := db.TxContext() + defer committer.Close() + assert.NoError(t, err) + assert.NoError(t, issues_model.DeleteIssueLabel(ctx, issue, label, doer)) + assert.NoError(t, committer.Commit()) + + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ + Type: issues_model.CommentTypeLabel, + PosterID: doerID, + IssueID: issueID, + LabelID: labelID, + }, `content=""`) + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) + assert.EqualValues(t, expectedNumIssues, label.NumIssues) + assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues) + } + testSuccess(1, 1, 2) + testSuccess(2, 5, 2) + testSuccess(1, 1, 2) // delete non-existent IssueLabel + + unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{}) +} diff --git a/models/issues/main_test.go b/models/issues/main_test.go index 30f6ff02fb..e34bef62ca 100644 --- a/models/issues/main_test.go +++ b/models/issues/main_test.go @@ -2,14 +2,20 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package issues +package issues_test import ( "path/filepath" "testing" + _ "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" + _ "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" + _ "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" + + "github.com/stretchr/testify/assert" ) func init() { @@ -17,14 +23,18 @@ func init() { setting.LoadForTest() } +func TestFixturesAreConsistent(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + unittest.CheckConsistencyFor(t, + &issues_model.Issue{}, + &issues_model.PullRequest{}, + &issues_model.Milestone{}, + &issues_model.Label{}, + ) +} + func TestMain(m *testing.M) { unittest.MainTest(m, &unittest.TestOptions{ GiteaRootPath: filepath.Join("..", ".."), - FixtureFiles: []string{ - "reaction.yml", - "user.yml", - "repository.yml", - "milestone.yml", - }, }) } diff --git a/models/issues/milestone.go b/models/issues/milestone.go index f7172f6448..6c10959108 100644 --- a/models/issues/milestone.go +++ b/models/issues/milestone.go @@ -292,11 +292,17 @@ func DeleteMilestoneByRepoID(repoID, id int64) error { return err } - numMilestones, err := countRepoMilestones(ctx, repo.ID) + numMilestones, err := CountMilestones(ctx, GetMilestonesOption{ + RepoID: repo.ID, + State: api.StateAll, + }) if err != nil { return err } - numClosedMilestones, err := countRepoClosedMilestones(ctx, repo.ID) + numClosedMilestones, err := CountMilestones(ctx, GetMilestonesOption{ + RepoID: repo.ID, + State: api.StateClosed, + }) if err != nil { return err } @@ -428,13 +434,6 @@ func GetMilestonesByRepoIDs(repoIDs []int64, page int, isClosed bool, sortType s ) } -// ____ _ _ -// / ___|| |_ __ _| |_ ___ -// \___ \| __/ _` | __/ __| -// ___) | || (_| | |_\__ \ -// |____/ \__\__,_|\__|___/ -// - // MilestonesStats represents milestone statistic information. type MilestonesStats struct { OpenCount, ClosedCount int64 @@ -503,23 +502,13 @@ func GetMilestonesStatsByRepoCondAndKw(repoCond builder.Cond, keyword string) (* return stats, nil } -func countRepoMilestones(ctx context.Context, repoID int64) (int64, error) { - return db.GetEngine(ctx). - Where("repo_id=?", repoID). - Count(new(Milestone)) -} - -func countRepoClosedMilestones(ctx context.Context, repoID int64) (int64, error) { +// CountMilestones returns number of milestones in given repository with other options +func CountMilestones(ctx context.Context, opts GetMilestonesOption) (int64, error) { return db.GetEngine(ctx). - Where("repo_id=? AND is_closed=?", repoID, true). + Where(opts.toCond()). Count(new(Milestone)) } -// CountRepoClosedMilestones returns number of closed milestones in given repository. -func CountRepoClosedMilestones(repoID int64) (int64, error) { - return countRepoClosedMilestones(db.DefaultContext, repoID) -} - // CountMilestonesByRepoCond map from repo conditions to number of milestones matching the options` func CountMilestonesByRepoCond(repoCond builder.Cond, isClosed bool) (map[int64]int64, error) { sess := db.GetEngine(db.DefaultContext).Where("is_closed = ?", isClosed) diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index e087318320..a6fbf9c23b 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -2,44 +2,46 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package issues +package issues_test import ( "sort" "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/timeutil" "github.com/stretchr/testify/assert" "xorm.io/builder" ) func TestMilestone_State(t *testing.T) { - assert.Equal(t, api.StateOpen, (&Milestone{IsClosed: false}).State()) - assert.Equal(t, api.StateClosed, (&Milestone{IsClosed: true}).State()) + assert.Equal(t, api.StateOpen, (&issues_model.Milestone{IsClosed: false}).State()) + assert.Equal(t, api.StateClosed, (&issues_model.Milestone{IsClosed: true}).State()) } func TestGetMilestoneByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - milestone, err := GetMilestoneByRepoID(db.DefaultContext, 1, 1) + milestone, err := issues_model.GetMilestoneByRepoID(db.DefaultContext, 1, 1) assert.NoError(t, err) assert.EqualValues(t, 1, milestone.ID) assert.EqualValues(t, 1, milestone.RepoID) - _, err = GetMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) - assert.True(t, IsErrMilestoneNotExist(err)) + _, err = issues_model.GetMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + assert.True(t, issues_model.IsErrMilestoneNotExist(err)) } func TestGetMilestonesByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64, state api.StateType) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) - milestones, _, err := GetMilestones(GetMilestonesOption{ + milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{ RepoID: repo.ID, State: state, }) @@ -76,7 +78,7 @@ func TestGetMilestonesByRepoID(t *testing.T) { test(3, api.StateClosed) test(3, api.StateAll) - milestones, _, err := GetMilestones(GetMilestonesOption{ + milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{ RepoID: unittest.NonexistentID, State: api.StateOpen, }) @@ -87,9 +89,9 @@ func TestGetMilestonesByRepoID(t *testing.T) { func TestGetMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - test := func(sortType string, sortCond func(*Milestone) int) { + test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - milestones, _, err := GetMilestones(GetMilestonesOption{ + milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, @@ -106,7 +108,7 @@ func TestGetMilestones(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - milestones, _, err = GetMilestones(GetMilestonesOption{ + milestones, _, err = issues_model.GetMilestones(issues_model.GetMilestonesOption{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, @@ -125,22 +127,22 @@ func TestGetMilestones(t *testing.T) { assert.True(t, sort.IntsAreSorted(values)) } } - test("furthestduedate", func(milestone *Milestone) int { + test("furthestduedate", func(milestone *issues_model.Milestone) int { return -int(milestone.DeadlineUnix) }) - test("leastcomplete", func(milestone *Milestone) int { + test("leastcomplete", func(milestone *issues_model.Milestone) int { return milestone.Completeness }) - test("mostcomplete", func(milestone *Milestone) int { + test("mostcomplete", func(milestone *issues_model.Milestone) int { return -milestone.Completeness }) - test("leastissues", func(milestone *Milestone) int { + test("leastissues", func(milestone *issues_model.Milestone) int { return milestone.NumIssues }) - test("mostissues", func(milestone *Milestone) int { + test("mostissues", func(milestone *issues_model.Milestone) int { return -milestone.NumIssues }) - test("soonestduedate", func(milestone *Milestone) int { + test("soonestduedate", func(milestone *issues_model.Milestone) int { return int(milestone.DeadlineUnix) }) } @@ -149,7 +151,10 @@ func TestCountRepoMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) - count, err := countRepoMilestones(db.DefaultContext, repoID) + count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + RepoID: repoID, + State: api.StateAll, + }) assert.NoError(t, err) assert.EqualValues(t, repo.NumMilestones, count) } @@ -157,7 +162,10 @@ func TestCountRepoMilestones(t *testing.T) { test(2) test(3) - count, err := countRepoMilestones(db.DefaultContext, unittest.NonexistentID) + count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + RepoID: unittest.NonexistentID, + State: api.StateAll, + }) assert.NoError(t, err) assert.EqualValues(t, 0, count) } @@ -166,7 +174,10 @@ func TestCountRepoClosedMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) - count, err := CountRepoClosedMilestones(repoID) + count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + RepoID: repoID, + State: api.StateClosed, + }) assert.NoError(t, err) assert.EqualValues(t, repo.NumClosedMilestones, count) } @@ -174,7 +185,10 @@ func TestCountRepoClosedMilestones(t *testing.T) { test(2) test(3) - count, err := CountRepoClosedMilestones(unittest.NonexistentID) + count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + RepoID: unittest.NonexistentID, + State: api.StateClosed, + }) assert.NoError(t, err) assert.EqualValues(t, 0, count) } @@ -188,12 +202,12 @@ func TestCountMilestonesByRepoIDs(t *testing.T) { repo1OpenCount, repo1ClosedCount := milestonesCount(1) repo2OpenCount, repo2ClosedCount := milestonesCount(2) - openCounts, err := CountMilestonesByRepoCond(builder.In("repo_id", []int64{1, 2}), false) + openCounts, err := issues_model.CountMilestonesByRepoCond(builder.In("repo_id", []int64{1, 2}), false) assert.NoError(t, err) assert.EqualValues(t, repo1OpenCount, openCounts[1]) assert.EqualValues(t, repo2OpenCount, openCounts[2]) - closedCounts, err := CountMilestonesByRepoCond(builder.In("repo_id", []int64{1, 2}), true) + closedCounts, err := issues_model.CountMilestonesByRepoCond(builder.In("repo_id", []int64{1, 2}), true) assert.NoError(t, err) assert.EqualValues(t, repo1ClosedCount, closedCounts[1]) assert.EqualValues(t, repo2ClosedCount, closedCounts[2]) @@ -203,9 +217,9 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - test := func(sortType string, sortCond func(*Milestone) int) { + test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - openMilestones, err := GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, false, sortType) + openMilestones, err := issues_model.GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, false, sortType) assert.NoError(t, err) assert.Len(t, openMilestones, repo1.NumOpenMilestones+repo2.NumOpenMilestones) values := make([]int, len(openMilestones)) @@ -214,7 +228,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - closedMilestones, err := GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, true, sortType) + closedMilestones, err := issues_model.GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, true, sortType) assert.NoError(t, err) assert.Len(t, closedMilestones, repo1.NumClosedMilestones+repo2.NumClosedMilestones) values = make([]int, len(closedMilestones)) @@ -224,22 +238,22 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { assert.True(t, sort.IntsAreSorted(values)) } } - test("furthestduedate", func(milestone *Milestone) int { + test("furthestduedate", func(milestone *issues_model.Milestone) int { return -int(milestone.DeadlineUnix) }) - test("leastcomplete", func(milestone *Milestone) int { + test("leastcomplete", func(milestone *issues_model.Milestone) int { return milestone.Completeness }) - test("mostcomplete", func(milestone *Milestone) int { + test("mostcomplete", func(milestone *issues_model.Milestone) int { return -milestone.Completeness }) - test("leastissues", func(milestone *Milestone) int { + test("leastissues", func(milestone *issues_model.Milestone) int { return milestone.NumIssues }) - test("mostissues", func(milestone *Milestone) int { + test("mostissues", func(milestone *issues_model.Milestone) int { return -milestone.NumIssues }) - test("soonestduedate", func(milestone *Milestone) int { + test("soonestduedate", func(milestone *issues_model.Milestone) int { return int(milestone.DeadlineUnix) }) } @@ -249,7 +263,7 @@ func TestGetMilestonesStats(t *testing.T) { test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) - stats, err := GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": repoID})) + stats, err := issues_model.GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": repoID})) assert.NoError(t, err) assert.EqualValues(t, repo.NumMilestones-repo.NumClosedMilestones, stats.OpenCount) assert.EqualValues(t, repo.NumClosedMilestones, stats.ClosedCount) @@ -258,7 +272,7 @@ func TestGetMilestonesStats(t *testing.T) { test(2) test(3) - stats, err := GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": unittest.NonexistentID})) + stats, err := issues_model.GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": unittest.NonexistentID})) assert.NoError(t, err) assert.EqualValues(t, 0, stats.OpenCount) assert.EqualValues(t, 0, stats.ClosedCount) @@ -266,8 +280,75 @@ func TestGetMilestonesStats(t *testing.T) { repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - milestoneStats, err := GetMilestonesStatsByRepoCond(builder.In("repo_id", []int64{repo1.ID, repo2.ID})) + milestoneStats, err := issues_model.GetMilestonesStatsByRepoCond(builder.In("repo_id", []int64{repo1.ID, repo2.ID})) assert.NoError(t, err) assert.EqualValues(t, repo1.NumOpenMilestones+repo2.NumOpenMilestones, milestoneStats.OpenCount) assert.EqualValues(t, repo1.NumClosedMilestones+repo2.NumClosedMilestones, milestoneStats.ClosedCount) } + +func TestNewMilestone(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + milestone := &issues_model.Milestone{ + RepoID: 1, + Name: "milestoneName", + Content: "milestoneContent", + } + + assert.NoError(t, issues_model.NewMilestone(milestone)) + unittest.AssertExistsAndLoadBean(t, milestone) + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) +} + +func TestChangeMilestoneStatus(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + + assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, true)) + unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1") + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) + + assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, false)) + unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=0") + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) +} + +func TestDeleteMilestoneByRepoID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + assert.NoError(t, issues_model.DeleteMilestoneByRepoID(1, 1)) + unittest.AssertNotExistsBean(t, &issues_model.Milestone{ID: 1}) + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}) + + assert.NoError(t, issues_model.DeleteMilestoneByRepoID(unittest.NonexistentID, unittest.NonexistentID)) +} + +func TestUpdateMilestone(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + milestone.Name = " newMilestoneName " + milestone.Content = "newMilestoneContent" + assert.NoError(t, issues_model.UpdateMilestone(milestone, milestone.IsClosed)) + milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + assert.EqualValues(t, "newMilestoneName", milestone.Name) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) +} + +func TestUpdateMilestoneCounters(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{MilestoneID: 1}, + "is_closed=0").(*issues_model.Issue) + + issue.IsClosed = true + issue.ClosedUnix = timeutil.TimeStampNow() + _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) + assert.NoError(t, err) + assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) + + issue.IsClosed = false + issue.ClosedUnix = 0 + _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) + assert.NoError(t, err) + assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) +} diff --git a/models/pull.go b/models/issues/pull.go index 238eb16636..f2ca19b03e 100644 --- a/models/pull.go +++ b/models/issues/pull.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -25,6 +25,83 @@ import ( "xorm.io/builder" ) +// ErrPullRequestNotExist represents a "PullRequestNotExist" kind of error. +type ErrPullRequestNotExist struct { + ID int64 + IssueID int64 + HeadRepoID int64 + BaseRepoID int64 + HeadBranch string + BaseBranch string +} + +// IsErrPullRequestNotExist checks if an error is a ErrPullRequestNotExist. +func IsErrPullRequestNotExist(err error) bool { + _, ok := err.(ErrPullRequestNotExist) + return ok +} + +func (err ErrPullRequestNotExist) Error() string { + return fmt.Sprintf("pull request does not exist [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", + err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) +} + +// ErrPullRequestAlreadyExists represents a "PullRequestAlreadyExists"-error +type ErrPullRequestAlreadyExists struct { + ID int64 + IssueID int64 + HeadRepoID int64 + BaseRepoID int64 + HeadBranch string + BaseBranch string +} + +// IsErrPullRequestAlreadyExists checks if an error is a ErrPullRequestAlreadyExists. +func IsErrPullRequestAlreadyExists(err error) bool { + _, ok := err.(ErrPullRequestAlreadyExists) + return ok +} + +// Error does pretty-printing :D +func (err ErrPullRequestAlreadyExists) Error() string { + return fmt.Sprintf("pull request already exists for these targets [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", + err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) +} + +// ErrPullRequestHeadRepoMissing represents a "ErrPullRequestHeadRepoMissing" error +type ErrPullRequestHeadRepoMissing struct { + ID int64 + HeadRepoID int64 +} + +// IsErrErrPullRequestHeadRepoMissing checks if an error is a ErrPullRequestHeadRepoMissing. +func IsErrErrPullRequestHeadRepoMissing(err error) bool { + _, ok := err.(ErrPullRequestHeadRepoMissing) + return ok +} + +// Error does pretty-printing :D +func (err ErrPullRequestHeadRepoMissing) Error() string { + return fmt.Sprintf("pull request head repo missing [id: %d, head_repo_id: %d]", + err.ID, err.HeadRepoID) +} + +// ErrPullWasClosed is used close a closed pull request +type ErrPullWasClosed struct { + ID int64 + Index int64 +} + +// IsErrPullWasClosed checks if an error is a ErrErrPullWasClosed. +func IsErrPullWasClosed(err error) bool { + _, ok := err.(ErrPullWasClosed) + return ok +} + +func (err ErrPullWasClosed) Error() string { + return fmt.Sprintf("Pull request [%d] %d was already closed", err.ID, err.Index) +} + // PullRequestType defines pull request type type PullRequestType int @@ -98,7 +175,8 @@ func init() { db.RegisterModel(new(PullRequest)) } -func deletePullsByBaseRepoID(ctx context.Context, repoID int64) error { +// DeletePullsByBaseRepoID deletes all pull requests by the base repository ID +func DeletePullsByBaseRepoID(ctx context.Context, repoID int64) error { deleteCond := builder.Select("id").From("pull_request").Where(builder.Eq{"pull_request.base_repo_id": repoID}) // Delete scheduled auto merges @@ -219,7 +297,7 @@ func (pr *PullRequest) LoadIssueCtx(ctx context.Context) (err error) { return nil } - pr.Issue, err = getIssueByID(ctx, pr.IssueID) + pr.Issue, err = GetIssueByID(ctx, pr.IssueID) if err == nil { pr.Issue.PullRequest = pr } @@ -420,14 +498,14 @@ func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue defer committer.Close() ctx.WithContext(outerCtx) - if err = newIssue(ctx, issue.Poster, NewIssueOptions{ + if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ Repo: repo, Issue: issue, LabelIDs: labelIDs, Attachments: uuids, IsPull: true, }); err != nil { - if IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { return err } return fmt.Errorf("newIssue: %v", err) @@ -691,3 +769,70 @@ func (pr *PullRequest) Mergeable() bool { return pr.Status != PullRequestStatusChecking && pr.Status != PullRequestStatusConflict && pr.Status != PullRequestStatusError && !pr.IsWorkInProgress() } + +// HasEnoughApprovals returns true if pr has enough granted approvals. +func HasEnoughApprovals(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { + if protectBranch.RequiredApprovals == 0 { + return true + } + return GetGrantedApprovalsCount(ctx, protectBranch, pr) >= protectBranch.RequiredApprovals +} + +// GetGrantedApprovalsCount returns the number of granted approvals for pr. A granted approval must be authored by a user in an approval whitelist. +func GetGrantedApprovalsCount(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) int64 { + sess := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). + And("type = ?", ReviewTypeApprove). + And("official = ?", true). + And("dismissed = ?", false) + if protectBranch.DismissStaleApprovals { + sess = sess.And("stale = ?", false) + } + approvals, err := sess.Count(new(Review)) + if err != nil { + log.Error("GetGrantedApprovalsCount: %v", err) + return 0 + } + + return approvals +} + +// MergeBlockedByRejectedReview returns true if merge is blocked by rejected reviews +func MergeBlockedByRejectedReview(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { + if !protectBranch.BlockOnRejectedReviews { + return false + } + rejectExist, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). + And("type = ?", ReviewTypeReject). + And("official = ?", true). + And("dismissed = ?", false). + Exist(new(Review)) + if err != nil { + log.Error("MergeBlockedByRejectedReview: %v", err) + return true + } + + return rejectExist +} + +// MergeBlockedByOfficialReviewRequests block merge because of some review request to official reviewer +// of from official review +func MergeBlockedByOfficialReviewRequests(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { + if !protectBranch.BlockOnOfficialReviewRequests { + return false + } + has, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). + And("type = ?", ReviewTypeRequest). + And("official = ?", true). + Exist(new(Review)) + if err != nil { + log.Error("MergeBlockedByOfficialReviewRequests: %v", err) + return true + } + + return has +} + +// MergeBlockedByOutdatedBranch returns true if merge is blocked by an outdated head branch +func MergeBlockedByOutdatedBranch(protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { + return protectBranch.BlockOnOutdatedBranch && pr.CommitsBehind > 0 +} diff --git a/models/pull_list.go b/models/issues/pull_list.go index fb14d3beac..9ca536909e 100644 --- a/models/pull_list.go +++ b/models/issues/pull_list.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" diff --git a/models/pull_test.go b/models/issues/pull_test.go index 00bbfc798a..0d1991383d 100644 --- a/models/pull_test.go +++ b/models/issues/pull_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -15,7 +16,7 @@ import ( func TestPullRequest_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadAttributes()) assert.NotNil(t, pr.Merger) assert.Equal(t, pr.MergerID, pr.Merger.ID) @@ -23,7 +24,7 @@ func TestPullRequest_LoadAttributes(t *testing.T) { func TestPullRequest_LoadIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadIssue()) assert.NotNil(t, pr.Issue) assert.Equal(t, int64(2), pr.Issue.ID) @@ -34,7 +35,7 @@ func TestPullRequest_LoadIssue(t *testing.T) { func TestPullRequest_LoadBaseRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadBaseRepo()) assert.NotNil(t, pr.BaseRepo) assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID) @@ -45,7 +46,7 @@ func TestPullRequest_LoadBaseRepo(t *testing.T) { func TestPullRequest_LoadHeadRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadHeadRepo()) assert.NotNil(t, pr.HeadRepo) assert.Equal(t, pr.HeadRepoID, pr.HeadRepo.ID) @@ -57,7 +58,7 @@ func TestPullRequest_LoadHeadRepo(t *testing.T) { func TestPullRequestsNewest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, count, err := PullRequests(1, &PullRequestsOptions{ + prs, count, err := issues_model.PullRequests(1, &issues_model.PullRequestsOptions{ ListOptions: db.ListOptions{ Page: 1, }, @@ -76,7 +77,7 @@ func TestPullRequestsNewest(t *testing.T) { func TestPullRequestsOldest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, count, err := PullRequests(1, &PullRequestsOptions{ + prs, count, err := issues_model.PullRequests(1, &issues_model.PullRequestsOptions{ ListOptions: db.ListOptions{ Page: 1, }, @@ -95,30 +96,30 @@ func TestPullRequestsOldest(t *testing.T) { func TestGetUnmergedPullRequest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := GetUnmergedPullRequest(1, 1, "branch2", "master", PullRequestFlowGithub) + pr, err := issues_model.GetUnmergedPullRequest(1, 1, "branch2", "master", issues_model.PullRequestFlowGithub) assert.NoError(t, err) assert.Equal(t, int64(2), pr.ID) - _, err = GetUnmergedPullRequest(1, 9223372036854775807, "branch1", "master", PullRequestFlowGithub) + _, err = issues_model.GetUnmergedPullRequest(1, 9223372036854775807, "branch1", "master", issues_model.PullRequestFlowGithub) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - exist, err := HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2") + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2") assert.NoError(t, err) assert.Equal(t, true, exist) - exist, err = HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "not_exist_branch") + exist, err = issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "not_exist_branch") assert.NoError(t, err) assert.Equal(t, false, exist) } func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, err := GetUnmergedPullRequestsByHeadInfo(1, "branch2") + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(1, "branch2") assert.NoError(t, err) assert.Len(t, prs, 1) for _, pr := range prs { @@ -129,7 +130,7 @@ func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) { func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, err := GetUnmergedPullRequestsByBaseInfo(1, "master") + prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(1, "master") assert.NoError(t, err) assert.Len(t, prs, 1) pr := prs[0] @@ -140,51 +141,51 @@ func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) { func TestGetPullRequestByIndex(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := GetPullRequestByIndex(db.DefaultContext, 1, 2) + pr, err := issues_model.GetPullRequestByIndex(db.DefaultContext, 1, 2) assert.NoError(t, err) assert.Equal(t, int64(1), pr.BaseRepoID) assert.Equal(t, int64(2), pr.Index) - _, err = GetPullRequestByIndex(db.DefaultContext, 9223372036854775807, 9223372036854775807) + _, err = issues_model.GetPullRequestByIndex(db.DefaultContext, 9223372036854775807, 9223372036854775807) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) - _, err = GetPullRequestByIndex(db.DefaultContext, 1, 0) + _, err = issues_model.GetPullRequestByIndex(db.DefaultContext, 1, 0) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestGetPullRequestByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := GetPullRequestByID(db.DefaultContext, 1) + pr, err := issues_model.GetPullRequestByID(db.DefaultContext, 1) assert.NoError(t, err) assert.Equal(t, int64(1), pr.ID) assert.Equal(t, int64(2), pr.IssueID) - _, err = GetPullRequestByID(db.DefaultContext, 9223372036854775807) + _, err = issues_model.GetPullRequestByID(db.DefaultContext, 9223372036854775807) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestGetPullRequestByIssueID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := GetPullRequestByIssueID(db.DefaultContext, 2) + pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, 2) assert.NoError(t, err) assert.Equal(t, int64(2), pr.IssueID) - _, err = GetPullRequestByIssueID(db.DefaultContext, 9223372036854775807) + _, err = issues_model.GetPullRequestByIssueID(db.DefaultContext, 9223372036854775807) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestPullRequest_Update(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) pr.BaseBranch = "baseBranch" pr.HeadBranch = "headBranch" pr.Update() - pr = unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: pr.ID}).(*PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}).(*issues_model.PullRequest) assert.Equal(t, "baseBranch", pr.BaseBranch) assert.Equal(t, "headBranch", pr.HeadBranch) unittest.CheckConsistencyFor(t, pr) @@ -192,14 +193,14 @@ func TestPullRequest_Update(t *testing.T) { func TestPullRequest_UpdateCols(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := &PullRequest{ + pr := &issues_model.PullRequest{ ID: 1, BaseBranch: "baseBranch", HeadBranch: "headBranch", } assert.NoError(t, pr.UpdateCols("head_branch")) - pr = unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.Equal(t, "master", pr.BaseBranch) assert.Equal(t, "headBranch", pr.HeadBranch) unittest.CheckConsistencyFor(t, pr) @@ -208,17 +209,17 @@ func TestPullRequest_UpdateCols(t *testing.T) { func TestPullRequestList_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs := []*PullRequest{ - unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest), - unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest), + prs := []*issues_model.PullRequest{ + unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest), + unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest), } - assert.NoError(t, PullRequestList(prs).LoadAttributes()) + assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes()) for _, pr := range prs { assert.NotNil(t, pr.Issue) assert.Equal(t, pr.IssueID, pr.Issue.ID) } - assert.NoError(t, PullRequestList([]*PullRequest{}).LoadAttributes()) + assert.NoError(t, issues_model.PullRequestList([]*issues_model.PullRequest{}).LoadAttributes()) } // TODO TestAddTestPullRequestTask @@ -226,7 +227,7 @@ func TestPullRequestList_LoadAttributes(t *testing.T) { func TestPullRequest_IsWorkInProgress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) pr.LoadIssue() assert.False(t, pr.IsWorkInProgress()) @@ -241,7 +242,7 @@ func TestPullRequest_IsWorkInProgress(t *testing.T) { func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) pr.LoadIssue() assert.Empty(t, pr.GetWorkInProgressPrefix()) @@ -253,3 +254,24 @@ func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) { pr.Issue.Title = "[wip] " + original assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix()) } + +func TestDeleteOrphanedObjects(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + countBefore, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) + assert.NoError(t, err) + + _, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003}) + assert.NoError(t, err) + + orphaned, err := db.CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id") + assert.NoError(t, err) + assert.EqualValues(t, 3, orphaned) + + err = db.DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id") + assert.NoError(t, err) + + countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) + assert.NoError(t, err) + assert.EqualValues(t, countBefore, countAfter) +} diff --git a/models/issues/reaction_test.go b/models/issues/reaction_test.go index b1216a3a69..ee1b6687a2 100644 --- a/models/issues/reaction_test.go +++ b/models/issues/reaction_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package issues +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -17,12 +18,12 @@ import ( ) func addReaction(t *testing.T, doerID, issueID, commentID int64, content string) { - var reaction *Reaction + var reaction *issues_model.Reaction var err error if commentID == 0 { - reaction, err = CreateIssueReaction(doerID, issueID, content) + reaction, err = issues_model.CreateIssueReaction(doerID, issueID, content) } else { - reaction, err = CreateCommentReaction(doerID, issueID, commentID, content) + reaction, err = issues_model.CreateCommentReaction(doerID, issueID, commentID, content) } assert.NoError(t, err) assert.NotNil(t, reaction) @@ -37,7 +38,7 @@ func TestIssueAddReaction(t *testing.T) { addReaction(t, user1.ID, issue1ID, 0, "heart") - unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) } func TestIssueAddDuplicateReaction(t *testing.T) { @@ -49,15 +50,15 @@ func TestIssueAddDuplicateReaction(t *testing.T) { addReaction(t, user1.ID, issue1ID, 0, "heart") - reaction, err := CreateReaction(&ReactionOptions{ + reaction, err := issues_model.CreateReaction(&issues_model.ReactionOptions{ DoerID: user1.ID, IssueID: issue1ID, Type: "heart", }) assert.Error(t, err) - assert.Equal(t, ErrReactionAlreadyExist{Reaction: "heart"}, err) + assert.Equal(t, issues_model.ErrReactionAlreadyExist{Reaction: "heart"}, err) - existingR := unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}).(*Reaction) + existingR := unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}).(*issues_model.Reaction) assert.Equal(t, existingR.ID, reaction.ID) } @@ -70,10 +71,10 @@ func TestIssueDeleteReaction(t *testing.T) { addReaction(t, user1.ID, issue1ID, 0, "heart") - err := DeleteIssueReaction(user1.ID, issue1ID, "heart") + err := issues_model.DeleteIssueReaction(user1.ID, issue1ID, "heart") assert.NoError(t, err) - unittest.AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) + unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) } func TestIssueReactionCount(t *testing.T) { @@ -98,7 +99,7 @@ func TestIssueReactionCount(t *testing.T) { addReaction(t, user4.ID, issueID, 0, "heart") addReaction(t, ghost.ID, issueID, 0, "-1") - reactionsList, _, err := FindReactions(db.DefaultContext, FindReactionsOptions{ + reactionsList, _, err := issues_model.FindReactions(db.DefaultContext, issues_model.FindReactionsOptions{ IssueID: issueID, }) assert.NoError(t, err) @@ -128,7 +129,7 @@ func TestIssueCommentAddReaction(t *testing.T) { addReaction(t, user1.ID, issue1ID, comment1ID, "heart") - unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) } func TestIssueCommentDeleteReaction(t *testing.T) { @@ -147,7 +148,7 @@ func TestIssueCommentDeleteReaction(t *testing.T) { addReaction(t, user3.ID, issue1ID, comment1ID, "heart") addReaction(t, user4.ID, issue1ID, comment1ID, "+1") - reactionsList, _, err := FindReactions(db.DefaultContext, FindReactionsOptions{ + reactionsList, _, err := issues_model.FindReactions(db.DefaultContext, issues_model.FindReactionsOptions{ IssueID: issue1ID, CommentID: comment1ID, }) @@ -168,7 +169,7 @@ func TestIssueCommentReactionCount(t *testing.T) { var comment1ID int64 = 1 addReaction(t, user1.ID, issue1ID, comment1ID, "heart") - assert.NoError(t, DeleteCommentReaction(user1.ID, issue1ID, comment1ID, "heart")) + assert.NoError(t, issues_model.DeleteCommentReaction(user1.ID, issue1ID, comment1ID, "heart")) - unittest.AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) + unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) } diff --git a/models/review.go b/models/issues/review.go index e92caba938..ee65bec3f8 100644 --- a/models/review.go +++ b/models/issues/review.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -17,11 +17,47 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "xorm.io/builder" ) +// ErrReviewNotExist represents a "ReviewNotExist" kind of error. +type ErrReviewNotExist struct { + ID int64 +} + +// IsErrReviewNotExist checks if an error is a ErrReviewNotExist. +func IsErrReviewNotExist(err error) bool { + _, ok := err.(ErrReviewNotExist) + return ok +} + +func (err ErrReviewNotExist) Error() string { + return fmt.Sprintf("review does not exist [id: %d]", err.ID) +} + +// ErrNotValidReviewRequest an not allowed review request modify +type ErrNotValidReviewRequest struct { + Reason string + UserID int64 + RepoID int64 +} + +// IsErrNotValidReviewRequest checks if an error is a ErrNotValidReviewRequest. +func IsErrNotValidReviewRequest(err error) bool { + _, ok := err.(ErrNotValidReviewRequest) + return ok +} + +func (err ErrNotValidReviewRequest) Error() string { + return fmt.Sprintf("%s [user_id: %d, repo_id: %d]", + err.Reason, + err.UserID, + err.RepoID) +} + // ReviewType defines the sort of feedback a review gives type ReviewType int @@ -105,7 +141,7 @@ func (r *Review) loadIssue(ctx context.Context) (err error) { if r.Issue != nil { return } - r.Issue, err = getIssueByID(ctx, r.IssueID) + r.Issue, err = GetIssueByID(ctx, r.IssueID) return } @@ -967,3 +1003,16 @@ func (r *Review) GetExternalName() string { return r.OriginalAuthor } // GetExternalID ExternalUserRemappable interface func (r *Review) GetExternalID() int64 { return r.OriginalAuthorID } + +// UpdateReviewsMigrationsByType updates reviews' migrations information via given git service type and original id and poster id +func UpdateReviewsMigrationsByType(tp structs.GitServiceType, originalAuthorID string, posterID int64) error { + _, err := db.GetEngine(db.DefaultContext).Table("review"). + Where("original_author_id = ?", originalAuthorID). + And(migratedIssueCond(tp)). + Update(map[string]interface{}{ + "reviewer_id": posterID, + "original_author": "", + "original_author_id": 0, + }) + return err +} diff --git a/models/review_test.go b/models/issues/review_test.go index 93291f9f57..3506604b46 100644 --- a/models/review_test.go +++ b/models/issues/review_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -16,34 +17,34 @@ import ( func TestGetReviewByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review, err := GetReviewByID(db.DefaultContext, 1) + review, err := issues_model.GetReviewByID(db.DefaultContext, 1) assert.NoError(t, err) assert.Equal(t, "Demo Review", review.Content) - assert.Equal(t, ReviewTypeApprove, review.Type) + assert.Equal(t, issues_model.ReviewTypeApprove, review.Type) - _, err = GetReviewByID(db.DefaultContext, 23892) + _, err = issues_model.GetReviewByID(db.DefaultContext, 23892) assert.Error(t, err) - assert.True(t, IsErrReviewNotExist(err), "IsErrReviewNotExist") + assert.True(t, issues_model.IsErrReviewNotExist(err), "IsErrReviewNotExist") } func TestReview_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review := unittest.AssertExistsAndLoadBean(t, &Review{ID: 1}).(*Review) + review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 1}).(*issues_model.Review) assert.NoError(t, review.LoadAttributes(db.DefaultContext)) assert.NotNil(t, review.Issue) assert.NotNil(t, review.Reviewer) - invalidReview1 := unittest.AssertExistsAndLoadBean(t, &Review{ID: 2}).(*Review) + invalidReview1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 2}).(*issues_model.Review) assert.Error(t, invalidReview1.LoadAttributes(db.DefaultContext)) - invalidReview2 := unittest.AssertExistsAndLoadBean(t, &Review{ID: 3}).(*Review) + invalidReview2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 3}).(*issues_model.Review) assert.Error(t, invalidReview2.LoadAttributes(db.DefaultContext)) } func TestReview_LoadCodeComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review := unittest.AssertExistsAndLoadBean(t, &Review{ID: 4}).(*Review) + review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 4}).(*issues_model.Review) assert.NoError(t, review.LoadAttributes(db.DefaultContext)) assert.NoError(t, review.LoadCodeComments(db.DefaultContext)) assert.Len(t, review.CodeComments, 1) @@ -51,18 +52,18 @@ func TestReview_LoadCodeComments(t *testing.T) { } func TestReviewType_Icon(t *testing.T) { - assert.Equal(t, "check", ReviewTypeApprove.Icon()) - assert.Equal(t, "diff", ReviewTypeReject.Icon()) - assert.Equal(t, "comment", ReviewTypeComment.Icon()) - assert.Equal(t, "comment", ReviewTypeUnknown.Icon()) - assert.Equal(t, "dot-fill", ReviewTypeRequest.Icon()) - assert.Equal(t, "comment", ReviewType(6).Icon()) + assert.Equal(t, "check", issues_model.ReviewTypeApprove.Icon()) + assert.Equal(t, "diff", issues_model.ReviewTypeReject.Icon()) + assert.Equal(t, "comment", issues_model.ReviewTypeComment.Icon()) + assert.Equal(t, "comment", issues_model.ReviewTypeUnknown.Icon()) + assert.Equal(t, "dot-fill", issues_model.ReviewTypeRequest.Icon()) + assert.Equal(t, "comment", issues_model.ReviewType(6).Icon()) } func TestFindReviews(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - reviews, err := FindReviews(db.DefaultContext, FindReviewOptions{ - Type: ReviewTypeApprove, + reviews, err := issues_model.FindReviews(db.DefaultContext, issues_model.FindReviewOptions{ + Type: issues_model.ReviewTypeApprove, IssueID: 2, ReviewerID: 1, }) @@ -73,66 +74,66 @@ func TestFindReviews(t *testing.T) { func TestGetCurrentReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - review, err := GetCurrentReview(db.DefaultContext, user, issue) + review, err := issues_model.GetCurrentReview(db.DefaultContext, user, issue) assert.NoError(t, err) assert.NotNil(t, review) - assert.Equal(t, ReviewTypePending, review.Type) + assert.Equal(t, issues_model.ReviewTypePending, review.Type) assert.Equal(t, "Pending Review", review.Content) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 7}).(*user_model.User) - review2, err := GetCurrentReview(db.DefaultContext, user2, issue) + review2, err := issues_model.GetCurrentReview(db.DefaultContext, user2, issue) assert.Error(t, err) - assert.True(t, IsErrReviewNotExist(err)) + assert.True(t, issues_model.IsErrReviewNotExist(err)) assert.Nil(t, review2) } func TestCreateReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - review, err := CreateReview(db.DefaultContext, CreateReviewOptions{ + review, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ Content: "New Review", - Type: ReviewTypePending, + Type: issues_model.ReviewTypePending, Issue: issue, Reviewer: user, }) assert.NoError(t, err) assert.Equal(t, "New Review", review.Content) - unittest.AssertExistsAndLoadBean(t, &Review{Content: "New Review"}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Review{Content: "New Review"}) } func TestGetReviewersByIssueID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 3}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) - expectedReviews := []*Review{} + expectedReviews := []*issues_model.Review{} expectedReviews = append(expectedReviews, - &Review{ + &issues_model.Review{ Reviewer: user3, - Type: ReviewTypeReject, + Type: issues_model.ReviewTypeReject, UpdatedUnix: 946684812, }, - &Review{ + &issues_model.Review{ Reviewer: user4, - Type: ReviewTypeApprove, + Type: issues_model.ReviewTypeApprove, UpdatedUnix: 946684813, }, - &Review{ + &issues_model.Review{ Reviewer: user2, - Type: ReviewTypeReject, + Type: issues_model.ReviewTypeReject, UpdatedUnix: 946684814, }) - allReviews, err := GetReviewersByIssueID(issue.ID) + allReviews, err := issues_model.GetReviewersByIssueID(issue.ID) for _, reviewer := range allReviews { assert.NoError(t, reviewer.LoadReviewer()) } @@ -149,53 +150,53 @@ func TestGetReviewersByIssueID(t *testing.T) { func TestDismissReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample := unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) - approveReviewExample := unittest.AssertExistsAndLoadBean(t, &Review{ID: 8}).(*Review) + rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) + approveReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 8}).(*issues_model.Review) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(rejectReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(rejectReviewExample, true)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) - assert.NoError(t, DismissReview(requestReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(requestReviewExample, true)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(requestReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(requestReviewExample, true)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(requestReviewExample, false)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(requestReviewExample, false)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(requestReviewExample, false)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(requestReviewExample, false)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(rejectReviewExample, false)) + assert.NoError(t, issues_model.DismissReview(rejectReviewExample, false)) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(approveReviewExample, true)) + assert.NoError(t, issues_model.DismissReview(approveReviewExample, true)) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.True(t, approveReviewExample.Dismissed) diff --git a/models/issue_stopwatch.go b/models/issues/stopwatch.go index 2cb4a62bd3..e7ac1314e9 100644 --- a/models/issue_stopwatch.go +++ b/models/issues/stopwatch.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -215,7 +215,7 @@ func CreateIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss return err } if exists { - issue, err := getIssueByID(ctx, sw.IssueID) + issue, err := GetIssueByID(ctx, sw.IssueID) if err != nil { return err } diff --git a/models/issues/stopwatch_test.go b/models/issues/stopwatch_test.go new file mode 100644 index 0000000000..c0573964d5 --- /dev/null +++ b/models/issues/stopwatch_test.go @@ -0,0 +1,79 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package issues_test + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/timeutil" + + "github.com/stretchr/testify/assert" +) + +func TestCancelStopwatch(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + user1, err := user_model.GetUserByID(1) + assert.NoError(t, err) + + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + assert.NoError(t, err) + issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) + assert.NoError(t, err) + + err = issues_model.CancelStopwatch(user1, issue1) + assert.NoError(t, err) + unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: user1.ID, IssueID: issue1.ID}) + + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeCancelTracking, PosterID: user1.ID, IssueID: issue1.ID}) + + assert.Nil(t, issues_model.CancelStopwatch(user1, issue2)) +} + +func TestStopwatchExists(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + assert.True(t, issues_model.StopwatchExists(1, 1)) + assert.False(t, issues_model.StopwatchExists(1, 2)) +} + +func TestHasUserStopwatch(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + exists, sw, err := issues_model.HasUserStopwatch(db.DefaultContext, 1) + assert.NoError(t, err) + assert.True(t, exists) + assert.Equal(t, int64(1), sw.ID) + + exists, _, err = issues_model.HasUserStopwatch(db.DefaultContext, 3) + assert.NoError(t, err) + assert.False(t, exists) +} + +func TestCreateOrStopIssueStopwatch(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + user2, err := user_model.GetUserByID(2) + assert.NoError(t, err) + user3, err := user_model.GetUserByID(3) + assert.NoError(t, err) + + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + assert.NoError(t, err) + issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) + assert.NoError(t, err) + + assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(user3, issue1)) + sw := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: 3, IssueID: 1}).(*issues_model.Stopwatch) + assert.LessOrEqual(t, sw.CreatedUnix, timeutil.TimeStampNow()) + + assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(user2, issue2)) + unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: 2, IssueID: 2}) + unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 2, IssueID: 2}) +} diff --git a/models/issue_tracked_time.go b/models/issues/tracked_time.go index 30b3905bbc..54179bd3ab 100644 --- a/models/issue_tracked_time.go +++ b/models/issues/tracked_time.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -48,7 +48,7 @@ func (t *TrackedTime) LoadAttributes() (err error) { func (t *TrackedTime) loadAttributes(ctx context.Context) (err error) { if t.Issue == nil { - t.Issue, err = getIssueByID(ctx, t.IssueID) + t.Issue, err = GetIssueByID(ctx, t.IssueID) if err != nil { return } diff --git a/models/issue_tracked_time_test.go b/models/issues/tracked_time_test.go index a628329712..787ba9b701 100644 --- a/models/issue_tracked_time_test.go +++ b/models/issues/tracked_time_test.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "time" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -21,20 +22,20 @@ func TestAddTime(t *testing.T) { user3, err := user_model.GetUserByID(3) assert.NoError(t, err) - issue1, err := GetIssueByID(1) + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) assert.NoError(t, err) // 3661 = 1h 1min 1s - trackedTime, err := AddTime(user3, issue1, 3661, time.Now()) + trackedTime, err := issues_model.AddTime(user3, issue1, 3661, time.Now()) assert.NoError(t, err) assert.Equal(t, int64(3), trackedTime.UserID) assert.Equal(t, int64(1), trackedTime.IssueID) assert.Equal(t, int64(3661), trackedTime.Time) - tt := unittest.AssertExistsAndLoadBean(t, &TrackedTime{UserID: 3, IssueID: 1}).(*TrackedTime) + tt := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 3, IssueID: 1}).(*issues_model.TrackedTime) assert.Equal(t, int64(3661), tt.Time) - comment := unittest.AssertExistsAndLoadBean(t, &Comment{Type: CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}).(*Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}).(*issues_model.Comment) assert.Equal(t, comment.Content, "1 hour 1 minute") } @@ -42,39 +43,39 @@ func TestGetTrackedTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // by Issue - times, err := GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{IssueID: 1}) + times, err := issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 1}) assert.NoError(t, err) assert.Len(t, times, 1) assert.Equal(t, int64(400), times[0].Time) - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{IssueID: -1}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: -1}) assert.NoError(t, err) assert.Len(t, times, 0) // by User - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{UserID: 1}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 1}) assert.NoError(t, err) assert.Len(t, times, 3) assert.Equal(t, int64(400), times[0].Time) - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{UserID: 3}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 3}) assert.NoError(t, err) assert.Len(t, times, 0) // by Repo - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{RepositoryID: 2}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 2}) assert.NoError(t, err) assert.Len(t, times, 3) assert.Equal(t, int64(1), times[0].Time) - issue, err := GetIssueByID(times[0].IssueID) + issue, err := issues_model.GetIssueByID(db.DefaultContext, times[0].IssueID) assert.NoError(t, err) assert.Equal(t, issue.RepoID, int64(2)) - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{RepositoryID: 1}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 1}) assert.NoError(t, err) assert.Len(t, times, 5) - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{RepositoryID: 10}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 10}) assert.NoError(t, err) assert.Len(t, times, 0) } @@ -82,7 +83,7 @@ func TestGetTrackedTimes(t *testing.T) { func TestTotalTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - total, err := TotalTimes(&FindTrackedTimesOptions{IssueID: 1}) + total, err := issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 1}) assert.NoError(t, err) assert.Len(t, total, 1) for user, time := range total { @@ -90,7 +91,7 @@ func TestTotalTimes(t *testing.T) { assert.Equal(t, "6 minutes 40 seconds", time) } - total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 2}) + total, err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 2}) assert.NoError(t, err) assert.Len(t, total, 2) for user, time := range total { @@ -103,7 +104,7 @@ func TestTotalTimes(t *testing.T) { } } - total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 5}) + total, err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 5}) assert.NoError(t, err) assert.Len(t, total, 1) for user, time := range total { @@ -111,7 +112,7 @@ func TestTotalTimes(t *testing.T) { assert.Equal(t, "1 second", time) } - total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 4}) + total, err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 4}) assert.NoError(t, err) assert.Len(t, total, 2) } diff --git a/models/main_test.go b/models/main_test.go index 96231e4704..bb2fedc15a 100644 --- a/models/main_test.go +++ b/models/main_test.go @@ -7,7 +7,6 @@ package models import ( "testing" - issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -28,10 +27,6 @@ func TestFixturesAreConsistent(t *testing.T) { unittest.CheckConsistencyFor(t, &user_model.User{}, &repo_model.Repository{}, - &Issue{}, - &PullRequest{}, - &issues_model.Milestone{}, - &Label{}, &organization.Team{}, &Action{}) } diff --git a/models/migrate.go b/models/migrate.go index 7b12bc9c93..0af3891cb8 100644 --- a/models/migrate.go +++ b/models/migrate.go @@ -10,8 +10,6 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/structs" - - "xorm.io/builder" ) // InsertMilestones creates milestones of repository. @@ -41,7 +39,7 @@ func InsertMilestones(ms ...*issues_model.Milestone) (err error) { } // InsertIssues insert issues to database -func InsertIssues(issues ...*Issue) error { +func InsertIssues(issues ...*issues_model.Issue) error { ctx, committer, err := db.TxContext() if err != nil { return err @@ -56,14 +54,14 @@ func InsertIssues(issues ...*Issue) error { return committer.Commit() } -func insertIssue(ctx context.Context, issue *Issue) error { +func insertIssue(ctx context.Context, issue *issues_model.Issue) error { sess := db.GetEngine(ctx) if _, err := sess.NoAutoTime().Insert(issue); err != nil { return err } - issueLabels := make([]IssueLabel, 0, len(issue.Labels)) + issueLabels := make([]issues_model.IssueLabel, 0, len(issue.Labels)) for _, label := range issue.Labels { - issueLabels = append(issueLabels, IssueLabel{ + issueLabels = append(issueLabels, issues_model.IssueLabel{ IssueID: issue.ID, LabelID: label.ID, }) @@ -95,7 +93,7 @@ func insertIssue(ctx context.Context, issue *Issue) error { } // InsertIssueComments inserts many comments of issues. -func InsertIssueComments(comments []*Comment) error { +func InsertIssueComments(comments []*issues_model.Comment) error { if len(comments) == 0 { return nil } @@ -127,7 +125,8 @@ func InsertIssueComments(comments []*Comment) error { } for issueID := range issueIDs { - if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?", issueID, CommentTypeComment, issueID); err != nil { + if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?", + issueID, issues_model.CommentTypeComment, issueID); err != nil { return err } } @@ -135,7 +134,7 @@ func InsertIssueComments(comments []*Comment) error { } // InsertPullRequests inserted pull requests -func InsertPullRequests(prs ...*PullRequest) error { +func InsertPullRequests(prs ...*issues_model.PullRequest) error { ctx, committer, err := db.TxContext() if err != nil { return err @@ -182,37 +181,13 @@ func InsertReleases(rels ...*Release) error { return committer.Commit() } -func migratedIssueCond(tp structs.GitServiceType) builder.Cond { - return builder.In("issue_id", - builder.Select("issue.id"). - From("issue"). - InnerJoin("repository", "issue.repo_id = repository.id"). - Where(builder.Eq{ - "repository.original_service_type": tp, - }), - ) -} - -// UpdateReviewsMigrationsByType updates reviews' migrations information via given git service type and original id and poster id -func UpdateReviewsMigrationsByType(tp structs.GitServiceType, originalAuthorID string, posterID int64) error { - _, err := db.GetEngine(db.DefaultContext).Table("review"). - Where("original_author_id = ?", originalAuthorID). - And(migratedIssueCond(tp)). - Update(map[string]interface{}{ - "reviewer_id": posterID, - "original_author": "", - "original_author_id": 0, - }) - return err -} - // UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, userID int64) error { - if err := UpdateIssuesMigrationsByType(tp, externalUserID, userID); err != nil { + if err := issues_model.UpdateIssuesMigrationsByType(tp, externalUserID, userID); err != nil { return err } - if err := UpdateCommentsMigrationsByType(tp, externalUserID, userID); err != nil { + if err := issues_model.UpdateCommentsMigrationsByType(tp, externalUserID, userID); err != nil { return err } @@ -220,8 +195,8 @@ func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, us return err } - if err := UpdateReactionsMigrationsByType(tp, externalUserID, userID); err != nil { + if err := issues_model.UpdateReactionsMigrationsByType(tp, externalUserID, userID); err != nil { return err } - return UpdateReviewsMigrationsByType(tp, externalUserID, userID) + return issues_model.UpdateReviewsMigrationsByType(tp, externalUserID, userID) } diff --git a/models/migrate_test.go b/models/migrate_test.go index ce28b3ca7c..b6525278ec 100644 --- a/models/migrate_test.go +++ b/models/migrate_test.go @@ -41,7 +41,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { reponame := "repo1" repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) assert.EqualValues(t, milestone.ID, 1) reaction := &issues_model.Reaction{ @@ -51,7 +51,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { foreignIndex := int64(12345) title := "issuetitle1" - is := &Issue{ + is := &issues_model.Issue{ RepoID: repo.ID, MilestoneID: milestone.ID, Repo: repo, @@ -61,7 +61,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { PosterID: owner.ID, Poster: owner, IsClosed: true, - Labels: []*Label{label}, + Labels: []*issues_model.Label{label}, Reactions: []*issues_model.Reaction{reaction}, ForeignReference: &foreignreference.ForeignReference{ ForeignIndex: strconv.FormatInt(foreignIndex, 10), @@ -72,9 +72,9 @@ func assertCreateIssues(t *testing.T, isPull bool) { err := InsertIssues(is) assert.NoError(t, err) - i := unittest.AssertExistsAndLoadBean(t, &Issue{Title: title}).(*Issue) + i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title}).(*issues_model.Issue) assert.Nil(t, i.ForeignReference) - err = i.LoadAttributes() + err = i.LoadAttributes(db.DefaultContext) assert.NoError(t, err) assert.EqualValues(t, strconv.FormatInt(foreignIndex, 10), i.ForeignReference.ForeignIndex) unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: owner.ID, IssueID: i.ID}) @@ -90,7 +90,7 @@ func TestMigrate_CreateIssuesIsPullTrue(t *testing.T) { func TestMigrate_InsertIssueComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) reaction := &issues_model.Reaction{ @@ -98,7 +98,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) { UserID: owner.ID, } - comment := &Comment{ + comment := &issues_model.Comment{ PosterID: owner.ID, Poster: owner, IssueID: issue.ID, @@ -106,13 +106,13 @@ func TestMigrate_InsertIssueComments(t *testing.T) { Reactions: []*issues_model.Reaction{reaction}, } - err := InsertIssueComments([]*Comment{comment}) + err := InsertIssueComments([]*issues_model.Comment{comment}) assert.NoError(t, err) - issueModified := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) + issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) assert.EqualValues(t, issue.NumComments+1, issueModified.NumComments) - unittest.CheckConsistencyFor(t, &Issue{}) + unittest.CheckConsistencyFor(t, &issues_model.Issue{}) } func TestMigrate_InsertPullRequests(t *testing.T) { @@ -121,7 +121,7 @@ func TestMigrate_InsertPullRequests(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - i := &Issue{ + i := &issues_model.Issue{ RepoID: repo.ID, Repo: repo, Title: "title1", @@ -131,16 +131,16 @@ func TestMigrate_InsertPullRequests(t *testing.T) { Poster: owner, } - p := &PullRequest{ + p := &issues_model.PullRequest{ Issue: i, } err := InsertPullRequests(p) assert.NoError(t, err) - _ = unittest.AssertExistsAndLoadBean(t, &PullRequest{IssueID: i.ID}).(*PullRequest) + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID}).(*issues_model.PullRequest) - unittest.CheckConsistencyFor(t, &Issue{}, &PullRequest{}) + unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.PullRequest{}) } func TestMigrate_InsertReleases(t *testing.T) { diff --git a/models/migrations/v111.go b/models/migrations/v111.go index 02624da66a..65fe7c5332 100644 --- a/models/migrations/v111.go +++ b/models/migrations/v111.go @@ -131,7 +131,7 @@ func addBranchProtectionCanPushAndEnableWhitelist(x *xorm.Engine) error { Authorize int } - // getUserRepoPermission static function based on models.IsOfficialReviewer at 5d78792385 + // getUserRepoPermission static function based on issues_model.IsOfficialReviewer at 5d78792385 getUserRepoPermission := func(sess *xorm.Session, repo *Repository, user *User) (Permission, error) { var perm Permission diff --git a/models/notification.go b/models/notification.go index ac5abc6f92..3f0e374b83 100644 --- a/models/notification.go +++ b/models/notification.go @@ -11,6 +11,7 @@ import ( "strconv" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -66,9 +67,9 @@ type Notification struct { UpdatedBy int64 `xorm:"INDEX NOT NULL"` - Issue *Issue `xorm:"-"` + Issue *issues_model.Issue `xorm:"-"` Repository *repo_model.Repository `xorm:"-"` - Comment *Comment `xorm:"-"` + Comment *issues_model.Comment `xorm:"-"` User *user_model.User `xorm:"-"` CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"` @@ -204,7 +205,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n return err } - issue, err := getIssueByID(ctx, issueID) + issue, err := issues_model.GetIssueByID(ctx, issueID) if err != nil { return err } @@ -214,14 +215,14 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n toNotify[receiverID] = struct{}{} } else { toNotify = make(map[int64]struct{}, 32) - issueWatches, err := GetIssueWatchersIDs(ctx, issueID, true) + issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true) if err != nil { return err } for _, id := range issueWatches { toNotify[id] = struct{}{} } - if !(issue.IsPull && HasWorkInProgressPrefix(issue.Title)) { + if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) { repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID) if err != nil { return err @@ -230,7 +231,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n toNotify[id] = struct{}{} } } - issueParticipants, err := issue.getParticipantIDsByIssue(ctx) + issueParticipants, err := issue.GetParticipantIDsByIssue(ctx) if err != nil { return err } @@ -241,7 +242,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n // dont notify user who cause notification delete(toNotify, notificationAuthorID) // explicit unwatch on issue - issueUnWatches, err := GetIssueWatchersIDs(ctx, issueID, false) + issueUnWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, false) if err != nil { return err } @@ -303,7 +304,7 @@ func notificationExists(notifications []*Notification, issueID, userID int64) bo return false } -func createIssueNotification(ctx context.Context, userID int64, issue *Issue, commentID, updatedByID int64) error { +func createIssueNotification(ctx context.Context, userID int64, issue *issues_model.Issue, commentID, updatedByID int64) error { notification := &Notification{ UserID: userID, RepoID: issue.RepoID, @@ -415,21 +416,21 @@ func (n *Notification) loadRepo(ctx context.Context) (err error) { func (n *Notification) loadIssue(ctx context.Context) (err error) { if n.Issue == nil && n.IssueID != 0 { - n.Issue, err = getIssueByID(ctx, n.IssueID) + n.Issue, err = issues_model.GetIssueByID(ctx, n.IssueID) if err != nil { return fmt.Errorf("getIssueByID [%d]: %v", n.IssueID, err) } - return n.Issue.loadAttributes(ctx) + return n.Issue.LoadAttributes(ctx) } return nil } func (n *Notification) loadComment(ctx context.Context) (err error) { if n.Comment == nil && n.CommentID != 0 { - n.Comment, err = GetCommentByID(ctx, n.CommentID) + n.Comment, err = issues_model.GetCommentByID(ctx, n.CommentID) if err != nil { - if IsErrCommentNotExist(err) { - return ErrCommentNotExist{ + if issues_model.IsErrCommentNotExist(err) { + return issues_model.ErrCommentNotExist{ ID: n.CommentID, IssueID: n.IssueID, } @@ -456,7 +457,7 @@ func (n *Notification) GetRepo() (*repo_model.Repository, error) { } // GetIssue returns the issue of the notification -func (n *Notification) GetIssue() (*Issue, error) { +func (n *Notification) GetIssue() (*issues_model.Issue, error) { return n.Issue, n.loadIssue(db.DefaultContext) } @@ -489,7 +490,7 @@ func (nl NotificationList) LoadAttributes() error { var err error for i := 0; i < len(nl); i++ { err = nl[i].LoadAttributes() - if err != nil && !IsErrCommentNotExist(err) { + if err != nil && !issues_model.IsErrCommentNotExist(err) { return err } } @@ -519,7 +520,7 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error) repos := make(map[int64]*repo_model.Repository, len(repoIDs)) left := len(repoIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -592,22 +593,22 @@ func (nl NotificationList) LoadIssues() ([]int, error) { } issueIDs := nl.getPendingIssueIDs() - issues := make(map[int64]*Issue, len(issueIDs)) + issues := make(map[int64]*issues_model.Issue, len(issueIDs)) left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } rows, err := db.GetEngine(db.DefaultContext). In("id", issueIDs[:limit]). - Rows(new(Issue)) + Rows(new(issues_model.Issue)) if err != nil { return nil, err } for rows.Next() { - var issue Issue + var issue issues_model.Issue err = rows.Scan(&issue) if err != nil { rows.Close() @@ -678,22 +679,22 @@ func (nl NotificationList) LoadComments() ([]int, error) { } commentIDs := nl.getPendingCommentIDs() - comments := make(map[int64]*Comment, len(commentIDs)) + comments := make(map[int64]*issues_model.Comment, len(commentIDs)) left := len(commentIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } rows, err := db.GetEngine(db.DefaultContext). In("id", commentIDs[:limit]). - Rows(new(Comment)) + Rows(new(issues_model.Comment)) if err != nil { return nil, err } for rows.Next() { - var comment Comment + var comment issues_model.Comment err = rows.Scan(&comment) if err != nil { rows.Close() @@ -747,6 +748,15 @@ func GetUIDsAndNotificationCounts(since, until timeutil.TimeStamp) ([]UserIDCoun return res, db.GetEngine(db.DefaultContext).SQL(sql, since, until, NotificationStatusUnread).Find(&res) } +// SetIssueReadBy sets issue to be read by given user. +func SetIssueReadBy(ctx context.Context, issueID, userID int64) error { + if err := issues_model.UpdateIssueUserByRead(userID, issueID); err != nil { + return err + } + + return setIssueNotificationStatusReadIfUnread(ctx, userID, issueID) +} + func setIssueNotificationStatusReadIfUnread(ctx context.Context, userID, issueID int64) error { notification, err := getIssueNotification(ctx, userID, issueID) // ignore if not exists diff --git a/models/notification_test.go b/models/notification_test.go index 15c29389c8..16ff02d6c0 100644 --- a/models/notification_test.go +++ b/models/notification_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -16,14 +17,14 @@ import ( func TestCreateOrUpdateIssueNotifications(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) assert.NoError(t, CreateOrUpdateIssueNotifications(issue.ID, 0, 2, 0)) // User 9 is inactive, thus notifications for user 1 and 4 are created notf := unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID}).(*Notification) assert.Equal(t, NotificationStatusUnread, notf.Status) - unittest.CheckConsistencyFor(t, &Issue{ID: issue.ID}) + unittest.CheckConsistencyFor(t, &issues_model.Issue{ID: issue.ID}) notf = unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID}).(*Notification) assert.Equal(t, NotificationStatusUnread, notf.Status) diff --git a/models/org_team.go b/models/org_team.go index 7ff3095273..5d29e33337 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -153,7 +154,7 @@ func removeAllRepositories(ctx context.Context, t *organization.Team) (err error } // Remove all IssueWatches a user has subscribed to in the repositories - if err = removeIssueWatchersByRepoID(ctx, user.ID, repo.ID); err != nil { + if err = issues_model.RemoveIssueWatchersByRepoID(ctx, user.ID, repo.ID); err != nil { return err } } @@ -216,7 +217,7 @@ func removeRepository(ctx context.Context, t *organization.Team, repo *repo_mode } // Remove all IssueWatches a user has subscribed to in the repositories - if err := removeIssueWatchersByRepoID(ctx, teamUser.UID, repo.ID); err != nil { + if err := issues_model.RemoveIssueWatchersByRepoID(ctx, teamUser.UID, repo.ID); err != nil { return err } } diff --git a/models/repo.go b/models/repo.go index a8aa18381d..e9d83f5f32 100644 --- a/models/repo.go +++ b/models/repo.go @@ -281,7 +281,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { &access_model.Access{RepoID: repo.ID}, &Action{RepoID: repo.ID}, &repo_model.Collaboration{RepoID: repoID}, - &Comment{RefRepoID: repoID}, + &issues_model.Comment{RefRepoID: repoID}, &git_model.CommitStatus{RepoID: repoID}, &git_model.DeletedBranch{RepoID: repoID}, &webhook.HookTask{RepoID: repoID}, @@ -306,18 +306,18 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { } // Delete Labels and related objects - if err := deleteLabelsByRepoID(ctx, repoID); err != nil { + if err := issues_model.DeleteLabelsByRepoID(ctx, repoID); err != nil { return err } // Delete Pulls and related objects - if err := deletePullsByBaseRepoID(ctx, repoID); err != nil { + if err := issues_model.DeletePullsByBaseRepoID(ctx, repoID); err != nil { return err } // Delete Issues and related objects var attachmentPaths []string - if attachmentPaths, err = deleteIssuesByRepoID(ctx, repoID); err != nil { + if attachmentPaths, err = issues_model.DeleteIssuesByRepoID(ctx, repoID); err != nil { return err } @@ -576,16 +576,11 @@ func repoStatsCorrectNum(ctx context.Context, id int64, isPull bool, field strin } func repoStatsCorrectNumClosedIssues(ctx context.Context, id int64) error { - return repoStatsCorrectNumClosed(ctx, id, false, "num_closed_issues") + return repo_model.StatsCorrectNumClosed(ctx, id, false, "num_closed_issues") } func repoStatsCorrectNumClosedPulls(ctx context.Context, id int64) error { - return repoStatsCorrectNumClosed(ctx, id, true, "num_closed_pulls") -} - -func repoStatsCorrectNumClosed(ctx context.Context, id int64, isPull bool, field string) error { - _, err := db.GetEngine(ctx).Exec("UPDATE `repository` SET "+field+"=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_closed=? AND is_pull=?) WHERE id=?", id, true, isPull, id) - return err + return repo_model.StatsCorrectNumClosed(ctx, id, true, "num_closed_pulls") } func statsQuery(args ...interface{}) func(context.Context) ([]map[string][]byte, error) { @@ -687,12 +682,11 @@ func CheckRepoStats(ctx context.Context) error { continue } - rawResult, err := e.Query("SELECT COUNT(*) FROM `repository` WHERE fork_id=?", repo.ID) + _, err = e.SQL("SELECT COUNT(*) FROM `repository` WHERE fork_id=?", repo.ID).Get(&repo.NumForks) if err != nil { log.Error("Select count of forks[%d]: %v", repo.ID, err) continue } - repo.NumForks = int(parseCountResult(rawResult)) if _, err = e.ID(repo.ID).Cols("num_forks").Update(repo); err != nil { log.Error("UpdateRepository[%d]: %v", id, err) diff --git a/models/repo/repo.go b/models/repo/repo.go index 57d85435eb..f6097d2d6a 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -25,6 +25,22 @@ import ( "code.gitea.io/gitea/modules/util" ) +// ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo. +type ErrUserDoesNotHaveAccessToRepo struct { + UserID int64 + RepoName string +} + +// IsErrUserDoesNotHaveAccessToRepo checks if an error is a ErrRepoFileAlreadyExists. +func IsErrUserDoesNotHaveAccessToRepo(err error) bool { + _, ok := err.(ErrUserDoesNotHaveAccessToRepo) + return ok +} + +func (err ErrUserDoesNotHaveAccessToRepo) Error() string { + return fmt.Sprintf("user doesn't have access to repo [user_id: %d, repo_name: %s]", err.UserID, err.RepoName) +} + var ( reservedRepoNames = []string{".", "..", "-"} reservedRepoPatterns = []string{"*.git", "*.wiki", "*.rss", "*.atom"} @@ -743,3 +759,34 @@ func CountRepositories(ctx context.Context, opts CountRepositoryOptions) (int64, } return count, nil } + +// StatsCorrectNumClosed update repository's issue related numbers +func StatsCorrectNumClosed(ctx context.Context, id int64, isPull bool, field string) error { + _, err := db.Exec(ctx, "UPDATE `repository` SET "+field+"=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_closed=? AND is_pull=?) WHERE id=?", id, true, isPull, id) + return err +} + +// UpdateRepoIssueNumbers update repository issue numbers +func UpdateRepoIssueNumbers(ctx context.Context, repoID int64, isPull, isClosed bool) error { + e := db.GetEngine(ctx) + if isPull { + if _, err := e.ID(repoID).Decr("num_pulls").Update(new(Repository)); err != nil { + return err + } + if isClosed { + if _, err := e.ID(repoID).Decr("num_closed_pulls").Update(new(Repository)); err != nil { + return err + } + } + } else { + if _, err := e.ID(repoID).Decr("num_issues").Update(new(Repository)); err != nil { + return err + } + if isClosed { + if _, err := e.ID(repoID).Decr("num_closed_issues").Update(new(Repository)); err != nil { + return err + } + } + } + return nil +} diff --git a/models/repo_activity.go b/models/repo_activity.go index 06710ff1ac..6a3636ab07 100644 --- a/models/repo_activity.go +++ b/models/repo_activity.go @@ -11,6 +11,7 @@ import ( "time" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -29,15 +30,15 @@ type ActivityAuthorData struct { // ActivityStats represets issue and pull request information. type ActivityStats struct { - OpenedPRs PullRequestList + OpenedPRs issues_model.PullRequestList OpenedPRAuthorCount int64 - MergedPRs PullRequestList + MergedPRs issues_model.PullRequestList MergedPRAuthorCount int64 - OpenedIssues IssueList + OpenedIssues issues_model.IssueList OpenedIssueAuthorCount int64 - ClosedIssues IssueList + ClosedIssues issues_model.IssueList ClosedIssueAuthorCount int64 - UnresolvedIssues IssueList + UnresolvedIssues issues_model.IssueList PublishedReleases []*Release PublishedReleaseAuthorCount int64 Code *git.CodeActivityStats @@ -212,7 +213,7 @@ func (stats *ActivityStats) FillPullRequests(repoID int64, fromTime time.Time) e // Merged pull requests sess := pullRequestsForActivityStatement(repoID, fromTime, true) sess.OrderBy("pull_request.merged_unix DESC") - stats.MergedPRs = make(PullRequestList, 0) + stats.MergedPRs = make(issues_model.PullRequestList, 0) if err = sess.Find(&stats.MergedPRs); err != nil { return err } @@ -230,7 +231,7 @@ func (stats *ActivityStats) FillPullRequests(repoID int64, fromTime time.Time) e // Opened pull requests sess = pullRequestsForActivityStatement(repoID, fromTime, false) sess.OrderBy("issue.created_unix ASC") - stats.OpenedPRs = make(PullRequestList, 0) + stats.OpenedPRs = make(issues_model.PullRequestList, 0) if err = sess.Find(&stats.OpenedPRs); err != nil { return err } @@ -271,7 +272,7 @@ func (stats *ActivityStats) FillIssues(repoID int64, fromTime time.Time) error { // Closed issues sess := issuesForActivityStatement(repoID, fromTime, true, false) sess.OrderBy("issue.closed_unix DESC") - stats.ClosedIssues = make(IssueList, 0) + stats.ClosedIssues = make(issues_model.IssueList, 0) if err = sess.Find(&stats.ClosedIssues); err != nil { return err } @@ -286,7 +287,7 @@ func (stats *ActivityStats) FillIssues(repoID int64, fromTime time.Time) error { // New issues sess = issuesForActivityStatement(repoID, fromTime, false, false) sess.OrderBy("issue.created_unix ASC") - stats.OpenedIssues = make(IssueList, 0) + stats.OpenedIssues = make(issues_model.IssueList, 0) if err = sess.Find(&stats.OpenedIssues); err != nil { return err } @@ -312,7 +313,7 @@ func (stats *ActivityStats) FillUnresolvedIssues(repoID int64, fromTime time.Tim sess.And("issue.is_pull = ?", prs) } sess.OrderBy("issue.updated_unix DESC") - stats.UnresolvedIssues = make(IssueList, 0) + stats.UnresolvedIssues = make(issues_model.IssueList, 0) return sess.Find(&stats.UnresolvedIssues) } diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go index 7d43115b23..c8866421bd 100644 --- a/models/repo_collaboration.go +++ b/models/repo_collaboration.go @@ -10,6 +10,7 @@ import ( "fmt" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -101,7 +102,7 @@ func reconsiderRepoIssuesAssignee(ctx context.Context, repo *repo_model.Reposito if _, err := db.GetEngine(ctx).Where(builder.Eq{"assignee_id": uid}). In("issue_id", builder.Select("id").From("issue").Where(builder.Eq{"repo_id": repo.ID})). - Delete(&IssueAssignees{}); err != nil { + Delete(&issues_model.IssueAssignees{}); err != nil { return fmt.Errorf("Could not delete assignee[%d] %v", uid, err) } return nil @@ -116,5 +117,5 @@ func reconsiderWatches(ctx context.Context, repo *repo_model.Repository, uid int } // Remove all IssueWatches a user has subscribed to in the repository - return removeIssueWatchersByRepoID(ctx, uid, repo.ID) + return issues_model.RemoveIssueWatchersByRepoID(ctx, uid, repo.ID) } diff --git a/models/repo_transfer.go b/models/repo_transfer.go index 79cfc699c8..7d07fb252c 100644 --- a/models/repo_transfer.go +++ b/models/repo_transfer.go @@ -10,6 +10,7 @@ import ( "os" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -376,7 +377,7 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_mo INNER JOIN issue ON issue.id = com.issue_id WHERE com.type = ? AND issue.repo_id = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != ?)) - ) AS il_too)`, CommentTypeLabel, repo.ID, newOwner.ID); err != nil { + ) AS il_too)`, issues_model.CommentTypeLabel, repo.ID, newOwner.ID); err != nil { return fmt.Errorf("Unable to remove old org label comments: %v", err) } } diff --git a/models/statistic.go b/models/statistic.go index dfc236ec58..55ace626c8 100644 --- a/models/statistic.go +++ b/models/statistic.go @@ -97,7 +97,7 @@ func GetStatistic() (stats Statistic) { stats.Counter.Issue = stats.Counter.IssueClosed + stats.Counter.IssueOpen - stats.Counter.Comment, _ = e.Count(new(Comment)) + stats.Counter.Comment, _ = e.Count(new(issues_model.Comment)) stats.Counter.Oauth = 0 stats.Counter.Follow, _ = e.Count(new(user_model.Follow)) stats.Counter.Mirror, _ = e.Count(new(repo_model.Mirror)) @@ -105,7 +105,7 @@ func GetStatistic() (stats Statistic) { stats.Counter.AuthSource = auth.CountSources() stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook)) stats.Counter.Milestone, _ = e.Count(new(issues_model.Milestone)) - stats.Counter.Label, _ = e.Count(new(Label)) + stats.Counter.Label, _ = e.Count(new(issues_model.Label)) stats.Counter.HookTask, _ = e.Count(new(webhook.HookTask)) stats.Counter.Team, _ = e.Count(new(organization.Team)) stats.Counter.Attachment, _ = e.Count(new(repo_model.Attachment)) diff --git a/models/user.go b/models/user.go index 59ec643d55..49374014aa 100644 --- a/models/user.go +++ b/models/user.go @@ -16,7 +16,7 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/models/issues" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" @@ -78,12 +78,12 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { &user_model.Follow{UserID: u.ID}, &user_model.Follow{FollowID: u.ID}, &Action{UserID: u.ID}, - &IssueUser{UID: u.ID}, + &issues_model.IssueUser{UID: u.ID}, &user_model.EmailAddress{UID: u.ID}, &user_model.UserOpenID{UID: u.ID}, - &issues.Reaction{UserID: u.ID}, + &issues_model.Reaction{UserID: u.ID}, &organization.TeamUser{UID: u.ID}, - &Stopwatch{UserID: u.ID}, + &issues_model.Stopwatch{UserID: u.ID}, &user_model.Setting{UserID: u.ID}, &pull_model.AutoMerge{DoerID: u.ID}, &pull_model.ReviewState{UserID: u.ID}, @@ -101,8 +101,8 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { // Delete Comments const batchSize = 50 for start := 0; ; start += batchSize { - comments := make([]*Comment, 0, batchSize) - if err = e.Where("type=? AND poster_id=?", CommentTypeComment, u.ID).Limit(batchSize, start).Find(&comments); err != nil { + comments := make([]*issues_model.Comment, 0, batchSize) + if err = e.Where("type=? AND poster_id=?", issues_model.CommentTypeComment, u.ID).Limit(batchSize, start).Find(&comments); err != nil { return err } if len(comments) == 0 { @@ -110,14 +110,14 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { } for _, comment := range comments { - if err = deleteComment(ctx, comment); err != nil { + if err = issues_model.DeleteComment(ctx, comment); err != nil { return err } } } // Delete Reactions - if err = issues.DeleteReaction(ctx, &issues.ReactionOptions{DoerID: u.ID}); err != nil { + if err = issues_model.DeleteReaction(ctx, &issues_model.ReactionOptions{DoerID: u.ID}); err != nil { return err } } @@ -189,7 +189,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { // ***** END: GPGPublicKey ***** // Clear assignee. - if _, err = db.DeleteByBean(ctx, &IssueAssignees{AssigneeID: u.ID}); err != nil { + if _, err = db.DeleteByBean(ctx, &issues_model.IssueAssignees{AssigneeID: u.ID}); err != nil { return fmt.Errorf("clear assignee: %v", err) } diff --git a/modules/context/repo.go b/modules/context/repo.go index 05ced909a8..c2b8306b9d 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" @@ -83,7 +84,7 @@ type Repository struct { // CanWriteToBranch checks if the branch is writable by the user func (r *Repository) CanWriteToBranch(user *user_model.User, branch string) bool { - return models.CanMaintainerWriteToBranch(r.Permission, branch, user) + return issues_model.CanMaintainerWriteToBranch(r.Permission, branch, user) } // CanEnableEditor returns true if repository is editable and user has proper access level. @@ -158,11 +159,11 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use } // CanUseTimetracker returns whether or not a user can use the timetracker. -func (r *Repository) CanUseTimetracker(issue *models.Issue, user *user_model.User) bool { +func (r *Repository) CanUseTimetracker(issue *issues_model.Issue, user *user_model.User) bool { // Checking for following: // 1. Is timetracker enabled // 2. Is the user a contributor, admin, poster or assignee and do the repository policies require this? - isAssigned, _ := models.IsUserAssignedToIssue(db.DefaultContext, issue, user) + isAssigned, _ := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user) return r.Repository.IsTimetrackerEnabled() && (!r.Repository.AllowOnlyContributorsToTrackTime() || r.Permission.CanWriteIssuesOrPulls(issue.IsPull) || issue.IsPoster(user.ID) || isAssigned) } diff --git a/modules/convert/convert.go b/modules/convert/convert.go index 4e8aa59067..c8cb23261e 100644 --- a/modules/convert/convert.go +++ b/modules/convert/convert.go @@ -11,11 +11,11 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -55,7 +55,7 @@ func ToBranch(repo *repo_model.Repository, b *git.Branch, c *git.Commit, bp *git if err != nil { return nil, err } - canPush = models.CanMaintainerWriteToBranch(perms, b.Name, user) + canPush = issues_model.CanMaintainerWriteToBranch(perms, b.Name, user) } return &api.Branch{ diff --git a/modules/convert/issue.go b/modules/convert/issue.go index a4512e424f..35eff05229 100644 --- a/modules/convert/issue.go +++ b/modules/convert/issue.go @@ -9,7 +9,6 @@ import ( "net/url" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -23,7 +22,7 @@ import ( // it assumes some fields assigned with values: // Required - Poster, Labels, // Optional - Milestone, Assignee, PullRequest -func ToAPIIssue(issue *models.Issue) *api.Issue { +func ToAPIIssue(issue *issues_model.Issue) *api.Issue { if err := issue.LoadLabels(db.DefaultContext); err != nil { return &api.Issue{} } @@ -100,7 +99,7 @@ func ToAPIIssue(issue *models.Issue) *api.Issue { } // ToAPIIssueList converts an IssueList to API format -func ToAPIIssueList(il models.IssueList) []*api.Issue { +func ToAPIIssueList(il issues_model.IssueList) []*api.Issue { result := make([]*api.Issue, len(il)) for i := range il { result[i] = ToAPIIssue(il[i]) @@ -109,7 +108,7 @@ func ToAPIIssueList(il models.IssueList) []*api.Issue { } // ToTrackedTime converts TrackedTime to API format -func ToTrackedTime(t *models.TrackedTime) (apiT *api.TrackedTime) { +func ToTrackedTime(t *issues_model.TrackedTime) (apiT *api.TrackedTime) { apiT = &api.TrackedTime{ ID: t.ID, IssueID: t.IssueID, @@ -128,13 +127,13 @@ func ToTrackedTime(t *models.TrackedTime) (apiT *api.TrackedTime) { } // ToStopWatches convert Stopwatch list to api.StopWatches -func ToStopWatches(sws []*models.Stopwatch) (api.StopWatches, error) { +func ToStopWatches(sws []*issues_model.Stopwatch) (api.StopWatches, error) { result := api.StopWatches(make([]api.StopWatch, 0, len(sws))) - issueCache := make(map[int64]*models.Issue) + issueCache := make(map[int64]*issues_model.Issue) repoCache := make(map[int64]*repo_model.Repository) var ( - issue *models.Issue + issue *issues_model.Issue repo *repo_model.Repository ok bool err error @@ -143,7 +142,7 @@ func ToStopWatches(sws []*models.Stopwatch) (api.StopWatches, error) { for _, sw := range sws { issue, ok = issueCache[sw.IssueID] if !ok { - issue, err = models.GetIssueByID(sw.IssueID) + issue, err = issues_model.GetIssueByID(db.DefaultContext, sw.IssueID) if err != nil { return nil, err } @@ -170,7 +169,7 @@ func ToStopWatches(sws []*models.Stopwatch) (api.StopWatches, error) { } // ToTrackedTimeList converts TrackedTimeList to API format -func ToTrackedTimeList(tl models.TrackedTimeList) api.TrackedTimeList { +func ToTrackedTimeList(tl issues_model.TrackedTimeList) api.TrackedTimeList { result := make([]*api.TrackedTime, 0, len(tl)) for _, t := range tl { result = append(result, ToTrackedTime(t)) @@ -179,7 +178,7 @@ func ToTrackedTimeList(tl models.TrackedTimeList) api.TrackedTimeList { } // ToLabel converts Label to API format -func ToLabel(label *models.Label, repo *repo_model.Repository, org *user_model.User) *api.Label { +func ToLabel(label *issues_model.Label, repo *repo_model.Repository, org *user_model.User) *api.Label { result := &api.Label{ ID: label.ID, Name: label.Name, @@ -206,7 +205,7 @@ func ToLabel(label *models.Label, repo *repo_model.Repository, org *user_model.U } // ToLabelList converts list of Label to API format -func ToLabelList(labels []*models.Label, repo *repo_model.Repository, org *user_model.User) []*api.Label { +func ToLabelList(labels []*issues_model.Label, repo *repo_model.Repository, org *user_model.User) []*api.Label { result := make([]*api.Label, len(labels)) for i := range labels { result[i] = ToLabel(labels[i], repo, org) diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index eaa7f64ea3..ccc94b2496 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -5,16 +5,16 @@ package convert import ( - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" ) -// ToComment converts a models.Comment to the api.Comment format -func ToComment(c *models.Comment) *api.Comment { +// ToComment converts a issues_model.Comment to the api.Comment format +func ToComment(c *issues_model.Comment) *api.Comment { return &api.Comment{ ID: c.ID, Poster: ToUser(c.Poster, nil), @@ -27,8 +27,8 @@ func ToComment(c *models.Comment) *api.Comment { } } -// ToTimelineComment converts a models.Comment to the api.TimelineComment format -func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineComment { +// ToTimelineComment converts a issues_model.Comment to the api.TimelineComment format +func ToTimelineComment(c *issues_model.Comment, doer *user_model.User) *api.TimelineComment { err := c.LoadMilestone() if err != nil { log.Error("LoadMilestone: %v", err) @@ -105,7 +105,7 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo } if c.RefIssueID != 0 { - issue, err := models.GetIssueByID(c.RefIssueID) + issue, err := issues_model.GetIssueByID(db.DefaultContext, c.RefIssueID) if err != nil { log.Error("GetIssueByID(%d): %v", c.RefIssueID, err) return nil @@ -114,7 +114,7 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo } if c.RefCommentID != 0 { - com, err := models.GetCommentByID(db.DefaultContext, c.RefCommentID) + com, err := issues_model.GetCommentByID(db.DefaultContext, c.RefCommentID) if err != nil { log.Error("GetCommentByID(%d): %v", c.RefCommentID, err) return nil diff --git a/modules/convert/issue_test.go b/modules/convert/issue_test.go index b237c18f69..5bf04bcb52 100644 --- a/modules/convert/issue_test.go +++ b/modules/convert/issue_test.go @@ -9,7 +9,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -22,7 +21,7 @@ import ( func TestLabel_ToLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &models.Label{ID: 1}).(*models.Label) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID}).(*repo_model.Repository) assert.Equal(t, &api.Label{ ID: label.ID, diff --git a/modules/convert/pull.go b/modules/convert/pull.go index 310a7626c9..9c31f9bd2c 100644 --- a/modules/convert/pull.go +++ b/modules/convert/pull.go @@ -8,7 +8,7 @@ import ( "context" "fmt" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" user_model "code.gitea.io/gitea/models/user" @@ -20,7 +20,7 @@ import ( // ToAPIPullRequest assumes following fields have been assigned with valid values: // Required - Issue // Optional - Merger -func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_model.User) *api.PullRequest { +func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User) *api.PullRequest { var ( baseBranch *git.Branch headBranch *git.Branch @@ -114,7 +114,7 @@ func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_mo } } - if pr.Flow == models.PullRequestFlowAGit { + if pr.Flow == issues_model.PullRequestFlowAGit { gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) if err != nil { log.Error("OpenRepository[%s]: %v", pr.GetGitRefName(), err) @@ -132,7 +132,7 @@ func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_mo apiPullRequest.Head.Name = "" } - if pr.HeadRepo != nil && pr.Flow == models.PullRequestFlowGithub { + if pr.HeadRepo != nil && pr.Flow == issues_model.PullRequestFlowGithub { p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) if err != nil { log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) diff --git a/modules/convert/pull_review.go b/modules/convert/pull_review.go index 907ccafb66..93ce208224 100644 --- a/modules/convert/pull_review.go +++ b/modules/convert/pull_review.go @@ -8,13 +8,13 @@ import ( "context" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" ) // ToPullReview convert a review to api format -func ToPullReview(ctx context.Context, r *models.Review, doer *user_model.User) (*api.PullReview, error) { +func ToPullReview(ctx context.Context, r *issues_model.Review, doer *user_model.User) (*api.PullReview, error) { if err := r.LoadAttributes(ctx); err != nil { if !user_model.IsErrUserNotExist(err) { return nil, err @@ -44,15 +44,15 @@ func ToPullReview(ctx context.Context, r *models.Review, doer *user_model.User) } switch r.Type { - case models.ReviewTypeApprove: + case issues_model.ReviewTypeApprove: result.State = api.ReviewStateApproved - case models.ReviewTypeReject: + case issues_model.ReviewTypeReject: result.State = api.ReviewStateRequestChanges - case models.ReviewTypeComment: + case issues_model.ReviewTypeComment: result.State = api.ReviewStateComment - case models.ReviewTypePending: + case issues_model.ReviewTypePending: result.State = api.ReviewStatePending - case models.ReviewTypeRequest: + case issues_model.ReviewTypeRequest: result.State = api.ReviewStateRequestReview } @@ -60,11 +60,11 @@ func ToPullReview(ctx context.Context, r *models.Review, doer *user_model.User) } // ToPullReviewList convert a list of review to it's api format -func ToPullReviewList(ctx context.Context, rl []*models.Review, doer *user_model.User) ([]*api.PullReview, error) { +func ToPullReviewList(ctx context.Context, rl []*issues_model.Review, doer *user_model.User) ([]*api.PullReview, error) { result := make([]*api.PullReview, 0, len(rl)) for i := range rl { // show pending reviews only for the user who created them - if rl[i].Type == models.ReviewTypePending && !(doer.IsAdmin || doer.ID == rl[i].ReviewerID) { + if rl[i].Type == issues_model.ReviewTypePending && !(doer.IsAdmin || doer.ID == rl[i].ReviewerID) { continue } r, err := ToPullReview(ctx, rl[i], doer) @@ -77,7 +77,7 @@ func ToPullReviewList(ctx context.Context, rl []*models.Review, doer *user_model } // ToPullReviewCommentList convert the CodeComments of an review to it's api format -func ToPullReviewCommentList(ctx context.Context, review *models.Review, doer *user_model.User) ([]*api.PullReviewComment, error) { +func ToPullReviewCommentList(ctx context.Context, review *issues_model.Review, doer *user_model.User) ([]*api.PullReviewComment, error) { if err := review.LoadAttributes(ctx); err != nil { if !user_model.IsErrUserNotExist(err) { return nil, err diff --git a/modules/convert/pull_test.go b/modules/convert/pull_test.go index 8574ccfd26..10ef311399 100644 --- a/modules/convert/pull_test.go +++ b/modules/convert/pull_test.go @@ -7,7 +7,7 @@ package convert import ( "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -21,7 +21,7 @@ func TestPullRequest_APIFormat(t *testing.T) { // with HeadRepo assert.NoError(t, unittest.PrepareTestDatabase()) headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 1}).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadAttributes()) assert.NoError(t, pr.LoadIssue()) apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil) @@ -35,7 +35,7 @@ func TestPullRequest_APIFormat(t *testing.T) { }, apiPullRequest.Head) // withOut HeadRepo - pr = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 1}).(*models.PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadIssue()) assert.NoError(t, pr.LoadAttributes()) // simulate fork deletion diff --git a/modules/doctor/dbconsistency.go b/modules/doctor/dbconsistency.go index 18cb2cdac6..b23807cca2 100644 --- a/modules/doctor/dbconsistency.go +++ b/modules/doctor/dbconsistency.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/migrations" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/log" @@ -64,10 +65,10 @@ func genericOrphanCheck(name, subject, refobject, joincond string) consistencyCh return consistencyCheck{ Name: name, Counter: func() (int64, error) { - return models.CountOrphanedObjects(subject, refobject, joincond) + return db.CountOrphanedObjects(subject, refobject, joincond) }, Fixer: func() (int64, error) { - err := models.DeleteOrphanedObjects(subject, refobject, joincond) + err := db.DeleteOrphanedObjects(subject, refobject, joincond) return -1, err }, } @@ -84,20 +85,20 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er { // find labels without existing repo or org Name: "Orphaned Labels without existing repository or organisation", - Counter: models.CountOrphanedLabels, - Fixer: asFixer(models.DeleteOrphanedLabels), + Counter: issues_model.CountOrphanedLabels, + Fixer: asFixer(issues_model.DeleteOrphanedLabels), }, { // find IssueLabels without existing label Name: "Orphaned Issue Labels without existing label", - Counter: models.CountOrphanedIssueLabels, - Fixer: asFixer(models.DeleteOrphanedIssueLabels), + Counter: issues_model.CountOrphanedIssueLabels, + Fixer: asFixer(issues_model.DeleteOrphanedIssueLabels), }, { // find issues without existing repository Name: "Orphaned Issues without existing repository", - Counter: models.CountOrphanedIssues, - Fixer: asFixer(models.DeleteOrphanedIssues), + Counter: issues_model.CountOrphanedIssues, + Fixer: asFixer(issues_model.DeleteOrphanedIssues), }, // find releases without existing repository genericOrphanCheck("Orphaned Releases without existing repository", @@ -127,22 +128,22 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er // find label comments with empty labels { Name: "Label comments with empty labels", - Counter: models.CountCommentTypeLabelWithEmptyLabel, - Fixer: models.FixCommentTypeLabelWithEmptyLabel, + Counter: issues_model.CountCommentTypeLabelWithEmptyLabel, + Fixer: issues_model.FixCommentTypeLabelWithEmptyLabel, FixedMessage: "Fixed", }, // find label comments with labels from outside the repository { Name: "Label comments with labels from outside the repository", - Counter: models.CountCommentTypeLabelWithOutsideLabels, - Fixer: models.FixCommentTypeLabelWithOutsideLabels, + Counter: issues_model.CountCommentTypeLabelWithOutsideLabels, + Fixer: issues_model.FixCommentTypeLabelWithOutsideLabels, FixedMessage: "Removed", }, // find issue_label with labels from outside the repository { Name: "IssueLabels with Labels from outside the repository", - Counter: models.CountIssueLabelWithOutsideLabels, - Fixer: models.FixIssueLabelWithOutsideLabels, + Counter: issues_model.CountIssueLabelWithOutsideLabels, + Fixer: issues_model.FixIssueLabelWithOutsideLabels, FixedMessage: "Removed", }, { diff --git a/modules/doctor/mergebase.go b/modules/doctor/mergebase.go index 61ee9e212b..46369290a1 100644 --- a/modules/doctor/mergebase.go +++ b/modules/doctor/mergebase.go @@ -9,8 +9,8 @@ import ( "fmt" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" @@ -18,13 +18,13 @@ import ( "xorm.io/builder" ) -func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*repo_model.Repository, *models.PullRequest) error) error { +func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*repo_model.Repository, *issues_model.PullRequest) error) error { return db.Iterate( ctx, - new(models.PullRequest), + new(issues_model.PullRequest), builder.Eq{"base_repo_id": repo.ID}, func(idx int, bean interface{}) error { - return each(repo, bean.(*models.PullRequest)) + return each(repo, bean.(*issues_model.PullRequest)) }, ) } @@ -35,7 +35,7 @@ func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) erro numPRsUpdated := 0 err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { numRepos++ - return iteratePRs(ctx, repo, func(repo *repo_model.Repository, pr *models.PullRequest) error { + return iteratePRs(ctx, repo, func(repo *repo_model.Repository, pr *issues_model.PullRequest) error { numPRs++ pr.BaseRepo = repo repoPath := repo.RepoPath() diff --git a/modules/eventsource/manager_run.go b/modules/eventsource/manager_run.go index 127979ad63..6055cf7232 100644 --- a/modules/eventsource/manager_run.go +++ b/modules/eventsource/manager_run.go @@ -9,6 +9,7 @@ import ( "time" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/json" @@ -84,7 +85,7 @@ loop: then = now if setting.Service.EnableTimetracking { - usersStopwatches, err := models.GetUIDsAndStopwatch() + usersStopwatches, err := issues_model.GetUIDsAndStopwatch() if err != nil { log.Error("Unable to get GetUIDsAndStopwatch: %v", err) return diff --git a/modules/indexer/issues/db.go b/modules/indexer/issues/db.go index e2badf64f2..d21c86337e 100644 --- a/modules/indexer/issues/db.go +++ b/modules/indexer/issues/db.go @@ -7,8 +7,8 @@ package issues import ( "context" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" ) // DBIndexer implements Indexer interface to use database's like search @@ -44,7 +44,7 @@ func (i *DBIndexer) Close() { // Search dummy function func (i *DBIndexer) Search(ctx context.Context, kw string, repoIDs []int64, limit, start int) (*SearchResult, error) { - total, ids, err := models.SearchIssueIDsByKeyword(ctx, kw, repoIDs, limit, start) + total, ids, err := issues_model.SearchIssueIDsByKeyword(ctx, kw, repoIDs, limit, start) if err != nil { return nil, err } diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go index 85de4c75b3..da6a200aef 100644 --- a/modules/indexer/issues/indexer.go +++ b/modules/indexer/issues/indexer.go @@ -12,8 +12,8 @@ import ( "sync" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" @@ -320,7 +320,7 @@ func populateIssueIndexer(ctx context.Context) { // UpdateRepoIndexer add/update all issues of the repositories func UpdateRepoIndexer(repo *repo_model.Repository) { - is, err := models.Issues(&models.IssuesOptions{ + is, err := issues_model.Issues(&issues_model.IssuesOptions{ RepoID: repo.ID, IsClosed: util.OptionalBoolNone, IsPull: util.OptionalBoolNone, @@ -329,7 +329,7 @@ func UpdateRepoIndexer(repo *repo_model.Repository) { log.Error("Issues: %v", err) return } - if err = models.IssueList(is).LoadDiscussComments(); err != nil { + if err = issues_model.IssueList(is).LoadDiscussComments(); err != nil { log.Error("LoadComments: %v", err) return } @@ -339,10 +339,10 @@ func UpdateRepoIndexer(repo *repo_model.Repository) { } // UpdateIssueIndexer add/update an issue to the issue indexer -func UpdateIssueIndexer(issue *models.Issue) { +func UpdateIssueIndexer(issue *issues_model.Issue) { var comments []string for _, comment := range issue.Comments { - if comment.Type == models.CommentTypeComment { + if comment.Type == issues_model.CommentTypeComment { comments = append(comments, comment.Content) } } @@ -362,7 +362,7 @@ func UpdateIssueIndexer(issue *models.Issue) { // DeleteRepoIssueIndexer deletes repo's all issues indexes func DeleteRepoIssueIndexer(repo *repo_model.Repository) { var ids []int64 - ids, err := models.GetIssueIDsByRepoID(db.DefaultContext, repo.ID) + ids, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, repo.ID) if err != nil { log.Error("getIssueIDsByRepoID failed: %v", err) return diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index 547498a9dc..e438f41485 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/graceful" @@ -33,7 +34,7 @@ func NewNotifier() base.Notifier { return &actionNotifier{} } -func (a *actionNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (a *actionNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { if err := issue.LoadPoster(); err != nil { log.Error("issue.LoadPoster: %v", err) return @@ -58,7 +59,7 @@ func (a *actionNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_mo } // NotifyIssueChangeStatus notifies close or reopen issue to notifiers -func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, closeOrReopen bool) { +func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) { // Compose comment action, could be plain comment, close or reopen issue/pull request. // This object will be used to notify watchers in the end of function. act := &models.Action{ @@ -92,7 +93,7 @@ func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *m // NotifyCreateIssueComment notifies comment on an issue to notifiers func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { act := &models.Action{ ActUserID: doer.ID, @@ -126,7 +127,7 @@ func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *r } } -func (a *actionNotifier) NotifyNewPullRequest(pull *models.PullRequest, mentions []*user_model.User) { +func (a *actionNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, mentions []*user_model.User) { if err := pull.LoadIssue(); err != nil { log.Error("pull.LoadIssue: %v", err) return @@ -207,7 +208,7 @@ func (a *actionNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, re } } -func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment, mentions []*user_model.User) { +func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("actionNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -239,7 +240,7 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review } } - if review.Type != models.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" { + if review.Type != issues_model.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" { action := &models.Action{ ActUserID: review.Reviewer.ID, ActUser: review.Reviewer, @@ -252,9 +253,9 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review } switch review.Type { - case models.ReviewTypeApprove: + case issues_model.ReviewTypeApprove: action.OpType = models.ActionApprovePullRequest - case models.ReviewTypeReject: + case issues_model.ReviewTypeReject: action.OpType = models.ActionRejectPullRequest default: action.OpType = models.ActionCommentPull @@ -268,7 +269,7 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review } } -func (*actionNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (*actionNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { if err := models.NotifyWatchers(&models.Action{ ActUserID: doer.ID, ActUser: doer, @@ -282,7 +283,7 @@ func (*actionNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user } } -func (*actionNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func (*actionNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { reviewerName := review.Reviewer.Name if len(review.OriginalAuthor) > 0 { reviewerName = review.OriginalAuthor diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go index 2b8be18ad3..31fa8f5f18 100644 --- a/modules/notification/base/notifier.go +++ b/modules/notification/base/notifier.go @@ -6,6 +6,7 @@ package base import ( "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -21,30 +22,30 @@ type Notifier interface { NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldRepoName string) NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) - NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) - NotifyIssueChangeStatus(*user_model.User, *models.Issue, *models.Comment, bool) - NotifyDeleteIssue(*user_model.User, *models.Issue) - NotifyIssueChangeMilestone(doer *user_model.User, issue *models.Issue, oldMilestoneID int64) - NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) - NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) - NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) - NotifyIssueClearLabels(doer *user_model.User, issue *models.Issue) - NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) - NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldRef string) - NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label) - NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) - NotifyMergePullRequest(*models.PullRequest, *user_model.User) - NotifyPullRequestSynchronized(doer *user_model.User, pr *models.PullRequest) - NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment, mentions []*user_model.User) - NotifyPullRequestCodeComment(pr *models.PullRequest, comment *models.Comment, mentions []*user_model.User) - NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *models.PullRequest, oldBranch string) - NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) - NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) + NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) + NotifyIssueChangeStatus(*user_model.User, *issues_model.Issue, *issues_model.Comment, bool) + NotifyDeleteIssue(*user_model.User, *issues_model.Issue) + NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) + NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) + NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) + NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) + NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) + NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) + NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string) + NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, + addedLabels, removedLabels []*issues_model.Label) + NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) + NotifyMergePullRequest(*issues_model.PullRequest, *user_model.User) + NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) + NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) + NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) + NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) + NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) + NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) - NotifyUpdateComment(*user_model.User, *models.Comment, string) - NotifyDeleteComment(*user_model.User, *models.Comment) + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User) + NotifyUpdateComment(*user_model.User, *issues_model.Comment, string) + NotifyDeleteComment(*user_model.User, *issues_model.Comment) NotifyNewRelease(rel *models.Release) NotifyUpdateRelease(doer *user_model.User, rel *models.Release) NotifyDeleteRelease(doer *user_model.User, rel *models.Release) diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go index 29b5f0c97e..d336f09301 100644 --- a/modules/notification/base/null.go +++ b/modules/notification/base/null.go @@ -6,6 +6,7 @@ package base import ( "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -23,59 +24,59 @@ func (*NullNotifier) Run() { // NotifyCreateIssueComment places a place holder function func (*NullNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) { + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User) { } // NotifyNewIssue places a place holder function -func (*NullNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (*NullNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { } // NotifyIssueChangeStatus places a place holder function -func (*NullNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, isClosed bool) { +func (*NullNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { } // NotifyDeleteIssue notify when some issue deleted -func (*NullNotifier) NotifyDeleteIssue(doer *user_model.User, issue *models.Issue) { +func (*NullNotifier) NotifyDeleteIssue(doer *user_model.User, issue *issues_model.Issue) { } // NotifyNewPullRequest places a place holder function -func (*NullNotifier) NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func (*NullNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { } // NotifyPullRequestReview places a place holder function -func (*NullNotifier) NotifyPullRequestReview(pr *models.PullRequest, r *models.Review, comment *models.Comment, mentions []*user_model.User) { +func (*NullNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { } // NotifyPullRequestCodeComment places a place holder function -func (*NullNotifier) NotifyPullRequestCodeComment(pr *models.PullRequest, comment *models.Comment, mentions []*user_model.User) { +func (*NullNotifier) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) { } // NotifyMergePullRequest places a place holder function -func (*NullNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (*NullNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { } // NotifyPullRequestSynchronized places a place holder function -func (*NullNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *models.PullRequest) { +func (*NullNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) { } // NotifyPullRequestChangeTargetBranch places a place holder function -func (*NullNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *models.PullRequest, oldBranch string) { +func (*NullNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { } // NotifyPullRequestPushCommits notifies when push commits to pull request's head branch -func (*NullNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) { +func (*NullNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { } // NotifyPullRevieweDismiss notifies when a review was dismissed by repo admin -func (*NullNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func (*NullNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { } // NotifyUpdateComment places a place holder function -func (*NullNotifier) NotifyUpdateComment(doer *user_model.User, c *models.Comment, oldContent string) { +func (*NullNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) { } // NotifyDeleteComment places a place holder function -func (*NullNotifier) NotifyDeleteComment(doer *user_model.User, c *models.Comment) { +func (*NullNotifier) NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) { } // NotifyNewRelease places a place holder function @@ -91,36 +92,36 @@ func (*NullNotifier) NotifyDeleteRelease(doer *user_model.User, rel *models.Rele } // NotifyIssueChangeMilestone places a place holder function -func (*NullNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *models.Issue, oldMilestoneID int64) { +func (*NullNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { } // NotifyIssueChangeContent places a place holder function -func (*NullNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) { +func (*NullNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) { } // NotifyIssueChangeAssignee places a place holder function -func (*NullNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func (*NullNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { } // NotifyPullReviewRequest places a place holder function -func (*NullNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) { +func (*NullNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { } // NotifyIssueClearLabels places a place holder function -func (*NullNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *models.Issue) { +func (*NullNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) { } // NotifyIssueChangeTitle places a place holder function -func (*NullNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (*NullNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { } // NotifyIssueChangeRef places a place holder function -func (*NullNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (*NullNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { } // NotifyIssueChangeLabels places a place holder function -func (*NullNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label) { +func (*NullNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, + addedLabels, removedLabels []*issues_model.Label) { } // NotifyCreateRepository places a place holder function diff --git a/modules/notification/indexer/indexer.go b/modules/notification/indexer/indexer.go index 48a491f3f1..fc9afdd4bc 100644 --- a/modules/notification/indexer/indexer.go +++ b/modules/notification/indexer/indexer.go @@ -5,7 +5,7 @@ package indexer import ( - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -30,9 +30,9 @@ func NewNotifier() base.Notifier { } func (r *indexerNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { - if comment.Type == models.CommentTypeComment { + if comment.Type == issues_model.CommentTypeComment { if issue.Comments == nil { if err := issue.LoadDiscussComments(); err != nil { log.Error("LoadComments failed: %v", err) @@ -46,16 +46,16 @@ func (r *indexerNotifier) NotifyCreateIssueComment(doer *user_model.User, repo * } } -func (r *indexerNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (r *indexerNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { issue_indexer.UpdateIssueIndexer(issue) } -func (r *indexerNotifier) NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func (r *indexerNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { issue_indexer.UpdateIssueIndexer(pr.Issue) } -func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *models.Comment, oldContent string) { - if c.Type == models.CommentTypeComment { +func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) { + if c.Type == issues_model.CommentTypeComment { var found bool if c.Issue.Comments != nil { for i := 0; i < len(c.Issue.Comments); i++ { @@ -78,8 +78,8 @@ func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C } } -func (r *indexerNotifier) NotifyDeleteComment(doer *user_model.User, comment *models.Comment) { - if comment.Type == models.CommentTypeComment { +func (r *indexerNotifier) NotifyDeleteComment(doer *user_model.User, comment *issues_model.Comment) { + if comment.Type == issues_model.CommentTypeComment { if err := comment.LoadIssue(); err != nil { log.Error("LoadIssue: %v", err) return @@ -142,14 +142,14 @@ func (r *indexerNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *r } } -func (r *indexerNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) { +func (r *indexerNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) { issue_indexer.UpdateIssueIndexer(issue) } -func (r *indexerNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (r *indexerNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { issue_indexer.UpdateIssueIndexer(issue) } -func (r *indexerNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldRef string) { +func (r *indexerNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string) { issue_indexer.UpdateIssueIndexer(issue) } diff --git a/modules/notification/mail/mail.go b/modules/notification/mail/mail.go index 138e438751..1f217304b0 100644 --- a/modules/notification/mail/mail.go +++ b/modules/notification/mail/mail.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/graceful" @@ -29,21 +30,21 @@ func NewNotifier() base.Notifier { } func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyCreateIssueComment Issue[%d] #%d in [%d]", issue.ID, issue.Index, issue.RepoID)) defer finished() var act models.ActionType - if comment.Type == models.CommentTypeClose { + if comment.Type == issues_model.CommentTypeClose { act = models.ActionCloseIssue - } else if comment.Type == models.CommentTypeReopen { + } else if comment.Type == issues_model.CommentTypeReopen { act = models.ActionReopenIssue - } else if comment.Type == models.CommentTypeComment { + } else if comment.Type == issues_model.CommentTypeComment { act = models.ActionCommentIssue - } else if comment.Type == models.CommentTypeCode { + } else if comment.Type == issues_model.CommentTypeCode { act = models.ActionCommentIssue - } else if comment.Type == models.CommentTypePullRequestPush { + } else if comment.Type == issues_model.CommentTypePullRequestPush { act = 0 } @@ -52,13 +53,13 @@ func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *rep } } -func (m *mailNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (m *mailNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { if err := mailer.MailParticipants(issue, issue.Poster, models.ActionCreateIssue, mentions); err != nil { log.Error("MailParticipants: %v", err) } } -func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, isClosed bool) { +func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { var actionType models.ActionType if issue.IsPull { if isClosed { @@ -79,34 +80,34 @@ func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *mod } } -func (m *mailNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (m *mailNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { if err := issue.LoadPullRequest(); err != nil { log.Error("issue.LoadPullRequest: %v", err) return } - if issue.IsPull && models.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { + if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { if err := mailer.MailParticipants(issue, doer, models.ActionPullRequestReadyForReview, nil); err != nil { log.Error("MailParticipants: %v", err) } } } -func (m *mailNotifier) NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func (m *mailNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { if err := mailer.MailParticipants(pr.Issue, pr.Issue.Poster, models.ActionCreatePullRequest, mentions); err != nil { log.Error("MailParticipants: %v", err) } } -func (m *mailNotifier) NotifyPullRequestReview(pr *models.PullRequest, r *models.Review, comment *models.Comment, mentions []*user_model.User) { +func (m *mailNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() var act models.ActionType - if comment.Type == models.CommentTypeClose { + if comment.Type == issues_model.CommentTypeClose { act = models.ActionCloseIssue - } else if comment.Type == models.CommentTypeReopen { + } else if comment.Type == issues_model.CommentTypeReopen { act = models.ActionReopenIssue - } else if comment.Type == models.CommentTypeComment { + } else if comment.Type == issues_model.CommentTypeComment { act = models.ActionCommentPull } if err := mailer.MailParticipantsComment(ctx, comment, act, pr.Issue, mentions); err != nil { @@ -114,7 +115,7 @@ func (m *mailNotifier) NotifyPullRequestReview(pr *models.PullRequest, r *models } } -func (m *mailNotifier) NotifyPullRequestCodeComment(pr *models.PullRequest, comment *models.Comment, mentions []*user_model.User) { +func (m *mailNotifier) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestCodeComment Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -123,7 +124,7 @@ func (m *mailNotifier) NotifyPullRequestCodeComment(pr *models.PullRequest, comm } } -func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { // mail only sent to added assignees and not self-assignee if !removed && doer.ID != assignee.ID && (assignee.EmailNotifications() == user_model.EmailNotificationsEnabled || assignee.EmailNotifications() == user_model.EmailNotificationsOnMention) { ct := fmt.Sprintf("Assigned #%d.", issue.Index) @@ -133,7 +134,7 @@ func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *m } } -func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) { +func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { if isRequest && doer.ID != reviewer.ID && (reviewer.EmailNotifications() == user_model.EmailNotificationsEnabled || reviewer.EmailNotifications() == user_model.EmailNotificationsOnMention) { ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL()) if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil { @@ -142,7 +143,7 @@ func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *mod } } -func (m *mailNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (m *mailNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { if err := pr.LoadIssue(); err != nil { log.Error("pr.LoadIssue: %v", err) return @@ -152,7 +153,7 @@ func (m *mailNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user } } -func (m *mailNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) { +func (m *mailNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestPushCommits Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -179,7 +180,7 @@ func (m *mailNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *m m.NotifyCreateIssueComment(doer, comment.Issue.Repo, comment.Issue, comment, nil) } -func (m *mailNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func (m *mailNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRevieweDismiss Review[%d] in Issue[%d]", review.ID, review.IssueID)) defer finished() diff --git a/modules/notification/notification.go b/modules/notification/notification.go index 90ff87941f..d60a880bec 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -6,6 +6,7 @@ package notification import ( "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -40,7 +41,7 @@ func NewContext() { // NotifyCreateIssueComment notifies issue comment related message to notifiers func NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { for _, notifier := range notifiers { notifier.NotifyCreateIssueComment(doer, repo, issue, comment, mentions) @@ -48,91 +49,91 @@ func NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository } // NotifyNewIssue notifies new issue to notifiers -func NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { for _, notifier := range notifiers { notifier.NotifyNewIssue(issue, mentions) } } // NotifyIssueChangeStatus notifies close or reopen issue to notifiers -func NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, closeOrReopen bool) { +func NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) { for _, notifier := range notifiers { notifier.NotifyIssueChangeStatus(doer, issue, actionComment, closeOrReopen) } } // NotifyDeleteIssue notify when some issue deleted -func NotifyDeleteIssue(doer *user_model.User, issue *models.Issue) { +func NotifyDeleteIssue(doer *user_model.User, issue *issues_model.Issue) { for _, notifier := range notifiers { notifier.NotifyDeleteIssue(doer, issue) } } // NotifyMergePullRequest notifies merge pull request to notifiers -func NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { for _, notifier := range notifiers { notifier.NotifyMergePullRequest(pr, doer) } } // NotifyNewPullRequest notifies new pull request to notifiers -func NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { for _, notifier := range notifiers { notifier.NotifyNewPullRequest(pr, mentions) } } // NotifyPullRequestSynchronized notifies Synchronized pull request -func NotifyPullRequestSynchronized(doer *user_model.User, pr *models.PullRequest) { +func NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) { for _, notifier := range notifiers { notifier.NotifyPullRequestSynchronized(doer, pr) } } // NotifyPullRequestReview notifies new pull request review -func NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment, mentions []*user_model.User) { +func NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { for _, notifier := range notifiers { notifier.NotifyPullRequestReview(pr, review, comment, mentions) } } // NotifyPullRequestCodeComment notifies new pull request code comment -func NotifyPullRequestCodeComment(pr *models.PullRequest, comment *models.Comment, mentions []*user_model.User) { +func NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) { for _, notifier := range notifiers { notifier.NotifyPullRequestCodeComment(pr, comment, mentions) } } // NotifyPullRequestChangeTargetBranch notifies when a pull request's target branch was changed -func NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *models.PullRequest, oldBranch string) { +func NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { for _, notifier := range notifiers { notifier.NotifyPullRequestChangeTargetBranch(doer, pr, oldBranch) } } // NotifyPullRequestPushCommits notifies when push commits to pull request's head branch -func NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) { +func NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyPullRequestPushCommits(doer, pr, comment) } } // NotifyPullRevieweDismiss notifies when a review was dismissed by repo admin -func NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyPullRevieweDismiss(doer, review, comment) } } // NotifyUpdateComment notifies update comment to notifiers -func NotifyUpdateComment(doer *user_model.User, c *models.Comment, oldContent string) { +func NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) { for _, notifier := range notifiers { notifier.NotifyUpdateComment(doer, c, oldContent) } } // NotifyDeleteComment notifies delete comment to notifiers -func NotifyDeleteComment(doer *user_model.User, c *models.Comment) { +func NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyDeleteComment(doer, c) } @@ -160,57 +161,57 @@ func NotifyDeleteRelease(doer *user_model.User, rel *models.Release) { } // NotifyIssueChangeMilestone notifies change milestone to notifiers -func NotifyIssueChangeMilestone(doer *user_model.User, issue *models.Issue, oldMilestoneID int64) { +func NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { for _, notifier := range notifiers { notifier.NotifyIssueChangeMilestone(doer, issue, oldMilestoneID) } } // NotifyIssueChangeContent notifies change content to notifiers -func NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) { +func NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) { for _, notifier := range notifiers { notifier.NotifyIssueChangeContent(doer, issue, oldContent) } } // NotifyIssueChangeAssignee notifies change content to notifiers -func NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyIssueChangeAssignee(doer, issue, assignee, removed, comment) } } // NotifyPullReviewRequest notifies Request Review change -func NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) { +func NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyPullReviewRequest(doer, issue, reviewer, isRequest, comment) } } // NotifyIssueClearLabels notifies clear labels to notifiers -func NotifyIssueClearLabels(doer *user_model.User, issue *models.Issue) { +func NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) { for _, notifier := range notifiers { notifier.NotifyIssueClearLabels(doer, issue) } } // NotifyIssueChangeTitle notifies change title to notifiers -func NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { for _, notifier := range notifiers { notifier.NotifyIssueChangeTitle(doer, issue, oldTitle) } } // NotifyIssueChangeRef notifies change reference to notifiers -func NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldRef string) { +func NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string) { for _, notifier := range notifiers { notifier.NotifyIssueChangeRef(doer, issue, oldRef) } } // NotifyIssueChangeLabels notifies change labels to notifiers -func NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label, +func NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, + addedLabels, removedLabels []*issues_model.Label, ) { for _, notifier := range notifiers { notifier.NotifyIssueChangeLabels(doer, issue, addedLabels, removedLabels) diff --git a/modules/notification/ui/ui.go b/modules/notification/ui/ui.go index 037167f640..74866a3363 100644 --- a/modules/notification/ui/ui.go +++ b/modules/notification/ui/ui.go @@ -7,6 +7,7 @@ package ui import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/graceful" @@ -53,7 +54,7 @@ func (ns *notificationService) Run() { } func (ns *notificationService) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { opts := issueNotificationOpts{ IssueID: issue.ID, @@ -76,7 +77,7 @@ func (ns *notificationService) NotifyCreateIssueComment(doer *user_model.User, r } } -func (ns *notificationService) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (ns *notificationService) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: issue.ID, NotificationAuthorID: issue.Poster.ID, @@ -90,19 +91,19 @@ func (ns *notificationService) NotifyNewIssue(issue *models.Issue, mentions []*u } } -func (ns *notificationService) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, isClosed bool) { +func (ns *notificationService) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: issue.ID, NotificationAuthorID: doer.ID, }) } -func (ns *notificationService) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (ns *notificationService) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { if err := issue.LoadPullRequest(); err != nil { log.Error("issue.LoadPullRequest: %v", err) return } - if issue.IsPull && models.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { + if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: issue.ID, NotificationAuthorID: doer.ID, @@ -110,14 +111,14 @@ func (ns *notificationService) NotifyIssueChangeTitle(doer *user_model.User, iss } } -func (ns *notificationService) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (ns *notificationService) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: pr.Issue.ID, NotificationAuthorID: doer.ID, }) } -func (ns *notificationService) NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func (ns *notificationService) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { if err := pr.LoadIssue(); err != nil { log.Error("Unable to load issue: %d for pr: %d: Error: %v", pr.IssueID, pr.ID, err) return @@ -131,7 +132,7 @@ func (ns *notificationService) NotifyNewPullRequest(pr *models.PullRequest, ment for _, id := range repoWatchers { toNotify[id] = struct{}{} } - issueParticipants, err := models.GetParticipantsIDsByIssueID(pr.IssueID) + issueParticipants, err := issues_model.GetParticipantsIDsByIssueID(pr.IssueID) if err != nil { log.Error("GetParticipantsIDsByIssueID: %v", err) return @@ -152,7 +153,7 @@ func (ns *notificationService) NotifyNewPullRequest(pr *models.PullRequest, ment } } -func (ns *notificationService) NotifyPullRequestReview(pr *models.PullRequest, r *models.Review, c *models.Comment, mentions []*user_model.User) { +func (ns *notificationService) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, c *issues_model.Comment, mentions []*user_model.User) { opts := issueNotificationOpts{ IssueID: pr.Issue.ID, NotificationAuthorID: r.Reviewer.ID, @@ -174,7 +175,7 @@ func (ns *notificationService) NotifyPullRequestReview(pr *models.PullRequest, r } } -func (ns *notificationService) NotifyPullRequestCodeComment(pr *models.PullRequest, c *models.Comment, mentions []*user_model.User) { +func (ns *notificationService) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, c *issues_model.Comment, mentions []*user_model.User) { for _, mention := range mentions { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: pr.Issue.ID, @@ -185,7 +186,7 @@ func (ns *notificationService) NotifyPullRequestCodeComment(pr *models.PullReque } } -func (ns *notificationService) NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) { +func (ns *notificationService) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { opts := issueNotificationOpts{ IssueID: pr.IssueID, NotificationAuthorID: doer.ID, @@ -194,7 +195,7 @@ func (ns *notificationService) NotifyPullRequestPushCommits(doer *user_model.Use _ = ns.issueQueue.Push(opts) } -func (ns *notificationService) NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func (ns *notificationService) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { opts := issueNotificationOpts{ IssueID: review.IssueID, NotificationAuthorID: doer.ID, @@ -203,7 +204,7 @@ func (ns *notificationService) NotifyPullRevieweDismiss(doer *user_model.User, r _ = ns.issueQueue.Push(opts) } -func (ns *notificationService) NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func (ns *notificationService) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { if !removed && doer.ID != assignee.ID { opts := issueNotificationOpts{ IssueID: issue.ID, @@ -219,7 +220,7 @@ func (ns *notificationService) NotifyIssueChangeAssignee(doer *user_model.User, } } -func (ns *notificationService) NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) { +func (ns *notificationService) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { if isRequest { opts := issueNotificationOpts{ IssueID: issue.ID, diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go index 38077f2180..be71d18fda 100644 --- a/modules/notification/webhook/webhook.go +++ b/modules/notification/webhook/webhook.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -39,7 +40,7 @@ func NewNotifier() base.Notifier { return &webhookNotifier{} } -func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *models.Issue) { +func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueClearLabels User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -147,7 +148,7 @@ func (m *webhookNotifier) NotifyMigrateRepository(doer, u *user_model.User, repo } } -func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeAssignee User: %s[%d] Issue[%d] #%d in [%d] Assignee %s[%d] removed: %t", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID, assignee.Name, assignee.ID, removed)) defer finished() @@ -196,7 +197,7 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue } } -func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeTitle User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -240,7 +241,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *m } } -func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, isClosed bool) { +func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeStatus User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -283,7 +284,7 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue * } } -func (m *webhookNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (m *webhookNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { if err := issue.LoadRepo(db.DefaultContext); err != nil { log.Error("issue.LoadRepo: %v", err) return @@ -305,7 +306,7 @@ func (m *webhookNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_m } } -func (m *webhookNotifier) NotifyNewPullRequest(pull *models.PullRequest, mentions []*user_model.User) { +func (m *webhookNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyNewPullRequest Pull[%d] #%d in [%d]", pull.ID, pull.Index, pull.BaseRepoID)) defer finished() @@ -334,7 +335,7 @@ func (m *webhookNotifier) NotifyNewPullRequest(pull *models.PullRequest, mention } } -func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) { +func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeContent User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -373,7 +374,7 @@ func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue } } -func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.Comment, oldContent string) { +func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) { var err error if err = c.LoadPoster(); err != nil { @@ -385,7 +386,7 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C return } - if err = c.Issue.LoadAttributes(); err != nil { + if err = c.Issue.LoadAttributes(db.DefaultContext); err != nil { log.Error("LoadAttributes: %v", err) return } @@ -427,7 +428,7 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C } func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { mode, _ := access_model.AccessLevel(doer, repo) @@ -457,7 +458,7 @@ func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo * } } -func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *models.Comment) { +func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *issues_model.Comment) { var err error if err = comment.LoadPoster(); err != nil { @@ -469,7 +470,7 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *mo return } - if err = comment.Issue.LoadAttributes(); err != nil { + if err = comment.Issue.LoadAttributes(db.DefaultContext); err != nil { log.Error("LoadAttributes: %v", err) return } @@ -501,8 +502,8 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *mo } } -func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label, +func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, + addedLabels, removedLabels []*issues_model.Label, ) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeLabels User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -550,7 +551,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue * } } -func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *models.Issue, oldMilestoneID int64) { +func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeMilestone User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -562,7 +563,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issu hookAction = api.HookIssueDemilestoned } - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(db.DefaultContext); err != nil { log.Error("issue.LoadAttributes failed: %v", err) return } @@ -621,7 +622,7 @@ func (m *webhookNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_ } } -func (*webhookNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (*webhookNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyMergePullRequest Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -662,7 +663,7 @@ func (*webhookNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *use } } -func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *models.PullRequest, oldBranch string) { +func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestChangeTargetBranch Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -696,18 +697,18 @@ func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.U } } -func (m *webhookNotifier) NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment, mentions []*user_model.User) { +func (m *webhookNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() var reviewHookType webhook.HookEventType switch review.Type { - case models.ReviewTypeApprove: + case issues_model.ReviewTypeApprove: reviewHookType = webhook.HookEventPullRequestReviewApproved - case models.ReviewTypeComment: + case issues_model.ReviewTypeComment: reviewHookType = webhook.HookEventPullRequestComment - case models.ReviewTypeReject: + case issues_model.ReviewTypeReject: reviewHookType = webhook.HookEventPullRequestReviewRejected default: // unsupported review webhook type here @@ -756,7 +757,7 @@ func (m *webhookNotifier) NotifyCreateRef(pusher *user_model.User, repo *repo_mo } } -func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *models.PullRequest) { +func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestSynchronized Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -764,7 +765,7 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, p log.Error("pr.LoadIssue: %v", err) return } - if err := pr.Issue.LoadAttributes(); err != nil { + if err := pr.Issue.LoadAttributes(db.DefaultContext); err != nil { log.Error("LoadAttributes: %v", err) return } diff --git a/modules/repository/init.go b/modules/repository/init.go index 285fe81dbe..f5cef3301d 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -16,6 +16,7 @@ import ( "time" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -113,7 +114,7 @@ func GetLabelTemplateFile(name string) ([][3]string, error) { if len(color) == 6 { color = "#" + color } - if !models.LabelColorPattern.MatchString(color) { + if !issues_model.LabelColorPattern.MatchString(color) { return nil, ErrIssueLabelTemplateLoad{name, fmt.Errorf("bad HTML color code in line: %s", line)} } @@ -453,9 +454,9 @@ func InitializeLabels(ctx context.Context, id int64, labelTemplate string, isOrg return err } - labels := make([]*models.Label, len(list)) + labels := make([]*issues_model.Label, len(list)) for i := 0; i < len(list); i++ { - labels[i] = &models.Label{ + labels[i] = &issues_model.Label{ Name: list[i][0], Description: list[i][2], Color: list[i][1], @@ -467,7 +468,7 @@ func InitializeLabels(ctx context.Context, id int64, labelTemplate string, isOrg } } for _, label := range labels { - if err = models.NewLabel(ctx, label); err != nil { + if err = issues_model.NewLabel(ctx, label); err != nil { return err } } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index c0be5c1fa5..b77928fc9c 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -26,6 +26,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/avatars" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -374,7 +375,7 @@ func NewFuncMap() []template.FuncMap { // the table is NOT sorted with this header return "" }, - "RenderLabels": func(labels []*models.Label) template.HTML { + "RenderLabels": func(labels []*issues_model.Label) template.HTML { html := `<span class="labels-list">` for _, label := range labels { // Protect against nil value in labels - shouldn't happen but would cause a panic if so diff --git a/routers/api/v1/misc/nodeinfo.go b/routers/api/v1/misc/nodeinfo.go index c786544e14..bd629b87ca 100644 --- a/routers/api/v1/misc/nodeinfo.go +++ b/routers/api/v1/misc/nodeinfo.go @@ -8,7 +8,7 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" @@ -42,8 +42,8 @@ func NodeInfo(ctx *context.APIContext) { usersActiveMonth := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeOneMonthAgo})) usersActiveHalfyear := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeHaveYearAgo})) - allIssues, _ := models.CountIssues(&models.IssuesOptions{}) - allComments, _ := models.CountComments(&models.FindCommentsOptions{}) + allIssues, _ := issues_model.CountIssues(&issues_model.IssuesOptions{}) + allComments, _ := issues_model.CountComments(&issues_model.FindCommentsOptions{}) nodeInfoUsage = structs.NodeInfoUsage{ Users: structs.NodeInfoUsageUsers{ diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index 4effd6b3e0..7d8d34504f 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" ) @@ -41,7 +42,7 @@ func GetThread(ctx *context.APIContext) { if n == nil { return } - if err := n.LoadAttributes(); err != nil && !models.IsErrCommentNotExist(err) { + if err := n.LoadAttributes(); err != nil && !issues_model.IsErrCommentNotExist(err) { ctx.InternalServerError(err) return } @@ -93,7 +94,7 @@ func ReadThread(ctx *context.APIContext) { ctx.InternalServerError(err) return } - if err = notif.LoadAttributes(); err != nil && !models.IsErrCommentNotExist(err) { + if err = notif.LoadAttributes(); err != nil && !issues_model.IsErrCommentNotExist(err) { ctx.InternalServerError(err) return } diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index 9844ea21d2..a67bd56dfc 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -43,13 +43,13 @@ func ListLabels(ctx *context.APIContext) { // "200": // "$ref": "#/responses/LabelList" - labels, err := models.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) + labels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByOrgID", err) return } - count, err := models.CountLabelsByOrgID(ctx.Org.Organization.ID) + count, err := issues_model.CountLabelsByOrgID(ctx.Org.Organization.ID) if err != nil { ctx.InternalServerError(err) return @@ -88,18 +88,18 @@ func CreateLabel(ctx *context.APIContext) { if len(form.Color) == 6 { form.Color = "#" + form.Color } - if !models.LabelColorPattern.MatchString(form.Color) { + if !issues_model.LabelColorPattern.MatchString(form.Color) { ctx.Error(http.StatusUnprocessableEntity, "ColorPattern", fmt.Errorf("bad color code: %s", form.Color)) return } - label := &models.Label{ + label := &issues_model.Label{ Name: form.Name, Color: form.Color, OrgID: ctx.Org.Organization.ID, Description: form.Description, } - if err := models.NewLabel(ctx, label); err != nil { + if err := issues_model.NewLabel(ctx, label); err != nil { ctx.Error(http.StatusInternalServerError, "NewLabel", err) return } @@ -131,17 +131,17 @@ func GetLabel(ctx *context.APIContext) { // "$ref": "#/responses/Label" var ( - label *models.Label + label *issues_model.Label err error ) strID := ctx.Params(":id") if intID, err2 := strconv.ParseInt(strID, 10, 64); err2 != nil { - label, err = models.GetLabelInOrgByName(ctx, ctx.Org.Organization.ID, strID) + label, err = issues_model.GetLabelInOrgByName(ctx, ctx.Org.Organization.ID, strID) } else { - label, err = models.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, intID) + label, err = issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, intID) } if err != nil { - if models.IsErrOrgLabelNotExist(err) { + if issues_model.IsErrOrgLabelNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetLabelByOrgID", err) @@ -183,9 +183,9 @@ func EditLabel(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" form := web.GetForm(ctx).(*api.EditLabelOption) - label, err := models.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.ParamsInt64(":id")) + label, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrOrgLabelNotExist(err) { + if issues_model.IsErrOrgLabelNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) @@ -201,7 +201,7 @@ func EditLabel(ctx *context.APIContext) { if len(label.Color) == 6 { label.Color = "#" + label.Color } - if !models.LabelColorPattern.MatchString(label.Color) { + if !issues_model.LabelColorPattern.MatchString(label.Color) { ctx.Error(http.StatusUnprocessableEntity, "ColorPattern", fmt.Errorf("bad color code: %s", label.Color)) return } @@ -209,7 +209,7 @@ func EditLabel(ctx *context.APIContext) { if form.Description != nil { label.Description = *form.Description } - if err := models.UpdateLabel(label); err != nil { + if err := issues_model.UpdateLabel(label); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateLabel", err) return } @@ -238,7 +238,7 @@ func DeleteLabel(ctx *context.APIContext) { // "204": // "$ref": "#/responses/empty" - if err := models.DeleteLabel(ctx.Org.Organization.ID, ctx.ParamsInt64(":id")); err != nil { + if err := issues_model.DeleteLabel(ctx.Org.Organization.ID, ctx.ParamsInt64(":id")); err != nil { ctx.Error(http.StatusInternalServerError, "DeleteLabel", err) return } diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index ffa3ddc784..2190094bac 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -557,7 +557,7 @@ func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) { // Called from both CreateFile or UpdateFile to handle both func createOrUpdateFile(ctx *context.APIContext, opts *files_service.UpdateRepoFileOptions) (*api.FileResponse, error) { if !canWriteFiles(ctx, opts.OldBranch) { - return nil, models.ErrUserDoesNotHaveAccessToRepo{ + return nil, repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, } @@ -614,7 +614,7 @@ func DeleteFile(ctx *context.APIContext) { apiOpts := web.GetForm(ctx).(*api.DeleteFileOptions) if !canWriteFiles(ctx, apiOpts.BranchName) { - ctx.Error(http.StatusForbidden, "DeleteFile", models.ErrUserDoesNotHaveAccessToRepo{ + ctx.Error(http.StatusForbidden, "DeleteFile", repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) @@ -712,7 +712,7 @@ func GetContents(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !canReadFiles(ctx.Repo) { - ctx.Error(http.StatusInternalServerError, "GetContentsOrList", models.ErrUserDoesNotHaveAccessToRepo{ + ctx.Error(http.StatusInternalServerError, "GetContentsOrList", repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index c394ad1756..ddad18ef62 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -12,7 +12,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" @@ -184,7 +183,7 @@ func SearchIssues(ctx *context.APIContext) { return } - var issues []*models.Issue + var issues []*issues_model.Issue var filteredCount int64 keyword := ctx.FormTrim("q") @@ -233,7 +232,7 @@ func SearchIssues(ctx *context.APIContext) { // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(includedLabelNames) > 0 || len(includedMilestones) > 0 { - issuesOpt := &models.IssuesOptions{ + issuesOpt := &issues_model.IssuesOptions{ ListOptions: db.ListOptions{ Page: ctx.FormInt("page"), PageSize: limit, @@ -269,7 +268,7 @@ func SearchIssues(ctx *context.APIContext) { issuesOpt.ReviewRequestedID = ctxUserID } - if issues, err = models.Issues(issuesOpt); err != nil { + if issues, err = issues_model.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err) return } @@ -277,7 +276,7 @@ func SearchIssues(ctx *context.APIContext) { issuesOpt.ListOptions = db.ListOptions{ Page: -1, } - if filteredCount, err = models.CountIssues(issuesOpt); err != nil { + if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "CountIssues", err) return } @@ -379,7 +378,7 @@ func ListIssues(ctx *context.APIContext) { isClosed = util.OptionalBoolFalse } - var issues []*models.Issue + var issues []*issues_model.Issue var filteredCount int64 keyword := ctx.FormTrim("q") @@ -397,7 +396,7 @@ func ListIssues(ctx *context.APIContext) { } if splitted := strings.Split(ctx.FormString("labels"), ","); len(splitted) > 0 { - labelIDs, err = models.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) + labelIDs, err = issues_model.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err) return @@ -463,7 +462,7 @@ func ListIssues(ctx *context.APIContext) { // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { - issuesOpt := &models.IssuesOptions{ + issuesOpt := &issues_model.IssuesOptions{ ListOptions: listOptions, RepoID: ctx.Repo.Repository.ID, IsClosed: isClosed, @@ -478,7 +477,7 @@ func ListIssues(ctx *context.APIContext) { MentionedID: mentionedByID, } - if issues, err = models.Issues(issuesOpt); err != nil { + if issues, err = issues_model.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err) return } @@ -486,7 +485,7 @@ func ListIssues(ctx *context.APIContext) { issuesOpt.ListOptions = db.ListOptions{ Page: -1, } - if filteredCount, err = models.CountIssues(issuesOpt); err != nil { + if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "CountIssues", err) return } @@ -547,9 +546,9 @@ func GetIssue(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -598,7 +597,7 @@ func CreateIssue(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) } - issue := &models.Issue{ + issue := &issues_model.Issue{ RepoID: ctx.Repo.Repository.ID, Repo: ctx.Repo.Repository, Title: form.Title, @@ -613,7 +612,7 @@ func CreateIssue(ctx *context.APIContext) { var err error if ctx.Repo.CanWrite(unit.TypeIssues) { issue.MilestoneID = form.Milestone - assigneeIDs, err = models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) + assigneeIDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) if err != nil { if user_model.IsErrUserNotExist(err) { ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) @@ -637,7 +636,7 @@ func CreateIssue(ctx *context.APIContext) { return } if !valid { - ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) + ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) return } } @@ -647,7 +646,7 @@ func CreateIssue(ctx *context.APIContext) { } if err := issue_service.NewIssue(ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) return } @@ -657,7 +656,7 @@ func CreateIssue(ctx *context.APIContext) { if form.Closed { if err := issue_service.ChangeStatus(issue, ctx.Doer, true); err != nil { - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies") return } @@ -667,7 +666,7 @@ func CreateIssue(ctx *context.APIContext) { } // Refetch from database to assign some automatic values - issue, err = models.GetIssueByID(issue.ID) + issue, err = issues_model.GetIssueByID(ctx, issue.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetIssueByID", err) return @@ -716,9 +715,9 @@ func EditIssue(ctx *context.APIContext) { // "$ref": "#/responses/error" form := web.GetForm(ctx).(*api.EditIssueOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -728,7 +727,7 @@ func EditIssue(ctx *context.APIContext) { issue.Repo = ctx.Repo.Repository canWrite := ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) - err = issue.LoadAttributes() + err = issue.LoadAttributes(ctx) if err != nil { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return @@ -764,7 +763,7 @@ func EditIssue(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(deadline.Unix()) } - if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { + if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } @@ -813,9 +812,9 @@ func EditIssue(ctx *context.APIContext) { } issue.IsClosed = api.StateClosed == api.StateType(*form.State) } - statusChangeComment, titleChanged, err := models.UpdateIssueByAPI(issue, ctx.Doer) + statusChangeComment, titleChanged, err := issues_model.UpdateIssueByAPI(issue, ctx.Doer) if err != nil { - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies") return } @@ -832,7 +831,7 @@ func EditIssue(ctx *context.APIContext) { } // Refetch from database to assign some automatic values - issue, err = models.GetIssueByID(issue.ID) + issue, err = issues_model.GetIssueByID(ctx, issue.ID) if err != nil { ctx.InternalServerError(err) return @@ -872,9 +871,9 @@ func DeleteIssue(ctx *context.APIContext) { // "$ref": "#/responses/forbidden" // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByID", err) @@ -928,9 +927,9 @@ func UpdateIssueDeadline(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" form := web.GetForm(ctx).(*api.EditDeadlineOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -951,7 +950,7 @@ func UpdateIssueDeadline(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(deadline.Unix()) } - if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { + if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 22533c3810..89038e4f16 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -10,7 +10,7 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -65,33 +65,33 @@ func ListIssueComments(ctx *context.APIContext) { ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) return } - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) return } issue.Repo = ctx.Repo.Repository - opts := &models.FindCommentsOptions{ + opts := &issues_model.FindCommentsOptions{ IssueID: issue.ID, Since: since, Before: before, - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, } - comments, err := models.FindComments(ctx, opts) + comments, err := issues_model.FindComments(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "FindComments", err) return } - totalCount, err := models.CountComments(opts) + totalCount, err := issues_model.CountComments(opts) if err != nil { ctx.InternalServerError(err) return } - if err := models.CommentList(comments).LoadPosters(); err != nil { + if err := issues_model.CommentList(comments).LoadPosters(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } @@ -157,35 +157,35 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) return } - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) return } issue.Repo = ctx.Repo.Repository - opts := &models.FindCommentsOptions{ + opts := &issues_model.FindCommentsOptions{ ListOptions: utils.GetListOptions(ctx), IssueID: issue.ID, Since: since, Before: before, - Type: models.CommentTypeUnknown, + Type: issues_model.CommentTypeUnknown, } - comments, err := models.FindComments(ctx, opts) + comments, err := issues_model.FindComments(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "FindComments", err) return } - if err := models.CommentList(comments).LoadPosters(); err != nil { + if err := issues_model.CommentList(comments).LoadPosters(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } var apiComments []*api.TimelineComment for _, comment := range comments { - if comment.Type != models.CommentTypeCode && isXRefCommentAccessible(ctx, ctx.Doer, comment, issue.RepoID) { + if comment.Type != issues_model.CommentTypeCode && isXRefCommentAccessible(ctx, ctx.Doer, comment, issue.RepoID) { comment.Issue = issue apiComments = append(apiComments, convert.ToTimelineComment(comment, ctx.Doer)) } @@ -195,9 +195,9 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { ctx.JSON(http.StatusOK, &apiComments) } -func isXRefCommentAccessible(ctx stdCtx.Context, user *user_model.User, c *models.Comment, issueRepoID int64) bool { +func isXRefCommentAccessible(ctx stdCtx.Context, user *user_model.User, c *issues_model.Comment, issueRepoID int64) bool { // Remove comments that the user has no permissions to see - if models.CommentTypeIsRef(c.Type) && c.RefRepoID != issueRepoID && c.RefRepoID != 0 { + if issues_model.CommentTypeIsRef(c.Type) && c.RefRepoID != issueRepoID && c.RefRepoID != 0 { var err error // Set RefRepo for description in template c.RefRepo, err = repo_model.GetRepositoryByIDCtx(ctx, c.RefRepoID) @@ -261,41 +261,41 @@ func ListRepoIssueComments(ctx *context.APIContext) { return } - opts := &models.FindCommentsOptions{ + opts := &issues_model.FindCommentsOptions{ ListOptions: utils.GetListOptions(ctx), RepoID: ctx.Repo.Repository.ID, - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, Since: since, Before: before, } - comments, err := models.FindComments(ctx, opts) + comments, err := issues_model.FindComments(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "FindComments", err) return } - totalCount, err := models.CountComments(opts) + totalCount, err := issues_model.CountComments(opts) if err != nil { ctx.InternalServerError(err) return } - if err = models.CommentList(comments).LoadPosters(); err != nil { + if err = issues_model.CommentList(comments).LoadPosters(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } apiComments := make([]*api.Comment, len(comments)) - if err := models.CommentList(comments).LoadIssues(); err != nil { + if err := issues_model.CommentList(comments).LoadIssues(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadIssues", err) return } - if err := models.CommentList(comments).LoadPosters(); err != nil { + if err := issues_model.CommentList(comments).LoadPosters(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } - if _, err := models.CommentList(comments).Issues().LoadRepositories(); err != nil { + if _, err := issues_model.CommentList(comments).Issues().LoadRepositories(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadRepositories", err) return } @@ -343,7 +343,7 @@ func CreateIssueComment(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" form := web.GetForm(ctx).(*api.CreateIssueCommentOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) return @@ -399,9 +399,9 @@ func GetIssueComment(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -418,7 +418,7 @@ func GetIssueComment(ctx *context.APIContext) { return } - if comment.Type != models.CommentTypeComment { + if comment.Type != issues_model.CommentTypeComment { ctx.Status(http.StatusNoContent) return } @@ -526,9 +526,9 @@ func EditIssueCommentDeprecated(ctx *context.APIContext) { } func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -541,7 +541,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) return } - if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeReview && comment.Type != models.CommentTypeCode { + if comment.Type != issues_model.CommentTypeComment && comment.Type != issues_model.CommentTypeReview && comment.Type != issues_model.CommentTypeCode { ctx.Status(http.StatusNoContent) return } @@ -629,9 +629,9 @@ func DeleteIssueCommentDeprecated(ctx *context.APIContext) { } func deleteIssueComment(ctx *context.APIContext) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -642,7 +642,7 @@ func deleteIssueComment(ctx *context.APIContext) { if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.IsAdmin()) { ctx.Status(http.StatusForbidden) return - } else if comment.Type != models.CommentTypeComment { + } else if comment.Type != issues_model.CommentTypeComment { ctx.Status(http.StatusNoContent) return } diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index 0193eb4230..50c09e02fa 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -8,7 +8,7 @@ package repo import ( "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -46,9 +46,9 @@ func ListIssueLabels(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -56,7 +56,7 @@ func ListIssueLabels(ctx *context.APIContext) { return } - if err := issue.LoadAttributes(); err != nil { + if err := issue.LoadAttributes(ctx); err != nil { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } @@ -111,7 +111,7 @@ func AddIssueLabels(ctx *context.APIContext) { return } - labels, err = models.GetLabelsByIssueID(ctx, issue.ID) + labels, err = issues_model.GetLabelsByIssueID(ctx, issue.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByIssueID", err) return @@ -158,9 +158,9 @@ func DeleteIssueLabel(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -173,9 +173,9 @@ func DeleteIssueLabel(ctx *context.APIContext) { return } - label, err := models.GetLabelByID(ctx, ctx.ParamsInt64(":id")) + label, err := issues_model.GetLabelByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrLabelNotExist(err) { + if issues_model.IsErrLabelNotExist(err) { ctx.Error(http.StatusUnprocessableEntity, "", err) } else { ctx.Error(http.StatusInternalServerError, "GetLabelByID", err) @@ -237,7 +237,7 @@ func ReplaceIssueLabels(ctx *context.APIContext) { return } - labels, err = models.GetLabelsByIssueID(ctx, issue.ID) + labels, err = issues_model.GetLabelsByIssueID(ctx, issue.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByIssueID", err) return @@ -276,9 +276,9 @@ func ClearIssueLabels(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -299,10 +299,10 @@ func ClearIssueLabels(ctx *context.APIContext) { ctx.Status(http.StatusNoContent) } -func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) (issue *models.Issue, labels []*models.Label, err error) { - issue, err = models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) (issue *issues_model.Issue, labels []*issues_model.Label, err error) { + issue, err = issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -310,7 +310,7 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) return } - labels, err = models.GetLabelsByIDs(form.Labels) + labels, err = issues_model.GetLabelsByIDs(form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByIDs", err) return diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index 45be7a92dd..f4c40d2bcd 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -8,7 +8,6 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -49,9 +48,9 @@ func GetIssueCommentReactions(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -176,9 +175,9 @@ func DeleteIssueCommentReaction(ctx *context.APIContext) { } func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -271,9 +270,9 @@ func GetIssueReactions(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -391,9 +390,9 @@ func DeleteIssueReaction(ctx *context.APIContext) { } func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) { - issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index 382f294346..941b22e454 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -8,7 +8,7 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/routers/api/v1/utils" @@ -55,7 +55,7 @@ func StartIssueStopwatch(ctx *context.APIContext) { return } - if err := models.CreateIssueStopwatch(ctx, ctx.Doer, issue); err != nil { + if err := issues_model.CreateIssueStopwatch(ctx, ctx.Doer, issue); err != nil { ctx.Error(http.StatusInternalServerError, "CreateOrStopIssueStopwatch", err) return } @@ -104,7 +104,7 @@ func StopIssueStopwatch(ctx *context.APIContext) { return } - if err := models.FinishIssueStopwatch(ctx, ctx.Doer, issue); err != nil { + if err := issues_model.FinishIssueStopwatch(ctx, ctx.Doer, issue); err != nil { ctx.Error(http.StatusInternalServerError, "CreateOrStopIssueStopwatch", err) return } @@ -153,7 +153,7 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { return } - if err := models.CancelStopwatch(ctx.Doer, issue); err != nil { + if err := issues_model.CancelStopwatch(ctx.Doer, issue); err != nil { ctx.Error(http.StatusInternalServerError, "CancelStopwatch", err) return } @@ -161,10 +161,10 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { ctx.Status(http.StatusNoContent) } -func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.Issue, error) { - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*issues_model.Issue, error) { + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -183,7 +183,7 @@ func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.I return nil, errors.New("Cannot use time tracker") } - if models.StopwatchExists(ctx.Doer.ID, issue.ID) != shouldExist { + if issues_model.StopwatchExists(ctx.Doer.ID, issue.ID) != shouldExist { if shouldExist { ctx.Error(http.StatusConflict, "StopwatchExists", "cannot stop/cancel a non existent stopwatch") err = errors.New("cannot stop/cancel a non existent stopwatch") @@ -219,13 +219,13 @@ func GetStopwatches(ctx *context.APIContext) { // "200": // "$ref": "#/responses/StopWatchList" - sws, err := models.GetUserStopwatches(ctx.Doer.ID, utils.GetListOptions(ctx)) + sws, err := issues_model.GetUserStopwatches(ctx.Doer.ID, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetUserStopwatches", err) return } - count, err := models.CountUserStopwatches(ctx.Doer.ID) + count, err := issues_model.CountUserStopwatches(ctx.Doer.ID) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index a608ba2278..5e03e42b4c 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -8,7 +8,7 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -105,9 +105,9 @@ func DelIssueSubscription(ctx *context.APIContext) { } func setIssueSubscription(ctx *context.APIContext, watch bool) { - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -133,7 +133,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { return } - current, err := models.CheckIssueWatch(user, issue) + current, err := issues_model.CheckIssueWatch(user, issue) if err != nil { ctx.Error(http.StatusInternalServerError, "CheckIssueWatch", err) return @@ -146,7 +146,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { } // Update watch state - if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, watch); err != nil { + if err := issues_model.CreateOrUpdateIssueWatch(user.ID, issue.ID, watch); err != nil { ctx.Error(http.StatusInternalServerError, "CreateOrUpdateIssueWatch", err) return } @@ -186,9 +186,9 @@ func CheckIssueSubscription(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -197,7 +197,7 @@ func CheckIssueSubscription(ctx *context.APIContext) { return } - watching, err := models.CheckIssueWatch(ctx.Doer, issue) + watching, err := issues_model.CheckIssueWatch(ctx.Doer, issue) if err != nil { ctx.InternalServerError(err) return @@ -252,9 +252,9 @@ func GetIssueSubscribers(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -263,7 +263,7 @@ func GetIssueSubscribers(ctx *context.APIContext) { return } - iwl, err := models.GetIssueWatchers(ctx, issue.ID, utils.GetListOptions(ctx)) + iwl, err := issues_model.GetIssueWatchers(ctx, issue.ID, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetIssueWatchers", err) return @@ -284,7 +284,7 @@ func GetIssueSubscribers(ctx *context.APIContext) { apiUsers = append(apiUsers, convert.ToUser(v, ctx.Doer)) } - count, err := models.CountIssueWatchers(ctx, issue.ID) + count, err := issues_model.CountIssueWatchers(ctx, issue.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "CountIssueWatchers", err) return diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index 19e1a82590..b9a6c5af64 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -9,8 +9,8 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" @@ -76,9 +76,9 @@ func ListTrackedTimes(ctx *context.APIContext) { ctx.NotFound("Timetracker is disabled") return } - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -86,7 +86,7 @@ func ListTrackedTimes(ctx *context.APIContext) { return } - opts := &models.FindTrackedTimesOptions{ + opts := &issues_model.FindTrackedTimesOptions{ ListOptions: utils.GetListOptions(ctx), RepositoryID: ctx.Repo.Repository.ID, IssueID: issue.ID, @@ -122,13 +122,13 @@ func ListTrackedTimes(ctx *context.APIContext) { } } - count, err := models.CountTrackedTimes(opts) + count, err := issues_model.CountTrackedTimes(opts) if err != nil { ctx.InternalServerError(err) return } - trackedTimes, err := models.GetTrackedTimes(ctx, opts) + trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) return @@ -180,9 +180,9 @@ func AddTime(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" form := web.GetForm(ctx).(*api.AddTimeOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -215,7 +215,7 @@ func AddTime(ctx *context.APIContext) { created = form.Created } - trackedTime, err := models.AddTime(user, issue, form.Time, created) + trackedTime, err := issues_model.AddTime(user, issue, form.Time, created) if err != nil { ctx.Error(http.StatusInternalServerError, "AddTime", err) return @@ -261,9 +261,9 @@ func ResetIssueTime(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -280,7 +280,7 @@ func ResetIssueTime(ctx *context.APIContext) { return } - err = models.DeleteIssueUserTimes(issue, ctx.Doer) + err = issues_model.DeleteIssueUserTimes(issue, ctx.Doer) if err != nil { if db.IsErrNotExist(err) { ctx.Error(http.StatusNotFound, "DeleteIssueUserTimes", err) @@ -332,9 +332,9 @@ func DeleteTime(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -351,7 +351,7 @@ func DeleteTime(ctx *context.APIContext) { return } - time, err := models.GetTrackedTimeByID(ctx.ParamsInt64(":id")) + time, err := issues_model.GetTrackedTimeByID(ctx.ParamsInt64(":id")) if err != nil { if db.IsErrNotExist(err) { ctx.NotFound(err) @@ -371,7 +371,7 @@ func DeleteTime(ctx *context.APIContext) { return } - err = models.DeleteTime(time) + err = issues_model.DeleteTime(time) if err != nil { ctx.Error(http.StatusInternalServerError, "DeleteTime", err) return @@ -434,12 +434,12 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { return } - opts := &models.FindTrackedTimesOptions{ + opts := &issues_model.FindTrackedTimesOptions{ UserID: user.ID, RepositoryID: ctx.Repo.Repository.ID, } - trackedTimes, err := models.GetTrackedTimes(ctx, opts) + trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) return @@ -504,7 +504,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { return } - opts := &models.FindTrackedTimesOptions{ + opts := &issues_model.FindTrackedTimesOptions{ ListOptions: utils.GetListOptions(ctx), RepositoryID: ctx.Repo.Repository.ID, } @@ -541,13 +541,13 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { } } - count, err := models.CountTrackedTimes(opts) + count, err := issues_model.CountTrackedTimes(opts) if err != nil { ctx.InternalServerError(err) return } - trackedTimes, err := models.GetTrackedTimes(ctx, opts) + trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) return @@ -592,7 +592,7 @@ func ListMyTrackedTimes(ctx *context.APIContext) { // "200": // "$ref": "#/responses/TrackedTimeList" - opts := &models.FindTrackedTimesOptions{ + opts := &issues_model.FindTrackedTimesOptions{ ListOptions: utils.GetListOptions(ctx), UserID: ctx.Doer.ID, } @@ -603,13 +603,13 @@ func ListMyTrackedTimes(ctx *context.APIContext) { return } - count, err := models.CountTrackedTimes(opts) + count, err := issues_model.CountTrackedTimes(opts) if err != nil { ctx.InternalServerError(err) return } - trackedTimes, err := models.GetTrackedTimes(ctx, opts) + trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) return diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index 4332b8e627..8b1e298668 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -11,7 +11,7 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -49,13 +49,13 @@ func ListLabels(ctx *context.APIContext) { // "200": // "$ref": "#/responses/LabelList" - labels, err := models.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) + labels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByRepoID", err) return } - count, err := models.CountLabelsByRepoID(ctx.Repo.Repository.ID) + count, err := issues_model.CountLabelsByRepoID(ctx.Repo.Repository.ID) if err != nil { ctx.InternalServerError(err) return @@ -94,17 +94,17 @@ func GetLabel(ctx *context.APIContext) { // "$ref": "#/responses/Label" var ( - label *models.Label + label *issues_model.Label err error ) strID := ctx.Params(":id") if intID, err2 := strconv.ParseInt(strID, 10, 64); err2 != nil { - label, err = models.GetLabelInRepoByName(ctx, ctx.Repo.Repository.ID, strID) + label, err = issues_model.GetLabelInRepoByName(ctx, ctx.Repo.Repository.ID, strID) } else { - label, err = models.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, intID) + label, err = issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, intID) } if err != nil { - if models.IsErrRepoLabelNotExist(err) { + if issues_model.IsErrRepoLabelNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) @@ -150,18 +150,18 @@ func CreateLabel(ctx *context.APIContext) { if len(form.Color) == 6 { form.Color = "#" + form.Color } - if !models.LabelColorPattern.MatchString(form.Color) { + if !issues_model.LabelColorPattern.MatchString(form.Color) { ctx.Error(http.StatusUnprocessableEntity, "ColorPattern", fmt.Errorf("bad color code: %s", form.Color)) return } - label := &models.Label{ + label := &issues_model.Label{ Name: form.Name, Color: form.Color, RepoID: ctx.Repo.Repository.ID, Description: form.Description, } - if err := models.NewLabel(ctx, label); err != nil { + if err := issues_model.NewLabel(ctx, label); err != nil { ctx.Error(http.StatusInternalServerError, "NewLabel", err) return } @@ -206,9 +206,9 @@ func EditLabel(ctx *context.APIContext) { // "$ref": "#/responses/validationError" form := web.GetForm(ctx).(*api.EditLabelOption) - label, err := models.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) + label, err := issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrRepoLabelNotExist(err) { + if issues_model.IsErrRepoLabelNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) @@ -224,7 +224,7 @@ func EditLabel(ctx *context.APIContext) { if len(label.Color) == 6 { label.Color = "#" + label.Color } - if !models.LabelColorPattern.MatchString(label.Color) { + if !issues_model.LabelColorPattern.MatchString(label.Color) { ctx.Error(http.StatusUnprocessableEntity, "ColorPattern", fmt.Errorf("bad color code: %s", label.Color)) return } @@ -232,7 +232,7 @@ func EditLabel(ctx *context.APIContext) { if form.Description != nil { label.Description = *form.Description } - if err := models.UpdateLabel(label); err != nil { + if err := issues_model.UpdateLabel(label); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateLabel", err) return } @@ -266,7 +266,7 @@ func DeleteLabel(ctx *context.APIContext) { // "204": // "$ref": "#/responses/empty" - if err := models.DeleteLabel(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil { + if err := issues_model.DeleteLabel(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil { ctx.Error(http.StatusInternalServerError, "DeleteLabel", err) return } diff --git a/routers/api/v1/repo/patch.go b/routers/api/v1/repo/patch.go index 6dbf979701..40afe2d92b 100644 --- a/routers/api/v1/repo/patch.go +++ b/routers/api/v1/repo/patch.go @@ -9,6 +9,7 @@ import ( "time" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" @@ -78,7 +79,7 @@ func ApplyDiffPatch(ctx *context.APIContext) { } if !canWriteFiles(ctx, apiOpts.BranchName) { - ctx.Error(http.StatusInternalServerError, "ApplyPatch", models.ErrUserDoesNotHaveAccessToRepo{ + ctx.Error(http.StatusInternalServerError, "ApplyPatch", repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 393f2d1576..50d2c9484f 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -92,7 +92,7 @@ func ListPullRequests(ctx *context.APIContext) { listOptions := utils.GetListOptions(ctx) - prs, maxResults, err := models.PullRequests(ctx.Repo.Repository.ID, &models.PullRequestsOptions{ + prs, maxResults, err := issues_model.PullRequests(ctx.Repo.Repository.ID, &issues_model.PullRequestsOptions{ ListOptions: listOptions, State: ctx.FormTrim("state"), SortType: ctx.FormTrim("sort"), @@ -160,9 +160,9 @@ func GetPullRequest(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -220,9 +220,9 @@ func DownloadPullDiffOrPatch(ctx *context.APIContext) { // "$ref": "#/responses/string" // "404": // "$ref": "#/responses/notFound" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.InternalServerError(err) @@ -297,14 +297,14 @@ func CreatePullRequest(ctx *context.APIContext) { defer headGitRepo.Close() // Check if another PR exists with the same targets - existingPr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch, models.PullRequestFlowGithub) + existingPr, err := issues_model.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch, issues_model.PullRequestFlowGithub) if err != nil { - if !models.IsErrPullRequestNotExist(err) { + if !issues_model.IsErrPullRequestNotExist(err) { ctx.Error(http.StatusInternalServerError, "GetUnmergedPullRequest", err) return } } else { - err = models.ErrPullRequestAlreadyExists{ + err = issues_model.ErrPullRequestAlreadyExists{ ID: existingPr.ID, IssueID: existingPr.Index, HeadRepoID: existingPr.HeadRepoID, @@ -317,7 +317,7 @@ func CreatePullRequest(ctx *context.APIContext) { } if len(form.Labels) > 0 { - labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) + labels, err := issues_model.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDs", err) return @@ -331,7 +331,7 @@ func CreatePullRequest(ctx *context.APIContext) { } if ctx.Repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels) + orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err) return @@ -364,7 +364,7 @@ func CreatePullRequest(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) } - prIssue := &models.Issue{ + prIssue := &issues_model.Issue{ RepoID: repo.ID, Title: form.Title, PosterID: ctx.Doer.ID, @@ -374,7 +374,7 @@ func CreatePullRequest(ctx *context.APIContext) { Content: form.Body, DeadlineUnix: deadlineUnix, } - pr := &models.PullRequest{ + pr := &issues_model.PullRequest{ HeadRepoID: headRepo.ID, BaseRepoID: repo.ID, HeadBranch: headBranch, @@ -382,11 +382,11 @@ func CreatePullRequest(ctx *context.APIContext) { HeadRepo: headRepo, BaseRepo: repo, MergeBase: compareInfo.MergeBase, - Type: models.PullRequestGitea, + Type: issues_model.PullRequestGitea, } // Get all assignee IDs - assigneeIDs, err := models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) + assigneeIDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) if err != nil { if user_model.IsErrUserNotExist(err) { ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) @@ -409,13 +409,13 @@ func CreatePullRequest(ctx *context.APIContext) { return } if !valid { - ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) + ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) return } } if err := pull_service.NewPullRequest(ctx, repo, prIssue, labelIDs, []string{}, pr, assigneeIDs); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) return } @@ -470,9 +470,9 @@ func EditPullRequest(ctx *context.APIContext) { // "$ref": "#/responses/validationError" form := web.GetForm(ctx).(*api.EditPullRequestOption) - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -510,7 +510,7 @@ func EditPullRequest(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(deadline.Unix()) } - if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { + if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } @@ -548,14 +548,14 @@ func EditPullRequest(ctx *context.APIContext) { } if ctx.Repo.CanWrite(unit.TypePullRequests) && form.Labels != nil { - labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) + labels, err := issues_model.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDsError", err) return } if ctx.Repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels) + orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err) return @@ -564,7 +564,7 @@ func EditPullRequest(ctx *context.APIContext) { labels = append(labels, orgLabels...) } - if err = models.ReplaceIssueLabels(issue, labels, ctx.Doer); err != nil { + if err = issues_model.ReplaceIssueLabels(issue, labels, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "ReplaceLabelsError", err) return } @@ -577,9 +577,9 @@ func EditPullRequest(ctx *context.APIContext) { } issue.IsClosed = api.StateClosed == api.StateType(*form.State) } - statusChangeComment, titleChanged, err := models.UpdateIssueByAPI(issue, ctx.Doer) + statusChangeComment, titleChanged, err := issues_model.UpdateIssueByAPI(issue, ctx.Doer) if err != nil { - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies") return } @@ -602,10 +602,10 @@ func EditPullRequest(ctx *context.APIContext) { return } if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.Doer, form.Base); err != nil { - if models.IsErrPullRequestAlreadyExists(err) { + if issues_model.IsErrPullRequestAlreadyExists(err) { ctx.Error(http.StatusConflict, "IsErrPullRequestAlreadyExists", err) return - } else if models.IsErrIssueIsClosed(err) { + } else if issues_model.IsErrIssueIsClosed(err) { ctx.Error(http.StatusUnprocessableEntity, "IsErrIssueIsClosed", err) return } else if models.IsErrPullRequestHasMerged(err) { @@ -632,9 +632,9 @@ func EditPullRequest(ctx *context.APIContext) { } // Refetch from database - pr, err = models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pr.Index) + pr, err = issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pr.Index) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -676,9 +676,9 @@ func IsPullRequestMerged(ctx *context.APIContext) { // "404": // description: pull request has not been merged - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -730,9 +730,9 @@ func MergePullRequest(ctx *context.APIContext) { form := web.GetForm(ctx).(*forms.MergePullRequestForm) - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -753,7 +753,7 @@ func MergePullRequest(ctx *context.APIContext) { if ctx.IsSigned { // Update issue-user. - if err = pr.Issue.ReadBy(ctx, ctx.Doer.ID); err != nil { + if err = models.SetIssueReadBy(ctx, pr.Issue.ID, ctx.Doer.ID); err != nil { ctx.Error(http.StatusInternalServerError, "ReadBy", err) return } @@ -868,7 +868,7 @@ func MergePullRequest(ctx *context.APIContext) { if form.DeleteBranchAfterMerge { // Don't cleanup when there are other PR's that use this branch as head branch. - exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) if err != nil { ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return @@ -902,7 +902,7 @@ func MergePullRequest(ctx *context.APIContext) { } return } - if err := models.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil { + if err := issues_model.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil { // Do not fail here as branch has already been deleted log.Error("DeleteBranch: %v", err) } @@ -1079,9 +1079,9 @@ func UpdatePullRequest(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -1177,9 +1177,9 @@ func CancelScheduledAutoMerge(ctx *context.APIContext) { // "$ref": "#/responses/notFound" pullIndex := ctx.ParamsInt64(":index") - pull, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pullIndex) + pull, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pullIndex) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() return } @@ -1254,9 +1254,9 @@ func GetPullRequestCommits(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 5175fa921f..57548f2102 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -9,7 +9,7 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" user_model "code.gitea.io/gitea/models/user" @@ -61,9 +61,9 @@ func ListPullReviews(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -81,19 +81,19 @@ func ListPullReviews(ctx *context.APIContext) { return } - opts := models.FindReviewOptions{ + opts := issues_model.FindReviewOptions{ ListOptions: utils.GetListOptions(ctx), - Type: models.ReviewTypeUnknown, + Type: issues_model.ReviewTypeUnknown, IssueID: pr.IssueID, } - allReviews, err := models.FindReviews(ctx, opts) + allReviews, err := issues_model.FindReviews(ctx, opts) if err != nil { ctx.InternalServerError(err) return } - count, err := models.CountReviews(opts) + count, err := issues_model.CountReviews(opts) if err != nil { ctx.InternalServerError(err) return @@ -261,7 +261,7 @@ func DeletePullReview(ctx *context.APIContext) { return } - if err := models.DeleteReview(review); err != nil { + if err := issues_model.DeleteReview(review); err != nil { ctx.Error(http.StatusInternalServerError, "DeleteReview", fmt.Errorf("can not delete ReviewID: %d", review.ID)) return } @@ -307,9 +307,9 @@ func CreatePullReview(ctx *context.APIContext) { // "$ref": "#/responses/validationError" opts := web.GetForm(ctx).(*api.CreatePullReviewOptions) - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -435,7 +435,7 @@ func SubmitPullReview(ctx *context.APIContext) { return } - if review.Type != models.ReviewTypePending { + if review.Type != issues_model.ReviewTypePending { ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("only a pending review can be submitted")) return } @@ -447,7 +447,7 @@ func SubmitPullReview(ctx *context.APIContext) { } // if review stay pending return - if reviewType == models.ReviewTypePending { + if reviewType == issues_model.ReviewTypePending { ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("review stay pending")) return } @@ -475,7 +475,7 @@ func SubmitPullReview(ctx *context.APIContext) { } // preparePullReviewType return ReviewType and false or nil and true if an error happen -func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, event api.ReviewStateType, body string, hasComments bool) (models.ReviewType, bool) { +func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest, event api.ReviewStateType, body string, hasComments bool) (issues_model.ReviewType, bool) { if err := pr.LoadIssue(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadIssue", err) return -1, true @@ -484,7 +484,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even needsBody := true hasBody := len(strings.TrimSpace(body)) > 0 - var reviewType models.ReviewType + var reviewType issues_model.ReviewType switch event { case api.ReviewStateApproved: // can not approve your own PR @@ -492,7 +492,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("approve your own pull is not allowed")) return -1, true } - reviewType = models.ReviewTypeApprove + reviewType = issues_model.ReviewTypeApprove needsBody = false case api.ReviewStateRequestChanges: @@ -501,10 +501,10 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("reject your own pull is not allowed")) return -1, true } - reviewType = models.ReviewTypeReject + reviewType = issues_model.ReviewTypeReject case api.ReviewStateComment: - reviewType = models.ReviewTypeComment + reviewType = issues_model.ReviewTypeComment needsBody = false // if there is no body we need to ensure that there are comments if !hasBody && !hasComments { @@ -512,7 +512,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even return -1, true } default: - reviewType = models.ReviewTypePending + reviewType = issues_model.ReviewTypePending } // reject reviews with empty body if a body is required for this call @@ -525,10 +525,10 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even } // prepareSingleReview return review, related pull and false or nil, nil and true if an error happen -func prepareSingleReview(ctx *context.APIContext) (*models.Review, *models.PullRequest, bool) { - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func prepareSingleReview(ctx *context.APIContext) (*issues_model.Review, *issues_model.PullRequest, bool) { + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -536,9 +536,9 @@ func prepareSingleReview(ctx *context.APIContext) (*models.Review, *models.PullR return nil, nil, true } - review, err := models.GetReviewByID(ctx, ctx.ParamsInt64(":id")) + review, err := issues_model.GetReviewByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrReviewNotExist(err) { + if issues_model.IsErrReviewNotExist(err) { ctx.NotFound("GetReviewByID", err) } else { ctx.Error(http.StatusInternalServerError, "GetReviewByID", err) @@ -553,7 +553,7 @@ func prepareSingleReview(ctx *context.APIContext) (*models.Review, *models.PullR } // make sure that the user has access to this review if it is pending - if review.Type == models.ReviewTypePending && review.ReviewerID != ctx.Doer.ID && !ctx.Doer.IsAdmin { + if review.Type == issues_model.ReviewTypePending && review.ReviewerID != ctx.Doer.ID && !ctx.Doer.IsAdmin { ctx.NotFound("GetReviewByID") return nil, nil, true } @@ -648,9 +648,9 @@ func DeleteReviewRequests(ctx *context.APIContext) { } func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions, isAdd bool) { - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -690,7 +690,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions err = issue_service.IsValidReviewRequest(ctx, reviewer, ctx.Doer, isAdd, pr.Issue, &permDoer) if err != nil { - if models.IsErrNotValidReviewRequest(err) { + if issues_model.IsErrNotValidReviewRequest(err) { ctx.Error(http.StatusUnprocessableEntity, "NotValidReviewRequest", err) return } @@ -701,9 +701,9 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions reviewers = append(reviewers, reviewer) } - var reviews []*models.Review + var reviews []*issues_model.Review if isAdd { - reviews = make([]*models.Review, 0, len(reviewers)) + reviews = make([]*issues_model.Review, 0, len(reviewers)) } for _, reviewer := range reviewers { @@ -739,7 +739,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions err = issue_service.IsValidTeamReviewRequest(ctx, teamReviewer, ctx.Doer, isAdd, pr.Issue) if err != nil { - if models.IsErrNotValidReviewRequest(err) { + if issues_model.IsErrNotValidReviewRequest(err) { ctx.Error(http.StatusUnprocessableEntity, "NotValidReviewRequest", err) return } @@ -876,7 +876,7 @@ func dismissReview(ctx *context.APIContext, msg string, isDismiss bool) { return } - if review.Type != models.ReviewTypeApprove && review.Type != models.ReviewTypeReject { + if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject { ctx.Error(http.StatusForbidden, "", "not need to dismiss this review because it's type is not Approve or change request") return } @@ -892,7 +892,7 @@ func dismissReview(ctx *context.APIContext, msg string, isDismiss bool) { return } - if review, err = models.GetReviewByID(ctx, review.ID); err != nil { + if review, err = issues_model.GetReviewByID(ctx, review.ID); err != nil { ctx.Error(http.StatusInternalServerError, "GetReviewByID", err) return } diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index eb2bbc1e5f..93aa450f9c 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -11,7 +11,7 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -141,8 +141,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { continue } - pr, err := models.GetPullRequestByIndex(ctx, repo.ID, pullIndex) - if err != nil && !models.IsErrPullRequestNotExist(err) { + pr, err := issues_model.GetPullRequestByIndex(ctx, repo.ID, pullIndex) + if err != nil && !issues_model.IsErrPullRequestNotExist(err) { log.Error("Failed to get PR by index %v Error: %v", pullIndex, err) ctx.JSON(http.StatusInternalServerError, private.Response{ Err: fmt.Sprintf("Failed to get PR by index %v Error: %v", pullIndex, err), @@ -202,8 +202,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { continue } - pr, err := models.GetUnmergedPullRequest(repo.ID, baseRepo.ID, branch, baseRepo.DefaultBranch, models.PullRequestFlowGithub) - if err != nil && !models.IsErrPullRequestNotExist(err) { + pr, err := issues_model.GetUnmergedPullRequest(repo.ID, baseRepo.ID, branch, baseRepo.DefaultBranch, issues_model.PullRequestFlowGithub) + if err != nil && !issues_model.IsErrPullRequestNotExist(err) { log.Error("Failed to get active PR in: %-v Branch: %s to: %-v Branch: %s Error: %v", repo, branch, baseRepo, baseRepo.DefaultBranch, err) ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{ Err: fmt.Sprintf( diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 411319f2e6..cadfea782c 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" perm_model "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" "code.gitea.io/gitea/models/unit" @@ -57,7 +58,7 @@ func (ctx *preReceiveContext) CanWriteCode() bool { if !ctx.loadPusherAndPermission() { return false } - ctx.canWriteCode = models.CanMaintainerWriteToBranch(ctx.userPerm, ctx.branchName, ctx.user) || ctx.deployKeyAccessMode >= perm_model.AccessModeWrite + ctx.canWriteCode = issues_model.CanMaintainerWriteToBranch(ctx.userPerm, ctx.branchName, ctx.user) || ctx.deployKeyAccessMode >= perm_model.AccessModeWrite ctx.checkedCanWriteCode = true } return ctx.canWriteCode @@ -296,7 +297,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullN // 6b. Merge (from UI or API) // Get the PR, user and permissions for the user in the repository - pr, err := models.GetPullRequestByID(ctx, ctx.opts.PullRequestID) + pr, err := issues_model.GetPullRequestByID(ctx, ctx.opts.PullRequestID) if err != nil { log.Error("Unable to get PullRequest %d Error: %v", ctx.opts.PullRequestID, err) ctx.JSON(http.StatusInternalServerError, private.Response{ diff --git a/routers/web/org/org_labels.go b/routers/web/org/org_labels.go index bfa9f162c3..185e1eee31 100644 --- a/routers/web/org/org_labels.go +++ b/routers/web/org/org_labels.go @@ -7,8 +7,8 @@ package org import ( "net/http" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/web" @@ -17,7 +17,7 @@ import ( // RetrieveLabels find all the labels of an organization func RetrieveLabels(ctx *context.Context) { - labels, err := models.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), db.ListOptions{}) + labels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("RetrieveLabels.GetLabels", err) return @@ -43,13 +43,13 @@ func NewLabel(ctx *context.Context) { return } - l := &models.Label{ + l := &issues_model.Label{ OrgID: ctx.Org.Organization.ID, Name: form.Title, Description: form.Description, Color: form.Color, } - if err := models.NewLabel(ctx, l); err != nil { + if err := issues_model.NewLabel(ctx, l); err != nil { ctx.ServerError("NewLabel", err) return } @@ -59,10 +59,10 @@ func NewLabel(ctx *context.Context) { // UpdateLabel update a label's name and color func UpdateLabel(ctx *context.Context) { form := web.GetForm(ctx).(*forms.CreateLabelForm) - l, err := models.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, form.ID) + l, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, form.ID) if err != nil { switch { - case models.IsErrOrgLabelNotExist(err): + case issues_model.IsErrOrgLabelNotExist(err): ctx.Error(http.StatusNotFound) default: ctx.ServerError("UpdateLabel", err) @@ -73,7 +73,7 @@ func UpdateLabel(ctx *context.Context) { l.Name = form.Title l.Description = form.Description l.Color = form.Color - if err := models.UpdateLabel(l); err != nil { + if err := issues_model.UpdateLabel(l); err != nil { ctx.ServerError("UpdateLabel", err) return } @@ -82,7 +82,7 @@ func UpdateLabel(ctx *context.Context) { // DeleteLabel delete a label func DeleteLabel(ctx *context.Context) { - if err := models.DeleteLabel(ctx.Org.Organization.ID, ctx.FormInt64("id")); err != nil { + if err := issues_model.DeleteLabel(ctx.Org.Organization.ID, ctx.FormInt64("id")); err != nil { ctx.Flash.Error("DeleteLabel: " + err.Error()) } else { ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success")) diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 84ad803ee5..4bd2af4e8e 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" @@ -44,7 +45,7 @@ type Branch struct { DeletedBranch *git_model.DeletedBranch CommitsAhead int CommitsBehind int - LatestPullRequest *models.PullRequest + LatestPullRequest *issues_model.PullRequest MergeMovedOn bool } @@ -264,7 +265,7 @@ func loadOneBranch(ctx *context.Context, rawBranch, defaultBranch *git.Branch, p } } - pr, err := models.GetLatestPullRequestByHeadInfo(ctx.Repo.Repository.ID, branchName) + pr, err := issues_model.GetLatestPullRequestByHeadInfo(ctx.Repo.Repository.ID, branchName) if err != nil { ctx.ServerError("GetLatestPullRequestByHeadInfo", err) return nil diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 44e89062e8..605594d5a9 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -747,9 +748,9 @@ func CompareDiff(ctx *context.Context) { ctx.Data["HeadTags"] = headTags if ctx.Data["PageIsComparePull"] == true { - pr, err := models.GetUnmergedPullRequest(ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadBranch, ci.BaseBranch, models.PullRequestFlowGithub) + pr, err := issues_model.GetUnmergedPullRequest(ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadBranch, ci.BaseBranch, issues_model.PullRequestFlowGithub) if err != nil { - if !models.IsErrPullRequestNotExist(err) { + if !issues_model.IsErrPullRequestNotExist(err) { ctx.ServerError("GetUnmergedPullRequest", err) return } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 38ee933044..11d2daeeff 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -183,11 +183,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti } } - var issueStats *models.IssueStats + var issueStats *issues_model.IssueStats if forceEmpty { - issueStats = &models.IssueStats{} + issueStats = &issues_model.IssueStats{} } else { - issueStats, err = models.GetIssueStats(&models.IssueStatsOptions{ + issueStats, err = issues_model.GetIssueStats(&issues_model.IssueStatsOptions{ RepoID: repo.ID, Labels: selectLabels, MilestoneID: milestoneID, @@ -228,11 +228,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti mileIDs = []int64{milestoneID} } - var issues []*models.Issue + var issues []*issues_model.Issue if forceEmpty { - issues = []*models.Issue{} + issues = []*issues_model.Issue{} } else { - issues, err = models.Issues(&models.IssuesOptions{ + issues, err = issues_model.Issues(&issues_model.IssuesOptions{ ListOptions: db.ListOptions{ Page: pager.Paginater.Current(), PageSize: setting.UI.IssuePagingNum, @@ -256,7 +256,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti } } - issueList := models.IssueList(issues) + issueList := issues_model.IssueList(issues) approvalCounts, err := issueList.GetApprovalCounts(ctx) if err != nil { ctx.ServerError("ApprovalCounts", err) @@ -296,14 +296,14 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti return } - labels, err := models.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByRepoID", err) return } if repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) + orgLabels, err := issues_model.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByOrgID", err) return @@ -330,11 +330,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti if !ok || len(counts) == 0 { return 0 } - reviewTyp := models.ReviewTypeApprove + reviewTyp := issues_model.ReviewTypeApprove if typ == "reject" { - reviewTyp = models.ReviewTypeReject + reviewTyp = issues_model.ReviewTypeReject } else if typ == "waiting" { - reviewTyp = models.ReviewTypeRequest + reviewTyp = issues_model.ReviewTypeRequest } for _, count := range counts { if count.Type == reviewTyp { @@ -483,24 +483,24 @@ type repoReviewerSelection struct { IsTeam bool Team *organization.Team User *user_model.User - Review *models.Review + Review *issues_model.Review CanChange bool Checked bool ItemID int64 } // RetrieveRepoReviewers find all reviewers of a repository -func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, issue *models.Issue, canChooseReviewer bool) { +func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, issue *issues_model.Issue, canChooseReviewer bool) { ctx.Data["CanChooseReviewer"] = canChooseReviewer - originalAuthorReviews, err := models.GetReviewersFromOriginalAuthorsByIssueID(issue.ID) + originalAuthorReviews, err := issues_model.GetReviewersFromOriginalAuthorsByIssueID(issue.ID) if err != nil { ctx.ServerError("GetReviewersFromOriginalAuthorsByIssueID", err) return } ctx.Data["OriginalReviews"] = originalAuthorReviews - reviews, err := models.GetReviewersByIssueID(issue.ID) + reviews, err := issues_model.GetReviewersByIssueID(issue.ID) if err != nil { ctx.ServerError("GetReviewersByIssueID", err) return @@ -549,7 +549,7 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is for _, review := range reviews { tmp := &repoReviewerSelection{ - Checked: review.Type == models.ReviewTypeRequest, + Checked: review.Type == issues_model.ReviewTypeRequest, Review: review, ItemID: review.ReviewerID, } @@ -561,10 +561,10 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is if ctx.Repo.IsAdmin() { // Admin can dismiss or re-request any review requests tmp.CanChange = true - } else if ctx.Doer != nil && ctx.Doer.ID == review.ReviewerID && review.Type == models.ReviewTypeRequest { + } else if ctx.Doer != nil && ctx.Doer.ID == review.ReviewerID && review.Type == issues_model.ReviewTypeRequest { // A user can refuse review requests tmp.CanChange = true - } else if (canChooseReviewer || (ctx.Doer != nil && ctx.Doer.ID == issue.PosterID)) && review.Type != models.ReviewTypeRequest && + } else if (canChooseReviewer || (ctx.Doer != nil && ctx.Doer.ID == issue.PosterID)) && review.Type != issues_model.ReviewTypeRequest && ctx.Doer.ID != review.ReviewerID { // The poster of the PR, a manager, or official reviewers can re-request review from other reviewers tmp.CanChange = true @@ -670,19 +670,19 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is } // RetrieveRepoMetas find all the meta information of a repository -func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull bool) []*models.Label { +func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull bool) []*issues_model.Label { if !ctx.Repo.CanWriteIssuesOrPulls(isPull) { return nil } - labels, err := models.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByRepoID", err) return nil } ctx.Data["Labels"] = labels if repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) + orgLabels, err := issues_model.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { return nil } @@ -763,10 +763,10 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleDirs, ctx.Data[issueTemplateTitleKey] = meta.Title ctx.Data[ctxDataKey] = templateBody labelIDs := make([]string, 0, len(meta.Labels)) - if repoLabels, err := models.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, "", db.ListOptions{}); err == nil { + if repoLabels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, "", db.ListOptions{}); err == nil { ctx.Data["Labels"] = repoLabels if ctx.Repo.Owner.IsOrganization() { - if orgLabels, err := models.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}); err == nil { + if orgLabels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}); err == nil { ctx.Data["OrgLabels"] = orgLabels repoLabels = append(repoLabels, orgLabels...) } @@ -969,7 +969,7 @@ func ValidateRepoMetas(ctx *context.Context, form forms.CreateIssueForm, isPull } if !valid { - ctx.ServerError("canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) + ctx.ServerError("canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) return nil, nil, 0, 0 } } @@ -1017,7 +1017,7 @@ func NewIssuePost(ctx *context.Context) { return } - issue := &models.Issue{ + issue := &issues_model.Issue{ RepoID: repo.ID, Repo: repo, Title: form.Title, @@ -1029,7 +1029,7 @@ func NewIssuePost(ctx *context.Context) { } if err := issue_service.NewIssue(repo, issue, labelIDs, attachments, assigneeIDs); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) return } @@ -1038,7 +1038,7 @@ func NewIssuePost(ctx *context.Context) { } if projectID > 0 { - if err := models.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { + if err := issues_model.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { ctx.ServerError("ChangeProjectAssign", err) return } @@ -1053,29 +1053,29 @@ func NewIssuePost(ctx *context.Context) { } // roleDescriptor returns the Role Descriptor for a comment in/with the given repo, poster and issue -func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *models.Issue) (models.RoleDescriptor, error) { +func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue) (issues_model.RoleDescriptor, error) { perm, err := access_model.GetUserRepoPermission(ctx, repo, poster) if err != nil { - return models.RoleDescriptorNone, err + return issues_model.RoleDescriptorNone, err } // By default the poster has no roles on the comment. - roleDescriptor := models.RoleDescriptorNone + roleDescriptor := issues_model.RoleDescriptorNone // Check if the poster is owner of the repo. if perm.IsOwner() { // If the poster isn't a admin, enable the owner role. if !poster.IsAdmin { - roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorOwner) + roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner) } else { // Otherwise check if poster is the real repo admin. ok, err := access_model.IsUserRealRepoAdmin(repo, poster) if err != nil { - return models.RoleDescriptorNone, err + return issues_model.RoleDescriptorNone, err } if ok { - roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorOwner) + roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner) } } } @@ -1083,18 +1083,18 @@ func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *use // Is the poster can write issues or pulls to the repo, enable the Writer role. // Only enable this if the poster doesn't have the owner role already. if !roleDescriptor.HasRole("Owner") && perm.CanWriteIssuesOrPulls(issue.IsPull) { - roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorWriter) + roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorWriter) } // If the poster is the actual poster of the issue, enable Poster role. if issue.IsPoster(poster.ID) { - roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorPoster) + roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorPoster) } return roleDescriptor, nil } -func getBranchData(ctx *context.Context, issue *models.Issue) { +func getBranchData(ctx *context.Context, issue *issues_model.Issue) { ctx.Data["BaseBranch"] = nil ctx.Data["HeadBranch"] = nil ctx.Data["HeadUserName"] = nil @@ -1131,9 +1131,9 @@ func ViewIssue(ctx *context.Context) { } } - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound("GetIssueByIndex", err) } else { ctx.ServerError("GetIssueByIndex", err) @@ -1182,7 +1182,7 @@ func ViewIssue(ctx *context.Context) { ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled upload.AddUploadContext(ctx, "comment") - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(ctx); err != nil { ctx.ServerError("LoadAttributes", err) return } @@ -1194,11 +1194,11 @@ func ViewIssue(ctx *context.Context) { ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, issue.Title) - iw := new(models.IssueWatch) + iw := new(issues_model.IssueWatch) if ctx.Doer != nil { iw.UserID = ctx.Doer.ID iw.IssueID = issue.ID - iw.IsWatching, err = models.CheckIssueWatch(ctx.Doer, issue) + iw.IsWatching, err = issues_model.CheckIssueWatch(ctx.Doer, issue) if err != nil { ctx.ServerError("CheckIssueWatch", err) return @@ -1239,7 +1239,7 @@ func ViewIssue(ctx *context.Context) { for i := range issue.Labels { labelIDMark[issue.Labels[i].ID] = true } - labels, err := models.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByRepoID", err) return @@ -1247,7 +1247,7 @@ func ViewIssue(ctx *context.Context) { ctx.Data["Labels"] = labels if repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) + orgLabels, err := issues_model.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByOrgID", err) return @@ -1279,7 +1279,7 @@ func ViewIssue(ctx *context.Context) { if issue.IsPull { canChooseReviewer := ctx.Repo.CanWrite(unit.TypePullRequests) if !canChooseReviewer && ctx.Doer != nil && ctx.IsSigned { - canChooseReviewer, err = models.IsOfficialReviewer(ctx, issue, ctx.Doer) + canChooseReviewer, err = issues_model.IsOfficialReviewer(ctx, issue, ctx.Doer) if err != nil { ctx.ServerError("IsOfficialReviewer", err) return @@ -1294,35 +1294,35 @@ func ViewIssue(ctx *context.Context) { if ctx.IsSigned { // Update issue-user. - if err = issue.ReadBy(ctx, ctx.Doer.ID); err != nil { + if err = models.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) return } } var ( - role models.RoleDescriptor + role issues_model.RoleDescriptor ok bool - marked = make(map[int64]models.RoleDescriptor) - comment *models.Comment + marked = make(map[int64]issues_model.RoleDescriptor) + comment *issues_model.Comment participants = make([]*user_model.User, 1, 10) ) if ctx.Repo.Repository.IsTimetrackerEnabled() { if ctx.IsSigned { // Deal with the stopwatch - ctx.Data["IsStopwatchRunning"] = models.StopwatchExists(ctx.Doer.ID, issue.ID) + ctx.Data["IsStopwatchRunning"] = issues_model.StopwatchExists(ctx.Doer.ID, issue.ID) if !ctx.Data["IsStopwatchRunning"].(bool) { var exists bool - var sw *models.Stopwatch - if exists, sw, err = models.HasUserStopwatch(ctx, ctx.Doer.ID); err != nil { + var sw *issues_model.Stopwatch + if exists, sw, err = issues_model.HasUserStopwatch(ctx, ctx.Doer.ID); err != nil { ctx.ServerError("HasUserStopwatch", err) return } ctx.Data["HasUserStopwatch"] = exists if exists { // Add warning if the user has already a stopwatch - var otherIssue *models.Issue - if otherIssue, err = models.GetIssueByID(sw.IssueID); err != nil { + var otherIssue *issues_model.Issue + if otherIssue, err = issues_model.GetIssueByID(ctx, sw.IssueID); err != nil { ctx.ServerError("GetIssueByID", err) return } @@ -1338,7 +1338,7 @@ func ViewIssue(ctx *context.Context) { } else { ctx.Data["CanUseTimetracker"] = false } - if ctx.Data["WorkingUsers"], err = models.TotalTimes(&models.FindTrackedTimesOptions{IssueID: issue.ID}); err != nil { + if ctx.Data["WorkingUsers"], err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: issue.ID}); err != nil { ctx.ServerError("TotalTimes", err) return } @@ -1366,7 +1366,7 @@ func ViewIssue(ctx *context.Context) { return } - if comment.Type == models.CommentTypeComment || comment.Type == models.CommentTypeReview { + if comment.Type == issues_model.CommentTypeComment || comment.Type == issues_model.CommentTypeReview { if err := comment.LoadAttachments(); err != nil { ctx.ServerError("LoadAttachments", err) return @@ -1396,12 +1396,12 @@ func ViewIssue(ctx *context.Context) { } marked[comment.PosterID] = comment.ShowRole participants = addParticipant(comment.Poster, participants) - } else if comment.Type == models.CommentTypeLabel { + } else if comment.Type == issues_model.CommentTypeLabel { if err = comment.LoadLabel(); err != nil { ctx.ServerError("LoadLabel", err) return } - } else if comment.Type == models.CommentTypeMilestone { + } else if comment.Type == issues_model.CommentTypeMilestone { if err = comment.LoadMilestone(); err != nil { ctx.ServerError("LoadMilestone", err) return @@ -1416,7 +1416,7 @@ func ViewIssue(ctx *context.Context) { if comment.MilestoneID > 0 && comment.Milestone == nil { comment.Milestone = ghostMilestone } - } else if comment.Type == models.CommentTypeProject { + } else if comment.Type == issues_model.CommentTypeProject { if err = comment.LoadProject(); err != nil { ctx.ServerError("LoadProject", err) @@ -1436,19 +1436,19 @@ func ViewIssue(ctx *context.Context) { comment.Project = ghostProject } - } else if comment.Type == models.CommentTypeAssignees || comment.Type == models.CommentTypeReviewRequest { + } else if comment.Type == issues_model.CommentTypeAssignees || comment.Type == issues_model.CommentTypeReviewRequest { if err = comment.LoadAssigneeUserAndTeam(); err != nil { ctx.ServerError("LoadAssigneeUserAndTeam", err) return } - } else if comment.Type == models.CommentTypeRemoveDependency || comment.Type == models.CommentTypeAddDependency { + } else if comment.Type == issues_model.CommentTypeRemoveDependency || comment.Type == issues_model.CommentTypeAddDependency { if err = comment.LoadDepIssueDetails(); err != nil { - if !models.IsErrIssueNotExist(err) { + if !issues_model.IsErrIssueNotExist(err) { ctx.ServerError("LoadDepIssueDetails", err) return } } - } else if comment.Type == models.CommentTypeCode || comment.Type == models.CommentTypeReview || comment.Type == models.CommentTypeDismissReview { + } else if comment.Type == issues_model.CommentTypeCode || comment.Type == issues_model.CommentTypeReview || comment.Type == issues_model.CommentTypeDismissReview { comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{ URLPrefix: ctx.Repo.RepoLink, Metas: ctx.Repo.Repository.ComposeMetas(), @@ -1459,7 +1459,7 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("RenderString", err) return } - if err = comment.LoadReview(); err != nil && !models.IsErrReviewNotExist(err) { + if err = comment.LoadReview(); err != nil && !issues_model.IsErrReviewNotExist(err) { ctx.ServerError("LoadReview", err) return } @@ -1502,14 +1502,14 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("LoadResolveDoer", err) return } - } else if comment.Type == models.CommentTypePullRequestPush { + } else if comment.Type == issues_model.CommentTypePullRequestPush { participants = addParticipant(comment.Poster, participants) if err = comment.LoadPushCommits(ctx); err != nil { ctx.ServerError("LoadPushCommits", err) return } - } else if comment.Type == models.CommentTypeAddTimeManual || - comment.Type == models.CommentTypeStopTracking { + } else if comment.Type == issues_model.CommentTypeAddTimeManual || + comment.Type == issues_model.CommentTypeStopTracking { // drop error since times could be pruned from DB.. _ = comment.LoadTime() } @@ -1562,7 +1562,7 @@ func ViewIssue(ctx *context.Context) { return } - if ctx.Data["CanMarkConversation"], err = models.CanMarkConversation(issue, ctx.Doer); err != nil { + if ctx.Data["CanMarkConversation"], err = issues_model.CanMarkConversation(issue, ctx.Doer); err != nil { ctx.ServerError("CanMarkConversation", err) return } @@ -1621,11 +1621,11 @@ func ViewIssue(ctx *context.Context) { if ctx.Doer != nil { showMergeInstructions = pull.ProtectedBranch.CanUserPush(ctx.Doer.ID) } - ctx.Data["IsBlockedByApprovals"] = !models.HasEnoughApprovals(ctx, pull.ProtectedBranch, pull) - ctx.Data["IsBlockedByRejection"] = models.MergeBlockedByRejectedReview(ctx, pull.ProtectedBranch, pull) - ctx.Data["IsBlockedByOfficialReviewRequests"] = models.MergeBlockedByOfficialReviewRequests(ctx, pull.ProtectedBranch, pull) - ctx.Data["IsBlockedByOutdatedBranch"] = models.MergeBlockedByOutdatedBranch(pull.ProtectedBranch, pull) - ctx.Data["GrantedApprovals"] = models.GetGrantedApprovalsCount(ctx, pull.ProtectedBranch, pull) + ctx.Data["IsBlockedByApprovals"] = !issues_model.HasEnoughApprovals(ctx, pull.ProtectedBranch, pull) + ctx.Data["IsBlockedByRejection"] = issues_model.MergeBlockedByRejectedReview(ctx, pull.ProtectedBranch, pull) + ctx.Data["IsBlockedByOfficialReviewRequests"] = issues_model.MergeBlockedByOfficialReviewRequests(ctx, pull.ProtectedBranch, pull) + ctx.Data["IsBlockedByOutdatedBranch"] = issues_model.MergeBlockedByOutdatedBranch(pull.ProtectedBranch, pull) + ctx.Data["GrantedApprovals"] = issues_model.GetGrantedApprovalsCount(ctx, pull.ProtectedBranch, pull) ctx.Data["RequireSigned"] = pull.ProtectedBranch.RequireSignedCommits ctx.Data["ChangedProtectedFiles"] = pull.ChangedProtectedFiles ctx.Data["IsBlockedByChangedProtectedFiles"] = len(pull.ChangedProtectedFiles) != 0 @@ -1655,7 +1655,7 @@ func ViewIssue(ctx *context.Context) { (!pull.HasMerged || ctx.Data["HeadBranchCommitID"] == ctx.Data["PullHeadCommitID"]) if isPullBranchDeletable && pull.HasMerged { - exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pull.HeadRepoID, pull.HeadBranch) + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pull.HeadRepoID, pull.HeadBranch) if err != nil { ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return @@ -1722,7 +1722,7 @@ func ViewIssue(ctx *context.Context) { } hiddenCommentTypes, _ = new(big.Int).SetString(val, 10) // we can safely ignore the failed conversion here } - ctx.Data["ShouldShowCommentType"] = func(commentType models.CommentType) bool { + ctx.Data["ShouldShowCommentType"] = func(commentType issues_model.CommentType) bool { return hiddenCommentTypes == nil || hiddenCommentTypes.Bit(int(commentType)) == 0 } @@ -1730,10 +1730,10 @@ func ViewIssue(ctx *context.Context) { } // GetActionIssue will return the issue which is used in the context. -func GetActionIssue(ctx *context.Context) *models.Issue { - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func GetActionIssue(ctx *context.Context) *issues_model.Issue { + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - ctx.NotFoundOrServerError("GetIssueByIndex", models.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError("GetIssueByIndex", issues_model.IsErrIssueNotExist, err) return nil } issue.Repo = ctx.Repo.Repository @@ -1741,21 +1741,21 @@ func GetActionIssue(ctx *context.Context) *models.Issue { if ctx.Written() { return nil } - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(ctx); err != nil { ctx.ServerError("LoadAttributes", nil) return nil } return issue } -func checkIssueRights(ctx *context.Context, issue *models.Issue) { +func checkIssueRights(ctx *context.Context, issue *issues_model.Issue) { if issue.IsPull && !ctx.Repo.CanRead(unit.TypePullRequests) || !issue.IsPull && !ctx.Repo.CanRead(unit.TypeIssues) { ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) } } -func getActionIssues(ctx *context.Context) []*models.Issue { +func getActionIssues(ctx *context.Context) []*issues_model.Issue { commaSeparatedIssueIDs := ctx.FormString("issue_ids") if len(commaSeparatedIssueIDs) == 0 { return nil @@ -1769,7 +1769,7 @@ func getActionIssues(ctx *context.Context) []*models.Issue { } issueIDs = append(issueIDs, issueID) } - issues, err := models.GetIssuesByIDs(ctx, issueIDs) + issues, err := issues_model.GetIssuesByIDs(ctx, issueIDs) if err != nil { ctx.ServerError("GetIssuesByIDs", err) return nil @@ -1782,7 +1782,7 @@ func getActionIssues(ctx *context.Context) []*models.Issue { ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) return nil } - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(ctx); err != nil { ctx.ServerError("LoadAttributes", err) return nil } @@ -1792,9 +1792,9 @@ func getActionIssues(ctx *context.Context) []*models.Issue { // GetIssueInfo get an issue of a repository func GetIssueInfo(ctx *context.Context) { - issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.Error(http.StatusNotFound) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err.Error()) @@ -1916,9 +1916,9 @@ func UpdateIssueContent(ctx *context.Context) { // UpdateIssueDeadline updates an issue deadline func UpdateIssueDeadline(ctx *context.Context) { form := web.GetForm(ctx).(*api.EditDeadlineOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound("GetIssueByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err.Error()) @@ -1939,7 +1939,7 @@ func UpdateIssueDeadline(ctx *context.Context) { deadlineUnix = timeutil.TimeStamp(deadline.Unix()) } - if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { + if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err.Error()) return } @@ -2002,7 +2002,7 @@ func UpdateIssueAssignee(ctx *context.Context) { return } if !valid { - ctx.ServerError("canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name}) + ctx.ServerError("canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name}) return } @@ -2080,7 +2080,7 @@ func UpdatePullReviewRequest(ctx *context.Context) { err = issue_service.IsValidTeamReviewRequest(ctx, team, ctx.Doer, action == "attach", issue) if err != nil { - if models.IsErrNotValidReviewRequest(err) { + if issues_model.IsErrNotValidReviewRequest(err) { log.Warn( "UpdatePullReviewRequest: refusing to add invalid team review request for UID[%d] team %s to %s#%d owned by UID[%d]: Error: %v", team.OrgID, team.Name, issue.Repo.FullName(), issue.Index, issue.Repo.ID, @@ -2118,7 +2118,7 @@ func UpdatePullReviewRequest(ctx *context.Context) { err = issue_service.IsValidReviewRequest(ctx, reviewer, ctx.Doer, action == "attach", issue, nil) if err != nil { - if models.IsErrNotValidReviewRequest(err) { + if issues_model.IsErrNotValidReviewRequest(err) { log.Warn( "UpdatePullReviewRequest: refusing to add invalid review request for %-v to %-v#%d: Error: %v", reviewer, issue.Repo, issue.Index, @@ -2215,7 +2215,7 @@ func SearchIssues(ctx *context.Context) { return } - var issues []*models.Issue + var issues []*issues_model.Issue var filteredCount int64 keyword := ctx.FormTrim("q") @@ -2264,7 +2264,7 @@ func SearchIssues(ctx *context.Context) { // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(includedLabelNames) > 0 || len(includedMilestones) > 0 { - issuesOpt := &models.IssuesOptions{ + issuesOpt := &issues_model.IssuesOptions{ ListOptions: db.ListOptions{ Page: ctx.FormInt("page"), PageSize: limit, @@ -2300,7 +2300,7 @@ func SearchIssues(ctx *context.Context) { issuesOpt.ReviewRequestedID = ctxUserID } - if issues, err = models.Issues(issuesOpt); err != nil { + if issues, err = issues_model.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err.Error()) return } @@ -2308,7 +2308,7 @@ func SearchIssues(ctx *context.Context) { issuesOpt.ListOptions = db.ListOptions{ Page: -1, } - if filteredCount, err = models.CountIssues(issuesOpt); err != nil { + if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "CountIssues", err.Error()) return } @@ -2356,7 +2356,7 @@ func ListIssues(ctx *context.Context) { isClosed = util.OptionalBoolFalse } - var issues []*models.Issue + var issues []*issues_model.Issue var filteredCount int64 keyword := ctx.FormTrim("q") @@ -2374,7 +2374,7 @@ func ListIssues(ctx *context.Context) { } if splitted := strings.Split(ctx.FormString("labels"), ","); len(splitted) > 0 { - labelIDs, err = models.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) + labelIDs, err = issues_model.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return @@ -2443,7 +2443,7 @@ func ListIssues(ctx *context.Context) { // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { - issuesOpt := &models.IssuesOptions{ + issuesOpt := &issues_model.IssuesOptions{ ListOptions: listOptions, RepoID: ctx.Repo.Repository.ID, IsClosed: isClosed, @@ -2458,7 +2458,7 @@ func ListIssues(ctx *context.Context) { MentionedID: mentionedByID, } - if issues, err = models.Issues(issuesOpt); err != nil { + if issues, err = issues_model.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return } @@ -2466,7 +2466,7 @@ func ListIssues(ctx *context.Context) { issuesOpt.ListOptions = db.ListOptions{ Page: -1, } - if filteredCount, err = models.CountIssues(issuesOpt); err != nil { + if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return } @@ -2493,14 +2493,14 @@ func UpdateIssueStatus(ctx *context.Context) { log.Warn("Unrecognized action: %s", action) } - if _, err := models.IssueList(issues).LoadRepositories(); err != nil { + if _, err := issues_model.IssueList(issues).LoadRepositories(); err != nil { ctx.ServerError("LoadRepositories", err) return } for _, issue := range issues { if issue.IsClosed != isClosed { if err := issue_service.ChangeStatus(issue, ctx.Doer, isClosed); err != nil { - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { ctx.JSON(http.StatusPreconditionFailed, map[string]interface{}{ "error": "cannot close this issue because it still has open dependencies", }) @@ -2564,7 +2564,7 @@ func NewComment(ctx *context.Context) { return } - var comment *models.Comment + var comment *issues_model.Comment defer func() { // Check if issue admin/poster changes the status of issue. if (ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) || (ctx.IsSigned && issue.IsPoster(ctx.Doer.ID))) && @@ -2572,14 +2572,14 @@ func NewComment(ctx *context.Context) { !(issue.IsPull && issue.PullRequest.HasMerged) { // Duplication and conflict check should apply to reopen pull request. - var pr *models.PullRequest + var pr *issues_model.PullRequest if form.Status == "reopen" && issue.IsPull { pull := issue.PullRequest var err error - pr, err = models.GetUnmergedPullRequest(pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch, pull.Flow) + pr, err = issues_model.GetUnmergedPullRequest(pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch, pull.Flow) if err != nil { - if !models.IsErrPullRequestNotExist(err) { + if !issues_model.IsErrPullRequestNotExist(err) { ctx.ServerError("GetUnmergedPullRequest", err) return } @@ -2599,7 +2599,7 @@ func NewComment(ctx *context.Context) { if err := issue_service.ChangeStatus(issue, ctx.Doer, isClosed); err != nil { log.Error("ChangeStatus: %v", err) - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { if issue.IsPull { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.pr_close_blocked")) ctx.Redirect(fmt.Sprintf("%s/pulls/%d", ctx.Repo.RepoLink, issue.Index)) @@ -2648,14 +2648,14 @@ func NewComment(ctx *context.Context) { // UpdateCommentContent change comment of issue's content func UpdateCommentContent(ctx *context.Context) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err) return } if err := comment.LoadIssue(); err != nil { - ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err) return } @@ -2664,7 +2664,7 @@ func UpdateCommentContent(ctx *context.Context) { return } - if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeReview && comment.Type != models.CommentTypeCode { + if comment.Type != issues_model.CommentTypeComment && comment.Type != issues_model.CommentTypeReview && comment.Type != issues_model.CommentTypeCode { ctx.Error(http.StatusNoContent) return } @@ -2714,21 +2714,21 @@ func UpdateCommentContent(ctx *context.Context) { // DeleteComment delete comment of issue func DeleteComment(ctx *context.Context) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err) return } if err := comment.LoadIssue(); err != nil { - ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err) return } if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { ctx.Error(http.StatusForbidden) return - } else if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode { + } else if comment.Type != issues_model.CommentTypeComment && comment.Type != issues_model.CommentTypeCode { ctx.Error(http.StatusNoContent) return } @@ -2790,7 +2790,7 @@ func ChangeIssueReaction(ctx *context.Context) { } // Reload new reactions issue.Reactions = nil - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(ctx); err != nil { log.Info("issue.LoadAttributes: %s", err) break } @@ -2804,7 +2804,7 @@ func ChangeIssueReaction(ctx *context.Context) { // Reload new reactions issue.Reactions = nil - if err := issue.LoadAttributes(); err != nil { + if err := issue.LoadAttributes(ctx); err != nil { log.Info("issue.LoadAttributes: %s", err) break } @@ -2840,14 +2840,14 @@ func ChangeIssueReaction(ctx *context.Context) { // ChangeCommentReaction create a reaction for comment func ChangeCommentReaction(ctx *context.Context) { form := web.GetForm(ctx).(*forms.ReactionForm) - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err) return } if err := comment.LoadIssue(); err != nil { - ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err) return } @@ -2874,7 +2874,7 @@ func ChangeCommentReaction(ctx *context.Context) { return } - if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode && comment.Type != models.CommentTypeReview { + if comment.Type != issues_model.CommentTypeComment && comment.Type != issues_model.CommentTypeCode && comment.Type != issues_model.CommentTypeReview { ctx.Error(http.StatusNoContent) return } @@ -2948,11 +2948,11 @@ func addParticipant(poster *user_model.User, participants []*user_model.User) [] return append(participants, poster) } -func filterXRefComments(ctx *context.Context, issue *models.Issue) error { +func filterXRefComments(ctx *context.Context, issue *issues_model.Issue) error { // Remove comments that the user has no permissions to see for i := 0; i < len(issue.Comments); { c := issue.Comments[i] - if models.CommentTypeIsRef(c.Type) && c.RefRepoID != issue.RepoID && c.RefRepoID != 0 { + if issues_model.CommentTypeIsRef(c.Type) && c.RefRepoID != issue.RepoID && c.RefRepoID != 0 { var err error // Set RefRepo for description in template c.RefRepo, err = repo_model.GetRepositoryByID(c.RefRepoID) @@ -2985,13 +2985,13 @@ func GetIssueAttachments(ctx *context.Context) { // GetCommentAttachments returns attachments for the comment func GetCommentAttachments(ctx *context.Context) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err) return } attachments := make([]*api.Attachment, 0) - if comment.Type == models.CommentTypeComment { + if comment.Type == issues_model.CommentTypeComment { if err := comment.LoadAttachments(); err != nil { ctx.ServerError("LoadAttachments", err) return @@ -3006,9 +3006,9 @@ func GetCommentAttachments(ctx *context.Context) { func updateAttachments(ctx *context.Context, item interface{}, files []string) error { var attachments []*repo_model.Attachment switch content := item.(type) { - case *models.Issue: + case *issues_model.Issue: attachments = content.Attachments - case *models.Comment: + case *issues_model.Comment: attachments = content.Attachments default: return fmt.Errorf("unknown Type: %T", content) @@ -3024,9 +3024,9 @@ func updateAttachments(ctx *context.Context, item interface{}, files []string) e var err error if len(files) > 0 { switch content := item.(type) { - case *models.Issue: - err = models.UpdateIssueAttachments(content.ID, files) - case *models.Comment: + case *issues_model.Issue: + err = issues_model.UpdateIssueAttachments(content.ID, files) + case *issues_model.Comment: err = content.UpdateAttachments(files) default: return fmt.Errorf("unknown Type: %T", content) @@ -3036,9 +3036,9 @@ func updateAttachments(ctx *context.Context, item interface{}, files []string) e } } switch content := item.(type) { - case *models.Issue: + case *issues_model.Issue: content.Attachments, err = repo_model.GetAttachmentsByIssueID(ctx, content.ID) - case *models.Comment: + case *issues_model.Comment: content.Attachments, err = repo_model.GetAttachmentsByCommentID(ctx, content.ID) default: return fmt.Errorf("unknown Type: %T", content) @@ -3060,17 +3060,17 @@ func attachmentsHTML(ctx *context.Context, attachments []*repo_model.Attachment, } // combineLabelComments combine the nearby label comments as one. -func combineLabelComments(issue *models.Issue) { - var prev, cur *models.Comment +func combineLabelComments(issue *issues_model.Issue) { + var prev, cur *issues_model.Comment for i := 0; i < len(issue.Comments); i++ { cur = issue.Comments[i] if i > 0 { prev = issue.Comments[i-1] } - if i == 0 || cur.Type != models.CommentTypeLabel || + if i == 0 || cur.Type != issues_model.CommentTypeLabel || (prev != nil && prev.PosterID != cur.PosterID) || (prev != nil && cur.CreatedUnix-prev.CreatedUnix >= 60) { - if cur.Type == models.CommentTypeLabel && cur.Label != nil { + if cur.Type == issues_model.CommentTypeLabel && cur.Label != nil { if cur.Content != "1" { cur.RemovedLabels = append(cur.RemovedLabels, cur.Label) } else { @@ -3081,7 +3081,7 @@ func combineLabelComments(issue *models.Issue) { } if cur.Label != nil { // now cur MUST be label comment - if prev.Type == models.CommentTypeLabel { // we can combine them only prev is a label comment + if prev.Type == issues_model.CommentTypeLabel { // we can combine them only prev is a label comment if cur.Content != "1" { // remove labels from the AddedLabels list if the label that was removed is already // in this list, and if it's not in this list, add the label to RemovedLabels diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index 407832dffe..d8a21c7fd7 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -11,8 +11,7 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" - issuesModel "code.gitea.io/gitea/models/issues" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" @@ -31,7 +30,7 @@ func GetContentHistoryOverview(ctx *context.Context) { } lang := ctx.Locale.Language() - editedHistoryCountMap, _ := issuesModel.QueryIssueContentHistoryEditedCountMap(ctx, issue.ID) + editedHistoryCountMap, _ := issues_model.QueryIssueContentHistoryEditedCountMap(ctx, issue.ID) ctx.JSON(http.StatusOK, map[string]interface{}{ "i18n": map[string]interface{}{ "textEdited": i18n.Tr(lang, "repo.issues.content_history.edited"), @@ -51,7 +50,7 @@ func GetContentHistoryList(ctx *context.Context) { return } - items, _ := issuesModel.FetchIssueContentHistoryList(ctx, issue.ID, commentID) + items, _ := issues_model.FetchIssueContentHistoryList(ctx, issue.ID, commentID) // render history list to HTML for frontend dropdown items: (name, value) // name is HTML of "avatar + userName + userAction + timeSince" @@ -89,8 +88,8 @@ func GetContentHistoryList(ctx *context.Context) { // canSoftDeleteContentHistory checks whether current user can soft-delete a history revision // Admins or owners can always delete history revisions. Normal users can only delete own history revisions. -func canSoftDeleteContentHistory(ctx *context.Context, issue *models.Issue, comment *models.Comment, - history *issuesModel.ContentHistory, +func canSoftDeleteContentHistory(ctx *context.Context, issue *issues_model.Issue, comment *issues_model.Comment, + history *issues_model.ContentHistory, ) bool { canSoftDelete := false if ctx.Repo.IsOwner() { @@ -118,7 +117,7 @@ func GetContentHistoryDetail(ctx *context.Context) { } historyID := ctx.FormInt64("history_id") - history, prevHistory, err := issuesModel.GetIssueContentHistoryAndPrev(ctx, historyID) + history, prevHistory, err := issues_model.GetIssueContentHistoryAndPrev(ctx, historyID) if err != nil { ctx.JSON(http.StatusNotFound, map[string]interface{}{ "message": "Can not find the content history", @@ -127,10 +126,10 @@ func GetContentHistoryDetail(ctx *context.Context) { } // get the related comment if this history revision is for a comment, otherwise the history revision is for an issue. - var comment *models.Comment + var comment *issues_model.Comment if history.CommentID != 0 { var err error - if comment, err = models.GetCommentByID(ctx, history.CommentID); err != nil { + if comment, err = issues_model.GetCommentByID(ctx, history.CommentID); err != nil { log.Error("can not get comment for issue content history %v. err=%v", historyID, err) return } @@ -186,16 +185,16 @@ func SoftDeleteContentHistory(ctx *context.Context) { commentID := ctx.FormInt64("comment_id") historyID := ctx.FormInt64("history_id") - var comment *models.Comment - var history *issuesModel.ContentHistory + var comment *issues_model.Comment + var history *issues_model.ContentHistory var err error if commentID != 0 { - if comment, err = models.GetCommentByID(ctx, commentID); err != nil { + if comment, err = issues_model.GetCommentByID(ctx, commentID); err != nil { log.Error("can not get comment for issue content history %v. err=%v", historyID, err) return } } - if history, err = issuesModel.GetIssueContentHistoryByID(ctx, historyID); err != nil { + if history, err = issues_model.GetIssueContentHistoryByID(ctx, historyID); err != nil { log.Error("can not get issue content history %v. err=%v", historyID, err) return } @@ -208,7 +207,7 @@ func SoftDeleteContentHistory(ctx *context.Context) { return } - err = issuesModel.SoftDeleteIssueContentHistory(ctx, historyID) + err = issues_model.SoftDeleteIssueContentHistory(ctx, historyID) log.Debug("soft delete issue content history. issue=%d, comment=%d, history=%d", issue.ID, commentID, historyID) ctx.JSON(http.StatusOK, map[string]interface{}{ "ok": err == nil, diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go index ec713238c6..d8d934ea1c 100644 --- a/routers/web/repo/issue_dependency.go +++ b/routers/web/repo/issue_dependency.go @@ -7,7 +7,7 @@ package repo import ( "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" ) @@ -15,7 +15,7 @@ import ( // AddDependency adds new dependencies func AddDependency(ctx *context.Context) { issueIndex := ctx.ParamsInt64("index") - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) if err != nil { ctx.ServerError("GetIssueByIndex", err) return @@ -38,7 +38,7 @@ func AddDependency(ctx *context.Context) { defer ctx.Redirect(issue.HTMLURL()) // Dependency - dep, err := models.GetIssueByID(depID) + dep, err := issues_model.GetIssueByID(ctx, depID) if err != nil { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_issue_not_exist")) return @@ -56,12 +56,12 @@ func AddDependency(ctx *context.Context) { return } - err = models.CreateIssueDependency(ctx.Doer, issue, dep) + err = issues_model.CreateIssueDependency(ctx.Doer, issue, dep) if err != nil { - if models.IsErrDependencyExists(err) { + if issues_model.IsErrDependencyExists(err) { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_exists")) return - } else if models.IsErrCircularDependency(err) { + } else if issues_model.IsErrCircularDependency(err) { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_cannot_create_circular")) return } else { @@ -74,7 +74,7 @@ func AddDependency(ctx *context.Context) { // RemoveDependency removes the dependency func RemoveDependency(ctx *context.Context) { issueIndex := ctx.ParamsInt64("index") - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) if err != nil { ctx.ServerError("GetIssueByIndex", err) return @@ -96,27 +96,27 @@ func RemoveDependency(ctx *context.Context) { // Dependency Type depTypeStr := ctx.Req.PostForm.Get("dependencyType") - var depType models.DependencyType + var depType issues_model.DependencyType switch depTypeStr { case "blockedBy": - depType = models.DependencyTypeBlockedBy + depType = issues_model.DependencyTypeBlockedBy case "blocking": - depType = models.DependencyTypeBlocking + depType = issues_model.DependencyTypeBlocking default: ctx.Error(http.StatusBadRequest, "GetDependecyType") return } // Dependency - dep, err := models.GetIssueByID(depID) + dep, err := issues_model.GetIssueByID(ctx, depID) if err != nil { ctx.ServerError("GetIssueByID", err) return } - if err = models.RemoveIssueDependency(ctx.Doer, issue, dep, depType); err != nil { - if models.IsErrDependencyNotExists(err) { + if err = issues_model.RemoveIssueDependency(ctx.Doer, issue, dep, depType); err != nil { + if issues_model.IsErrDependencyNotExists(err) { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_exist")) return } diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go index 2e72d659be..7af415a8fa 100644 --- a/routers/web/repo/issue_label.go +++ b/routers/web/repo/issue_label.go @@ -7,8 +7,8 @@ package repo import ( "net/http" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -56,7 +56,7 @@ func InitializeLabels(ctx *context.Context) { // RetrieveLabels find all the labels of a repository and organization func RetrieveLabels(ctx *context.Context) { - labels, err := models.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("RetrieveLabels.GetLabels", err) return @@ -69,7 +69,7 @@ func RetrieveLabels(ctx *context.Context) { ctx.Data["Labels"] = labels if ctx.Repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) + orgLabels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByOrgID", err) return @@ -111,13 +111,13 @@ func NewLabel(ctx *context.Context) { return } - l := &models.Label{ + l := &issues_model.Label{ RepoID: ctx.Repo.Repository.ID, Name: form.Title, Description: form.Description, Color: form.Color, } - if err := models.NewLabel(ctx, l); err != nil { + if err := issues_model.NewLabel(ctx, l); err != nil { ctx.ServerError("NewLabel", err) return } @@ -127,10 +127,10 @@ func NewLabel(ctx *context.Context) { // UpdateLabel update a label's name and color func UpdateLabel(ctx *context.Context) { form := web.GetForm(ctx).(*forms.CreateLabelForm) - l, err := models.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, form.ID) + l, err := issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, form.ID) if err != nil { switch { - case models.IsErrRepoLabelNotExist(err): + case issues_model.IsErrRepoLabelNotExist(err): ctx.Error(http.StatusNotFound) default: ctx.ServerError("UpdateLabel", err) @@ -141,7 +141,7 @@ func UpdateLabel(ctx *context.Context) { l.Name = form.Title l.Description = form.Description l.Color = form.Color - if err := models.UpdateLabel(l); err != nil { + if err := issues_model.UpdateLabel(l); err != nil { ctx.ServerError("UpdateLabel", err) return } @@ -150,7 +150,7 @@ func UpdateLabel(ctx *context.Context) { // DeleteLabel delete a label func DeleteLabel(ctx *context.Context) { - if err := models.DeleteLabel(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil { + if err := issues_model.DeleteLabel(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil { ctx.Flash.Error("DeleteLabel: " + err.Error()) } else { ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success")) @@ -177,9 +177,9 @@ func UpdateIssueLabel(ctx *context.Context) { } } case "attach", "detach", "toggle": - label, err := models.GetLabelByID(ctx, ctx.FormInt64("id")) + label, err := issues_model.GetLabelByID(ctx, ctx.FormInt64("id")) if err != nil { - if models.IsErrRepoLabelNotExist(err) { + if issues_model.IsErrRepoLabelNotExist(err) { ctx.Error(http.StatusNotFound, "GetLabelByID") } else { ctx.ServerError("GetLabelByID", err) @@ -191,7 +191,7 @@ func UpdateIssueLabel(ctx *context.Context) { // detach if any issues already have label, otherwise attach action = "attach" for _, issue := range issues { - if models.HasIssueLabel(ctx, issue.ID, label.ID) { + if issues_model.HasIssueLabel(ctx, issue.ID, label.ID) { action = "detach" break } diff --git a/routers/web/repo/issue_label_test.go b/routers/web/repo/issue_label_test.go index 5d7a29ee93..ea078e215c 100644 --- a/routers/web/repo/issue_label_test.go +++ b/routers/web/repo/issue_label_test.go @@ -9,7 +9,7 @@ import ( "strconv" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/web" @@ -37,7 +37,7 @@ func TestInitializeLabels(t *testing.T) { web.SetForm(ctx, &forms.InitializeLabelsForm{TemplateName: "Default"}) InitializeLabels(ctx) assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) - unittest.AssertExistsAndLoadBean(t, &models.Label{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ RepoID: 2, Name: "enhancement", Color: "#84b6eb", @@ -62,7 +62,7 @@ func TestRetrieveLabels(t *testing.T) { ctx.Req.Form.Set("sort", testCase.Sort) RetrieveLabels(ctx) assert.False(t, ctx.Written()) - labels, ok := ctx.Data["Labels"].([]*models.Label) + labels, ok := ctx.Data["Labels"].([]*issues_model.Label) assert.True(t, ok) if assert.Len(t, labels, len(testCase.ExpectedLabelIDs)) { for i, label := range labels { @@ -83,7 +83,7 @@ func TestNewLabel(t *testing.T) { }) NewLabel(ctx) assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) - unittest.AssertExistsAndLoadBean(t, &models.Label{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ Name: "newlabel", Color: "#abcdef", }) @@ -102,7 +102,7 @@ func TestUpdateLabel(t *testing.T) { }) UpdateLabel(ctx) assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) - unittest.AssertExistsAndLoadBean(t, &models.Label{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ ID: 2, Name: "newnameforlabel", Color: "#abcdef", @@ -118,8 +118,8 @@ func TestDeleteLabel(t *testing.T) { ctx.Req.Form.Set("id", "2") DeleteLabel(ctx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) - unittest.AssertNotExistsBean(t, &models.Label{ID: 2}) - unittest.AssertNotExistsBean(t, &models.IssueLabel{LabelID: 2}) + unittest.AssertNotExistsBean(t, &issues_model.Label{ID: 2}) + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{LabelID: 2}) assert.Equal(t, ctx.Tr("repo.issues.label_deletion_success"), ctx.Flash.SuccessMsg) } @@ -132,9 +132,9 @@ func TestUpdateIssueLabel_Clear(t *testing.T) { ctx.Req.Form.Set("action", "clear") UpdateIssueLabel(ctx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) - unittest.AssertNotExistsBean(t, &models.IssueLabel{IssueID: 1}) - unittest.AssertNotExistsBean(t, &models.IssueLabel{IssueID: 3}) - unittest.CheckConsistencyFor(t, &models.Label{}) + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: 1}) + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: 3}) + unittest.CheckConsistencyFor(t, &issues_model.Label{}) } func TestUpdateIssueLabel_Toggle(t *testing.T) { @@ -159,11 +159,11 @@ func TestUpdateIssueLabel_Toggle(t *testing.T) { UpdateIssueLabel(ctx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) for _, issueID := range testCase.IssueIDs { - unittest.AssertExistsIf(t, testCase.ExpectedAdd, &models.IssueLabel{ + unittest.AssertExistsIf(t, testCase.ExpectedAdd, &issues_model.IssueLabel{ IssueID: issueID, LabelID: testCase.LabelID, }) } - unittest.CheckConsistencyFor(t, &models.Label{}) + unittest.CheckConsistencyFor(t, &issues_model.Label{}) } } diff --git a/routers/web/repo/issue_lock.go b/routers/web/repo/issue_lock.go index 5ac5cac52e..a89ea47571 100644 --- a/routers/web/repo/issue_lock.go +++ b/routers/web/repo/issue_lock.go @@ -5,7 +5,7 @@ package repo import ( - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/forms" @@ -32,7 +32,7 @@ func LockIssue(ctx *context.Context) { return } - if err := models.LockIssue(&models.IssueLockOptions{ + if err := issues_model.LockIssue(&issues_model.IssueLockOptions{ Doer: ctx.Doer, Issue: issue, Reason: form.Reason, @@ -57,7 +57,7 @@ func UnlockIssue(ctx *context.Context) { return } - if err := models.UnlockIssue(&models.IssueLockOptions{ + if err := issues_model.UnlockIssue(&issues_model.IssueLockOptions{ Doer: ctx.Doer, Issue: issue, }); err != nil { diff --git a/routers/web/repo/issue_stopwatch.go b/routers/web/repo/issue_stopwatch.go index 4e1f6af039..68f89b258d 100644 --- a/routers/web/repo/issue_stopwatch.go +++ b/routers/web/repo/issue_stopwatch.go @@ -8,8 +8,8 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/eventsource" ) @@ -23,7 +23,7 @@ func IssueStopwatch(c *context.Context) { var showSuccessMessage bool - if !models.StopwatchExists(c.Doer.ID, issue.ID) { + if !issues_model.StopwatchExists(c.Doer.ID, issue.ID) { showSuccessMessage = true } @@ -32,7 +32,7 @@ func IssueStopwatch(c *context.Context) { return } - if err := models.CreateOrStopIssueStopwatch(c.Doer, issue); err != nil { + if err := issues_model.CreateOrStopIssueStopwatch(c.Doer, issue); err != nil { c.ServerError("CreateOrStopIssueStopwatch", err) return } @@ -56,12 +56,12 @@ func CancelStopwatch(c *context.Context) { return } - if err := models.CancelStopwatch(c.Doer, issue); err != nil { + if err := issues_model.CancelStopwatch(c.Doer, issue); err != nil { c.ServerError("CancelStopwatch", err) return } - stopwatches, err := models.GetUserStopwatches(c.Doer.ID, db.ListOptions{}) + stopwatches, err := issues_model.GetUserStopwatches(c.Doer.ID, db.ListOptions{}) if err != nil { c.ServerError("GetUserStopwatches", err) return @@ -87,7 +87,7 @@ func GetActiveStopwatch(ctx *context.Context) { return } - _, sw, err := models.HasUserStopwatch(ctx, ctx.Doer.ID) + _, sw, err := issues_model.HasUserStopwatch(ctx, ctx.Doer.ID) if err != nil { ctx.ServerError("HasUserStopwatch", err) return @@ -97,7 +97,7 @@ func GetActiveStopwatch(ctx *context.Context) { return } - issue, err := models.GetIssueByID(sw.IssueID) + issue, err := issues_model.GetIssueByID(ctx, sw.IssueID) if err != nil || issue == nil { ctx.ServerError("GetIssueByID", err) return diff --git a/routers/web/repo/issue_test.go b/routers/web/repo/issue_test.go index debd2a8a3c..ad82fe0f36 100644 --- a/routers/web/repo/issue_test.go +++ b/routers/web/repo/issue_test.go @@ -7,7 +7,7 @@ package repo import ( "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "github.com/stretchr/testify/assert" ) @@ -15,50 +15,50 @@ import ( func TestCombineLabelComments(t *testing.T) { kases := []struct { name string - beforeCombined []*models.Comment - afterCombined []*models.Comment + beforeCombined []*issues_model.Comment + afterCombined []*issues_model.Comment }{ { name: "kase 1", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", CreatedUnix: 0, - AddedLabels: []*models.Label{}, - Label: &models.Label{ + AddedLabels: []*issues_model.Label{}, + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, @@ -67,63 +67,63 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 2", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 70, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", CreatedUnix: 0, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", CreatedUnix: 70, - RemovedLabels: []*models.Label{ + RemovedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, @@ -132,63 +132,63 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 3", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 2, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", CreatedUnix: 0, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 2, Content: "", CreatedUnix: 0, - RemovedLabels: []*models.Label{ + RemovedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, @@ -197,33 +197,33 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 4", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/backport", }, CreatedUnix: 10, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", CreatedUnix: 10, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "kind/bug", }, @@ -231,7 +231,7 @@ func TestCombineLabelComments(t *testing.T) { Name: "kind/backport", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, @@ -239,41 +239,41 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 5", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 2, Content: "testtest", CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "kind/bug", }, @@ -281,21 +281,21 @@ func TestCombineLabelComments(t *testing.T) { CreatedUnix: 0, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 2, Content: "testtest", CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - RemovedLabels: []*models.Label{ + RemovedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, @@ -304,53 +304,53 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 6", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "reviewed/confirmed", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/feature", }, CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "reviewed/confirmed", }, @@ -366,7 +366,7 @@ func TestCombineLabelComments(t *testing.T) { for _, kase := range kases { t.Run(kase.name, func(t *testing.T) { - issue := models.Issue{ + issue := issues_model.Issue{ Comments: kase.beforeCombined, } combineLabelComments(&issue) diff --git a/routers/web/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go index 28274a7f7b..817a2c6d20 100644 --- a/routers/web/repo/issue_timetrack.go +++ b/routers/web/repo/issue_timetrack.go @@ -8,8 +8,8 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -43,7 +43,7 @@ func AddTimeManually(c *context.Context) { return } - if _, err := models.AddTime(c.Doer, issue, int64(total.Seconds()), time.Now()); err != nil { + if _, err := issues_model.AddTime(c.Doer, issue, int64(total.Seconds()), time.Now()); err != nil { c.ServerError("AddTime", err) return } @@ -62,7 +62,7 @@ func DeleteTime(c *context.Context) { return } - t, err := models.GetTrackedTimeByID(c.ParamsInt64(":timeid")) + t, err := issues_model.GetTrackedTimeByID(c.ParamsInt64(":timeid")) if err != nil { if db.IsErrNotExist(err) { c.NotFound("time not found", err) @@ -78,7 +78,7 @@ func DeleteTime(c *context.Context) { return } - if err = models.DeleteTime(t); err != nil { + if err = issues_model.DeleteTime(t); err != nil { c.ServerError("DeleteTime", err) return } diff --git a/routers/web/repo/issue_watch.go b/routers/web/repo/issue_watch.go index 53fec11cdc..5210ecf777 100644 --- a/routers/web/repo/issue_watch.go +++ b/routers/web/repo/issue_watch.go @@ -8,7 +8,7 @@ import ( "net/http" "strconv" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" ) @@ -48,7 +48,7 @@ func IssueWatch(ctx *context.Context) { return } - if err := models.CreateOrUpdateIssueWatch(ctx.Doer.ID, issue.ID, watch); err != nil { + if err := issues_model.CreateOrUpdateIssueWatch(ctx.Doer.ID, issue.ID, watch); err != nil { ctx.ServerError("CreateOrUpdateIssueWatch", err) return } diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index c1805944db..51c891dbf0 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -10,7 +10,7 @@ import ( "net/url" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" project_model "code.gitea.io/gitea/models/project" "code.gitea.io/gitea/models/unit" @@ -296,13 +296,13 @@ func ViewProject(ctx *context.Context) { boards[0].Title = ctx.Tr("repo.projects.type.uncategorized") } - issuesMap, err := models.LoadIssuesFromBoardList(boards) + issuesMap, err := issues_model.LoadIssuesFromBoardList(boards) if err != nil { ctx.ServerError("LoadIssuesOfBoards", err) return } - linkedPrsMap := make(map[int64][]*models.Issue) + linkedPrsMap := make(map[int64][]*issues_model.Issue) for _, issuesList := range issuesMap { for _, issue := range issuesList { var referencedIds []int64 @@ -313,7 +313,7 @@ func ViewProject(ctx *context.Context) { } if len(referencedIds) > 0 { - if linkedPrs, err := models.Issues(&models.IssuesOptions{ + if linkedPrs, err := issues_model.Issues(&issues_model.IssuesOptions{ IssueIDs: referencedIds, IsPull: util.OptionalBoolTrue, }); err == nil { @@ -358,7 +358,7 @@ func UpdateIssueProject(ctx *context.Context) { continue } - if err := models.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { + if err := issues_model.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { ctx.ServerError("ChangeProjectAssign", err) return } @@ -622,9 +622,9 @@ func MoveIssues(ctx *context.Context) { issueIDs = append(issueIDs, issue.IssueID) sortedIssueIDs[issue.Sorting] = issue.IssueID } - movedIssues, err := models.GetIssuesByIDs(ctx, issueIDs) + movedIssues, err := issues_model.GetIssuesByIDs(ctx, issueIDs) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound("IssueNotExisting", nil) } else { ctx.ServerError("GetIssueByID", err) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index c1a59ca8c0..6e8f575ad5 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" @@ -256,10 +257,10 @@ func ForkPost(ctx *context.Context) { ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name)) } -func checkPullInfo(ctx *context.Context) *models.Issue { - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func checkPullInfo(ctx *context.Context) *issues_model.Issue { + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound("GetIssueByIndex", err) } else { ctx.ServerError("GetIssueByIndex", err) @@ -294,7 +295,7 @@ func checkPullInfo(ctx *context.Context) *models.Issue { if ctx.IsSigned { // Update issue-user. - if err = issue.ReadBy(ctx, ctx.Doer.ID); err != nil { + if err = models.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) return nil } @@ -303,7 +304,7 @@ func checkPullInfo(ctx *context.Context) *models.Issue { return issue } -func setMergeTarget(ctx *context.Context, pull *models.PullRequest) { +func setMergeTarget(ctx *context.Context, pull *issues_model.PullRequest) { if ctx.Repo.Owner.Name == pull.MustHeadUserName() { ctx.Data["HeadTarget"] = pull.HeadBranch } else if pull.HeadRepo == nil { @@ -317,7 +318,7 @@ func setMergeTarget(ctx *context.Context, pull *models.PullRequest) { } // PrepareMergedViewPullInfo show meta information for a merged pull request view page -func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) *git.CompareInfo { +func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { pull := issue.PullRequest setMergeTarget(ctx, pull) @@ -395,7 +396,7 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) *git.C } // PrepareViewPullInfo show meta information for a pull request preview page -func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.CompareInfo { +func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes repo := ctx.Repo.Repository @@ -482,14 +483,14 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare } defer headGitRepo.Close() - if pull.Flow == models.PullRequestFlowGithub { + if pull.Flow == issues_model.PullRequestFlowGithub { headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch) } else { headBranchExist = git.IsReferenceExist(ctx, baseGitRepo.Path, pull.GetGitRefName()) } if headBranchExist { - if pull.Flow != models.PullRequestFlowGithub { + if pull.Flow != issues_model.PullRequestFlowGithub { headBranchSha, err = baseGitRepo.GetRefCommitID(pull.GetGitRefName()) } else { headBranchSha, err = headGitRepo.GetBranchCommitID(pull.HeadBranch) @@ -752,7 +753,7 @@ func ViewPullFiles(ctx *context.Context) { } if ctx.IsSigned && ctx.Doer != nil { - if ctx.Data["CanMarkConversation"], err = models.CanMarkConversation(issue, ctx.Doer); err != nil { + if ctx.Data["CanMarkConversation"], err = issues_model.CanMarkConversation(issue, ctx.Doer); err != nil { ctx.ServerError("CanMarkConversation", err) return } @@ -770,15 +771,15 @@ func ViewPullFiles(ctx *context.Context) { return } - currentReview, err := models.GetCurrentReview(ctx, ctx.Doer, issue) - if err != nil && !models.IsErrReviewNotExist(err) { + currentReview, err := issues_model.GetCurrentReview(ctx, ctx.Doer, issue) + if err != nil && !issues_model.IsErrReviewNotExist(err) { ctx.ServerError("GetCurrentReview", err) return } numPendingCodeComments := int64(0) if currentReview != nil { - numPendingCodeComments, err = models.CountComments(&models.FindCommentsOptions{ - Type: models.CommentTypeCode, + numPendingCodeComments, err = issues_model.CountComments(&issues_model.FindCommentsOptions{ + Type: issues_model.CommentTypeCode, ReviewID: currentReview.ID, IssueID: issue.ID, }) @@ -1062,7 +1063,7 @@ func MergePullRequest(ctx *context.Context) { if form.DeleteBranchAfterMerge { // Don't cleanup when other pr use this branch as head branch - exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) if err != nil { ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return @@ -1109,9 +1110,9 @@ func CancelAutoMergePullRequest(ctx *context.Context) { ctx.Redirect(fmt.Sprintf("%s/pulls/%d", ctx.Repo.RepoLink, issue.Index)) } -func stopTimerIfAvailable(user *user_model.User, issue *models.Issue) error { - if models.StopwatchExists(user.ID, issue.ID) { - if err := models.CreateOrStopIssueStopwatch(user, issue); err != nil { +func stopTimerIfAvailable(user *user_model.User, issue *issues_model.Issue) error { + if issues_model.StopwatchExists(user.ID, issue.ID) { + if err := issues_model.CreateOrStopIssueStopwatch(user, issue); err != nil { return err } } @@ -1190,7 +1191,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { return } - pullIssue := &models.Issue{ + pullIssue := &issues_model.Issue{ RepoID: repo.ID, Repo: repo, Title: form.Title, @@ -1200,7 +1201,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { IsPull: true, Content: form.Content, } - pullRequest := &models.PullRequest{ + pullRequest := &issues_model.PullRequest{ HeadRepoID: ci.HeadRepo.ID, BaseRepoID: repo.ID, HeadBranch: ci.HeadBranch, @@ -1208,14 +1209,14 @@ func CompareAndPullRequestPost(ctx *context.Context) { HeadRepo: ci.HeadRepo, BaseRepo: repo, MergeBase: ci.CompareInfo.MergeBase, - Type: models.PullRequestGitea, + Type: issues_model.PullRequestGitea, AllowMaintainerEdit: form.AllowMaintainerEdit, } // FIXME: check error in the case two people send pull request at almost same time, give nice error prompt // instead of 500. if err := pull_service.NewPullRequest(ctx, repo, pullIssue, labelIDs, attachments, pullRequest, assigneeIDs); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) return } else if git.IsErrPushRejected(err) { @@ -1262,7 +1263,7 @@ func CleanUpPullRequest(ctx *context.Context) { } // Don't cleanup when there are other PR's that use this branch as head branch. - exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) if err != nil { ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return @@ -1356,7 +1357,7 @@ func CleanUpPullRequest(ctx *context.Context) { deleteBranch(ctx, pr, gitRepo) } -func deleteBranch(ctx *context.Context, pr *models.PullRequest, gitRepo *git.Repository) { +func deleteBranch(ctx *context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository) { fullBranchName := pr.HeadRepo.Owner.Name + "/" + pr.HeadBranch if err := repo_service.DeleteBranch(ctx.Doer, pr.HeadRepo, gitRepo, pr.HeadBranch); err != nil { switch { @@ -1373,7 +1374,7 @@ func deleteBranch(ctx *context.Context, pr *models.PullRequest, gitRepo *git.Rep return } - if err := models.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.IssueID, pr.HeadBranch); err != nil { + if err := issues_model.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.IssueID, pr.HeadBranch); err != nil { // Do not fail here as branch has already been deleted log.Error("DeleteBranch: %v", err) } @@ -1393,9 +1394,9 @@ func DownloadPullPatch(ctx *context.Context) { // DownloadPullDiffOrPatch render a pull's raw diff or patch func DownloadPullDiffOrPatch(ctx *context.Context, patch bool) { - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.ServerError("GetPullRequestByIndex", err) @@ -1435,8 +1436,8 @@ func UpdatePullRequestTarget(ctx *context.Context) { } if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.Doer, targetBranch); err != nil { - if models.IsErrPullRequestAlreadyExists(err) { - err := err.(models.ErrPullRequestAlreadyExists) + if issues_model.IsErrPullRequestAlreadyExists(err) { + err := err.(issues_model.ErrPullRequestAlreadyExists) RepoRelPath := ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name errorMessage := ctx.Tr("repo.pulls.has_pull_request", html.EscapeString(ctx.Repo.RepoLink+"/pulls/"+strconv.FormatInt(err.IssueID, 10)), html.EscapeString(RepoRelPath), err.IssueID) // FIXME: Creates url insidde locale string @@ -1446,7 +1447,7 @@ func UpdatePullRequestTarget(ctx *context.Context) { "error": err.Error(), "user_error": errorMessage, }) - } else if models.IsErrIssueIsClosed(err) { + } else if issues_model.IsErrIssueIsClosed(err) { errorMessage := ctx.Tr("repo.pulls.is_closed") ctx.Flash.Error(errorMessage) @@ -1486,9 +1487,9 @@ func UpdatePullRequestTarget(ctx *context.Context) { func SetAllowEdits(ctx *context.Context) { form := web.GetForm(ctx).(*forms.UpdateAllowEditsForm) - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.ServerError("GetPullRequestByIndex", err) diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go index e051290200..cc7ae9bbfa 100644 --- a/routers/web/repo/pull_review.go +++ b/routers/web/repo/pull_review.go @@ -8,7 +8,7 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" pull_model "code.gitea.io/gitea/models/pull" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -31,8 +31,8 @@ func RenderNewCodeCommentForm(ctx *context.Context) { if !issue.IsPull { return } - currentReview, err := models.GetCurrentReview(ctx, ctx.Doer, issue) - if err != nil && !models.IsErrReviewNotExist(err) { + currentReview, err := issues_model.GetCurrentReview(ctx, ctx.Doer, issue) + if err != nil && !issues_model.IsErrReviewNotExist(err) { ctx.ServerError("GetCurrentReview", err) return } @@ -107,7 +107,7 @@ func UpdateResolveConversation(ctx *context.Context) { action := ctx.FormString("action") commentID := ctx.FormInt64("comment_id") - comment, err := models.GetCommentByID(ctx, commentID) + comment, err := issues_model.GetCommentByID(ctx, commentID) if err != nil { ctx.ServerError("GetIssueByID", err) return @@ -119,7 +119,7 @@ func UpdateResolveConversation(ctx *context.Context) { } var permResult bool - if permResult, err = models.CanMarkConversation(comment.Issue, ctx.Doer); err != nil { + if permResult, err = issues_model.CanMarkConversation(comment.Issue, ctx.Doer); err != nil { ctx.ServerError("CanMarkConversation", err) return } @@ -134,7 +134,7 @@ func UpdateResolveConversation(ctx *context.Context) { } if action == "Resolve" || action == "UnResolve" { - err = models.MarkConversation(comment, ctx.Doer, action == "Resolve") + err = issues_model.MarkConversation(comment, ctx.Doer, action == "Resolve") if err != nil { ctx.ServerError("MarkConversation", err) return @@ -153,8 +153,8 @@ func UpdateResolveConversation(ctx *context.Context) { }) } -func renderConversation(ctx *context.Context, comment *models.Comment) { - comments, err := models.FetchCodeCommentsByLine(ctx, comment.Issue, ctx.Doer, comment.TreePath, comment.Line) +func renderConversation(ctx *context.Context, comment *issues_model.Comment) { + comments, err := issues_model.FetchCodeCommentsByLine(ctx, comment.Issue, ctx.Doer, comment.TreePath, comment.Line) if err != nil { ctx.ServerError("FetchCodeCommentsByLine", err) return @@ -194,15 +194,15 @@ func SubmitReview(ctx *context.Context) { reviewType := form.ReviewType() switch reviewType { - case models.ReviewTypeUnknown: + case issues_model.ReviewTypeUnknown: ctx.ServerError("ReviewType", fmt.Errorf("unknown ReviewType: %s", form.Type)) return // can not approve/reject your own PR - case models.ReviewTypeApprove, models.ReviewTypeReject: + case issues_model.ReviewTypeApprove, issues_model.ReviewTypeReject: if issue.IsPoster(ctx.Doer.ID) { var translated string - if reviewType == models.ReviewTypeApprove { + if reviewType == issues_model.ReviewTypeApprove { translated = ctx.Tr("repo.issues.review.self.approval") } else { translated = ctx.Tr("repo.issues.review.self.rejection") @@ -221,7 +221,7 @@ func SubmitReview(ctx *context.Context) { _, comm, err := pull_service.SubmitReview(ctx, ctx.Doer, ctx.Repo.GitRepo, issue, reviewType, form.Content, form.CommitID, attachments) if err != nil { - if models.IsContentEmptyErr(err) { + if issues_model.IsContentEmptyErr(err) { ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty")) ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index)) } else { diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 9b4fc652f1..7fe80a2a4b 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -385,17 +385,17 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { viewType = ctx.FormString("type") switch viewType { case "assigned": - filterMode = models.FilterModeAssign + filterMode = issues_model.FilterModeAssign case "created_by": - filterMode = models.FilterModeCreate + filterMode = issues_model.FilterModeCreate case "mentioned": - filterMode = models.FilterModeMention + filterMode = issues_model.FilterModeMention case "review_requested": - filterMode = models.FilterModeReviewRequested + filterMode = issues_model.FilterModeReviewRequested case "your_repositories": fallthrough default: - filterMode = models.FilterModeYourRepositories + filterMode = issues_model.FilterModeYourRepositories viewType = "your_repositories" } @@ -416,7 +416,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { } isPullList := unitType == unit.TypePullRequests - opts := &models.IssuesOptions{ + opts := &issues_model.IssuesOptions{ IsPull: util.OptionalBoolOf(isPullList), SortType: sortType, IsArchived: util.OptionalBoolFalse, @@ -450,15 +450,15 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { } switch filterMode { - case models.FilterModeAll: - case models.FilterModeYourRepositories: - case models.FilterModeAssign: + case issues_model.FilterModeAll: + case issues_model.FilterModeYourRepositories: + case issues_model.FilterModeAssign: opts.AssigneeID = ctx.Doer.ID - case models.FilterModeCreate: + case issues_model.FilterModeCreate: opts.PosterID = ctx.Doer.ID - case models.FilterModeMention: + case issues_model.FilterModeMention: opts.MentionedID = ctx.Doer.ID - case models.FilterModeReviewRequested: + case issues_model.FilterModeReviewRequested: opts.ReviewRequestedID = ctx.Doer.ID } @@ -491,7 +491,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // USING NON-FINAL STATE OF opts FOR A QUERY. var issueCountByRepo map[int64]int64 if !forceEmpty { - issueCountByRepo, err = models.CountIssuesByRepo(opts) + issueCountByRepo, err = issues_model.CountIssuesByRepo(opts) if err != nil { ctx.ServerError("CountIssuesByRepo", err) return @@ -532,15 +532,15 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // Slice of Issues that will be displayed on the overview page // USING FINAL STATE OF opts FOR A QUERY. - var issues []*models.Issue + var issues []*issues_model.Issue if !forceEmpty { - issues, err = models.Issues(opts) + issues, err = issues_model.Issues(opts) if err != nil { ctx.ServerError("Issues", err) return } } else { - issues = []*models.Issue{} + issues = []*issues_model.Issue{} } // ---------------------------------- @@ -578,9 +578,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // ------------------------------- // Fill stats to post to ctx.Data. // ------------------------------- - var issueStats *models.IssueStats + var issueStats *issues_model.IssueStats if !forceEmpty { - statsOpts := models.UserIssueStatsOptions{ + statsOpts := issues_model.UserIssueStatsOptions{ UserID: ctx.Doer.ID, FilterMode: filterMode, IsPull: isPullList, @@ -592,13 +592,13 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { Team: team, } - issueStats, err = models.GetUserIssueStats(statsOpts) + issueStats, err = issues_model.GetUserIssueStats(statsOpts) if err != nil { ctx.ServerError("GetUserIssueStats Shown", err) return } } else { - issueStats = &models.IssueStats{} + issueStats = &issues_model.IssueStats{} } // Will be posted to ctx.Data. @@ -623,7 +623,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { ctx.Data["Issues"] = issues - approvalCounts, err := models.IssueList(issues).GetApprovalCounts(ctx) + approvalCounts, err := issues_model.IssueList(issues).GetApprovalCounts(ctx) if err != nil { ctx.ServerError("ApprovalCounts", err) return @@ -633,11 +633,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { if !ok || len(counts) == 0 { return 0 } - reviewTyp := models.ReviewTypeApprove + reviewTyp := issues_model.ReviewTypeApprove if typ == "reject" { - reviewTyp = models.ReviewTypeReject + reviewTyp = issues_model.ReviewTypeReject } else if typ == "waiting" { - reviewTyp = models.ReviewTypeRequest + reviewTyp = issues_model.ReviewTypeRequest } for _, count := range counts { if count.Type == reviewTyp { @@ -708,12 +708,12 @@ func getRepoIDs(reposQuery string) []int64 { return repoIDs } -func issueIDsFromSearch(ctx *context.Context, ctxUser *user_model.User, keyword string, opts *models.IssuesOptions) ([]int64, error) { +func issueIDsFromSearch(ctx *context.Context, ctxUser *user_model.User, keyword string, opts *issues_model.IssuesOptions) ([]int64, error) { if len(keyword) == 0 { return []int64{}, nil } - searchRepoIDs, err := models.GetRepoIDsForIssuesOptions(opts, ctxUser) + searchRepoIDs, err := issues_model.GetRepoIDsForIssuesOptions(opts, ctxUser) if err != nil { return nil, fmt.Errorf("GetRepoIDsForIssuesOptions: %v", err) } diff --git a/routers/web/user/stop_watch.go b/routers/web/user/stop_watch.go index 4b16c9aeda..f40d850fc1 100644 --- a/routers/web/user/stop_watch.go +++ b/routers/web/user/stop_watch.go @@ -7,15 +7,15 @@ package user import ( "net/http" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" ) // GetStopwatches get all stopwatches func GetStopwatches(ctx *context.Context) { - sws, err := models.GetUserStopwatches(ctx.Doer.ID, db.ListOptions{ + sws, err := issues_model.GetUserStopwatches(ctx.Doer.ID, db.ListOptions{ Page: ctx.FormInt("page"), PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), }) @@ -24,7 +24,7 @@ func GetStopwatches(ctx *context.Context) { return } - count, err := models.CountUserStopwatches(ctx.Doer.ID) + count, err := issues_model.CountUserStopwatches(ctx.Doer.ID) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return diff --git a/services/agit/agit.go b/services/agit/agit.go index cc520dbc76..7666093c51 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -10,7 +10,8 @@ import ( "os" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -97,9 +98,9 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva headBranch = curentTopicBranch } - pr, err := models.GetUnmergedPullRequest(repo.ID, repo.ID, headBranch, baseBranchName, models.PullRequestFlowAGit) + pr, err := issues_model.GetUnmergedPullRequest(repo.ID, repo.ID, headBranch, baseBranchName, issues_model.PullRequestFlowAGit) if err != nil { - if !models.IsErrPullRequestNotExist(err) { + if !issues_model.IsErrPullRequestNotExist(err) { log.Error("Failed to get unmerged agit flow pull request in repository: %s/%s Error: %v", ownerName, repoName, err) ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ "Err": fmt.Sprintf("Failed to get unmerged agit flow pull request in repository: %s/%s Error: %v", ownerName, repoName, err), @@ -134,7 +135,7 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva return nil } - prIssue := &models.Issue{ + prIssue := &issues_model.Issue{ RepoID: repo.ID, Title: title, PosterID: pusher.ID, @@ -143,7 +144,7 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva Content: description, } - pr := &models.PullRequest{ + pr := &issues_model.PullRequest{ HeadRepoID: repo.ID, BaseRepoID: repo.ID, HeadBranch: headBranch, @@ -152,12 +153,12 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva HeadRepo: repo, BaseRepo: repo, MergeBase: "", - Type: models.PullRequestGitea, - Flow: models.PullRequestFlowAGit, + Type: issues_model.PullRequestGitea, + Flow: issues_model.PullRequestFlowAGit, } if err := pull_service.NewPullRequest(ctx, repo, prIssue, []int64{}, []string{}, pr, []int64{}); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) return nil } @@ -249,7 +250,7 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva }) return nil } - comment, err := models.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i]) + comment, err := issues_model.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i]) if err == nil && comment != nil { notification.NotifyPullRequestPushCommits(pusher, pr, comment) } @@ -270,7 +271,7 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva // UserNameChanged handle user name change for agit flow pull func UserNameChanged(user *user_model.User, newName string) error { - pulls, err := models.GetAllUnmergedAgitPullRequestByPoster(user.ID) + pulls, err := issues_model.GetAllUnmergedAgitPullRequestByPoster(user.ID) if err != nil { return err } diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go index 0f74cd4b2a..edfd0f6cad 100644 --- a/services/asymkey/sign.go +++ b/services/asymkey/sign.go @@ -9,11 +9,11 @@ import ( "fmt" "strings" - "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" @@ -271,7 +271,7 @@ Loop: } // SignMerge determines if we should sign a PR merge commit to the base repository -func SignMerge(ctx context.Context, pr *models.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) { +func SignMerge(ctx context.Context, pr *issues_model.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) { if err := pr.LoadBaseRepoCtx(ctx); err != nil { log.Error("Unable to get Base Repo for pull request") return false, "", nil, err @@ -318,7 +318,7 @@ Loop: if protectedBranch == nil { return false, "", nil, &ErrWontSign{approved} } - if models.GetGrantedApprovalsCount(ctx, protectedBranch, pr) < 1 { + if issues_model.GetGrantedApprovalsCount(ctx, protectedBranch, pr) < 1 { return false, "", nil, &ErrWontSign{approved} } case baseSigned: diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index 3c7346ab58..d0f83f4a93 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -11,8 +11,8 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" repo_model "code.gitea.io/gitea/models/repo" @@ -52,7 +52,7 @@ func handle(data ...queue.Data) []queue.Data { return nil } -func addToQueue(pr *models.PullRequest, sha string) { +func addToQueue(pr *issues_model.PullRequest, sha string) { if err := prAutoMergeQueue.PushFunc(fmt.Sprintf("%d_%s", pr.ID, sha), func() error { log.Trace("Adding pullID: %d to the pull requests patch checking queue with sha %s", pr.ID, sha) return nil @@ -62,7 +62,7 @@ func addToQueue(pr *models.PullRequest, sha string) { } // ScheduleAutoMerge if schedule is false and no error, pull can be merged directly -func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *models.PullRequest, style repo_model.MergeStyle, message string) (scheduled bool, err error) { +func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest, style repo_model.MergeStyle, message string) (scheduled bool, err error) { err = db.WithTx(func(ctx context.Context) error { lastCommitStatus, err := pull_service.GetPullRequestCommitStatusState(ctx, pull) if err != nil { @@ -79,27 +79,27 @@ func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *models. } scheduled = true - _, err = models.CreateAutoMergeComment(ctx, models.CommentTypePRScheduledToAutoMerge, pull, doer) + _, err = issues_model.CreateAutoMergeComment(ctx, issues_model.CommentTypePRScheduledToAutoMerge, pull, doer) return err }, ctx) return } // RemoveScheduledAutoMerge cancels a previously scheduled pull request -func RemoveScheduledAutoMerge(ctx context.Context, doer *user_model.User, pull *models.PullRequest) error { +func RemoveScheduledAutoMerge(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest) error { return db.WithTx(func(ctx context.Context) error { if err := pull_model.DeleteScheduledAutoMerge(ctx, pull.ID); err != nil { return err } - _, err := models.CreateAutoMergeComment(ctx, models.CommentTypePRUnScheduledToAutoMerge, pull, doer) + _, err := issues_model.CreateAutoMergeComment(ctx, issues_model.CommentTypePRUnScheduledToAutoMerge, pull, doer) return err }, ctx) } // MergeScheduledPullRequest merges a previously scheduled pull request when all checks succeeded func MergeScheduledPullRequest(ctx context.Context, sha string, repo *repo_model.Repository) error { - pulls, err := getPullRequestsByHeadSHA(ctx, sha, repo, func(pr *models.PullRequest) bool { + pulls, err := getPullRequestsByHeadSHA(ctx, sha, repo, func(pr *issues_model.PullRequest) bool { return !pr.HasMerged && pr.CanAutoMerge() }) if err != nil { @@ -113,7 +113,7 @@ func MergeScheduledPullRequest(ctx context.Context, sha string, repo *repo_model return nil } -func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*models.PullRequest) bool) (map[int64]*models.PullRequest, error) { +func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*issues_model.PullRequest) bool) (map[int64]*issues_model.PullRequest, error) { gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) if err != nil { return nil, err @@ -125,7 +125,7 @@ func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model. return nil, err } - pulls := make(map[int64]*models.PullRequest) + pulls := make(map[int64]*issues_model.PullRequest) for _, ref := range refs { // Each pull branch starts with refs/pull/ we then go from there to find the index of the pr and then @@ -145,10 +145,10 @@ func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model. continue } - p, err := models.GetPullRequestByIndex(ctx, repo.ID, prIndex) + p, err := issues_model.GetPullRequestByIndex(ctx, repo.ID, prIndex) if err != nil { // If there is no pull request for this branch, we don't try to merge it. - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { continue } return nil, err @@ -168,7 +168,7 @@ func handlePull(pullID int64, sha string) { fmt.Sprintf("Handle AutoMerge of pull[%d] with sha[%s]", pullID, sha)) defer finished() - pr, err := models.GetPullRequestByID(ctx, pullID) + pr, err := issues_model.GetPullRequestByID(ctx, pullID) if err != nil { log.Error("GetPullRequestByID[%d]: %v", pullID, err) return diff --git a/services/comments/comments.go b/services/comments/comments.go index b80fddf93f..c40631359b 100644 --- a/services/comments/comments.go +++ b/services/comments/comments.go @@ -5,9 +5,8 @@ package comments import ( - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/issues" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" @@ -15,9 +14,9 @@ import ( ) // CreateIssueComment creates a plain issue comment. -func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issue *models.Issue, content string, attachments []string) (*models.Comment, error) { - comment, err := models.CreateComment(&models.CreateCommentOptions{ - Type: models.CommentTypeComment, +func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content string, attachments []string) (*issues_model.Comment, error) { + comment, err := issues_model.CreateComment(&issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeComment, Doer: doer, Repo: repo, Issue: issue, @@ -28,7 +27,7 @@ func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issu return nil, err } - mentions, err := models.FindAndUpdateIssueMentions(db.DefaultContext, issue, doer, comment.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(db.DefaultContext, issue, doer, comment.Content) if err != nil { return nil, err } @@ -39,28 +38,28 @@ func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issu } // UpdateComment updates information of comment. -func UpdateComment(c *models.Comment, doer *user_model.User, oldContent string) error { +func UpdateComment(c *issues_model.Comment, doer *user_model.User, oldContent string) error { needsContentHistory := c.Content != oldContent && - (c.Type == models.CommentTypeComment || c.Type == models.CommentTypeReview || c.Type == models.CommentTypeCode) + (c.Type == issues_model.CommentTypeComment || c.Type == issues_model.CommentTypeReview || c.Type == issues_model.CommentTypeCode) if needsContentHistory { - hasContentHistory, err := issues.HasIssueContentHistory(db.DefaultContext, c.IssueID, c.ID) + hasContentHistory, err := issues_model.HasIssueContentHistory(db.DefaultContext, c.IssueID, c.ID) if err != nil { return err } if !hasContentHistory { - if err = issues.SaveIssueContentHistory(db.DefaultContext, c.PosterID, c.IssueID, c.ID, + if err = issues_model.SaveIssueContentHistory(db.DefaultContext, c.PosterID, c.IssueID, c.ID, c.CreatedUnix, oldContent, true); err != nil { return err } } } - if err := models.UpdateComment(c, doer); err != nil { + if err := issues_model.UpdateComment(c, doer); err != nil { return err } if needsContentHistory { - err := issues.SaveIssueContentHistory(db.DefaultContext, doer.ID, c.IssueID, c.ID, timeutil.TimeStampNow(), c.Content, false) + err := issues_model.SaveIssueContentHistory(db.DefaultContext, doer.ID, c.IssueID, c.ID, timeutil.TimeStampNow(), c.Content, false) if err != nil { return err } @@ -72,8 +71,17 @@ func UpdateComment(c *models.Comment, doer *user_model.User, oldContent string) } // DeleteComment deletes the comment -func DeleteComment(doer *user_model.User, comment *models.Comment) error { - if err := models.DeleteComment(comment); err != nil { +func DeleteComment(doer *user_model.User, comment *issues_model.Comment) error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + if err := issues_model.DeleteComment(ctx, comment); err != nil { + return err + } + if err := committer.Commit(); err != nil { return err } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 23ac1abe3c..c9327bbd9b 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -11,6 +11,7 @@ import ( "strings" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" project_model "code.gitea.io/gitea/models/project" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" @@ -636,18 +637,18 @@ func (f *SubmitReviewForm) Validate(req *http.Request, errs binding.Errors) bind } // ReviewType will return the corresponding ReviewType for type -func (f SubmitReviewForm) ReviewType() models.ReviewType { +func (f SubmitReviewForm) ReviewType() issues_model.ReviewType { switch f.Type { case "approve": - return models.ReviewTypeApprove + return issues_model.ReviewTypeApprove case "comment": - return models.ReviewTypeComment + return issues_model.ReviewTypeComment case "reject": - return models.ReviewTypeReject + return issues_model.ReviewTypeReject case "": - return models.ReviewTypeComment // default to comment when doing quick-submit (Ctrl+Enter) on the review form + return issues_model.ReviewTypeComment // default to comment when doing quick-submit (Ctrl+Enter) on the review form default: - return models.ReviewTypeUnknown + return issues_model.ReviewTypeUnknown } } @@ -655,7 +656,7 @@ func (f SubmitReviewForm) ReviewType() models.ReviewType { func (f SubmitReviewForm) HasEmptyContent() bool { reviewType := f.ReviewType() - return (reviewType == models.ReviewTypeComment || reviewType == models.ReviewTypeReject) && + return (reviewType == issues_model.ReviewTypeComment || reviewType == issues_model.ReviewTypeReject) && len(strings.TrimSpace(f.Content)) == 0 } diff --git a/services/forms/user_form_hidden_comments.go b/services/forms/user_form_hidden_comments.go index e0c26e8ddf..35c1a6dd2a 100644 --- a/services/forms/user_form_hidden_comments.go +++ b/services/forms/user_form_hidden_comments.go @@ -7,69 +7,69 @@ package forms import ( "math/big" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" ) -type hiddenCommentTypeGroupsType map[string][]models.CommentType +type hiddenCommentTypeGroupsType map[string][]issues_model.CommentType // hiddenCommentTypeGroups maps the group names to comment types, these group names comes from the Web UI (appearance.tmpl) var hiddenCommentTypeGroups = hiddenCommentTypeGroupsType{ "reference": { - /*3*/ models.CommentTypeIssueRef, - /*4*/ models.CommentTypeCommitRef, - /*5*/ models.CommentTypeCommentRef, - /*6*/ models.CommentTypePullRef, + /*3*/ issues_model.CommentTypeIssueRef, + /*4*/ issues_model.CommentTypeCommitRef, + /*5*/ issues_model.CommentTypeCommentRef, + /*6*/ issues_model.CommentTypePullRef, }, "label": { - /*7*/ models.CommentTypeLabel, + /*7*/ issues_model.CommentTypeLabel, }, "milestone": { - /*8*/ models.CommentTypeMilestone, + /*8*/ issues_model.CommentTypeMilestone, }, "assignee": { - /*9*/ models.CommentTypeAssignees, + /*9*/ issues_model.CommentTypeAssignees, }, "title": { - /*10*/ models.CommentTypeChangeTitle, + /*10*/ issues_model.CommentTypeChangeTitle, }, "branch": { - /*11*/ models.CommentTypeDeleteBranch, - /*25*/ models.CommentTypeChangeTargetBranch, + /*11*/ issues_model.CommentTypeDeleteBranch, + /*25*/ issues_model.CommentTypeChangeTargetBranch, }, "time_tracking": { - /*12*/ models.CommentTypeStartTracking, - /*13*/ models.CommentTypeStopTracking, - /*14*/ models.CommentTypeAddTimeManual, - /*15*/ models.CommentTypeCancelTracking, - /*26*/ models.CommentTypeDeleteTimeManual, + /*12*/ issues_model.CommentTypeStartTracking, + /*13*/ issues_model.CommentTypeStopTracking, + /*14*/ issues_model.CommentTypeAddTimeManual, + /*15*/ issues_model.CommentTypeCancelTracking, + /*26*/ issues_model.CommentTypeDeleteTimeManual, }, "deadline": { - /*16*/ models.CommentTypeAddedDeadline, - /*17*/ models.CommentTypeModifiedDeadline, - /*18*/ models.CommentTypeRemovedDeadline, + /*16*/ issues_model.CommentTypeAddedDeadline, + /*17*/ issues_model.CommentTypeModifiedDeadline, + /*18*/ issues_model.CommentTypeRemovedDeadline, }, "dependency": { - /*19*/ models.CommentTypeAddDependency, - /*20*/ models.CommentTypeRemoveDependency, + /*19*/ issues_model.CommentTypeAddDependency, + /*20*/ issues_model.CommentTypeRemoveDependency, }, "lock": { - /*23*/ models.CommentTypeLock, - /*24*/ models.CommentTypeUnlock, + /*23*/ issues_model.CommentTypeLock, + /*24*/ issues_model.CommentTypeUnlock, }, "review_request": { - /*27*/ models.CommentTypeReviewRequest, + /*27*/ issues_model.CommentTypeReviewRequest, }, "pull_request_push": { - /*29*/ models.CommentTypePullRequestPush, + /*29*/ issues_model.CommentTypePullRequestPush, }, "project": { - /*30*/ models.CommentTypeProject, - /*31*/ models.CommentTypeProjectBoard, + /*30*/ issues_model.CommentTypeProject, + /*31*/ issues_model.CommentTypeProjectBoard, }, "issue_ref": { - /*33*/ models.CommentTypeChangeIssueRef, + /*33*/ issues_model.CommentTypeChangeIssueRef, }, } diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index e56c2de8fa..97daadbc67 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -20,9 +20,9 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" pull_model "code.gitea.io/gitea/models/pull" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/analyze" @@ -82,7 +82,7 @@ type DiffLine struct { Match int Type DiffLineType Content string - Comments []*models.Comment + Comments []*issues_model.Comment SectionInfo *DiffLineSectionInfo } @@ -704,8 +704,8 @@ type Diff struct { } // LoadComments loads comments into each line -func (diff *Diff) LoadComments(ctx context.Context, issue *models.Issue, currentUser *user_model.User) error { - allComments, err := models.FetchCodeComments(ctx, issue, currentUser) +func (diff *Diff) LoadComments(ctx context.Context, issue *issues_model.Issue, currentUser *user_model.User) error { + allComments, err := issues_model.FetchCodeComments(ctx, issue, currentUser) if err != nil { return err } @@ -1520,7 +1520,7 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff // SyncAndGetUserSpecificDiff is like GetDiff, except that user specific data such as which files the given user has already viewed on the given PR will also be set // Additionally, the database asynchronously is updated if files have changed since the last review -func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *models.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) { +func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *issues_model.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) { diff, err := GetDiff(gitRepo, opts, files...) if err != nil { return nil, err @@ -1583,7 +1583,7 @@ outer: } // CommentAsDiff returns c.Patch as *Diff -func CommentAsDiff(c *models.Comment) (*Diff, error) { +func CommentAsDiff(c *issues_model.Comment) (*Diff, error) { diff, err := ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(c.Patch), "") if err != nil { @@ -1601,7 +1601,7 @@ func CommentAsDiff(c *models.Comment) (*Diff, error) { } // CommentMustAsDiff executes AsDiff and logs the error instead of returning -func CommentMustAsDiff(c *models.Comment) *Diff { +func CommentMustAsDiff(c *issues_model.Comment) *Diff { if c == nil { return nil } diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index 3457785e5d..caca0e91d8 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -12,8 +12,8 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -669,7 +669,7 @@ func setupDefaultDiff() *Diff { func TestDiff_LoadComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) diff := setupDefaultDiff() assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user)) @@ -678,15 +678,15 @@ func TestDiff_LoadComments(t *testing.T) { func TestDiffLine_CanComment(t *testing.T) { assert.False(t, (&DiffLine{Type: DiffLineSection}).CanComment()) - assert.False(t, (&DiffLine{Type: DiffLineAdd, Comments: []*models.Comment{{Content: "bla"}}}).CanComment()) + assert.False(t, (&DiffLine{Type: DiffLineAdd, Comments: []*issues_model.Comment{{Content: "bla"}}}).CanComment()) assert.True(t, (&DiffLine{Type: DiffLineAdd}).CanComment()) assert.True(t, (&DiffLine{Type: DiffLineDel}).CanComment()) assert.True(t, (&DiffLine{Type: DiffLinePlain}).CanComment()) } func TestDiffLine_GetCommentSide(t *testing.T) { - assert.Equal(t, "previous", (&DiffLine{Comments: []*models.Comment{{Line: -3}}}).GetCommentSide()) - assert.Equal(t, "proposed", (&DiffLine{Comments: []*models.Comment{{Line: 3}}}).GetCommentSide()) + assert.Equal(t, "previous", (&DiffLine{Comments: []*issues_model.Comment{{Line: -3}}}).GetCommentSide()) + assert.Equal(t, "proposed", (&DiffLine{Comments: []*issues_model.Comment{{Line: 3}}}).GetCommentSide()) } func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) { diff --git a/services/gitdiff/main_test.go b/services/gitdiff/main_test.go index d4d9364ebf..17d0da6276 100644 --- a/services/gitdiff/main_test.go +++ b/services/gitdiff/main_test.go @@ -8,6 +8,7 @@ import ( "path/filepath" "testing" + _ "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/unittest" ) diff --git a/services/issue/assignee.go b/services/issue/assignee.go index 8cad03351c..7c00f472dd 100644 --- a/services/issue/assignee.go +++ b/services/issue/assignee.go @@ -7,8 +7,8 @@ package issue import ( "context" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -19,7 +19,7 @@ import ( ) // DeleteNotPassedAssignee deletes all assignees who aren't passed via the "assignees" array -func DeleteNotPassedAssignee(issue *models.Issue, doer *user_model.User, assignees []*user_model.User) (err error) { +func DeleteNotPassedAssignee(issue *issues_model.Issue, doer *user_model.User, assignees []*user_model.User) (err error) { var found bool oriAssignes := make([]*user_model.User, len(issue.Assignees)) _ = copy(oriAssignes, issue.Assignees) @@ -45,8 +45,8 @@ func DeleteNotPassedAssignee(issue *models.Issue, doer *user_model.User, assigne } // ToggleAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it. -func ToggleAssignee(issue *models.Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *models.Comment, err error) { - removed, comment, err = models.ToggleIssueAssignee(issue, doer, assigneeID) +func ToggleAssignee(issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *issues_model.Comment, err error) { + removed, comment, err = issues_model.ToggleIssueAssignee(issue, doer, assigneeID) if err != nil { return } @@ -63,11 +63,11 @@ func ToggleAssignee(issue *models.Issue, doer *user_model.User, assigneeID int64 } // ReviewRequest add or remove a review request from a user for this PR, and make comment for it. -func ReviewRequest(issue *models.Issue, doer, reviewer *user_model.User, isAdd bool) (comment *models.Comment, err error) { +func ReviewRequest(issue *issues_model.Issue, doer, reviewer *user_model.User, isAdd bool) (comment *issues_model.Comment, err error) { if isAdd { - comment, err = models.AddReviewRequest(issue, reviewer, doer) + comment, err = issues_model.AddReviewRequest(issue, reviewer, doer) } else { - comment, err = models.RemoveReviewRequest(issue, reviewer, doer) + comment, err = issues_model.RemoveReviewRequest(issue, reviewer, doer) } if err != nil { @@ -82,16 +82,16 @@ func ReviewRequest(issue *models.Issue, doer, reviewer *user_model.User, isAdd b } // IsValidReviewRequest Check permission for ReviewRequest -func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, isAdd bool, issue *models.Issue, permDoer *access_model.Permission) error { +func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, isAdd bool, issue *issues_model.Issue, permDoer *access_model.Permission) error { if reviewer.IsOrganization() { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Organization can't be added as reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, } } if doer.IsOrganization() { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Organization can't be doer to add reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -111,8 +111,8 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, } } - lastreview, err := models.GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID) - if err != nil && !models.IsErrReviewNotExist(err) { + lastreview, err := issues_model.GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID) + if err != nil && !issues_model.IsErrReviewNotExist(err) { return err } @@ -120,25 +120,25 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, if isAdd { pemResult = permReviewer.CanAccessAny(perm.AccessModeRead, unit.TypePullRequests) if !pemResult { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Reviewer can't read", UserID: doer.ID, RepoID: issue.Repo.ID, } } - if doer.ID == issue.PosterID && issue.OriginalAuthorID == 0 && lastreview != nil && lastreview.Type != models.ReviewTypeRequest { + if doer.ID == issue.PosterID && issue.OriginalAuthorID == 0 && lastreview != nil && lastreview.Type != issues_model.ReviewTypeRequest { return nil } pemResult = permDoer.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests) if !pemResult { - pemResult, err = models.IsOfficialReviewer(ctx, issue, doer) + pemResult, err = issues_model.IsOfficialReviewer(ctx, issue, doer) if err != nil { return err } if !pemResult { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Doer can't choose reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -147,20 +147,20 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, } if reviewer.ID == issue.PosterID && issue.OriginalAuthorID == 0 { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "poster of pr can't be reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, } } } else { - if lastreview != nil && lastreview.Type == models.ReviewTypeRequest && lastreview.ReviewerID == doer.ID { + if lastreview != nil && lastreview.Type == issues_model.ReviewTypeRequest && lastreview.ReviewerID == doer.ID { return nil } pemResult = permDoer.IsAdmin() if !pemResult { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Doer is not admin", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -172,9 +172,9 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, } // IsValidTeamReviewRequest Check permission for ReviewRequest Team -func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, doer *user_model.User, isAdd bool, issue *models.Issue) error { +func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, doer *user_model.User, isAdd bool, issue *issues_model.Issue) error { if doer.IsOrganization() { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Organization can't be doer to add reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -192,7 +192,7 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, hasTeam := organization.HasTeamRepo(ctx, reviewer.OrgID, reviewer.ID, issue.RepoID) if !hasTeam { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Reviewing team can't read repo", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -202,13 +202,13 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, doerCanWrite := permission.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests) if !doerCanWrite { - official, err := models.IsOfficialReviewer(ctx, issue, doer) + official, err := issues_model.IsOfficialReviewer(ctx, issue, doer) if err != nil { log.Error("Unable to Check if IsOfficialReviewer for %-v in %-v#%d", doer, issue.Repo, issue.Index) return err } if !official { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Doer can't choose reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -216,7 +216,7 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, } } } else if !permission.IsAdmin() { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Only admin users can remove team requests. Doer is not admin", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -227,11 +227,11 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, } // TeamReviewRequest add or remove a review request from a team for this PR, and make comment for it. -func TeamReviewRequest(issue *models.Issue, doer *user_model.User, reviewer *organization.Team, isAdd bool) (comment *models.Comment, err error) { +func TeamReviewRequest(issue *issues_model.Issue, doer *user_model.User, reviewer *organization.Team, isAdd bool) (comment *issues_model.Comment, err error) { if isAdd { - comment, err = models.AddTeamReviewRequest(issue, reviewer, doer) + comment, err = issues_model.AddTeamReviewRequest(issue, reviewer, doer) } else { - comment, err = models.RemoveTeamReviewRequest(issue, reviewer, doer) + comment, err = issues_model.RemoveTeamReviewRequest(issue, reviewer, doer) } if err != nil { diff --git a/services/issue/assignee_test.go b/services/issue/assignee_test.go index ff4d7029eb..5c8b822499 100644 --- a/services/issue/assignee_test.go +++ b/services/issue/assignee_test.go @@ -7,8 +7,8 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -19,7 +19,7 @@ func TestDeleteNotPassedAssignee(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Fake issue with assignees - issue, err := models.GetIssueWithAttrsByID(1) + issue, err := issues_model.GetIssueWithAttrsByID(1) assert.NoError(t, err) assert.EqualValues(t, 1, len(issue.Assignees)) @@ -27,7 +27,7 @@ func TestDeleteNotPassedAssignee(t *testing.T) { assert.NoError(t, err) // Check if he got removed - isAssigned, err := models.IsUserAssignedToIssue(db.DefaultContext, issue, user1) + isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user1) assert.NoError(t, err) assert.True(t, isAssigned) diff --git a/services/issue/commit.go b/services/issue/commit.go index 5140eebed1..1053a81162 100644 --- a/services/issue/commit.go +++ b/services/issue/commit.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -76,22 +77,22 @@ func timeLogToAmount(str string) int64 { return a } -func issueAddTime(issue *models.Issue, doer *user_model.User, time time.Time, timeLog string) error { +func issueAddTime(issue *issues_model.Issue, doer *user_model.User, time time.Time, timeLog string) error { amount := timeLogToAmount(timeLog) if amount == 0 { return nil } - _, err := models.AddTime(doer, issue, amount, time) + _, err := issues_model.AddTime(doer, issue, amount, time) return err } // getIssueFromRef returns the issue referenced by a ref. Returns a nil *Issue // if the provided ref references a non-existent issue. -func getIssueFromRef(repo *repo_model.Repository, index int64) (*models.Issue, error) { - issue, err := models.GetIssueByIndex(repo.ID, index) +func getIssueFromRef(repo *repo_model.Repository, index int64) (*issues_model.Issue, error) { + issue, err := issues_model.GetIssueByIndex(repo.ID, index) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { return nil, nil } return nil, err @@ -112,7 +113,7 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm refMarked := make(map[markKey]bool) var refRepo *repo_model.Repository - var refIssue *models.Issue + var refIssue *issues_model.Issue var err error for _, ref := range references.FindAllIssueReferences(c.Message) { @@ -153,7 +154,7 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm } message := fmt.Sprintf(`<a href="%s/commit/%s">%s</a>`, html.EscapeString(repo.Link()), html.EscapeString(url.PathEscape(c.Sha1)), html.EscapeString(strings.SplitN(c.Message, "\n", 2)[0])) - if err = models.CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil { + if err = issues_model.CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil { return err } diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go index 37283a7890..ce3f913627 100644 --- a/services/issue/commit_test.go +++ b/services/issue/commit_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -50,16 +51,16 @@ func TestUpdateIssuesCommit(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo.Owner = user - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 1, } - issueBean := &models.Issue{RepoID: repo.ID, Index: 4} + issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4} unittest.AssertNotExistsBean(t, commentBean) - unittest.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") + unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") @@ -77,16 +78,16 @@ func TestUpdateIssuesCommit(t *testing.T) { }, } repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) - commentBean = &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean = &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 6, } - issueBean = &models.Issue{RepoID: repo.ID, Index: 1} + issueBean = &issues_model.Issue{RepoID: repo.ID, Index: 1} unittest.AssertNotExistsBean(t, commentBean) - unittest.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") + unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch")) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") @@ -103,16 +104,16 @@ func TestUpdateIssuesCommit(t *testing.T) { }, } repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) - commentBean = &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean = &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef3", PosterID: user.ID, IssueID: 6, } - issueBean = &models.Issue{RepoID: repo.ID, Index: 1} + issueBean = &issues_model.Issue{RepoID: repo.ID, Index: 1} unittest.AssertNotExistsBean(t, commentBean) - unittest.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") + unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") @@ -136,9 +137,9 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo.Owner = user - issueBean := &models.Issue{RepoID: repo.ID, Index: 4} + issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4} - unittest.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") + unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &models.Action{}) @@ -161,14 +162,14 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) { } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 7, } - issueBean := &models.Issue{RepoID: repo.ID, Index: 2, ID: 7} + issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 2, ID: 7} unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") @@ -196,14 +197,14 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 1, } - issueBean := &models.Issue{RepoID: 1, Index: 1, ID: 1} + issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1} unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") @@ -231,14 +232,14 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) { } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 1, } - issueBean := &models.Issue{RepoID: 1, Index: 1, ID: 1} + issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1} unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") @@ -274,20 +275,20 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6}).(*repo_model.Repository) - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef3", PosterID: user.ID, IssueID: 6, } - commentBean2 := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean2 := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef4", PosterID: user.ID, IssueID: 6, } - issueBean := &models.Issue{RepoID: 3, Index: 1, ID: 6} + issueBean := &issues_model.Issue{RepoID: 3, Index: 1, ID: 6} unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, commentBean2) diff --git a/services/issue/content.go b/services/issue/content.go index a60878479b..6f493892f4 100644 --- a/services/issue/content.go +++ b/services/issue/content.go @@ -5,16 +5,16 @@ package issue import ( - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" ) // ChangeContent changes issue content, as the given user. -func ChangeContent(issue *models.Issue, doer *user_model.User, content string) (err error) { +func ChangeContent(issue *issues_model.Issue, doer *user_model.User, content string) (err error) { oldContent := issue.Content - if err := models.ChangeIssueContent(issue, doer, content); err != nil { + if err := issues_model.ChangeIssueContent(issue, doer, content); err != nil { return err } diff --git a/services/issue/issue.go b/services/issue/issue.go index 78a486727a..ded281e209 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -8,18 +8,22 @@ import ( "fmt" "code.gitea.io/gitea/models" + admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" + project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/notification" + "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util" ) // NewIssue creates new issue with labels for repository. -func NewIssue(repo *repo_model.Repository, issue *models.Issue, labelIDs []int64, uuids []string, assigneeIDs []int64) error { - if err := models.NewIssue(repo, issue, labelIDs, uuids); err != nil { +func NewIssue(repo *repo_model.Repository, issue *issues_model.Issue, labelIDs []int64, uuids []string, assigneeIDs []int64) error { + if err := issues_model.NewIssue(repo, issue, labelIDs, uuids); err != nil { return err } @@ -29,7 +33,7 @@ func NewIssue(repo *repo_model.Repository, issue *models.Issue, labelIDs []int64 } } - mentions, err := models.FindAndUpdateIssueMentions(db.DefaultContext, issue, issue.Poster, issue.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(db.DefaultContext, issue, issue.Poster, issue.Content) if err != nil { return err } @@ -46,11 +50,11 @@ func NewIssue(repo *repo_model.Repository, issue *models.Issue, labelIDs []int64 } // ChangeTitle changes the title of this issue, as the given user. -func ChangeTitle(issue *models.Issue, doer *user_model.User, title string) (err error) { +func ChangeTitle(issue *issues_model.Issue, doer *user_model.User, title string) (err error) { oldTitle := issue.Title issue.Title = title - if err = models.ChangeIssueTitle(issue, doer, oldTitle); err != nil { + if err = issues_model.ChangeIssueTitle(issue, doer, oldTitle); err != nil { return } @@ -60,11 +64,11 @@ func ChangeTitle(issue *models.Issue, doer *user_model.User, title string) (err } // ChangeIssueRef changes the branch of this issue, as the given user. -func ChangeIssueRef(issue *models.Issue, doer *user_model.User, ref string) error { +func ChangeIssueRef(issue *issues_model.Issue, doer *user_model.User, ref string) error { oldRef := issue.Ref issue.Ref = ref - if err := models.ChangeIssueRef(issue, doer, oldRef); err != nil { + if err := issues_model.ChangeIssueRef(issue, doer, oldRef); err != nil { return err } @@ -79,7 +83,7 @@ func ChangeIssueRef(issue *models.Issue, doer *user_model.User, ref string) erro // "assignees" (array): Logins for Users to assign to this issue. // Pass one or more user logins to replace the set of assignees on this Issue. // Send an empty array ([]) to clear all assignees from the Issue. -func UpdateAssignees(issue *models.Issue, oneAssignee string, multipleAssignees []string, doer *user_model.User) (err error) { +func UpdateAssignees(issue *issues_model.Issue, oneAssignee string, multipleAssignees []string, doer *user_model.User) (err error) { var allNewAssignees []*user_model.User // Keep the old assignee thingy for compatibility reasons @@ -129,9 +133,9 @@ func UpdateAssignees(issue *models.Issue, oneAssignee string, multipleAssignees } // DeleteIssue deletes an issue -func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *models.Issue) error { +func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue) error { // load issue before deleting it - if err := issue.LoadAttributes(); err != nil { + if err := issue.LoadAttributes(db.DefaultContext); err != nil { return err } if err := issue.LoadPullRequest(); err != nil { @@ -139,7 +143,7 @@ func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *models.I } // delete entries in database - if err := models.DeleteIssue(issue); err != nil { + if err := deleteIssue(issue); err != nil { return err } @@ -157,14 +161,14 @@ func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *models.I // AddAssigneeIfNotAssigned adds an assignee only if he isn't already assigned to the issue. // Also checks for access of assigned user -func AddAssigneeIfNotAssigned(issue *models.Issue, doer *user_model.User, assigneeID int64) (err error) { +func AddAssigneeIfNotAssigned(issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (err error) { assignee, err := user_model.GetUserByID(assigneeID) if err != nil { return err } // Check if the user is already assigned - isAssigned, err := models.IsUserAssignedToIssue(db.DefaultContext, issue, assignee) + isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, assignee) if err != nil { return err } @@ -178,7 +182,7 @@ func AddAssigneeIfNotAssigned(issue *models.Issue, doer *user_model.User, assign return err } if !valid { - return models.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name} + return repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name} } _, _, err = ToggleAssignee(issue, doer, assigneeID) @@ -191,7 +195,7 @@ func AddAssigneeIfNotAssigned(issue *models.Issue, doer *user_model.User, assign // GetRefEndNamesAndURLs retrieves the ref end names (e.g. refs/heads/branch-name -> branch-name) // and their respective URLs. -func GetRefEndNamesAndURLs(issues []*models.Issue, repoLink string) (map[int64]string, map[int64]string) { +func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[int64]string, map[int64]string) { issueRefEndNames := make(map[int64]string, len(issues)) issueRefURLs := make(map[int64]string, len(issues)) for _, issue := range issues { @@ -202,3 +206,77 @@ func GetRefEndNamesAndURLs(issues []*models.Issue, repoLink string) (map[int64]s } return issueRefEndNames, issueRefURLs } + +// deleteIssue deletes the issue +func deleteIssue(issue *issues_model.Issue) error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + e := db.GetEngine(ctx) + if _, err := e.ID(issue.ID).NoAutoCondition().Delete(issue); err != nil { + return err + } + + if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, issue.IsClosed); err != nil { + return err + } + + if err := models.DeleteIssueActions(ctx, issue.RepoID, issue.ID); err != nil { + return err + } + + // find attachments related to this issue and remove them + if err := issue.LoadAttributes(ctx); err != nil { + return err + } + + for i := range issue.Attachments { + admin_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", issue.Attachments[i].RelativePath()) + } + + // delete all database data still assigned to this issue + if err := issues_model.DeleteInIssue(ctx, issue.ID, + &issues_model.ContentHistory{}, + &issues_model.Comment{}, + &issues_model.IssueLabel{}, + &issues_model.IssueDependency{}, + &issues_model.IssueAssignees{}, + &issues_model.IssueUser{}, + &models.Notification{}, + &issues_model.Reaction{}, + &issues_model.IssueWatch{}, + &issues_model.Stopwatch{}, + &issues_model.TrackedTime{}, + &project_model.ProjectIssue{}, + &repo_model.Attachment{}, + &issues_model.PullRequest{}, + ); err != nil { + return err + } + + // References to this issue in other issues + if _, err := db.DeleteByBean(ctx, &issues_model.Comment{ + RefIssueID: issue.ID, + }); err != nil { + return err + } + + // Delete dependencies for issues in other repositories + if _, err := db.DeleteByBean(ctx, &issues_model.IssueDependency{ + DependencyID: issue.ID, + }); err != nil { + return err + } + + // delete from dependent issues + if _, err := db.DeleteByBean(ctx, &issues_model.Comment{ + DependentIssueID: issue.ID, + }); err != nil { + return err + } + + return committer.Commit() +} diff --git a/services/issue/issue_test.go b/services/issue/issue_test.go index caae773616..20f3a3296c 100644 --- a/services/issue/issue_test.go +++ b/services/issue/issue_test.go @@ -7,13 +7,17 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" "github.com/stretchr/testify/assert" ) func TestGetRefEndNamesAndURLs(t *testing.T) { - issues := []*models.Issue{ + issues := []*issues_model.Issue{ {ID: 1, Ref: "refs/heads/branch1"}, {ID: 2, Ref: "refs/tags/tag1"}, {ID: 3, Ref: "c0ffee"}, @@ -28,3 +32,56 @@ func TestGetRefEndNamesAndURLs(t *testing.T) { 3: repoLink + "/src/commit/c0ffee", }, urls) } + +func TestIssue_DeleteIssue(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + issueIDs, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) + assert.NoError(t, err) + assert.EqualValues(t, 5, len(issueIDs)) + + issue := &issues_model.Issue{ + RepoID: 1, + ID: issueIDs[2], + } + + err = deleteIssue(issue) + assert.NoError(t, err) + issueIDs, err = issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) + assert.NoError(t, err) + assert.EqualValues(t, 4, len(issueIDs)) + + // check attachment removal + attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 4) + assert.NoError(t, err) + issue, err = issues_model.GetIssueByID(db.DefaultContext, 4) + assert.NoError(t, err) + err = deleteIssue(issue) + assert.NoError(t, err) + assert.EqualValues(t, 2, len(attachments)) + for i := range attachments { + attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attachments[i].UUID) + assert.Error(t, err) + assert.True(t, repo_model.IsErrAttachmentNotExist(err)) + assert.Nil(t, attachment) + } + + // check issue dependencies + user, err := user_model.GetUserByID(1) + assert.NoError(t, err) + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + assert.NoError(t, err) + issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) + assert.NoError(t, err) + err = issues_model.CreateIssueDependency(user, issue1, issue2) + assert.NoError(t, err) + left, err := issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) + assert.NoError(t, err) + assert.False(t, left) + + err = deleteIssue(issue2) + assert.NoError(t, err) + left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) + assert.NoError(t, err) + assert.True(t, left) +} diff --git a/services/issue/label.go b/services/issue/label.go index 289466f604..bc5f9b910e 100644 --- a/services/issue/label.go +++ b/services/issue/label.go @@ -5,16 +5,16 @@ package issue import ( - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" ) // ClearLabels clears all of an issue's labels -func ClearLabels(issue *models.Issue, doer *user_model.User) (err error) { - if err = models.ClearIssueLabels(issue, doer); err != nil { +func ClearLabels(issue *issues_model.Issue, doer *user_model.User) (err error) { + if err = issues_model.ClearIssueLabels(issue, doer); err != nil { return } @@ -24,18 +24,18 @@ func ClearLabels(issue *models.Issue, doer *user_model.User) (err error) { } // AddLabel adds a new label to the issue. -func AddLabel(issue *models.Issue, doer *user_model.User, label *models.Label) error { - if err := models.NewIssueLabel(issue, label, doer); err != nil { +func AddLabel(issue *issues_model.Issue, doer *user_model.User, label *issues_model.Label) error { + if err := issues_model.NewIssueLabel(issue, label, doer); err != nil { return err } - notification.NotifyIssueChangeLabels(doer, issue, []*models.Label{label}, nil) + notification.NotifyIssueChangeLabels(doer, issue, []*issues_model.Label{label}, nil) return nil } // AddLabels adds a list of new labels to the issue. -func AddLabels(issue *models.Issue, doer *user_model.User, labels []*models.Label) error { - if err := models.NewIssueLabels(issue, labels, doer); err != nil { +func AddLabels(issue *issues_model.Issue, doer *user_model.User, labels []*issues_model.Label) error { + if err := issues_model.NewIssueLabels(issue, labels, doer); err != nil { return err } @@ -44,7 +44,7 @@ func AddLabels(issue *models.Issue, doer *user_model.User, labels []*models.Labe } // RemoveLabel removes a label from issue by given ID. -func RemoveLabel(issue *models.Issue, doer *user_model.User, label *models.Label) error { +func RemoveLabel(issue *issues_model.Issue, doer *user_model.User, label *issues_model.Label) error { ctx, committer, err := db.TxContext() if err != nil { return err @@ -61,12 +61,12 @@ func RemoveLabel(issue *models.Issue, doer *user_model.User, label *models.Label } if !perm.CanWriteIssuesOrPulls(issue.IsPull) { if label.OrgID > 0 { - return models.ErrOrgLabelNotExist{} + return issues_model.ErrOrgLabelNotExist{} } - return models.ErrRepoLabelNotExist{} + return issues_model.ErrRepoLabelNotExist{} } - if err := models.DeleteIssueLabel(ctx, issue, label, doer); err != nil { + if err := issues_model.DeleteIssueLabel(ctx, issue, label, doer); err != nil { return err } @@ -74,18 +74,18 @@ func RemoveLabel(issue *models.Issue, doer *user_model.User, label *models.Label return err } - notification.NotifyIssueChangeLabels(doer, issue, nil, []*models.Label{label}) + notification.NotifyIssueChangeLabels(doer, issue, nil, []*issues_model.Label{label}) return nil } // ReplaceLabels removes all current labels and add new labels to the issue. -func ReplaceLabels(issue *models.Issue, doer *user_model.User, labels []*models.Label) error { - old, err := models.GetLabelsByIssueID(db.DefaultContext, issue.ID) +func ReplaceLabels(issue *issues_model.Issue, doer *user_model.User, labels []*issues_model.Label) error { + old, err := issues_model.GetLabelsByIssueID(db.DefaultContext, issue.ID) if err != nil { return err } - if err := models.ReplaceIssueLabels(issue, labels, doer); err != nil { + if err := issues_model.ReplaceIssueLabels(issue, labels, doer); err != nil { return err } diff --git a/services/issue/label_test.go b/services/issue/label_test.go index 73e30e894f..120c9ea4f1 100644 --- a/services/issue/label_test.go +++ b/services/issue/label_test.go @@ -7,7 +7,7 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -27,15 +27,15 @@ func TestIssue_AddLabels(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: test.issueID}).(*models.Issue) - labels := make([]*models.Label, len(test.labelIDs)) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) + labels := make([]*issues_model.Label, len(test.labelIDs)) for i, labelID := range test.labelIDs { - labels[i] = unittest.AssertExistsAndLoadBean(t, &models.Label{ID: labelID}).(*models.Label) + labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) } doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) assert.NoError(t, AddLabels(issue, doer, labels)) for _, labelID := range test.labelIDs { - unittest.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: test.issueID, LabelID: labelID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: labelID}) } } } @@ -53,10 +53,10 @@ func TestIssue_AddLabel(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: test.issueID}).(*models.Issue) - label := unittest.AssertExistsAndLoadBean(t, &models.Label{ID: test.labelID}).(*models.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: test.labelID}).(*issues_model.Label) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) assert.NoError(t, AddLabel(issue, doer, label)) - unittest.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: test.issueID, LabelID: test.labelID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: test.labelID}) } } diff --git a/services/issue/milestone.go b/services/issue/milestone.go index 287f8ae285..af337c3f14 100644 --- a/services/issue/milestone.go +++ b/services/issue/milestone.go @@ -8,15 +8,14 @@ import ( "context" "fmt" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" ) -func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *models.Issue, oldMilestoneID int64) error { - if err := models.UpdateIssueCols(ctx, issue, "milestone_id"); err != nil { +func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) error { + if err := issues_model.UpdateIssueCols(ctx, issue, "milestone_id"); err != nil { return err } @@ -37,15 +36,15 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *mo return err } - opts := &models.CreateCommentOptions{ - Type: models.CommentTypeMilestone, + opts := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeMilestone, Doer: doer, Repo: issue.Repo, Issue: issue, OldMilestoneID: oldMilestoneID, MilestoneID: issue.MilestoneID, } - if _, err := models.CreateCommentCtx(ctx, opts); err != nil { + if _, err := issues_model.CreateCommentCtx(ctx, opts); err != nil { return err } } @@ -54,7 +53,7 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *mo } // ChangeMilestoneAssign changes assignment of milestone for issue. -func ChangeMilestoneAssign(issue *models.Issue, doer *user_model.User, oldMilestoneID int64) (err error) { +func ChangeMilestoneAssign(issue *issues_model.Issue, doer *user_model.User, oldMilestoneID int64) (err error) { ctx, committer, err := db.TxContext() if err != nil { return err diff --git a/services/issue/milestone_test.go b/services/issue/milestone_test.go index 80e37a8acd..d08b1ae8c7 100644 --- a/services/issue/milestone_test.go +++ b/services/issue/milestone_test.go @@ -7,7 +7,6 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -17,7 +16,7 @@ import ( func TestChangeMilestoneAssign(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{RepoID: 1}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: 1}).(*issues_model.Issue) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) assert.NotNil(t, issue) assert.NotNil(t, doer) @@ -25,11 +24,11 @@ func TestChangeMilestoneAssign(t *testing.T) { oldMilestoneID := issue.MilestoneID issue.MilestoneID = 2 assert.NoError(t, ChangeMilestoneAssign(issue, doer, oldMilestoneID)) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issue.ID, - Type: models.CommentTypeMilestone, + Type: issues_model.CommentTypeMilestone, MilestoneID: issue.MilestoneID, OldMilestoneID: oldMilestoneID, }) - unittest.CheckConsistencyFor(t, &issues_model.Milestone{}, &models.Issue{}) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}, &issues_model.Issue{}) } diff --git a/services/issue/status.go b/services/issue/status.go index d2b4fc303e..0da5c88762 100644 --- a/services/issue/status.go +++ b/services/issue/status.go @@ -7,25 +7,25 @@ package issue import ( "context" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" ) // ChangeStatus changes issue status to open or closed. -func ChangeStatus(issue *models.Issue, doer *user_model.User, closed bool) error { +func ChangeStatus(issue *issues_model.Issue, doer *user_model.User, closed bool) error { return changeStatusCtx(db.DefaultContext, issue, doer, closed) } // changeStatusCtx changes issue status to open or closed. // TODO: if context is not db.DefaultContext we get a deadlock!!! -func changeStatusCtx(ctx context.Context, issue *models.Issue, doer *user_model.User, closed bool) error { - comment, err := models.ChangeIssueStatus(ctx, issue, doer, closed) +func changeStatusCtx(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, closed bool) error { + comment, err := issues_model.ChangeIssueStatus(ctx, issue, doer, closed) if err != nil { - if models.IsErrDependenciesLeft(err) && closed { - if err := models.FinishIssueStopwatchIfPossible(ctx, doer, issue); err != nil { + if issues_model.IsErrDependenciesLeft(err) && closed { + if err := issues_model.FinishIssueStopwatchIfPossible(ctx, doer, issue); err != nil { log.Error("Unable to stop stopwatch for issue[%d]#%d: %v", issue.ID, issue.Index, err) } } @@ -33,7 +33,7 @@ func changeStatusCtx(ctx context.Context, issue *models.Issue, doer *user_model. } if closed { - if err := models.FinishIssueStopwatchIfPossible(ctx, doer, issue); err != nil { + if err := issues_model.FinishIssueStopwatchIfPossible(ctx, doer, issue); err != nil { return err } } diff --git a/services/mailer/mail.go b/services/mailer/mail.go index bdd7e25cab..81cfb2e31a 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -220,10 +221,10 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient prefix string // Fall back subject for bad templates, make sure subject is never empty fallback string - reviewComments []*models.Comment + reviewComments []*issues_model.Comment ) - commentType := models.CommentTypeComment + commentType := issues_model.CommentTypeComment if ctx.Comment != nil { commentType = ctx.Comment.Type link = ctx.Issue.HTMLURL() + "#" + ctx.Comment.HashTag() @@ -231,7 +232,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient link = ctx.Issue.HTMLURL() } - reviewType := models.ReviewTypeComment + reviewType := issues_model.ReviewTypeComment if ctx.Comment != nil && ctx.Comment.Review != nil { reviewType = ctx.Comment.Review.Type } @@ -254,7 +255,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient fallback = prefix + fallbackMailSubject(ctx.Issue) if ctx.Comment != nil && ctx.Comment.Review != nil { - reviewComments = make([]*models.Comment, 0, 10) + reviewComments = make([]*issues_model.Comment, 0, 10) for _, lines := range ctx.Comment.Review.CodeComments { for _, comments := range lines { reviewComments = append(reviewComments, comments...) @@ -328,7 +329,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient return msgs, nil } -func createReference(issue *models.Issue, comment *models.Comment, actionType models.ActionType) string { +func createReference(issue *issues_model.Issue, comment *issues_model.Comment, actionType models.ActionType) string { var path string if issue.IsPull { path = "pulls" @@ -400,7 +401,7 @@ func sanitizeSubject(subject string) string { } // SendIssueAssignedMail composes and sends issue assigned email -func SendIssueAssignedMail(issue *models.Issue, doer *user_model.User, content string, comment *models.Comment, recipients []*user_model.User) error { +func SendIssueAssignedMail(issue *issues_model.Issue, doer *user_model.User, content string, comment *issues_model.Comment, recipients []*user_model.User) error { if setting.MailService == nil { // No mail service configured return nil @@ -439,8 +440,8 @@ func SendIssueAssignedMail(issue *models.Issue, doer *user_model.User, content s // actionToTemplate returns the type and name of the action facing the user // (slightly different from models.ActionType) and the name of the template to use (based on availability) -func actionToTemplate(issue *models.Issue, actionType models.ActionType, - commentType models.CommentType, reviewType models.ReviewType, +func actionToTemplate(issue *issues_model.Issue, actionType models.ActionType, + commentType issues_model.CommentType, reviewType issues_model.ReviewType, ) (typeName, name, template string) { if issue.IsPull { typeName = "pull" @@ -464,20 +465,20 @@ func actionToTemplate(issue *models.Issue, actionType models.ActionType, name = "ready_for_review" default: switch commentType { - case models.CommentTypeReview: + case issues_model.CommentTypeReview: switch reviewType { - case models.ReviewTypeApprove: + case issues_model.ReviewTypeApprove: name = "approve" - case models.ReviewTypeReject: + case issues_model.ReviewTypeReject: name = "reject" default: name = "review" } - case models.CommentTypeCode: + case issues_model.CommentTypeCode: name = "code" - case models.CommentTypeAssignees: + case issues_model.CommentTypeAssignees: name = "assigned" - case models.CommentTypePullRequestPush: + case issues_model.CommentTypePullRequestPush: name = "push" default: name = "default" diff --git a/services/mailer/mail_comment.go b/services/mailer/mail_comment.go index baecd2a101..95d11ae8a1 100644 --- a/services/mailer/mail_comment.go +++ b/services/mailer/mail_comment.go @@ -8,20 +8,21 @@ import ( "context" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) // MailParticipantsComment sends new comment emails to repository watchers and mentioned people. -func MailParticipantsComment(ctx context.Context, c *models.Comment, opType models.ActionType, issue *models.Issue, mentions []*user_model.User) error { +func MailParticipantsComment(ctx context.Context, c *issues_model.Comment, opType models.ActionType, issue *issues_model.Issue, mentions []*user_model.User) error { if setting.MailService == nil { // No mail service configured return nil } content := c.Content - if c.Type == models.CommentTypePullRequestPush { + if c.Type == issues_model.CommentTypePullRequestPush { content = "" } if err := mailIssueCommentToParticipants( @@ -39,7 +40,7 @@ func MailParticipantsComment(ctx context.Context, c *models.Comment, opType mode } // MailMentionsComment sends email to users mentioned in a code comment -func MailMentionsComment(ctx context.Context, pr *models.PullRequest, c *models.Comment, mentions []*user_model.User) (err error) { +func MailMentionsComment(ctx context.Context, pr *issues_model.PullRequest, c *issues_model.Comment, mentions []*user_model.User) (err error) { if setting.MailService == nil { // No mail service configured return nil diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go index d479dd0d44..5c330f6e00 100644 --- a/services/mailer/mail_issue.go +++ b/services/mailer/mail_issue.go @@ -9,6 +9,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -16,17 +17,17 @@ import ( "code.gitea.io/gitea/modules/setting" ) -func fallbackMailSubject(issue *models.Issue) string { +func fallbackMailSubject(issue *issues_model.Issue) string { return fmt.Sprintf("[%s] %s (#%d)", issue.Repo.FullName(), issue.Title, issue.Index) } type mailCommentContext struct { context.Context - Issue *models.Issue + Issue *issues_model.Issue Doer *user_model.User ActionType models.ActionType Content string - Comment *models.Comment + Comment *issues_model.Comment } const ( @@ -57,21 +58,21 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo unfiltered[0] = ctx.Issue.PosterID // =========== Assignees =========== - ids, err := models.GetAssigneeIDsByIssue(ctx.Issue.ID) + ids, err := issues_model.GetAssigneeIDsByIssue(ctx.Issue.ID) if err != nil { return fmt.Errorf("GetAssigneeIDsByIssue(%d): %v", ctx.Issue.ID, err) } unfiltered = append(unfiltered, ids...) // =========== Participants (i.e. commenters, reviewers) =========== - ids, err = models.GetParticipantsIDsByIssueID(ctx.Issue.ID) + ids, err = issues_model.GetParticipantsIDsByIssueID(ctx.Issue.ID) if err != nil { return fmt.Errorf("GetParticipantsIDsByIssueID(%d): %v", ctx.Issue.ID, err) } unfiltered = append(unfiltered, ids...) // =========== Issue watchers =========== - ids, err = models.GetIssueWatchersIDs(ctx, ctx.Issue.ID, true) + ids, err = issues_model.GetIssueWatchersIDs(ctx, ctx.Issue.ID, true) if err != nil { return fmt.Errorf("GetIssueWatchersIDs(%d): %v", ctx.Issue.ID, err) } @@ -98,7 +99,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo } // Avoid mailing explicit unwatched - ids, err = models.GetIssueWatchersIDs(ctx, ctx.Issue.ID, false) + ids, err = issues_model.GetIssueWatchersIDs(ctx, ctx.Issue.ID, false) if err != nil { return fmt.Errorf("GetIssueWatchersIDs(%d): %v", ctx.Issue.ID, err) } @@ -171,7 +172,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi // MailParticipants sends new issue thread created emails to repository watchers // and mentioned people. -func MailParticipants(issue *models.Issue, doer *user_model.User, opType models.ActionType, mentions []*user_model.User) error { +func MailParticipants(issue *issues_model.Issue, doer *user_model.User, opType models.ActionType, mentions []*user_model.User) error { if setting.MailService == nil { // No mail service configured return nil diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go index baf426146a..83955a5896 100644 --- a/services/mailer/mail_test.go +++ b/services/mailer/mail_test.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -46,7 +47,7 @@ const bodyTpl = ` </html> ` -func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Repository, issue *models.Issue, comment *models.Comment) { +func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, comment *issues_model.Comment) { assert.NoError(t, unittest.PrepareTestDatabase()) mailService := setting.Mailer{ From: "test@gitea.com", @@ -57,9 +58,9 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer}).(*repo_model.Repository) - issue = unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue) + issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1, Repo: repo, Poster: doer}).(*issues_model.Issue) assert.NoError(t, issue.LoadRepo(db.DefaultContext)) - comment = unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment) + comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2, Issue: issue}).(*issues_model.Comment) return } @@ -162,8 +163,8 @@ func TestTemplateSelection(t *testing.T) { }, recipients, false, "TestTemplateSelection") expect(t, msg, "issue/default/subject", "issue/default/body") - pull := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2, Repo: repo, Poster: doer}).(*models.Issue) - comment = unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 4, Issue: pull}).(*models.Comment) + pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer}).(*issues_model.Issue) + comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull}).(*issues_model.Comment) msg = testComposeIssueCommentMessage(t, &mailCommentContext{ Context: context.TODO(), // TODO: use a correct context Issue: pull, Doer: doer, ActionType: models.ActionCommentPull, @@ -183,7 +184,7 @@ func TestTemplateServices(t *testing.T) { doer, _, issue, comment := prepareMailerTest(t) assert.NoError(t, issue.LoadRepo(db.DefaultContext)) - expect := func(t *testing.T, issue *models.Issue, comment *models.Comment, doer *user_model.User, + expect := func(t *testing.T, issue *issues_model.Issue, comment *issues_model.Comment, doer *user_model.User, actionType models.ActionType, fromMention bool, tplSubject, tplBody, expSubject, expBody string, ) { stpl := texttmpl.Must(texttmpl.New("issue/default").Parse(tplSubject)) @@ -268,8 +269,8 @@ func Test_createReference(t *testing.T) { pullIssue.IsPull = true type args struct { - issue *models.Issue - comment *models.Comment + issue *issues_model.Issue + comment *issues_model.Comment actionType models.ActionType } tests := []struct { diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index 408704adef..e71b2ca17a 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -45,14 +45,14 @@ type GiteaLocalUploader struct { repoOwner string repoName string repo *repo_model.Repository - labels map[string]*models.Label + labels map[string]*issues_model.Label milestones map[string]int64 - issues map[int64]*models.Issue + issues map[int64]*issues_model.Issue gitRepo *git.Repository prHeadCache map[string]struct{} sameApp bool userMap map[int64]int64 // external user id mapping to user id - prCache map[int64]*models.PullRequest + prCache map[int64]*issues_model.PullRequest gitServiceType structs.GitServiceType } @@ -63,12 +63,12 @@ func NewGiteaLocalUploader(ctx context.Context, doer *user_model.User, repoOwner doer: doer, repoOwner: repoOwner, repoName: repoName, - labels: make(map[string]*models.Label), + labels: make(map[string]*issues_model.Label), milestones: make(map[string]int64), - issues: make(map[int64]*models.Issue), + issues: make(map[int64]*issues_model.Issue), prHeadCache: make(map[string]struct{}), userMap: make(map[int64]int64), - prCache: make(map[int64]*models.PullRequest), + prCache: make(map[int64]*issues_model.PullRequest), } } @@ -76,17 +76,17 @@ func NewGiteaLocalUploader(ctx context.Context, doer *user_model.User, repoOwner func (g *GiteaLocalUploader) MaxBatchInsertSize(tp string) int { switch tp { case "issue": - return db.MaxBatchInsertSize(new(models.Issue)) + return db.MaxBatchInsertSize(new(issues_model.Issue)) case "comment": - return db.MaxBatchInsertSize(new(models.Comment)) + return db.MaxBatchInsertSize(new(issues_model.Comment)) case "milestone": return db.MaxBatchInsertSize(new(issues_model.Milestone)) case "label": - return db.MaxBatchInsertSize(new(models.Label)) + return db.MaxBatchInsertSize(new(issues_model.Label)) case "release": return db.MaxBatchInsertSize(new(models.Release)) case "pullrequest": - return db.MaxBatchInsertSize(new(models.PullRequest)) + return db.MaxBatchInsertSize(new(issues_model.PullRequest)) } return 10 } @@ -216,9 +216,9 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err // CreateLabels creates labels func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { - lbs := make([]*models.Label, 0, len(labels)) + lbs := make([]*issues_model.Label, 0, len(labels)) for _, label := range labels { - lbs = append(lbs, &models.Label{ + lbs = append(lbs, &issues_model.Label{ RepoID: g.repo.ID, Name: label.Name, Description: label.Description, @@ -226,7 +226,7 @@ func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { }) } - err := models.NewLabels(lbs...) + err := issues_model.NewLabels(lbs...) if err != nil { return err } @@ -339,9 +339,9 @@ func (g *GiteaLocalUploader) SyncTags() error { // CreateIssues creates issues func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { - iss := make([]*models.Issue, 0, len(issues)) + iss := make([]*issues_model.Issue, 0, len(issues)) for _, issue := range issues { - var labels []*models.Label + var labels []*issues_model.Label for _, label := range issue.Labels { lb, ok := g.labels[label.Name] if ok { @@ -366,7 +366,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { } } - is := models.Issue{ + is := issues_model.Issue{ RepoID: g.repo.ID, Repo: g.repo, Index: issue.Number, @@ -423,9 +423,9 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { // CreateComments creates comments of issues func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { - cms := make([]*models.Comment, 0, len(comments)) + cms := make([]*issues_model.Comment, 0, len(comments)) for _, comment := range comments { - var issue *models.Issue + var issue *issues_model.Issue issue, ok := g.issues[comment.IssueIndex] if !ok { return fmt.Errorf("comment references non existent IssueIndex %d", comment.IssueIndex) @@ -438,9 +438,9 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { comment.Updated = comment.Created } - cm := models.Comment{ + cm := issues_model.Comment{ IssueID: issue.ID, - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, Content: comment.Content, CreatedUnix: timeutil.TimeStamp(comment.Created.Unix()), UpdatedUnix: timeutil.TimeStamp(comment.Updated.Unix()), @@ -473,7 +473,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { // CreatePullRequests creates pull requests func (g *GiteaLocalUploader) CreatePullRequests(prs ...*base.PullRequest) error { - gprs := make([]*models.PullRequest, 0, len(prs)) + gprs := make([]*issues_model.PullRequest, 0, len(prs)) for _, pr := range prs { gpr, err := g.newPullRequest(pr) if err != nil { @@ -600,8 +600,8 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(pr *base.PullRequest) (head return head, nil } -func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullRequest, error) { - var labels []*models.Label +func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model.PullRequest, error) { + var labels []*issues_model.Label for _, label := range pr.Labels { lb, ok := g.labels[label.Name] if ok { @@ -629,7 +629,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR pr.Updated = pr.Created } - issue := models.Issue{ + issue := issues_model.Issue{ RepoID: g.repo.ID, Repo: g.repo, Title: pr.Title, @@ -660,7 +660,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR issue.Reactions = append(issue.Reactions, &res) } - pullRequest := models.PullRequest{ + pullRequest := issues_model.PullRequest{ HeadRepoID: g.repo.ID, HeadBranch: head, BaseRepoID: g.repo.ID, @@ -686,28 +686,28 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR return &pullRequest, nil } -func convertReviewState(state string) models.ReviewType { +func convertReviewState(state string) issues_model.ReviewType { switch state { case base.ReviewStatePending: - return models.ReviewTypePending + return issues_model.ReviewTypePending case base.ReviewStateApproved: - return models.ReviewTypeApprove + return issues_model.ReviewTypeApprove case base.ReviewStateChangesRequested: - return models.ReviewTypeReject + return issues_model.ReviewTypeReject case base.ReviewStateCommented: - return models.ReviewTypeComment + return issues_model.ReviewTypeComment case base.ReviewStateRequestReview: - return models.ReviewTypeRequest + return issues_model.ReviewTypeRequest default: - return models.ReviewTypePending + return issues_model.ReviewTypePending } } // CreateReviews create pull request reviews of currently migrated issues func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { - cms := make([]*models.Review, 0, len(reviews)) + cms := make([]*issues_model.Review, 0, len(reviews)) for _, review := range reviews { - var issue *models.Issue + var issue *issues_model.Issue issue, ok := g.issues[review.IssueIndex] if !ok { return fmt.Errorf("review references non existent IssueIndex %d", review.IssueIndex) @@ -716,7 +716,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { review.CreatedAt = time.Unix(int64(issue.CreatedUnix), 0) } - cm := models.Review{ + cm := issues_model.Review{ Type: convertReviewState(review.State), IssueID: issue.ID, Content: review.Content, @@ -733,7 +733,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { pr, ok := g.prCache[issue.ID] if !ok { var err error - pr, err = models.GetPullRequestByIssueIDWithNoAttributes(issue.ID) + pr, err = issues_model.GetPullRequestByIssueIDWithNoAttributes(issue.ID) if err != nil { return err } @@ -767,7 +767,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { _ = writer.Close() }(comment) - patch, _ = git.CutDiffAroundLine(reader, int64((&models.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) + patch, _ = git.CutDiffAroundLine(reader, int64((&issues_model.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) if comment.CreatedAt.IsZero() { comment.CreatedAt = review.CreatedAt @@ -776,8 +776,8 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { comment.UpdatedAt = comment.CreatedAt } - c := models.Comment{ - Type: models.CommentTypeCode, + c := issues_model.Comment{ + Type: issues_model.CommentTypeCode, IssueID: issue.ID, Content: comment.Content, Line: int64(line + comment.Position - 1), @@ -798,7 +798,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { cms = append(cms, &cm) } - return models.InsertReviews(cms) + return issues_model.InsertReviews(cms) } // Rollback when migrating failed, this will rollback all the changes. @@ -819,7 +819,7 @@ func (g *GiteaLocalUploader) Finish() error { } // update issue_index - if err := models.RecalculateIssueIndexForRepo(g.repo.ID); err != nil { + if err := issues_model.RecalculateIssueIndexForRepo(g.repo.ID); err != nil { return err } diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index bd7c6e0657..6ea1c20592 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -81,7 +81,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Empty(t, milestones) - labels, err := models.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) assert.NoError(t, err) assert.Len(t, labels, 12) @@ -105,7 +105,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Len(t, releases, 1) - issues, err := models.Issues(&models.IssuesOptions{ + issues, err := issues_model.Issues(&issues_model.IssuesOptions{ RepoID: repo.ID, IsPull: util.OptionalBoolFalse, SortType: "oldest", @@ -115,7 +115,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, issues[0].LoadDiscussComments()) assert.Empty(t, issues[0].Comments) - pulls, _, err := models.PullRequests(repo.ID, &models.PullRequestsOptions{ + pulls, _, err := issues_model.PullRequests(repo.ID, &issues_model.PullRequestsOptions{ SortType: "oldest", }) assert.NoError(t, err) diff --git a/services/pull/check.go b/services/pull/check.go index 94e7ca7161..6621a281fa 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -44,9 +45,9 @@ var ( ) // AddToTaskQueue adds itself to pull request test task queue. -func AddToTaskQueue(pr *models.PullRequest) { +func AddToTaskQueue(pr *issues_model.PullRequest) { err := prPatchCheckerQueue.PushFunc(strconv.FormatInt(pr.ID, 10), func() error { - pr.Status = models.PullRequestStatusChecking + pr.Status = issues_model.PullRequestStatusChecking err := pr.UpdateColsIfNotMerged("status") if err != nil { log.Error("AddToTaskQueue.UpdateCols[%d].(add to queue): %v", pr.ID, err) @@ -61,7 +62,7 @@ func AddToTaskQueue(pr *models.PullRequest) { } // CheckPullMergable check if the pull mergable based on all conditions (branch protection, merge options, ...) -func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *models.PullRequest, manuallMerge, force bool) error { +func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, manuallMerge, force bool) error { return db.WithTx(func(ctx context.Context) error { if pr.HasMerged { return ErrHasMerged @@ -114,7 +115,7 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce return err } - if noDeps, err := models.IssueNoDependenciesLeft(ctx, pr.Issue); err != nil { + if noDeps, err := issues_model.IssueNoDependenciesLeft(ctx, pr.Issue); err != nil { return err } else if !noDeps { return ErrDependenciesLeft @@ -125,7 +126,7 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce } // isSignedIfRequired check if merge will be signed if required -func isSignedIfRequired(ctx context.Context, pr *models.PullRequest, doer *user_model.User) (bool, error) { +func isSignedIfRequired(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User) (bool, error) { if err := pr.LoadProtectedBranchCtx(ctx); err != nil { return false, err } @@ -141,10 +142,10 @@ func isSignedIfRequired(ctx context.Context, pr *models.PullRequest, doer *user_ // checkAndUpdateStatus checks if pull request is possible to leaving checking status, // and set to be either conflict or mergeable. -func checkAndUpdateStatus(pr *models.PullRequest) { +func checkAndUpdateStatus(pr *issues_model.PullRequest) { // Status is not changed to conflict means mergeable. - if pr.Status == models.PullRequestStatusChecking { - pr.Status = models.PullRequestStatusMergeable + if pr.Status == issues_model.PullRequestStatusChecking { + pr.Status = issues_model.PullRequestStatusMergeable } // Make sure there is no waiting test to process before leaving the checking status. @@ -162,7 +163,7 @@ func checkAndUpdateStatus(pr *models.PullRequest) { // getMergeCommit checks if a pull request got merged // Returns the git.Commit of the pull request if merged -func getMergeCommit(ctx context.Context, pr *models.PullRequest) (*git.Commit, error) { +func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Commit, error) { if pr.BaseRepo == nil { var err error pr.BaseRepo, err = repo_model.GetRepositoryByID(pr.BaseRepoID) @@ -230,7 +231,7 @@ func getMergeCommit(ctx context.Context, pr *models.PullRequest) (*git.Commit, e // manuallyMerged checks if a pull request got manually merged // When a pull request got manually merged mark the pull request as merged -func manuallyMerged(ctx context.Context, pr *models.PullRequest) bool { +func manuallyMerged(ctx context.Context, pr *issues_model.PullRequest) bool { if err := pr.LoadBaseRepoCtx(ctx); err != nil { log.Error("PullRequest[%d].LoadBaseRepo: %v", pr.ID, err) return false @@ -254,7 +255,7 @@ func manuallyMerged(ctx context.Context, pr *models.PullRequest) bool { if commit != nil { pr.MergedCommitID = commit.ID.String() pr.MergedUnix = timeutil.TimeStamp(commit.Author.When.Unix()) - pr.Status = models.PullRequestStatusManuallyMerged + pr.Status = issues_model.PullRequestStatusManuallyMerged merger, _ := user_model.GetUserByEmail(commit.Author.Email) // When the commit author is unknown set the BaseRepo owner as merger @@ -287,7 +288,7 @@ func manuallyMerged(ctx context.Context, pr *models.PullRequest) bool { // InitializePullRequests checks and tests untested patches of pull requests. func InitializePullRequests(ctx context.Context) { - prs, err := models.GetPullRequestIDsByCheckStatus(models.PullRequestStatusChecking) + prs, err := issues_model.GetPullRequestIDsByCheckStatus(issues_model.PullRequestStatusChecking) if err != nil { log.Error("Find Checking PRs: %v", err) return @@ -323,7 +324,7 @@ func testPR(id int64) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("Test PR[%d] from patch checking queue", id)) defer finished() - pr, err := models.GetPullRequestByID(ctx, id) + pr, err := issues_model.GetPullRequestByID(ctx, id) if err != nil { log.Error("GetPullRequestByID[%d]: %v", id, err) return @@ -339,7 +340,7 @@ func testPR(id int64) { if err := TestPatch(pr); err != nil { log.Error("testPatch[%d]: %v", pr.ID, err) - pr.Status = models.PullRequestStatusError + pr.Status = issues_model.PullRequestStatusError if err := pr.UpdateCols("status"); err != nil { log.Error("update pr [%d] status to PullRequestStatusError failed: %v", pr.ID, err) } @@ -350,7 +351,7 @@ func testPR(id int64) { // CheckPrsForBaseBranch check all pulls with bseBrannch func CheckPrsForBaseBranch(baseRepo *repo_model.Repository, baseBranchName string) error { - prs, err := models.GetUnmergedPullRequestsByBaseInfo(baseRepo.ID, baseBranchName) + prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(baseRepo.ID, baseBranchName) if err != nil { return err } diff --git a/services/pull/check_test.go b/services/pull/check_test.go index bc4c45ffad..21fe675bbc 100644 --- a/services/pull/check_test.go +++ b/services/pull/check_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/queue" @@ -43,12 +43,12 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) { prPatchCheckerQueue = q.(queue.UniqueQueue) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) AddToTaskQueue(pr) assert.Eventually(t, func() bool { - pr = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) - return pr.Status == models.PullRequestStatusChecking + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + return pr.Status == issues_model.PullRequestStatusChecking }, 1*time.Second, 100*time.Millisecond) has, err := prPatchCheckerQueue.Has(strconv.FormatInt(pr.ID, 10)) @@ -72,8 +72,8 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) { assert.False(t, has) assert.NoError(t, err) - pr = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) - assert.Equal(t, models.PullRequestStatusChecking, pr.Status) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + assert.Equal(t, issues_model.PullRequestStatusChecking, pr.Status) for _, callback := range queueShutdown { callback() diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go index c0894c6c98..5d846129f6 100644 --- a/services/pull/commit_status.go +++ b/services/pull/commit_status.go @@ -8,9 +8,9 @@ package pull import ( "context" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/structs" @@ -83,7 +83,7 @@ func IsCommitStatusContextSuccess(commitStatuses []*git_model.CommitStatus, requ } // IsPullCommitStatusPass returns if all required status checks PASS -func IsPullCommitStatusPass(ctx context.Context, pr *models.PullRequest) (bool, error) { +func IsPullCommitStatusPass(ctx context.Context, pr *issues_model.PullRequest) (bool, error) { if err := pr.LoadProtectedBranchCtx(ctx); err != nil { return false, errors.Wrap(err, "GetLatestCommitStatus") } @@ -99,7 +99,7 @@ func IsPullCommitStatusPass(ctx context.Context, pr *models.PullRequest) (bool, } // GetPullRequestCommitStatusState returns pull request merged commit status state -func GetPullRequestCommitStatusState(ctx context.Context, pr *models.PullRequest) (structs.CommitStatusState, error) { +func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullRequest) (structs.CommitStatusState, error) { // Ensure HeadRepo is loaded if err := pr.LoadHeadRepoCtx(ctx); err != nil { return "", errors.Wrap(err, "LoadHeadRepo") @@ -112,15 +112,15 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *models.PullRequest } defer closer.Close() - if pr.Flow == models.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) { + if pr.Flow == issues_model.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) { return "", errors.New("Head branch does not exist, can not merge") } - if pr.Flow == models.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) { + if pr.Flow == issues_model.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) { return "", errors.New("Head branch does not exist, can not merge") } var sha string - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { sha, err = headGitRepo.GetBranchCommitID(pr.HeadBranch) } else { sha, err = headGitRepo.GetRefCommitID(pr.GetGitRefName()) diff --git a/services/pull/edits.go b/services/pull/edits.go index 11932d9ab8..2938f2b108 100644 --- a/services/pull/edits.go +++ b/services/pull/edits.go @@ -9,7 +9,7 @@ import ( "context" "errors" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -18,7 +18,7 @@ import ( var ErrUserHasNoPermissionForAction = errors.New("user not allowed to do this action") // SetAllowEdits allow edits from maintainers to PRs -func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *models.PullRequest, allow bool) error { +func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, allow bool) error { if doer == nil || !pr.Issue.IsPoster(doer.ID) { return ErrUserHasNoPermissionForAction } @@ -37,5 +37,5 @@ func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *models.PullRe } pr.AllowMaintainerEdit = allow - return models.UpdateAllowEdits(ctx, pr) + return issues_model.UpdateAllowEdits(ctx, pr) } diff --git a/services/pull/lfs.go b/services/pull/lfs.go index 490a904584..8cca0a91b7 100644 --- a/services/pull/lfs.go +++ b/services/pull/lfs.go @@ -12,15 +12,15 @@ import ( "strconv" "sync" - "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/git/pipeline" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" ) // LFSPush pushes lfs objects referred to in new commits in the head repository from the base repository -func LFSPush(ctx context.Context, tmpBasePath, mergeHeadSHA, mergeBaseSHA string, pr *models.PullRequest) error { +func LFSPush(ctx context.Context, tmpBasePath, mergeHeadSHA, mergeBaseSHA string, pr *issues_model.PullRequest) error { // Now we have to implement git lfs push // git rev-list --objects --filter=blob:limit=1k HEAD --not base // pass blob shas in to git cat-file --batch-check (possibly unnecessary) @@ -68,7 +68,7 @@ func LFSPush(ctx context.Context, tmpBasePath, mergeHeadSHA, mergeBaseSHA string return nil } -func createLFSMetaObjectsFromCatFileBatch(catFileBatchReader *io.PipeReader, wg *sync.WaitGroup, pr *models.PullRequest) { +func createLFSMetaObjectsFromCatFileBatch(catFileBatchReader *io.PipeReader, wg *sync.WaitGroup, pr *issues_model.PullRequest) { defer wg.Done() defer catFileBatchReader.Close() diff --git a/services/pull/merge.go b/services/pull/merge.go index eef1d17b64..aff800a1b6 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" repo_model "code.gitea.io/gitea/models/repo" @@ -38,7 +39,7 @@ import ( ) // GetDefaultMergeMessage returns default message used when merging pull request -func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *models.PullRequest, mergeStyle repo_model.MergeStyle) (string, error) { +func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle) (string, error) { if err := pr.LoadHeadRepo(); err != nil { return "", err } @@ -131,7 +132,7 @@ func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *models.PullRequest, // Merge merges pull request to base repository. // Caller should check PR is ready to be merged (review and status checks) -func Merge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) error { +func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) error { if err := pr.LoadHeadRepo(); err != nil { log.Error("LoadHeadRepo: %v", err) return fmt.Errorf("LoadHeadRepo: %v", err) @@ -213,7 +214,7 @@ func Merge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, b if close != ref.Issue.IsClosed { if err = issue_service.ChangeStatus(ref.Issue, doer, close); err != nil { // Allow ErrDependenciesLeft - if !models.IsErrDependenciesLeft(err) { + if !issues_model.IsErrDependenciesLeft(err) { return err } } @@ -223,7 +224,7 @@ func Merge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, b } // rawMerge perform the merge operation without changing any pull information in database -func rawMerge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) (string, error) { +func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) (string, error) { // Clone base repo. tmpBasePath, err := createTemporaryRepo(ctx, pr) if err != nil { @@ -635,7 +636,7 @@ func rawMerge(ctx context.Context, pr *models.PullRequest, doer *user_model.User return mergeCommitID, nil } -func commitAndSignNoAuthor(ctx context.Context, pr *models.PullRequest, message, signArg, tmpBasePath string, env []string) error { +func commitAndSignNoAuthor(ctx context.Context, pr *issues_model.PullRequest, message, signArg, tmpBasePath string, env []string) error { var outbuf, errbuf strings.Builder if signArg == "" { if err := git.NewCommand(ctx, "commit", "-m", message). @@ -663,7 +664,7 @@ func commitAndSignNoAuthor(ctx context.Context, pr *models.PullRequest, message, return nil } -func runMergeCommand(pr *models.PullRequest, mergeStyle repo_model.MergeStyle, cmd *git.Command, tmpBasePath string) error { +func runMergeCommand(pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle, cmd *git.Command, tmpBasePath string) error { var outbuf, errbuf strings.Builder if err := cmd.Run(&git.RunOpts{ Dir: tmpBasePath, @@ -747,7 +748,7 @@ func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string) ( } // IsUserAllowedToMerge check if user is allowed to merge PR with given permissions and branch protections -func IsUserAllowedToMerge(ctx context.Context, pr *models.PullRequest, p access_model.Permission, user *user_model.User) (bool, error) { +func IsUserAllowedToMerge(ctx context.Context, pr *issues_model.PullRequest, p access_model.Permission, user *user_model.User) (bool, error) { if user == nil { return false, nil } @@ -765,7 +766,7 @@ func IsUserAllowedToMerge(ctx context.Context, pr *models.PullRequest, p access_ } // CheckPullBranchProtections checks whether the PR is ready to be merged (reviews and status checks) -func CheckPullBranchProtections(ctx context.Context, pr *models.PullRequest, skipProtectedFilesCheck bool) (err error) { +func CheckPullBranchProtections(ctx context.Context, pr *issues_model.PullRequest, skipProtectedFilesCheck bool) (err error) { if err = pr.LoadBaseRepoCtx(ctx); err != nil { return fmt.Errorf("LoadBaseRepo: %v", err) } @@ -787,23 +788,23 @@ func CheckPullBranchProtections(ctx context.Context, pr *models.PullRequest, ski } } - if !models.HasEnoughApprovals(ctx, pr.ProtectedBranch, pr) { + if !issues_model.HasEnoughApprovals(ctx, pr.ProtectedBranch, pr) { return models.ErrDisallowedToMerge{ Reason: "Does not have enough approvals", } } - if models.MergeBlockedByRejectedReview(ctx, pr.ProtectedBranch, pr) { + if issues_model.MergeBlockedByRejectedReview(ctx, pr.ProtectedBranch, pr) { return models.ErrDisallowedToMerge{ Reason: "There are requested changes", } } - if models.MergeBlockedByOfficialReviewRequests(ctx, pr.ProtectedBranch, pr) { + if issues_model.MergeBlockedByOfficialReviewRequests(ctx, pr.ProtectedBranch, pr) { return models.ErrDisallowedToMerge{ Reason: "There are official review requests", } } - if models.MergeBlockedByOutdatedBranch(pr.ProtectedBranch, pr) { + if issues_model.MergeBlockedByOutdatedBranch(pr.ProtectedBranch, pr) { return models.ErrDisallowedToMerge{ Reason: "The head branch is behind the base branch", } @@ -823,7 +824,7 @@ func CheckPullBranchProtections(ctx context.Context, pr *models.PullRequest, ski } // MergedManually mark pr as merged manually -func MergedManually(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, commitID string) error { +func MergedManually(pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, commitID string) error { pullWorkingPool.CheckIn(fmt.Sprint(pr.ID)) defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID)) @@ -862,7 +863,7 @@ func MergedManually(pr *models.PullRequest, doer *user_model.User, baseGitRepo * pr.MergedCommitID = commitID pr.MergedUnix = timeutil.TimeStamp(commit.Author.When.Unix()) - pr.Status = models.PullRequestStatusManuallyMerged + pr.Status = issues_model.PullRequestStatusManuallyMerged pr.Merger = doer pr.MergerID = doer.ID diff --git a/services/pull/patch.go b/services/pull/patch.go index 6e2889b060..c7a69501c3 100644 --- a/services/pull/patch.go +++ b/services/pull/patch.go @@ -15,6 +15,7 @@ import ( "strings" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/graceful" @@ -27,7 +28,7 @@ import ( ) // DownloadDiffOrPatch will write the patch for the pr to the writer -func DownloadDiffOrPatch(ctx context.Context, pr *models.PullRequest, w io.Writer, patch, binary bool) error { +func DownloadDiffOrPatch(ctx context.Context, pr *issues_model.PullRequest, w io.Writer, patch, binary bool) error { if err := pr.LoadBaseRepoCtx(ctx); err != nil { log.Error("Unable to load base repository ID %d for pr #%d [%d]", pr.BaseRepoID, pr.Index, pr.ID) return err @@ -54,7 +55,7 @@ var patchErrorSuffices = []string{ } // TestPatch will test whether a simple patch will apply -func TestPatch(pr *models.PullRequest) error { +func TestPatch(pr *issues_model.PullRequest) error { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("TestPatch: Repo[%d]#%d", pr.BaseRepoID, pr.Index)) defer finished() @@ -88,7 +89,7 @@ func TestPatch(pr *models.PullRequest) error { pr.MergeBase = strings.TrimSpace(pr.MergeBase) // 2. Check for conflicts - if conflicts, err := checkConflicts(ctx, pr, gitRepo, tmpBasePath); err != nil || conflicts || pr.Status == models.PullRequestStatusEmpty { + if conflicts, err := checkConflicts(ctx, pr, gitRepo, tmpBasePath); err != nil || conflicts || pr.Status == issues_model.PullRequestStatusEmpty { return err } @@ -101,7 +102,7 @@ func TestPatch(pr *models.PullRequest) error { log.Trace("Found %d protected files changed", len(pr.ChangedProtectedFiles)) } - pr.Status = models.PullRequestStatusMergeable + pr.Status = issues_model.PullRequestStatusMergeable return nil } @@ -270,7 +271,7 @@ func AttemptThreeWayMerge(ctx context.Context, gitPath string, gitRepo *git.Repo return conflict, conflictedFiles, nil } -func checkConflicts(ctx context.Context, pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath string) (bool, error) { +func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository, tmpBasePath string) (bool, error) { // 1. checkConflicts resets the conflict status - therefore - reset the conflict status pr.ConflictedFiles = nil @@ -295,7 +296,7 @@ func checkConflicts(ctx context.Context, pr *models.PullRequest, gitRepo *git.Re } if treeHash == baseTree.ID.String() { log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID) - pr.Status = models.PullRequestStatusEmpty + pr.Status = issues_model.PullRequestStatusEmpty } return false, nil @@ -329,7 +330,7 @@ func checkConflicts(ctx context.Context, pr *models.PullRequest, gitRepo *git.Re // 3b. if the size of that patch is 0 - there can be no conflicts! if stat.Size() == 0 { log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID) - pr.Status = models.PullRequestStatusEmpty + pr.Status = issues_model.PullRequestStatusEmpty return false, nil } @@ -449,7 +450,7 @@ func checkConflicts(ctx context.Context, pr *models.PullRequest, gitRepo *git.Re // Note: `"err" could be non-nil` is due that if enable 3-way merge, it doesn't return any error on found conflicts. if len(pr.ConflictedFiles) > 0 { if conflict { - pr.Status = models.PullRequestStatusConflict + pr.Status = issues_model.PullRequestStatusConflict log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles) return true, nil @@ -516,8 +517,8 @@ func CheckUnprotectedFiles(repo *git.Repository, oldCommitID, newCommitID string } // checkPullFilesProtection check if pr changed protected files and save results -func checkPullFilesProtection(pr *models.PullRequest, gitRepo *git.Repository) error { - if pr.Status == models.PullRequestStatusEmpty { +func checkPullFilesProtection(pr *issues_model.PullRequest, gitRepo *git.Repository) error { + if pr.Status == issues_model.PullRequestStatusEmpty { pr.ChangedProtectedFiles = nil return nil } diff --git a/services/pull/pull.go b/services/pull/pull.go index 736520fda2..103fdc340d 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -35,7 +36,7 @@ import ( var pullWorkingPool = sync.NewExclusivePool() // NewPullRequest creates new pull request with labels for repository. -func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *models.Issue, labelIDs []int64, uuids []string, pr *models.PullRequest, assigneeIDs []int64) error { +func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *issues_model.Issue, labelIDs []int64, uuids []string, pr *issues_model.PullRequest, assigneeIDs []int64) error { if err := TestPatch(pr); err != nil { return err } @@ -47,7 +48,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode pr.CommitsAhead = divergence.Ahead pr.CommitsBehind = divergence.Behind - if err := models.NewPullRequest(ctx, repo, pull, labelIDs, uuids, pr); err != nil { + if err := issues_model.NewPullRequest(ctx, repo, pull, labelIDs, uuids, pr); err != nil { return err } @@ -66,7 +67,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode prCtx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("NewPullRequest: %s:%d", repo.FullName(), pr.Index)) defer finished() - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { err = PushToBaseRepo(prCtx, pr) } else { err = UpdateRef(prCtx, pr) @@ -75,7 +76,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode return err } - mentions, err := models.FindAndUpdateIssueMentions(ctx, pull, pull.Poster, pull.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, pull, pull.Poster, pull.Content) if err != nil { return err } @@ -102,7 +103,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode } if len(compareInfo.Commits) > 0 { - data := models.PushActionContent{IsForcePush: false} + data := issues_model.PushActionContent{IsForcePush: false} data.CommitIDs = make([]string, 0, len(compareInfo.Commits)) for i := len(compareInfo.Commits) - 1; i >= 0; i-- { data.CommitIDs = append(data.CommitIDs, compareInfo.Commits[i].ID.String()) @@ -113,8 +114,8 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode return err } - ops := &models.CreateCommentOptions{ - Type: models.CommentTypePullRequestPush, + ops := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypePullRequestPush, Doer: pull.Poster, Repo: repo, Issue: pr.Issue, @@ -122,14 +123,14 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode Content: string(dataJSON), } - _, _ = models.CreateComment(ops) + _, _ = issues_model.CreateComment(ops) } return nil } // ChangeTargetBranch changes the target branch of this pull request, as the given user. -func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_model.User, targetBranch string) (err error) { +func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, targetBranch string) (err error) { pullWorkingPool.CheckIn(fmt.Sprint(pr.ID)) defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID)) @@ -139,7 +140,7 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ } if pr.Issue.IsClosed { - return models.ErrIssueIsClosed{ + return issues_model.ErrIssueIsClosed{ ID: pr.Issue.ID, RepoID: pr.Issue.RepoID, Index: pr.Issue.Index, @@ -170,9 +171,9 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ } // Check if pull request for the new target branch already exists - existingPr, err := models.GetUnmergedPullRequest(pr.HeadRepoID, pr.BaseRepoID, pr.HeadBranch, targetBranch, models.PullRequestFlowGithub) + existingPr, err := issues_model.GetUnmergedPullRequest(pr.HeadRepoID, pr.BaseRepoID, pr.HeadBranch, targetBranch, issues_model.PullRequestFlowGithub) if existingPr != nil { - return models.ErrPullRequestAlreadyExists{ + return issues_model.ErrPullRequestAlreadyExists{ ID: existingPr.ID, IssueID: existingPr.Index, HeadRepoID: existingPr.HeadRepoID, @@ -181,7 +182,7 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ BaseBranch: existingPr.BaseBranch, } } - if err != nil && !models.IsErrPullRequestNotExist(err) { + if err != nil && !issues_model.IsErrPullRequestNotExist(err) { return err } @@ -196,8 +197,8 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ // Update target branch, PR diff and status // This is the same as checkAndUpdateStatus in check service, but also updates base_branch - if pr.Status == models.PullRequestStatusChecking { - pr.Status = models.PullRequestStatusMergeable + if pr.Status == issues_model.PullRequestStatusChecking { + pr.Status = issues_model.PullRequestStatusMergeable } // Update Commit Divergence @@ -213,22 +214,22 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ } // Create comment - options := &models.CreateCommentOptions{ - Type: models.CommentTypeChangeTargetBranch, + options := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeChangeTargetBranch, Doer: doer, Repo: pr.Issue.Repo, Issue: pr.Issue, OldRef: oldBranch, NewRef: targetBranch, } - if _, err = models.CreateComment(options); err != nil { + if _, err = issues_model.CreateComment(options); err != nil { return fmt.Errorf("CreateChangeTargetBranchComment: %v", err) } return nil } -func checkForInvalidation(ctx context.Context, requests models.PullRequestList, repoID int64, doer *user_model.User, branch string) error { +func checkForInvalidation(ctx context.Context, requests issues_model.PullRequestList, repoID int64, doer *user_model.User, branch string) error { repo, err := repo_model.GetRepositoryByID(repoID) if err != nil { return fmt.Errorf("GetRepositoryByID: %v", err) @@ -257,14 +258,14 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, // If you don't let it run all the way then you will lose data // TODO: graceful: AddTestPullRequestTask needs to become a queue! - prs, err := models.GetUnmergedPullRequestsByHeadInfo(repoID, branch) + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(repoID, branch) if err != nil { log.Error("Find pull requests [head_repo_id: %d, head_branch: %s]: %v", repoID, branch, err) return } if isSync { - requests := models.PullRequestList(prs) + requests := issues_model.PullRequestList(prs) if err = requests.LoadAttributes(); err != nil { log.Error("PullRequestList.LoadAttributes: %v", err) } @@ -280,11 +281,11 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, } if changed { // Mark old reviews as stale if diff to mergebase has changed - if err := models.MarkReviewsAsStale(pr.IssueID); err != nil { + if err := issues_model.MarkReviewsAsStale(pr.IssueID); err != nil { log.Error("MarkReviewsAsStale: %v", err) } } - if err := models.MarkReviewsAsNotStale(pr.IssueID, newCommitID); err != nil { + if err := issues_model.MarkReviewsAsNotStale(pr.IssueID, newCommitID); err != nil { log.Error("MarkReviewsAsNotStale: %v", err) } divergence, err := GetDiverging(ctx, pr) @@ -306,7 +307,7 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, for _, pr := range prs { log.Trace("Updating PR[%d]: composing new test task", pr.ID) - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { if err := PushToBaseRepo(ctx, pr); err != nil { log.Error("PushToBaseRepo: %v", err) continue @@ -316,14 +317,14 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, } AddToTaskQueue(pr) - comment, err := models.CreatePushPullComment(ctx, doer, pr, oldCommitID, newCommitID) + comment, err := issues_model.CreatePushPullComment(ctx, doer, pr, oldCommitID, newCommitID) if err == nil && comment != nil { notification.NotifyPullRequestPushCommits(doer, pr, comment) } } log.Trace("AddTestPullRequestTask [base_repo_id: %d, base_branch: %s]: finding pull requests", repoID, branch) - prs, err = models.GetUnmergedPullRequestsByBaseInfo(repoID, branch) + prs, err = issues_model.GetUnmergedPullRequestsByBaseInfo(repoID, branch) if err != nil { log.Error("Find pull requests [base_repo_id: %d, base_branch: %s]: %v", repoID, branch, err) return @@ -349,7 +350,7 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, // checkIfPRContentChanged checks if diff to target branch has changed by push // A commit can be considered to leave the PR untouched if the patch/diff with its merge base is unchanged -func checkIfPRContentChanged(ctx context.Context, pr *models.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) { +func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) { if err = pr.LoadHeadRepoCtx(ctx); err != nil { return false, fmt.Errorf("LoadHeadRepo: %v", err) } else if pr.HeadRepo == nil { @@ -421,11 +422,11 @@ func checkIfPRContentChanged(ctx context.Context, pr *models.PullRequest, oldCom // PushToBaseRepo pushes commits from branches of head repository to // corresponding branches of base repository. // FIXME: Only push branches that are actually updates? -func PushToBaseRepo(ctx context.Context, pr *models.PullRequest) (err error) { +func PushToBaseRepo(ctx context.Context, pr *issues_model.PullRequest) (err error) { return pushToBaseRepoHelper(ctx, pr, "") } -func pushToBaseRepoHelper(ctx context.Context, pr *models.PullRequest, prefixHeadBranch string) (err error) { +func pushToBaseRepoHelper(ctx context.Context, pr *issues_model.PullRequest, prefixHeadBranch string) (err error) { log.Trace("PushToBaseRepo[%d]: pushing commits to base repo '%s'", pr.BaseRepoID, pr.GetGitRefName()) if err := pr.LoadHeadRepoCtx(ctx); err != nil { @@ -481,7 +482,7 @@ func pushToBaseRepoHelper(ctx context.Context, pr *models.PullRequest, prefixHea } // UpdateRef update refs/pull/id/head directly for agit flow pull request -func UpdateRef(ctx context.Context, pr *models.PullRequest) (err error) { +func UpdateRef(ctx context.Context, pr *issues_model.PullRequest) (err error) { log.Trace("UpdateRef[%d]: upgate pull request ref in base repo '%s'", pr.ID, pr.GetGitRefName()) if err := pr.LoadBaseRepoCtx(ctx); err != nil { log.Error("Unable to load base repository for PR[%d] Error: %v", pr.ID, err) @@ -514,24 +515,24 @@ func (errs errlist) Error() string { // CloseBranchPulls close all the pull requests who's head branch is the branch func CloseBranchPulls(doer *user_model.User, repoID int64, branch string) error { - prs, err := models.GetUnmergedPullRequestsByHeadInfo(repoID, branch) + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(repoID, branch) if err != nil { return err } - prs2, err := models.GetUnmergedPullRequestsByBaseInfo(repoID, branch) + prs2, err := issues_model.GetUnmergedPullRequestsByBaseInfo(repoID, branch) if err != nil { return err } prs = append(prs, prs2...) - if err := models.PullRequestList(prs).LoadAttributes(); err != nil { + if err := issues_model.PullRequestList(prs).LoadAttributes(); err != nil { return err } var errs errlist for _, pr := range prs { - if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !models.IsErrPullWasClosed(err) && !models.IsErrDependenciesLeft(err) { + if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !issues_model.IsErrPullWasClosed(err) && !issues_model.IsErrDependenciesLeft(err) { errs = append(errs, err) } } @@ -550,12 +551,12 @@ func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *re var errs errlist for _, branch := range branches { - prs, err := models.GetUnmergedPullRequestsByHeadInfo(repo.ID, branch.Name) + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(repo.ID, branch.Name) if err != nil { return err } - if err = models.PullRequestList(prs).LoadAttributes(); err != nil { + if err = issues_model.PullRequestList(prs).LoadAttributes(); err != nil { return err } @@ -565,7 +566,7 @@ func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *re if pr.BaseRepoID == repo.ID { continue } - if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !models.IsErrPullWasClosed(err) { + if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !issues_model.IsErrPullWasClosed(err) { errs = append(errs, err) } } @@ -580,7 +581,7 @@ func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *re var commitMessageTrailersPattern = regexp.MustCompile(`(?:^|\n\n)(?:[\w-]+[ \t]*:[^\n]+\n*(?:[ \t]+[^\n]+\n*)*)+$`) // GetSquashMergeCommitMessages returns the commit messages between head and merge base (if there is one) -func GetSquashMergeCommitMessages(ctx context.Context, pr *models.PullRequest) string { +func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequest) string { if err := pr.LoadIssue(); err != nil { log.Error("Cannot load issue %d for PR id %d: Error: %v", pr.IssueID, pr.ID, err) return "" @@ -608,7 +609,7 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *models.PullRequest) s defer closer.Close() var headCommit *git.Commit - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { headCommit, err = gitRepo.GetBranchCommit(pr.HeadBranch) } else { pr.HeadCommitID, err = gitRepo.GetRefCommitID(pr.GetGitRefName()) @@ -736,13 +737,13 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *models.PullRequest) s } // GetIssuesLastCommitStatus returns a map of issue ID to the most recent commit's latest status -func GetIssuesLastCommitStatus(ctx context.Context, issues models.IssueList) (map[int64]*git_model.CommitStatus, error) { +func GetIssuesLastCommitStatus(ctx context.Context, issues issues_model.IssueList) (map[int64]*git_model.CommitStatus, error) { _, lastStatus, err := GetIssuesAllCommitStatus(ctx, issues) return lastStatus, err } // GetIssuesAllCommitStatus returns a map of issue ID to a list of all statuses for the most recent commit as well as a map of issue ID to only the commit's latest status -func GetIssuesAllCommitStatus(ctx context.Context, issues models.IssueList) (map[int64][]*git_model.CommitStatus, map[int64]*git_model.CommitStatus, error) { +func GetIssuesAllCommitStatus(ctx context.Context, issues issues_model.IssueList) (map[int64][]*git_model.CommitStatus, map[int64]*git_model.CommitStatus, error) { if err := issues.LoadPullRequests(); err != nil { return nil, nil, err } @@ -788,7 +789,7 @@ func GetIssuesAllCommitStatus(ctx context.Context, issues models.IssueList) (map } // getAllCommitStatus get pr's commit statuses. -func getAllCommitStatus(gitRepo *git.Repository, pr *models.PullRequest) (statuses []*git_model.CommitStatus, lastStatus *git_model.CommitStatus, err error) { +func getAllCommitStatus(gitRepo *git.Repository, pr *issues_model.PullRequest) (statuses []*git_model.CommitStatus, lastStatus *git_model.CommitStatus, err error) { sha, shaErr := gitRepo.GetRefCommitID(pr.GetGitRefName()) if shaErr != nil { return nil, nil, shaErr @@ -800,7 +801,7 @@ func getAllCommitStatus(gitRepo *git.Repository, pr *models.PullRequest) (status } // IsHeadEqualWithBranch returns if the commits of branchName are available in pull request head -func IsHeadEqualWithBranch(ctx context.Context, pr *models.PullRequest, branchName string) (bool, error) { +func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, branchName string) (bool, error) { var err error if err = pr.LoadBaseRepoCtx(ctx); err != nil { return false, err @@ -833,7 +834,7 @@ func IsHeadEqualWithBranch(ctx context.Context, pr *models.PullRequest, branchNa } var headCommit *git.Commit - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { headCommit, err = headGitRepo.GetBranchCommit(pr.HeadBranch) if err != nil { return false, err diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go index 09bae97780..9160c43460 100644 --- a/services/pull/pull_test.go +++ b/services/pull/pull_test.go @@ -8,7 +8,7 @@ package pull import ( "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" @@ -38,7 +38,7 @@ func TestPullRequest_CommitMessageTrailersPattern(t *testing.T) { func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadBaseRepo()) gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) @@ -68,7 +68,7 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) baseRepo.Units = []*repo_model.RepoUnit{&externalTracker} - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2, BaseRepo: baseRepo}).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadBaseRepo()) gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) diff --git a/services/pull/review.go b/services/pull/review.go index eac7279f9b..9cb58fa3a1 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -12,8 +12,8 @@ import ( "regexp" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -23,7 +23,7 @@ import ( ) // CreateCodeComment creates a comment on the code line -func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *models.Issue, line int64, content, treePath string, isReview bool, replyReviewID int64, latestCommitID string) (*models.Comment, error) { +func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, line int64, content, treePath string, isReview bool, replyReviewID int64, latestCommitID string) (*issues_model.Comment, error) { var ( existsReview bool err error @@ -37,7 +37,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. if !isReview && replyReviewID != 0 { // It's not part of a review; maybe a reply to a review comment or a single comment. // Check if there are reviews for that line already; if there are, this is a reply - if existsReview, err = models.ReviewExists(issue, treePath, line); err != nil { + if existsReview, err = issues_model.ReviewExists(issue, treePath, line); err != nil { return nil, err } } @@ -61,7 +61,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. return nil, err } - mentions, err := models.FindAndUpdateIssueMentions(ctx, issue, doer, comment.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comment.Content) if err != nil { return nil, err } @@ -71,14 +71,14 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. return comment, nil } - review, err := models.GetCurrentReview(ctx, doer, issue) + review, err := issues_model.GetCurrentReview(ctx, doer, issue) if err != nil { - if !models.IsErrReviewNotExist(err) { + if !issues_model.IsErrReviewNotExist(err) { return nil, err } - if review, err = models.CreateReview(ctx, models.CreateReviewOptions{ - Type: models.ReviewTypePending, + if review, err = issues_model.CreateReview(ctx, issues_model.CreateReviewOptions{ + Type: issues_model.ReviewTypePending, Reviewer: doer, Issue: issue, Official: false, @@ -103,7 +103,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. if !isReview && !existsReview { // Submit the review we've just created so the comment shows up in the issue view - if _, _, err = SubmitReview(ctx, doer, gitRepo, issue, models.ReviewTypeComment, "", latestCommitID, nil); err != nil { + if _, _, err = SubmitReview(ctx, doer, gitRepo, issue, issues_model.ReviewTypeComment, "", latestCommitID, nil); err != nil { return nil, err } } @@ -116,7 +116,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. var notEnoughLines = regexp.MustCompile(`exit status 128 - fatal: file .* has only \d+ lines?`) // createCodeComment creates a plain code comment at the specified line / path -func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *models.Issue, content, treePath string, line, reviewID int64) (*models.Comment, error) { +func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, treePath string, line, reviewID int64) (*issues_model.Comment, error) { var commitID, patch string if err := issue.LoadPullRequest(); err != nil { return nil, fmt.Errorf("GetPullRequestByIssueID: %v", err) @@ -135,11 +135,11 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo head := pr.GetGitRefName() if line > 0 { if reviewID != 0 { - first, err := models.FindComments(ctx, &models.FindCommentsOptions{ + first, err := issues_model.FindComments(ctx, &issues_model.FindCommentsOptions{ ReviewID: reviewID, Line: line, TreePath: treePath, - Type: models.CommentTypeCode, + Type: issues_model.CommentTypeCode, ListOptions: db.ListOptions{ PageSize: 1, Page: 1, @@ -149,13 +149,13 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo commitID = first[0].CommitSHA invalidated = first[0].Invalidated patch = first[0].Patch - } else if err != nil && !models.IsErrCommentNotExist(err) { + } else if err != nil && !issues_model.IsErrCommentNotExist(err) { return nil, fmt.Errorf("Find first comment for %d line %d path %s. Error: %v", reviewID, line, treePath, err) } else { - review, err := models.GetReviewByID(ctx, reviewID) + review, err := issues_model.GetReviewByID(ctx, reviewID) if err == nil && len(review.CommitID) > 0 { head = review.CommitID - } else if err != nil && !models.IsErrReviewNotExist(err) { + } else if err != nil && !issues_model.IsErrReviewNotExist(err) { return nil, fmt.Errorf("GetReviewByID %d. Error: %v", reviewID, err) } } @@ -196,14 +196,14 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo _ = writer.Close() }() - patch, err = git.CutDiffAroundLine(reader, int64((&models.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) + patch, err = git.CutDiffAroundLine(reader, int64((&issues_model.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) if err != nil { log.Error("Error whilst generating patch: %v", err) return nil, err } } - return models.CreateComment(&models.CreateCommentOptions{ - Type: models.CommentTypeCode, + return issues_model.CreateComment(&issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeCode, Doer: doer, Repo: repo, Issue: issue, @@ -218,14 +218,14 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo } // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist -func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *models.Issue, reviewType models.ReviewType, content, commitID string, attachmentUUIDs []string) (*models.Review, *models.Comment, error) { +func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, reviewType issues_model.ReviewType, content, commitID string, attachmentUUIDs []string) (*issues_model.Review, *issues_model.Comment, error) { pr, err := issue.GetPullRequest() if err != nil { return nil, nil, err } var stale bool - if reviewType != models.ReviewTypeApprove && reviewType != models.ReviewTypeReject { + if reviewType != issues_model.ReviewTypeApprove && reviewType != issues_model.ReviewTypeReject { stale = false } else { headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName()) @@ -243,12 +243,12 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos } } - review, comm, err := models.SubmitReview(doer, issue, reviewType, content, commitID, stale, attachmentUUIDs) + review, comm, err := issues_model.SubmitReview(doer, issue, reviewType, content, commitID, stale, attachmentUUIDs) if err != nil { return nil, nil, err } - mentions, err := models.FindAndUpdateIssueMentions(ctx, issue, doer, comm.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comm.Content) if err != nil { return nil, nil, err } @@ -258,7 +258,7 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos for _, lines := range review.CodeComments { for _, comments := range lines { for _, codeComment := range comments { - mentions, err := models.FindAndUpdateIssueMentions(ctx, issue, doer, codeComment.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, codeComment.Content) if err != nil { return nil, nil, err } @@ -271,17 +271,17 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos } // DismissReview dismissing stale review by repo admin -func DismissReview(ctx context.Context, reviewID int64, message string, doer *user_model.User, isDismiss bool) (comment *models.Comment, err error) { - review, err := models.GetReviewByID(ctx, reviewID) +func DismissReview(ctx context.Context, reviewID int64, message string, doer *user_model.User, isDismiss bool) (comment *issues_model.Comment, err error) { + review, err := issues_model.GetReviewByID(ctx, reviewID) if err != nil { return } - if review.Type != models.ReviewTypeApprove && review.Type != models.ReviewTypeReject { + if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject { return nil, fmt.Errorf("not need to dismiss this review because it's type is not Approve or change request") } - if err = models.DismissReview(review, isDismiss); err != nil { + if err = issues_model.DismissReview(review, isDismiss); err != nil { return } @@ -296,14 +296,14 @@ func DismissReview(ctx context.Context, reviewID int64, message string, doer *us if err = review.Issue.LoadPullRequest(); err != nil { return } - if err = review.Issue.LoadAttributes(); err != nil { + if err = review.Issue.LoadAttributes(ctx); err != nil { return } - comment, err = models.CreateComment(&models.CreateCommentOptions{ + comment, err = issues_model.CreateComment(&issues_model.CreateCommentOptions{ Doer: doer, Content: message, - Type: models.CommentTypeDismissReview, + Type: issues_model.CommentTypeDismissReview, ReviewID: review.ID, Issue: review.Issue, Repo: review.Issue.Repo, diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go index 6b01809d49..c1456ef0a9 100644 --- a/services/pull/temp_repo.go +++ b/services/pull/temp_repo.go @@ -13,6 +13,7 @@ import ( "strings" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" @@ -21,7 +22,7 @@ import ( // createTemporaryRepo creates a temporary repo with "base" for pr.BaseBranch and "tracking" for pr.HeadBranch // it also create a second base branch called "original_base" -func createTemporaryRepo(ctx context.Context, pr *models.PullRequest) (string, error) { +func createTemporaryRepo(ctx context.Context, pr *issues_model.PullRequest) (string, error) { if err := pr.LoadHeadRepoCtx(ctx); err != nil { log.Error("LoadHeadRepo: %v", err) return "", fmt.Errorf("LoadHeadRepo: %v", err) @@ -164,7 +165,7 @@ func createTemporaryRepo(ctx context.Context, pr *models.PullRequest) (string, e trackingBranch := "tracking" // Fetch head branch var headBranch string - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { headBranch = git.BranchPrefix + pr.HeadBranch } else if len(pr.HeadCommitID) == 40 { // for not created pull request headBranch = pr.HeadCommitID diff --git a/services/pull/update.go b/services/pull/update.go index 0ab8ffcd7d..e5e26462e5 100644 --- a/services/pull/update.go +++ b/services/pull/update.go @@ -9,6 +9,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -19,9 +20,9 @@ import ( ) // Update updates pull request with base branch. -func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User, message string, rebase bool) error { +func Update(ctx context.Context, pull *issues_model.PullRequest, doer *user_model.User, message string, rebase bool) error { var ( - pr *models.PullRequest + pr *issues_model.PullRequest style repo_model.MergeStyle ) @@ -33,7 +34,7 @@ func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User style = repo_model.MergeStyleRebaseUpdate } else { // use merge functions but switch repo's and branch's - pr = &models.PullRequest{ + pr = &issues_model.PullRequest{ HeadRepoID: pull.BaseRepoID, BaseRepoID: pull.HeadRepoID, HeadBranch: pull.BaseBranch, @@ -42,7 +43,7 @@ func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User style = repo_model.MergeStyleMerge } - if pull.Flow == models.PullRequestFlowAGit { + if pull.Flow == issues_model.PullRequestFlowAGit { // TODO: Not support update agit flow pull request's head branch return fmt.Errorf("Not support update agit flow pull request's head branch") } @@ -76,8 +77,8 @@ func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User } // IsUserAllowedToUpdate check if user is allowed to update PR with given permissions and branch protections -func IsUserAllowedToUpdate(ctx context.Context, pull *models.PullRequest, user *user_model.User) (mergeAllowed, rebaseAllowed bool, err error) { - if pull.Flow == models.PullRequestFlowAGit { +func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest, user *user_model.User) (mergeAllowed, rebaseAllowed bool, err error) { + if pull.Flow == issues_model.PullRequestFlowAGit { return false, false, nil } @@ -89,7 +90,7 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *models.PullRequest, user * return false, false, err } - pr := &models.PullRequest{ + pr := &issues_model.PullRequest{ HeadRepoID: pull.BaseRepoID, BaseRepoID: pull.HeadRepoID, HeadBranch: pull.BaseBranch, @@ -139,7 +140,7 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *models.PullRequest, user * } // GetDiverging determines how many commits a PR is ahead or behind the PR base branch -func GetDiverging(ctx context.Context, pr *models.PullRequest) (*git.DivergeObject, error) { +func GetDiverging(ctx context.Context, pr *issues_model.PullRequest) (*git.DivergeObject, error) { log.Trace("GetDiverging[%d]: compare commits", pr.ID) if err := pr.LoadBaseRepoCtx(ctx); err != nil { return nil, err diff --git a/services/repository/repository.go b/services/repository/repository.go index 6848eda101..4bde6879a6 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models" admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" @@ -105,7 +106,7 @@ func UpdateRepository(repo *repo_model.Repository, visibilityChanged bool) (err // LinkedRepository returns the linked repo if any func LinkedRepository(a *repo_model.Attachment) (*repo_model.Repository, unit.Type, error) { if a.IssueID != 0 { - iss, err := models.GetIssueByID(a.IssueID) + iss, err := issues_model.GetIssueByID(db.DefaultContext, a.IssueID) if err != nil { return nil, unit.TypeIssues, err } diff --git a/services/repository/template.go b/services/repository/template.go index 6a1bfaff5b..d7e8145811 100644 --- a/services/repository/template.go +++ b/services/repository/template.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -18,14 +19,14 @@ import ( // GenerateIssueLabels generates issue labels from a template repository func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { - templateLabels, err := models.GetLabelsByRepoID(ctx, templateRepo.ID, "", db.ListOptions{}) + templateLabels, err := issues_model.GetLabelsByRepoID(ctx, templateRepo.ID, "", db.ListOptions{}) if err != nil { return err } - newLabels := make([]*models.Label, 0, len(templateLabels)) + newLabels := make([]*issues_model.Label, 0, len(templateLabels)) for _, templateLabel := range templateLabels { - newLabels = append(newLabels, &models.Label{ + newLabels = append(newLabels, &issues_model.Label{ RepoID: generateRepo.ID, Name: templateLabel.Name, Description: templateLabel.Description, |