diff options
Diffstat (limited to 'models/issue.go')
-rw-r--r-- | models/issue.go | 259 |
1 files changed, 30 insertions, 229 deletions
diff --git a/models/issue.go b/models/issue.go index 32645463..94998d78 100644 --- a/models/issue.go +++ b/models/issue.go @@ -17,11 +17,11 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" + gouuid "github.com/satori/go.uuid" "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" - gouuid "github.com/gogits/gogs/modules/uuid" ) var ( @@ -218,7 +218,7 @@ func (i *Issue) ReadBy(uid int64) error { return UpdateIssueUserByRead(uid, i.ID) } -func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err error) { +func (i *Issue) changeStatus(e *xorm.Session, doer *User, repo *Repository, isClosed bool) (err error) { if i.IsClosed == isClosed { return nil } @@ -251,7 +251,7 @@ func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err er } // New action comment. - if _, err = createStatusComment(e, doer, i.Repo, i); err != nil { + if _, err = createStatusComment(e, doer, repo, i); err != nil { return err } @@ -259,14 +259,14 @@ func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err er } // ChangeStatus changes issue status to open/closed. -func (i *Issue) ChangeStatus(doer *User, isClosed bool) (err error) { +func (i *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (err error) { sess := x.NewSession() defer sessionRelease(sess) if err = sess.Begin(); err != nil { return err } - if err = i.changeStatus(sess, doer, isClosed); err != nil { + if err = i.changeStatus(sess, doer, repo, isClosed); err != nil { return err } @@ -364,7 +364,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) ActUserID: issue.Poster.Id, ActUserName: issue.Poster.Name, ActEmail: issue.Poster.Email, - OpType: CREATE_ISSUE, + OpType: ACTION_CREATE_ISSUE, Content: fmt.Sprintf("%d|%s", issue.Index, issue.Name), RepoID: repo.ID, RepoUserName: repo.Owner.Name, @@ -934,213 +934,6 @@ func UpdateIssueUsersByMentions(uids []int64, iid int64) error { return nil } -// .____ ___. .__ -// | | _____ \_ |__ ____ | | -// | | \__ \ | __ \_/ __ \| | -// | |___ / __ \| \_\ \ ___/| |__ -// |_______ (____ /___ /\___ >____/ -// \/ \/ \/ \/ - -// Label represents a label of repository for issues. -type Label struct { - ID int64 `xorm:"pk autoincr"` - RepoID int64 `xorm:"INDEX"` - Name string - Color string `xorm:"VARCHAR(7)"` - NumIssues int - NumClosedIssues int - NumOpenIssues int `xorm:"-"` - IsChecked bool `xorm:"-"` -} - -// CalOpenIssues calculates the open issues of label. -func (m *Label) CalOpenIssues() { - m.NumOpenIssues = m.NumIssues - m.NumClosedIssues -} - -// NewLabel creates new label of repository. -func NewLabel(l *Label) error { - _, err := x.Insert(l) - return err -} - -func getLabelByID(e Engine, id int64) (*Label, error) { - if id <= 0 { - return nil, ErrLabelNotExist{id} - } - - l := &Label{ID: id} - has, err := x.Get(l) - if err != nil { - return nil, err - } else if !has { - return nil, ErrLabelNotExist{l.ID} - } - return l, nil -} - -// GetLabelByID returns a label by given ID. -func GetLabelByID(id int64) (*Label, error) { - return getLabelByID(x, id) -} - -// GetLabelsByRepoID returns all labels that belong to given repository by ID. -func GetLabelsByRepoID(repoID int64) ([]*Label, error) { - labels := make([]*Label, 0, 10) - return labels, x.Where("repo_id=?", repoID).Find(&labels) -} - -func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) { - issueLabels, err := getIssueLabels(e, issueID) - if err != nil { - return nil, fmt.Errorf("getIssueLabels: %v", err) - } - - var label *Label - labels := make([]*Label, 0, len(issueLabels)) - for idx := range issueLabels { - label, err = getLabelByID(e, issueLabels[idx].LabelID) - if err != nil && !IsErrLabelNotExist(err) { - return nil, fmt.Errorf("getLabelByID: %v", err) - } - labels = append(labels, label) - } - return labels, nil -} - -// GetLabelsByIssueID returns all labels that belong to given issue by ID. -func GetLabelsByIssueID(issueID int64) ([]*Label, error) { - return getLabelsByIssueID(x, issueID) -} - -func updateLabel(e Engine, l *Label) error { - _, err := e.Id(l.ID).AllCols().Update(l) - return err -} - -// UpdateLabel updates label information. -func UpdateLabel(l *Label) error { - return updateLabel(x, l) -} - -// DeleteLabel delete a label of given repository. -func DeleteLabel(repoID, labelID int64) error { - l, err := GetLabelByID(labelID) - if err != nil { - if IsErrLabelNotExist(err) { - return nil - } - return err - } - - sess := x.NewSession() - defer sessionRelease(sess) - if err = sess.Begin(); err != nil { - return err - } - - if _, err = x.Where("label_id=?", labelID).Delete(new(IssueLabel)); err != nil { - return err - } else if _, err = sess.Delete(l); err != nil { - return err - } - return sess.Commit() -} - -// .___ .____ ___. .__ -// | | ______ ________ __ ____ | | _____ \_ |__ ____ | | -// | |/ ___// ___/ | \_/ __ \| | \__ \ | __ \_/ __ \| | -// | |\___ \ \___ \| | /\ ___/| |___ / __ \| \_\ \ ___/| |__ -// |___/____ >____ >____/ \___ >_______ (____ /___ /\___ >____/ -// \/ \/ \/ \/ \/ \/ \/ - -// IssueLabel represetns an issue-lable relation. -type IssueLabel struct { - ID int64 `xorm:"pk autoincr"` - IssueID int64 `xorm:"UNIQUE(s)"` - LabelID int64 `xorm:"UNIQUE(s)"` -} - -func hasIssueLabel(e Engine, issueID, labelID int64) bool { - has, _ := e.Where("issue_id=? AND label_id=?", issueID, labelID).Get(new(IssueLabel)) - return has -} - -// HasIssueLabel returns true if issue has been labeled. -func HasIssueLabel(issueID, labelID int64) bool { - return hasIssueLabel(x, issueID, labelID) -} - -func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) { - if _, err = e.Insert(&IssueLabel{ - IssueID: issue.ID, - LabelID: label.ID, - }); err != nil { - return err - } - - label.NumIssues++ - if issue.IsClosed { - label.NumClosedIssues++ - } - return updateLabel(e, label) -} - -// NewIssueLabel creates a new issue-label relation. -func NewIssueLabel(issue *Issue, label *Label) (err error) { - sess := x.NewSession() - defer sessionRelease(sess) - if err = sess.Begin(); err != nil { - return err - } - - if err = newIssueLabel(sess, issue, label); err != nil { - return err - } - - return sess.Commit() -} - -func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) { - issueLabels := make([]*IssueLabel, 0, 10) - return issueLabels, e.Where("issue_id=?", issueID).Asc("label_id").Find(&issueLabels) -} - -// GetIssueLabels returns all issue-label relations of given issue by ID. -func GetIssueLabels(issueID int64) ([]*IssueLabel, error) { - return getIssueLabels(x, issueID) -} - -func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) { - if _, err = e.Delete(&IssueLabel{ - IssueID: issue.ID, - LabelID: label.ID, - }); err != nil { - return err - } - - label.NumIssues-- - if issue.IsClosed { - label.NumClosedIssues-- - } - return updateLabel(e, label) -} - -// DeleteIssueLabel deletes issue-label relation. -func DeleteIssueLabel(issue *Issue, label *Label) (err error) { - sess := x.NewSession() - defer sessionRelease(sess) - if err = sess.Begin(); err != nil { - return err - } - - if err = deleteIssueLabel(sess, issue, label); err != nil { - return err - } - - return sess.Commit() -} - // _____ .__.__ __ // / \ |__| | ____ _______/ |_ ____ ____ ____ // / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \ @@ -1564,9 +1357,24 @@ func createComment(e *xorm.Session, u *User, repo *Repository, issue *Issue, com return nil, err } + // Compose comment action, could be plain comment, close or reopen issue. + // This object will be used to notify watchers in the end of function. + act := &Action{ + ActUserID: u.Id, + ActUserName: u.Name, + ActEmail: u.Email, + Content: fmt.Sprintf("%d|%s", issue.Index, strings.Split(content, "\n")[0]), + RepoID: repo.ID, + RepoUserName: repo.Owner.Name, + RepoName: repo.Name, + IsPrivate: repo.IsPrivate, + } + // Check comment type. switch cmtType { case COMMENT_TYPE_COMMENT: + act.OpType = ACTION_COMMENT_ISSUE + if _, err = e.Exec("UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", issue.ID); err != nil { return nil, err } @@ -1593,23 +1401,9 @@ func createComment(e *xorm.Session, u *User, repo *Repository, issue *Issue, com } } - // Notify watchers. - act := &Action{ - ActUserID: u.Id, - ActUserName: u.Name, - ActEmail: u.Email, - OpType: COMMENT_ISSUE, - Content: fmt.Sprintf("%d|%s", issue.Index, strings.Split(content, "\n")[0]), - RepoID: repo.ID, - RepoUserName: repo.Owner.Name, - RepoName: repo.Name, - IsPrivate: repo.IsPrivate, - } - if err = notifyWatchers(e, act); err != nil { - return nil, err - } - case COMMENT_TYPE_REOPEN: + act.OpType = ACTION_REOPEN_ISSUE + if issue.IsPull { _, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls-1 WHERE id=?", repo.ID) } else { @@ -1619,6 +1413,8 @@ func createComment(e *xorm.Session, u *User, repo *Repository, issue *Issue, com return nil, err } case COMMENT_TYPE_CLOSE: + act.OpType = ACTION_CLOSE_ISSUE + if issue.IsPull { _, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls+1 WHERE id=?", repo.ID) } else { @@ -1629,6 +1425,11 @@ func createComment(e *xorm.Session, u *User, repo *Repository, issue *Issue, com } } + // Notify watchers for whatever action comes in. + if err = notifyWatchers(e, act); err != nil { + return nil, fmt.Errorf("notifyWatchers: %v", err) + } + return comment, nil } |