diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2022-04-08 17:11:15 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-08 17:11:15 +0800 |
commit | 1dfa26e00e8e1ce6f6125335871da1d402a63466 (patch) | |
tree | d39414fb085ae52d6633ae9d064aabab2e7f75f8 /models | |
parent | 84ceaa98bd731431c7d3a7f65e59e7ad076a540f (diff) | |
download | gitea-1dfa26e00e8e1ce6f6125335871da1d402a63466.tar.gz gitea-1dfa26e00e8e1ce6f6125335871da1d402a63466.zip |
Move milestone to models/issues/ (#19278)
* Move milestone to models/issues/
* Fix lint
* Fix test
* Fix lint
* Fix lint
Diffstat (limited to 'models')
-rw-r--r-- | models/action.go | 2 | ||||
-rw-r--r-- | models/consistency_test.go | 70 | ||||
-rw-r--r-- | models/error.go | 27 | ||||
-rw-r--r-- | models/issue.go | 109 | ||||
-rw-r--r-- | models/issue_assignees.go | 4 | ||||
-rw-r--r-- | models/issue_comment.go | 51 | ||||
-rw-r--r-- | models/issue_comment_list.go | 7 | ||||
-rw-r--r-- | models/issue_label.go | 12 | ||||
-rw-r--r-- | models/issue_list.go | 3 | ||||
-rw-r--r-- | models/issue_lock.go | 4 | ||||
-rw-r--r-- | models/issue_project.go | 4 | ||||
-rw-r--r-- | models/issue_stopwatch.go | 14 | ||||
-rw-r--r-- | models/issue_test.go | 23 | ||||
-rw-r--r-- | models/issue_tracked_time.go | 12 | ||||
-rw-r--r-- | models/issue_xref.go | 8 | ||||
-rw-r--r-- | models/issues/main_test.go | 1 | ||||
-rw-r--r-- | models/issues/milestone.go (renamed from models/issue_milestone.go) | 97 | ||||
-rw-r--r-- | models/issues/milestone_test.go (renamed from models/issue_milestone_test.go) | 114 | ||||
-rw-r--r-- | models/main_test.go | 3 | ||||
-rw-r--r-- | models/migrate.go | 3 | ||||
-rw-r--r-- | models/migrate_test.go | 9 | ||||
-rw-r--r-- | models/notification.go | 2 | ||||
-rw-r--r-- | models/pull.go | 2 | ||||
-rw-r--r-- | models/repo.go | 11 | ||||
-rw-r--r-- | models/review.go | 16 | ||||
-rw-r--r-- | models/statistic.go | 3 |
26 files changed, 264 insertions, 347 deletions
diff --git a/models/action.go b/models/action.go index d3231641d9..3339d3b87a 100644 --- a/models/action.go +++ b/models/action.go @@ -243,7 +243,7 @@ func (a *Action) getCommentLink(ctx context.Context) string { return "#" } - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return "#" } diff --git a/models/consistency_test.go b/models/consistency_test.go index d49a0132f0..1593500361 100644 --- a/models/consistency_test.go +++ b/models/consistency_test.go @@ -8,7 +8,10 @@ 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/timeutil" "github.com/stretchr/testify/assert" ) @@ -33,3 +36,70 @@ func TestDeleteOrphanedObjects(t *testing.T) { 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{}) +} diff --git a/models/error.go b/models/error.go index 6233b2ea85..6846bf8320 100644 --- a/models/error.go +++ b/models/error.go @@ -1048,33 +1048,6 @@ func (err ErrLabelNotExist) Error() string { return fmt.Sprintf("label does not exist [label_id: %d]", err.LabelID) } -// _____ .__.__ __ -// / \ |__| | ____ _______/ |_ ____ ____ ____ -// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \ -// / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/ -// \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ > -// \/ \/ \/ \/ \/ - -// ErrMilestoneNotExist represents a "MilestoneNotExist" kind of error. -type ErrMilestoneNotExist struct { - ID int64 - RepoID int64 - Name string -} - -// IsErrMilestoneNotExist checks if an error is a ErrMilestoneNotExist. -func IsErrMilestoneNotExist(err error) bool { - _, ok := err.(ErrMilestoneNotExist) - return ok -} - -func (err ErrMilestoneNotExist) Error() string { - if len(err.Name) > 0 { - return fmt.Sprintf("milestone does not exist [name: %s, repo_id: %d]", err.Name, err.RepoID) - } - return fmt.Sprintf("milestone does not exist [id: %d, repo_id: %d]", err.ID, err.RepoID) -} - // ____ ___ .__ .___ // | | \______ | | _________ __| _/ // | | /\____ \| | / _ \__ \ / __ | diff --git a/models/issue.go b/models/issue.go index 751ff36c54..b1fa2d02ad 100644 --- a/models/issue.go +++ b/models/issue.go @@ -16,7 +16,7 @@ import ( admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/foreignreference" - "code.gitea.io/gitea/models/issues" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" project_model "code.gitea.io/gitea/models/project" @@ -46,14 +46,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 *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 *issues_model.Milestone `xorm:"-"` + Project *project_model.Project `xorm:"-"` Priority int AssigneeID int64 `xorm:"-"` Assignee *user_model.User `xorm:"-"` @@ -72,7 +72,7 @@ type Issue struct { Attachments []*repo_model.Attachment `xorm:"-"` Comments []*Comment `xorm:"-"` - Reactions issues.ReactionList `xorm:"-"` + Reactions issues_model.ReactionList `xorm:"-"` TotalTrackedTime int64 `xorm:"-"` Assignees []*user_model.User `xorm:"-"` ForeignReference *foreignreference.ForeignReference `xorm:"-"` @@ -124,11 +124,7 @@ func (issue *Issue) IsOverdue() bool { } // LoadRepo loads issue's repository -func (issue *Issue) LoadRepo() error { - return issue.loadRepo(db.DefaultContext) -} - -func (issue *Issue) loadRepo(ctx context.Context) (err error) { +func (issue *Issue) LoadRepo(ctx context.Context) (err error) { if issue.Repo == nil { issue.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, issue.RepoID) if err != nil { @@ -144,7 +140,7 @@ func (issue *Issue) IsTimetrackerEnabled() bool { } func (issue *Issue) isTimetrackerEnabled(ctx context.Context) bool { - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { log.Error(fmt.Sprintf("loadRepo: %v", err)) return false } @@ -244,17 +240,17 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) { if issue.Reactions != nil { return nil } - reactions, _, err := issues.FindReactions(ctx, issues.FindReactionsOptions{ + reactions, _, err := issues_model.FindReactions(ctx, issues_model.FindReactionsOptions{ IssueID: issue.ID, }) if err != nil { return err } - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return err } // Load reaction user data - if _, err := issues.ReactionList(reactions).LoadUsers(ctx, issue.Repo); err != nil { + if _, err := issues_model.ReactionList(reactions).LoadUsers(ctx, issue.Repo); err != nil { return err } @@ -297,10 +293,10 @@ func (issue *Issue) loadForeignReference(ctx context.Context) (err error) { return nil } -func (issue *Issue) loadMilestone(e db.Engine) (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 = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID) - if err != nil && !IsErrMilestoneNotExist(err) { + issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID) + if err != nil && !issues_model.IsErrMilestoneNotExist(err) { return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err) } } @@ -309,7 +305,7 @@ func (issue *Issue) loadMilestone(e db.Engine) (err error) { func (issue *Issue) loadAttributes(ctx context.Context) (err error) { e := db.GetEngine(ctx) - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return } @@ -321,7 +317,7 @@ func (issue *Issue) loadAttributes(ctx context.Context) (err error) { return } - if err = issue.loadMilestone(e); err != nil { + if err = issue.loadMilestone(ctx); err != nil { return } @@ -372,7 +368,7 @@ func (issue *Issue) LoadAttributes() error { // LoadMilestone load milestone of this issue. func (issue *Issue) LoadMilestone() error { - return issue.loadMilestone(db.GetEngine(db.DefaultContext)) + return issue.loadMilestone(db.DefaultContext) } // GetIsRead load the `IsRead` field of the issue @@ -391,7 +387,7 @@ func (issue *Issue) GetIsRead(userID int64) error { // APIURL returns the absolute APIURL to this issue. func (issue *Issue) APIURL() string { if issue.Repo == nil { - err := issue.LoadRepo() + err := issue.LoadRepo(db.DefaultContext) if err != nil { log.Error("Issue[%d].APIURL(): %v", issue.ID, err) return "" @@ -491,7 +487,7 @@ func ClearIssueLabels(issue *Issue, doer *user_model.User) (err error) { } defer committer.Close() - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return err } else if err = issue.loadPullRequest(db.GetEngine(ctx)); err != nil { return err @@ -539,7 +535,7 @@ func ReplaceIssueLabels(issue *Issue, labels []*Label, doer *user_model.User) (e } defer committer.Close() - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return err } @@ -607,7 +603,8 @@ func (issue *Issue) ReadBy(userID int64) error { return setIssueNotificationStatusReadIfUnread(db.GetEngine(db.DefaultContext), userID, issue.ID) } -func updateIssueCols(ctx context.Context, issue *Issue, cols ...string) error { +// 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 { return err } @@ -658,7 +655,7 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use issue.ClosedUnix = 0 } - if err := updateIssueCols(ctx, issue, "is_closed", "closed_unix"); err != nil { + if err := UpdateIssueCols(ctx, issue, "is_closed", "closed_unix"); err != nil { return nil, err } @@ -674,7 +671,7 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use // Update issue count of milestone if issue.MilestoneID > 0 { - if err := updateMilestoneCounters(ctx, issue.MilestoneID); err != nil { + if err := issues_model.UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil { return nil, err } } @@ -691,7 +688,7 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use cmtType = CommentTypeMergePull } - return createComment(ctx, &CreateCommentOptions{ + return CreateCommentCtx(ctx, &CreateCommentOptions{ Type: cmtType, Doer: doer, Repo: issue.Repo, @@ -707,7 +704,7 @@ func ChangeIssueStatus(issue *Issue, doer *user_model.User, isClosed bool) (*Com } defer committer.Close() - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return nil, err } if err := issue.loadPoster(db.GetEngine(ctx)); err != nil { @@ -734,11 +731,11 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err } defer committer.Close() - if err = updateIssueCols(ctx, issue, "name"); err != nil { + if err = UpdateIssueCols(ctx, issue, "name"); err != nil { return fmt.Errorf("updateIssueCols: %v", err) } - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return fmt.Errorf("loadRepo: %v", err) } @@ -750,7 +747,7 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err OldTitle: oldTitle, NewTitle: issue.Title, } - if _, err = createComment(ctx, opts); err != nil { + if _, err = CreateCommentCtx(ctx, opts); err != nil { return fmt.Errorf("createComment: %v", err) } if err = issue.addCrossReferences(ctx, doer, true); err != nil { @@ -768,11 +765,11 @@ func ChangeIssueRef(issue *Issue, doer *user_model.User, oldRef string) (err err } defer committer.Close() - if err = updateIssueCols(ctx, issue, "ref"); err != nil { + if err = UpdateIssueCols(ctx, issue, "ref"); err != nil { return fmt.Errorf("updateIssueCols: %v", err) } - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return fmt.Errorf("loadRepo: %v", err) } oldRefFriendly := strings.TrimPrefix(oldRef, git.BranchPrefix) @@ -786,7 +783,7 @@ func ChangeIssueRef(issue *Issue, doer *user_model.User, oldRef string) (err err OldRef: oldRefFriendly, NewRef: newRefFriendly, } - if _, err = createComment(ctx, opts); err != nil { + if _, err = CreateCommentCtx(ctx, opts); err != nil { return fmt.Errorf("createComment: %v", err) } @@ -811,7 +808,7 @@ func AddDeletePRBranchComment(doer *user_model.User, repo *repo_model.Repository Issue: issue, OldRef: branchName, } - if _, err = createComment(ctx, opts); err != nil { + if _, err = CreateCommentCtx(ctx, opts); err != nil { return err } @@ -846,12 +843,12 @@ func ChangeIssueContent(issue *Issue, doer *user_model.User, content string) (er } defer committer.Close() - hasContentHistory, err := issues.HasIssueContentHistory(ctx, issue.ID, 0) + hasContentHistory, err := issues_model.HasIssueContentHistory(ctx, issue.ID, 0) if err != nil { return fmt.Errorf("HasIssueContentHistory: %v", err) } if !hasContentHistory { - if err = issues.SaveIssueContentHistory(db.GetEngine(ctx), issue.PosterID, issue.ID, 0, + if err = issues_model.SaveIssueContentHistory(db.GetEngine(ctx), issue.PosterID, issue.ID, 0, issue.CreatedUnix, issue.Content, true); err != nil { return fmt.Errorf("SaveIssueContentHistory: %v", err) } @@ -859,11 +856,11 @@ func ChangeIssueContent(issue *Issue, doer *user_model.User, content string) (er issue.Content = content - if err = updateIssueCols(ctx, issue, "content"); err != nil { + if err = UpdateIssueCols(ctx, issue, "content"); err != nil { return fmt.Errorf("UpdateIssueCols: %v", err) } - if err = issues.SaveIssueContentHistory(db.GetEngine(ctx), doer.ID, issue.ID, 0, + if err = issues_model.SaveIssueContentHistory(db.GetEngine(ctx), doer.ID, issue.ID, 0, timeutil.TimeStampNow(), issue.Content, false); err != nil { return fmt.Errorf("SaveIssueContentHistory: %v", err) } @@ -943,8 +940,8 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) opts.Issue.Title = strings.TrimSpace(opts.Issue.Title) if opts.Issue.MilestoneID > 0 { - milestone, err := getMilestoneByRepoID(e, opts.Issue.RepoID, opts.Issue.MilestoneID) - if err != nil && !IsErrMilestoneNotExist(err) { + milestone, err := issues_model.GetMilestoneByRepoID(ctx, opts.Issue.RepoID, opts.Issue.MilestoneID) + if err != nil && !issues_model.IsErrMilestoneNotExist(err) { return fmt.Errorf("getMilestoneByID: %v", err) } @@ -968,7 +965,7 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) } if opts.Issue.MilestoneID > 0 { - if err := updateMilestoneCounters(ctx, opts.Issue.MilestoneID); err != nil { + if err := issues_model.UpdateMilestoneCounters(ctx, opts.Issue.MilestoneID); err != nil { return err } @@ -980,7 +977,7 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) OldMilestoneID: 0, MilestoneID: opts.Issue.MilestoneID, } - if _, err = createComment(ctx, opts); err != nil { + if _, err = CreateCommentCtx(ctx, opts); err != nil { return err } } @@ -1956,7 +1953,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment defer committer.Close() sess := db.GetEngine(ctx) - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return nil, false, fmt.Errorf("loadRepo: %v", err) } @@ -1983,7 +1980,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment OldTitle: currentIssue.Title, NewTitle: issue.Title, } - _, err := createComment(ctx, opts) + _, err := CreateCommentCtx(ctx, opts) if err != nil { return nil, false, fmt.Errorf("createComment: %v", err) } @@ -2015,7 +2012,7 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *us defer committer.Close() // Update the deadline - if err = updateIssueCols(ctx, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix}, "deadline_unix"); err != nil { + if err = UpdateIssueCols(ctx, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix}, "deadline_unix"); err != nil { return err } @@ -2104,14 +2101,14 @@ func deleteIssue(ctx context.Context, issue *Issue) error { // delete all database data still assigned to this issue if err := deleteInIssue(e, issue.ID, - &issues.ContentHistory{}, + &issues_model.ContentHistory{}, &Comment{}, &IssueLabel{}, &IssueDependency{}, &IssueAssignees{}, &IssueUser{}, &Notification{}, - &issues.Reaction{}, + &issues_model.Reaction{}, &IssueWatch{}, &Stopwatch{}, &TrackedTime{}, @@ -2242,7 +2239,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u if len(mentions) == 0 { return } - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return } @@ -2401,7 +2398,7 @@ func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []strin // Delete content histories if _, err = sess.In("issue_id", deleteCond). - Delete(&issues.ContentHistory{}); err != nil { + Delete(&issues_model.ContentHistory{}); err != nil { return } @@ -2429,7 +2426,7 @@ func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []strin } if _, err = sess.In("issue_id", deleteCond). - Delete(&issues.Reaction{}); err != nil { + Delete(&issues_model.Reaction{}); err != nil { return } diff --git a/models/issue_assignees.go b/models/issue_assignees.go index a91793f2f1..0f1f7b6576 100644 --- a/models/issue_assignees.go +++ b/models/issue_assignees.go @@ -120,7 +120,7 @@ func toggleIssueAssignee(ctx context.Context, issue *Issue, doer *user_model.Use } // Repo infos - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return false, nil, fmt.Errorf("loadRepo: %v", err) } @@ -133,7 +133,7 @@ func toggleIssueAssignee(ctx context.Context, issue *Issue, doer *user_model.Use AssigneeID: assigneeID, } // Comment - comment, err = createComment(ctx, opts) + comment, err = CreateCommentCtx(ctx, opts) if err != nil { return false, nil, fmt.Errorf("createComment: %v", err) } diff --git a/models/issue_comment.go b/models/issue_comment.go index 332ae7bdc5..39c2818eed 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -15,7 +15,7 @@ import ( "unicode/utf8" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/issues" + 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" @@ -209,8 +209,8 @@ type Comment struct { Project *project_model.Project `xorm:"-"` OldMilestoneID int64 MilestoneID int64 - OldMilestone *Milestone `xorm:"-"` - Milestone *Milestone `xorm:"-"` + OldMilestone *issues_model.Milestone `xorm:"-"` + Milestone *issues_model.Milestone `xorm:"-"` TimeID int64 Time *TrackedTime `xorm:"-"` AssigneeID int64 @@ -243,8 +243,8 @@ type Comment struct { // Reference issue in commit message CommitSHA string `xorm:"VARCHAR(40)"` - Attachments []*repo_model.Attachment `xorm:"-"` - Reactions issues.ReactionList `xorm:"-"` + Attachments []*repo_model.Attachment `xorm:"-"` + Reactions issues_model.ReactionList `xorm:"-"` // For view issue page. ShowRole RoleDescriptor `xorm:"-"` @@ -358,7 +358,7 @@ func (c *Comment) HTMLURL() string { log.Error("LoadIssue(%d): %v", c.IssueID, err) return "" } - err = c.Issue.loadRepo(db.DefaultContext) + err = c.Issue.LoadRepo(db.DefaultContext) if err != nil { // Silently dropping errors :unamused: log.Error("loadRepo(%d): %v", c.Issue.RepoID, err) return "" @@ -387,7 +387,7 @@ func (c *Comment) APIURL() string { log.Error("LoadIssue(%d): %v", c.IssueID, err) return "" } - err = c.Issue.loadRepo(db.DefaultContext) + err = c.Issue.LoadRepo(db.DefaultContext) if err != nil { // Silently dropping errors :unamused: log.Error("loadRepo(%d): %v", c.Issue.RepoID, err) return "" @@ -408,7 +408,7 @@ func (c *Comment) IssueURL() string { return "" } - err = c.Issue.loadRepo(db.DefaultContext) + err = c.Issue.LoadRepo(db.DefaultContext) if err != nil { // Silently dropping errors :unamused: log.Error("loadRepo(%d): %v", c.Issue.RepoID, err) return "" @@ -424,7 +424,7 @@ func (c *Comment) PRURL() string { return "" } - err = c.Issue.loadRepo(db.DefaultContext) + err = c.Issue.LoadRepo(db.DefaultContext) if err != nil { // Silently dropping errors :unamused: log.Error("loadRepo(%d): %v", c.Issue.RepoID, err) return "" @@ -495,7 +495,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 Milestone + var oldMilestone issues_model.Milestone has, err := db.GetEngine(db.DefaultContext).ID(c.OldMilestoneID).Get(&oldMilestone) if err != nil { return err @@ -505,7 +505,7 @@ func (c *Comment) LoadMilestone() error { } if c.MilestoneID > 0 { - var milestone Milestone + var milestone issues_model.Milestone has, err := db.GetEngine(db.DefaultContext).ID(c.MilestoneID).Get(&milestone) if err != nil { return err @@ -574,7 +574,7 @@ func (c *Comment) LoadAssigneeUserAndTeam() error { return err } - if err = c.Issue.LoadRepo(); err != nil { + if err = c.Issue.LoadRepo(db.DefaultContext); err != nil { return err } @@ -635,7 +635,7 @@ func (c *Comment) loadReactions(ctx context.Context, repo *repo_model.Repository if c.Reactions != nil { return nil } - c.Reactions, _, err = issues.FindReactions(ctx, issues.FindReactionsOptions{ + c.Reactions, _, err = issues_model.FindReactions(ctx, issues_model.FindReactionsOptions{ IssueID: c.IssueID, CommentID: c.ID, }) @@ -717,7 +717,7 @@ func (c *Comment) CodeCommentURL() string { log.Error("LoadIssue(%d): %v", c.IssueID, err) return "" } - err = c.Issue.loadRepo(db.DefaultContext) + err = c.Issue.LoadRepo(db.DefaultContext) if err != nil { // Silently dropping errors :unamused: log.Error("loadRepo(%d): %v", c.Issue.RepoID, err) return "" @@ -761,7 +761,8 @@ func (c *Comment) LoadPushCommits(ctx context.Context) (err error) { return err } -func createComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment, err error) { +// CreateCommentCtx creates comment with context +func CreateCommentCtx(ctx context.Context, opts *CreateCommentOptions) (_ *Comment, err error) { e := db.GetEngine(ctx) var LabelID int64 if opts.Label != nil { @@ -863,7 +864,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment } } // update the issue's updated_unix column - return updateIssueCols(ctx, opts.Issue, "updated_unix") + return UpdateIssueCols(ctx, opts.Issue, "updated_unix") } func createDeadlineComment(ctx context.Context, doer *user_model.User, issue *Issue, newDeadlineUnix timeutil.TimeStamp) (*Comment, error) { @@ -884,7 +885,7 @@ func createDeadlineComment(ctx context.Context, doer *user_model.User, issue *Is content = newDeadlineUnix.Format("2006-01-02") + "|" + issue.DeadlineUnix.Format("2006-01-02") } - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return nil, err } @@ -895,7 +896,7 @@ func createDeadlineComment(ctx context.Context, doer *user_model.User, issue *Is Issue: issue, Content: content, } - comment, err := createComment(ctx, opts) + comment, err := CreateCommentCtx(ctx, opts) if err != nil { return nil, err } @@ -908,7 +909,7 @@ func createIssueDependencyComment(ctx context.Context, doer *user_model.User, is if !add { cType = CommentTypeRemoveDependency } - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return } @@ -920,7 +921,7 @@ func createIssueDependencyComment(ctx context.Context, doer *user_model.User, is Issue: issue, DependentIssueID: dependentIssue.ID, } - if _, err = createComment(ctx, opts); err != nil { + if _, err = CreateCommentCtx(ctx, opts); err != nil { return } @@ -931,7 +932,7 @@ func createIssueDependencyComment(ctx context.Context, doer *user_model.User, is Issue: dependentIssue, DependentIssueID: issue.ID, } - _, err = createComment(ctx, opts) + _, err = CreateCommentCtx(ctx, opts) return } @@ -981,7 +982,7 @@ func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) { } defer committer.Close() - comment, err = createComment(ctx, opts) + comment, err = CreateCommentCtx(ctx, opts) if err != nil { return nil, err } @@ -1159,7 +1160,7 @@ func deleteComment(ctx context.Context, comment *Comment) error { return err } - if _, err := e.Delete(&issues.ContentHistory{ + if _, err := e.Delete(&issues_model.ContentHistory{ CommentID: comment.ID, }); err != nil { return err @@ -1178,7 +1179,7 @@ func deleteComment(ctx context.Context, comment *Comment) error { return err } - return issues.DeleteReaction(ctx, &issues.ReactionOptions{CommentID: comment.ID}) + return issues_model.DeleteReaction(ctx, &issues_model.ReactionOptions{CommentID: comment.ID}) } // CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS @@ -1230,7 +1231,7 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu return nil, err } - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return nil, err } diff --git a/models/issue_comment_list.go b/models/issue_comment_list.go index 2107f4790f..4133fc8761 100644 --- a/models/issue_comment_list.go +++ b/models/issue_comment_list.go @@ -8,6 +8,7 @@ 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" @@ -139,7 +140,7 @@ func (comments CommentList) loadMilestones(e db.Engine) error { return nil } - milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { limit := defaultMaxInSize @@ -182,7 +183,7 @@ func (comments CommentList) loadOldMilestones(e db.Engine) error { return nil } - milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { limit := defaultMaxInSize @@ -387,7 +388,7 @@ func (comments CommentList) loadDependentIssues(ctx context.Context) error { if comment.DependentIssue == nil { comment.DependentIssue = issues[comment.DependentIssueID] if comment.DependentIssue != nil { - if err := comment.DependentIssue.loadRepo(ctx); err != nil { + if err := comment.DependentIssue.LoadRepo(ctx); err != nil { return err } } diff --git a/models/issue_label.go b/models/issue_label.go index 453a0b14a9..016109e80f 100644 --- a/models/issue_label.go +++ b/models/issue_label.go @@ -586,7 +586,7 @@ func newIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *user_m return err } - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return } @@ -598,7 +598,7 @@ func newIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *user_m Label: label, Content: "1", } - if _, err = createComment(ctx, opts); err != nil { + if _, err = CreateCommentCtx(ctx, opts); err != nil { return err } @@ -618,7 +618,7 @@ func NewIssueLabel(issue *Issue, label *Label, doer *user_model.User) (err error defer committer.Close() sess := db.GetEngine(ctx) - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return err } @@ -642,7 +642,7 @@ func NewIssueLabel(issue *Issue, label *Label, doer *user_model.User) (err error // newIssueLabels add labels to an issue. It will check if the labels are valid for the issue func newIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer *user_model.User) (err error) { e := db.GetEngine(ctx) - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return err } for _, label := range labels { @@ -691,7 +691,7 @@ func deleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *use return nil } - if err = issue.loadRepo(ctx); err != nil { + if err = issue.LoadRepo(ctx); err != nil { return } @@ -702,7 +702,7 @@ func deleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *use Issue: issue, Label: label, } - if _, err = createComment(ctx, opts); err != nil { + if _, err = CreateCommentCtx(ctx, opts); err != nil { return err } diff --git a/models/issue_list.go b/models/issue_list.go index 8d7a3121b0..3116b49d8a 100644 --- a/models/issue_list.go +++ b/models/issue_list.go @@ -8,6 +8,7 @@ import ( "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" @@ -199,7 +200,7 @@ func (issues IssueList) loadMilestones(e db.Engine) error { return nil } - milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { limit := defaultMaxInSize diff --git a/models/issue_lock.go b/models/issue_lock.go index 20e94c7b21..a122f618d0 100644 --- a/models/issue_lock.go +++ b/models/issue_lock.go @@ -46,7 +46,7 @@ func updateIssueLock(opts *IssueLockOptions, lock bool) error { } defer committer.Close() - if err := updateIssueCols(ctx, opts.Issue, "is_locked"); err != nil { + if err := UpdateIssueCols(ctx, opts.Issue, "is_locked"); err != nil { return err } @@ -57,7 +57,7 @@ func updateIssueLock(opts *IssueLockOptions, lock bool) error { Type: commentType, Content: opts.Reason, } - if _, err := createComment(ctx, opt); err != nil { + if _, err := CreateCommentCtx(ctx, opt); err != nil { return err } diff --git a/models/issue_project.go b/models/issue_project.go index 526ac95152..0e993b39c5 100644 --- a/models/issue_project.go +++ b/models/issue_project.go @@ -129,12 +129,12 @@ func addUpdateIssueProject(ctx context.Context, issue *Issue, doer *user_model.U return err } - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return err } if oldProjectID > 0 || newProjectID > 0 { - if _, err := createComment(ctx, &CreateCommentOptions{ + if _, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Type: CommentTypeProject, Doer: doer, Repo: issue.Repo, diff --git a/models/issue_stopwatch.go b/models/issue_stopwatch.go index 3be9ad4e3f..80dd44642e 100644 --- a/models/issue_stopwatch.go +++ b/models/issue_stopwatch.go @@ -157,11 +157,11 @@ func FinishIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss return err } - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return err } - if _, err := createComment(ctx, &CreateCommentOptions{ + if _, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Doer: user, Issue: issue, Repo: issue.Repo, @@ -178,7 +178,7 @@ func FinishIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss // CreateIssueStopwatch creates a stopwatch if not exist, otherwise return an error func CreateIssueStopwatch(ctx context.Context, user *user_model.User, issue *Issue) error { e := db.GetEngine(ctx) - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return err } @@ -208,11 +208,11 @@ func CreateIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss return err } - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return err } - if _, err := createComment(ctx, &CreateCommentOptions{ + if _, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Doer: user, Issue: issue, Repo: issue.Repo, @@ -249,11 +249,11 @@ func cancelStopwatch(ctx context.Context, user *user_model.User, issue *Issue) e return err } - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return err } - if _, err := createComment(ctx, &CreateCommentOptions{ + if _, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Doer: user, Issue: issue, Repo: issue.Repo, diff --git a/models/issue_test.go b/models/issue_test.go index 71e0e8a2f7..7893df8a7f 100644 --- a/models/issue_test.go +++ b/models/issue_test.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/foreignreference" + 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" @@ -132,7 +133,7 @@ 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, UpdateIssueCols(db.DefaultContext, issue, "name")) then := time.Now().Unix() updatedIssue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) @@ -568,3 +569,23 @@ func TestIssueForeignReference(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, found.Index, issue.Index) } + +func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + miles := issues_model.MilestoneList{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone), + } + + assert.NoError(t, miles.LoadTotalTrackedTimes()) + + assert.Equal(t, int64(3682), miles[0].TotalTrackedTime) +} + +func TestLoadTotalTrackedTime(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + + assert.NoError(t, milestone.LoadTotalTrackedTime()) + + assert.Equal(t, int64(3682), milestone.TotalTrackedTime) +} diff --git a/models/issue_tracked_time.go b/models/issue_tracked_time.go index 2d7bef19e1..e675c79193 100644 --- a/models/issue_tracked_time.go +++ b/models/issue_tracked_time.go @@ -53,7 +53,7 @@ func (t *TrackedTime) loadAttributes(ctx context.Context) (err error) { if err != nil { return } - err = t.Issue.loadRepo(ctx) + err = t.Issue.LoadRepo(ctx) if err != nil { return } @@ -170,11 +170,11 @@ func AddTime(user *user_model.User, issue *Issue, amount int64, created time.Tim return nil, err } - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return nil, err } - if _, err := createComment(ctx, &CreateCommentOptions{ + if _, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Issue: issue, Repo: issue.Repo, Doer: user, @@ -254,10 +254,10 @@ func DeleteIssueUserTimes(issue *Issue, user *user_model.User) error { return ErrNotExist{} } - if err := issue.loadRepo(ctx); err != nil { + if err := issue.LoadRepo(ctx); err != nil { return err } - if _, err := createComment(ctx, &CreateCommentOptions{ + if _, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Issue: issue, Repo: issue.Repo, Doer: user, @@ -286,7 +286,7 @@ func DeleteTime(t *TrackedTime) error { return err } - if _, err := createComment(ctx, &CreateCommentOptions{ + if _, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Issue: t.Issue, Repo: t.Issue.Repo, Doer: t.User, diff --git a/models/issue_xref.go b/models/issue_xref.go index 7b2f097c1c..405f1dae22 100644 --- a/models/issue_xref.go +++ b/models/issue_xref.go @@ -129,7 +129,7 @@ func (issue *Issue) createCrossReferences(stdCtx context.Context, ctx *crossRefe RefAction: xref.Action, RefIsPull: ctx.OrigIssue.IsPull, } - _, err := createComment(stdCtx, opts) + _, err := CreateCommentCtx(stdCtx, opts) if err != nil { return err } @@ -150,7 +150,7 @@ func (issue *Issue) getCrossReferences(stdCtx context.Context, ctx *crossReferen for _, ref := range allrefs { if ref.Owner == "" && ref.Name == "" { // Issues in the same repository - if err := ctx.OrigIssue.loadRepo(stdCtx); err != nil { + if err := ctx.OrigIssue.LoadRepo(stdCtx); err != nil { return nil, err } refRepo = ctx.OrigIssue.Repo @@ -204,7 +204,7 @@ func (issue *Issue) verifyReferencedIssue(stdCtx context.Context, ctx *crossRefe if has, _ := e.Get(refIssue); !has { return nil, references.XRefActionNone, nil } - if err := refIssue.loadRepo(stdCtx); err != nil { + if err := refIssue.LoadRepo(stdCtx); err != nil { return nil, references.XRefActionNone, err } @@ -282,7 +282,7 @@ func (comment *Comment) LoadRefIssue() (err error) { } comment.RefIssue, err = GetIssueByID(comment.RefIssueID) if err == nil { - err = comment.RefIssue.loadRepo(db.DefaultContext) + err = comment.RefIssue.LoadRepo(db.DefaultContext) } return } diff --git a/models/issues/main_test.go b/models/issues/main_test.go index 1c786d005f..bec6176abd 100644 --- a/models/issues/main_test.go +++ b/models/issues/main_test.go @@ -22,5 +22,6 @@ func TestMain(m *testing.M) { "reaction.yml", "user.yml", "repository.yml", + "milestone.yml", ) } diff --git a/models/issue_milestone.go b/models/issues/milestone.go index a321718513..07c38754d4 100644 --- a/models/issue_milestone.go +++ b/models/issues/milestone.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" @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" @@ -20,6 +19,26 @@ import ( "xorm.io/builder" ) +// ErrMilestoneNotExist represents a "MilestoneNotExist" kind of error. +type ErrMilestoneNotExist struct { + ID int64 + RepoID int64 + Name string +} + +// IsErrMilestoneNotExist checks if an error is a ErrMilestoneNotExist. +func IsErrMilestoneNotExist(err error) bool { + _, ok := err.(ErrMilestoneNotExist) + return ok +} + +func (err ErrMilestoneNotExist) Error() string { + if len(err.Name) > 0 { + return fmt.Sprintf("milestone does not exist [name: %s, repo_id: %d]", err.Name, err.RepoID) + } + return fmt.Sprintf("milestone does not exist [id: %d, repo_id: %d]", err.ID, err.RepoID) +} + // Milestone represents a milestone of repository. type Milestone struct { ID int64 `xorm:"pk autoincr"` @@ -105,9 +124,10 @@ func NewMilestone(m *Milestone) (err error) { return committer.Commit() } -func getMilestoneByRepoID(e db.Engine, repoID, id int64) (*Milestone, error) { +// GetMilestoneByRepoID returns the milestone in a repository. +func GetMilestoneByRepoID(ctx context.Context, repoID, id int64) (*Milestone, error) { m := new(Milestone) - has, err := e.ID(id).Where("repo_id=?", repoID).Get(m) + has, err := db.GetEngine(ctx).ID(id).Where("repo_id=?", repoID).Get(m) if err != nil { return nil, err } else if !has { @@ -116,11 +136,6 @@ func getMilestoneByRepoID(e db.Engine, repoID, id int64) (*Milestone, error) { return m, nil } -// GetMilestoneByRepoID returns the milestone in a repository. -func GetMilestoneByRepoID(repoID, id int64) (*Milestone, error) { - return getMilestoneByRepoID(db.GetEngine(db.DefaultContext), repoID, id) -} - // GetMilestoneByRepoIDANDName return a milestone if one exist by name and repo func GetMilestoneByRepoIDANDName(repoID int64, name string) (*Milestone, error) { var mile Milestone @@ -166,11 +181,11 @@ func updateMilestone(ctx context.Context, m *Milestone) error { if err != nil { return err } - return updateMilestoneCounters(ctx, m.ID) + return UpdateMilestoneCounters(ctx, m.ID) } -// updateMilestoneCounters calculates NumIssues, NumClosesIssues and Completeness -func updateMilestoneCounters(ctx context.Context, id int64) error { +// UpdateMilestoneCounters calculates NumIssues, NumClosesIssues and Completeness +func UpdateMilestoneCounters(ctx context.Context, id int64) error { e := db.GetEngine(ctx) _, err := e.ID(id). SetExpr("num_issues", builder.Select("count(*)").From("issue").Where( @@ -250,65 +265,9 @@ func changeMilestoneStatus(ctx context.Context, m *Milestone, isClosed bool) err return updateRepoMilestoneNum(ctx, m.RepoID) } -func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *Issue, oldMilestoneID int64) error { - if err := updateIssueCols(ctx, issue, "milestone_id"); err != nil { - return err - } - - if oldMilestoneID > 0 { - if err := updateMilestoneCounters(ctx, oldMilestoneID); err != nil { - return err - } - } - - if issue.MilestoneID > 0 { - if err := updateMilestoneCounters(ctx, issue.MilestoneID); err != nil { - return err - } - } - - if oldMilestoneID > 0 || issue.MilestoneID > 0 { - if err := issue.loadRepo(ctx); err != nil { - return err - } - - opts := &CreateCommentOptions{ - Type: CommentTypeMilestone, - Doer: doer, - Repo: issue.Repo, - Issue: issue, - OldMilestoneID: oldMilestoneID, - MilestoneID: issue.MilestoneID, - } - if _, err := createComment(ctx, opts); err != nil { - return err - } - } - - return nil -} - -// ChangeMilestoneAssign changes assignment of milestone for issue. -func ChangeMilestoneAssign(issue *Issue, doer *user_model.User, oldMilestoneID int64) (err error) { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err = changeMilestoneAssign(ctx, doer, issue, oldMilestoneID); err != nil { - return err - } - - if err = committer.Commit(); err != nil { - return fmt.Errorf("Commit: %v", err) - } - return nil -} - // DeleteMilestoneByRepoID deletes a milestone from a repository. func DeleteMilestoneByRepoID(repoID, id int64) error { - m, err := GetMilestoneByRepoID(repoID, id) + m, err := GetMilestoneByRepoID(db.DefaultContext, repoID, id) if err != nil { if IsErrMilestoneNotExist(err) { return nil diff --git a/models/issue_milestone_test.go b/models/issues/milestone_test.go index 6593f78fa1..09f51de45c 100644 --- a/models/issue_milestone_test.go +++ b/models/issues/milestone_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 import ( "sort" @@ -11,10 +11,8 @@ import ( "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" "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" @@ -25,28 +23,15 @@ func TestMilestone_State(t *testing.T) { assert.Equal(t, api.StateClosed, (&Milestone{IsClosed: true}).State()) } -func TestNewMilestone(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := &Milestone{ - RepoID: 1, - Name: "milestoneName", - Content: "milestoneContent", - } - - assert.NoError(t, NewMilestone(milestone)) - unittest.AssertExistsAndLoadBean(t, milestone) - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &Milestone{}) -} - func TestGetMilestoneByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - milestone, err := GetMilestoneByRepoID(1, 1) + milestone, err := GetMilestoneByRepoID(db.DefaultContext, 1, 1) assert.NoError(t, err) assert.EqualValues(t, 1, milestone.ID) assert.EqualValues(t, 1, milestone.RepoID) - _, err = GetMilestoneByRepoID(unittest.NonexistentID, unittest.NonexistentID) + _, err = GetMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) assert.True(t, IsErrMilestoneNotExist(err)) } @@ -160,18 +145,6 @@ func TestGetMilestones(t *testing.T) { }) } -func TestUpdateMilestone(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - milestone := unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone) - milestone.Name = " newMilestoneName " - milestone.Content = "newMilestoneContent" - assert.NoError(t, UpdateMilestone(milestone, milestone.IsClosed)) - milestone = unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone) - assert.EqualValues(t, "newMilestoneName", milestone.Name) - unittest.CheckConsistencyFor(t, &Milestone{}) -} - func TestCountRepoMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { @@ -206,78 +179,6 @@ func TestCountRepoClosedMilestones(t *testing.T) { assert.EqualValues(t, 0, count) } -func TestChangeMilestoneStatus(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone) - - assert.NoError(t, ChangeMilestoneStatus(milestone, true)) - unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}, "is_closed=1") - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &Milestone{}) - - assert.NoError(t, ChangeMilestoneStatus(milestone, false)) - unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}, "is_closed=0") - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &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, updateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) - unittest.CheckConsistencyFor(t, &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, updateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) - unittest.CheckConsistencyFor(t, &Milestone{}) -} - -func TestChangeMilestoneAssign(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{RepoID: 1}).(*Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - assert.NotNil(t, issue) - assert.NotNil(t, doer) - - oldMilestoneID := issue.MilestoneID - issue.MilestoneID = 2 - assert.NoError(t, ChangeMilestoneAssign(issue, doer, oldMilestoneID)) - unittest.AssertExistsAndLoadBean(t, &Comment{ - IssueID: issue.ID, - Type: CommentTypeMilestone, - MilestoneID: issue.MilestoneID, - OldMilestoneID: oldMilestoneID, - }) - unittest.CheckConsistencyFor(t, &Milestone{}, &Issue{}) -} - -func TestDeleteMilestoneByRepoID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, DeleteMilestoneByRepoID(1, 1)) - unittest.AssertNotExistsBean(t, &Milestone{ID: 1}) - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}) - - assert.NoError(t, DeleteMilestoneByRepoID(unittest.NonexistentID, unittest.NonexistentID)) -} - -func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - miles := MilestoneList{ - unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone), - } - - assert.NoError(t, miles.LoadTotalTrackedTimes()) - - assert.Equal(t, int64(3682), miles[0].TotalTrackedTime) -} - func TestCountMilestonesByRepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) milestonesCount := func(repoID int64) (int, int) { @@ -343,15 +244,6 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { }) } -func TestLoadTotalTrackedTime(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone) - - assert.NoError(t, milestone.LoadTotalTrackedTime()) - - assert.Equal(t, int64(3682), milestone.TotalTrackedTime) -} - func TestGetMilestonesStats(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) diff --git a/models/main_test.go b/models/main_test.go index 08cb2386c0..00da59cbe6 100644 --- a/models/main_test.go +++ b/models/main_test.go @@ -7,6 +7,7 @@ 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" @@ -29,7 +30,7 @@ func TestFixturesAreConsistent(t *testing.T) { &repo_model.Repository{}, &Issue{}, &PullRequest{}, - &Milestone{}, + &issues_model.Milestone{}, &Label{}, &organization.Team{}, &Action{}) diff --git a/models/migrate.go b/models/migrate.go index 2470fd4336..7b12bc9c93 100644 --- a/models/migrate.go +++ b/models/migrate.go @@ -8,13 +8,14 @@ import ( "context" "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. -func InsertMilestones(ms ...*Milestone) (err error) { +func InsertMilestones(ms ...*issues_model.Milestone) (err error) { if len(ms) == 0 { return nil } diff --git a/models/migrate_test.go b/models/migrate_test.go index 6da434d76a..ce28b3ca7c 100644 --- a/models/migrate_test.go +++ b/models/migrate_test.go @@ -8,6 +8,7 @@ import ( "strconv" "testing" + "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/foreignreference" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -22,7 +23,7 @@ func TestMigrate_InsertMilestones(t *testing.T) { reponame := "repo1" repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) name := "milestonetest1" - ms := &Milestone{ + ms := &issues_model.Milestone{ RepoID: repo.ID, Name: name, } @@ -32,7 +33,7 @@ func TestMigrate_InsertMilestones(t *testing.T) { repoModified := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}).(*repo_model.Repository) assert.EqualValues(t, repo.NumMilestones+1, repoModified.NumMilestones) - unittest.CheckConsistencyFor(t, &Milestone{}) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) } func assertCreateIssues(t *testing.T, isPull bool) { @@ -41,7 +42,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { 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) - milestone := unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) assert.EqualValues(t, milestone.ID, 1) reaction := &issues_model.Reaction{ Type: "heart", @@ -90,7 +91,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.LoadRepo() + _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) reaction := &issues_model.Reaction{ Type: "heart", diff --git a/models/notification.go b/models/notification.go index 9d0dc38aa4..a1248c240b 100644 --- a/models/notification.go +++ b/models/notification.go @@ -255,7 +255,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n } } - err = issue.loadRepo(ctx) + err = issue.LoadRepo(ctx) if err != nil { return err } diff --git a/models/pull.go b/models/pull.go index 6abd9f04b2..439005deb4 100644 --- a/models/pull.go +++ b/models/pull.go @@ -407,7 +407,7 @@ func (pr *PullRequest) SetMerged() (bool, error) { return false, fmt.Errorf("PullRequest[%d] already closed", pr.Index) } - if err := pr.Issue.loadRepo(ctx); err != nil { + if err := pr.Issue.LoadRepo(ctx); err != nil { return false, err } diff --git a/models/repo.go b/models/repo.go index 628a102ee2..5073d1ceb9 100644 --- a/models/repo.go +++ b/models/repo.go @@ -19,6 +19,7 @@ import ( admin_model "code.gitea.io/gitea/models/admin" asymkey_model "code.gitea.io/gitea/models/asymkey" "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" project_model "code.gitea.io/gitea/models/project" @@ -698,7 +699,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { &webhook.HookTask{RepoID: repoID}, &LFSLock{RepoID: repoID}, &repo_model.LanguageStat{RepoID: repoID}, - &Milestone{RepoID: repoID}, + &issues_model.Milestone{RepoID: repoID}, &repo_model.Mirror{RepoID: repoID}, &Notification{RepoID: repoID}, &ProtectedBranch{RepoID: repoID}, @@ -945,10 +946,6 @@ func labelStatsCorrectNumClosedIssuesRepo(ctx context.Context, id int64) error { var milestoneStatsQueryNumIssues = "SELECT `milestone`.id FROM `milestone` WHERE `milestone`.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE `issue`.milestone_id=`milestone`.id AND `issue`.is_closed=?) OR `milestone`.num_issues!=(SELECT COUNT(*) FROM `issue` WHERE `issue`.milestone_id=`milestone`.id)" -func milestoneStatsCorrectNumIssues(ctx context.Context, id int64) error { - return updateMilestoneCounters(ctx, id) -} - func milestoneStatsCorrectNumIssuesRepo(ctx context.Context, id int64) error { e := db.GetEngine(ctx) results, err := e.Query(milestoneStatsQueryNumIssues+" AND `milestone`.repo_id = ?", true, id) @@ -957,7 +954,7 @@ func milestoneStatsCorrectNumIssuesRepo(ctx context.Context, id int64) error { } for _, result := range results { id, _ := strconv.ParseInt(string(result["id"]), 10, 64) - err = milestoneStatsCorrectNumIssues(ctx, id) + err = issues_model.UpdateMilestoneCounters(ctx, id) if err != nil { return err } @@ -1049,7 +1046,7 @@ func CheckRepoStats(ctx context.Context) error { // Milestone.Num{,Closed}Issues { statsQuery(milestoneStatsQueryNumIssues, true), - milestoneStatsCorrectNumIssues, + issues_model.UpdateMilestoneCounters, "milestone count 'num_closed_issues' and 'num_issues'", }, // User.NumRepos diff --git a/models/review.go b/models/review.go index f360d459cf..51818bc722 100644 --- a/models/review.go +++ b/models/review.go @@ -427,7 +427,7 @@ func SubmitReview(doer *user_model.User, issue *Issue, reviewType ReviewType, co } } - comm, err := createComment(ctx, &CreateCommentOptions{ + comm, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Type: CommentTypeReview, Doer: doer, Content: review.Content, @@ -662,7 +662,7 @@ func AddReviewRequest(issue *Issue, reviewer, doer *user_model.User) (*Comment, return nil, err } - comment, err := createComment(ctx, &CreateCommentOptions{ + comment, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Type: CommentTypeReviewRequest, Doer: doer, Repo: issue.Repo, @@ -717,7 +717,7 @@ func RemoveReviewRequest(issue *Issue, reviewer, doer *user_model.User) (*Commen } } - comment, err := createComment(ctx, &CreateCommentOptions{ + comment, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Type: CommentTypeReviewRequest, Doer: doer, Repo: issue.Repo, @@ -776,7 +776,7 @@ func AddTeamReviewRequest(issue *Issue, reviewer *organization.Team, doer *user_ } } - comment, err := createComment(ctx, &CreateCommentOptions{ + comment, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Type: CommentTypeReviewRequest, Doer: doer, Repo: issue.Repo, @@ -786,7 +786,7 @@ func AddTeamReviewRequest(issue *Issue, reviewer *organization.Team, doer *user_ ReviewID: review.ID, }) if err != nil { - return nil, fmt.Errorf("createComment(): %v", err) + return nil, fmt.Errorf("CreateCommentCtx(): %v", err) } return comment, committer.Commit() @@ -837,7 +837,7 @@ func RemoveTeamReviewRequest(issue *Issue, reviewer *organization.Team, doer *us return nil, committer.Commit() } - comment, err := createComment(ctx, &CreateCommentOptions{ + comment, err := CreateCommentCtx(ctx, &CreateCommentOptions{ Type: CommentTypeReviewRequest, Doer: doer, Repo: issue.Repo, @@ -846,7 +846,7 @@ func RemoveTeamReviewRequest(issue *Issue, reviewer *organization.Team, doer *us AssigneeTeamID: reviewer.ID, // Use AssigneeTeamID as reviewer team ID }) if err != nil { - return nil, fmt.Errorf("createComment(): %v", err) + return nil, fmt.Errorf("CreateCommentCtx(): %v", err) } return comment, committer.Commit() @@ -887,7 +887,7 @@ func CanMarkConversation(issue *Issue, doer *user_model.User) (permResult bool, } if doer.ID != issue.PosterID { - if err = issue.LoadRepo(); err != nil { + if err = issue.LoadRepo(db.DefaultContext); err != nil { return false, err } diff --git a/models/statistic.go b/models/statistic.go index a63cc2878b..87c1bd6d75 100644 --- a/models/statistic.go +++ b/models/statistic.go @@ -8,6 +8,7 @@ import ( asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" + 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" @@ -102,7 +103,7 @@ func GetStatistic() (stats Statistic) { stats.Counter.Release, _ = e.Count(new(Release)) stats.Counter.AuthSource = auth.CountSources() stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook)) - stats.Counter.Milestone, _ = e.Count(new(Milestone)) + stats.Counter.Milestone, _ = e.Count(new(issues_model.Milestone)) stats.Counter.Label, _ = e.Count(new(Label)) stats.Counter.HookTask, _ = e.Count(new(webhook.HookTask)) stats.Counter.Team, _ = e.Count(new(organization.Team)) |