diff options
author | kolaente <konrad@kola-entertainments.de> | 2018-07-17 23:23:58 +0200 |
---|---|---|
committer | techknowlogick <techknowlogick@users.noreply.github.com> | 2018-07-17 17:23:58 -0400 |
commit | 1bff02de55331e11de3627d5c5628feb2cd97387 (patch) | |
tree | d6d6ace5f246c1555b294bf096763260f7d74d7b /models/issue_dependency.go | |
parent | 7be5935c55dcdf198efdf1306bbeb2b54aa0b900 (diff) | |
download | gitea-1bff02de55331e11de3627d5c5628feb2cd97387.tar.gz gitea-1bff02de55331e11de3627d5c5628feb2cd97387.zip |
Added dependencies for issues (#2196) (#2531)
Diffstat (limited to 'models/issue_dependency.go')
-rw-r--r-- | models/issue_dependency.go | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/models/issue_dependency.go b/models/issue_dependency.go new file mode 100644 index 0000000000..157e9257c4 --- /dev/null +++ b/models/issue_dependency.go @@ -0,0 +1,137 @@ +// Copyright 2018 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 ( + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" +) + +// IssueDependency represents an issue dependency +type IssueDependency struct { + ID int64 `xorm:"pk autoincr"` + UserID int64 `xorm:"NOT NULL"` + IssueID int64 `xorm:"UNIQUE(issue_dependency) NOT NULL"` + DependencyID int64 `xorm:"UNIQUE(issue_dependency) NOT NULL"` + CreatedUnix util.TimeStamp `xorm:"created"` + UpdatedUnix util.TimeStamp `xorm:"updated"` +} + +// DependencyType Defines Dependency Type Constants +type DependencyType int + +// Define Dependency Types +const ( + DependencyTypeBlockedBy DependencyType = iota + DependencyTypeBlocking +) + +// CreateIssueDependency creates a new dependency for an issue +func CreateIssueDependency(user *User, issue, dep *Issue) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + // Check if it aleready exists + exists, err := issueDepExists(sess, issue.ID, dep.ID) + if err != nil { + return err + } + if exists { + return ErrDependencyExists{issue.ID, dep.ID} + } + // And if it would be circular + circular, err := issueDepExists(sess, dep.ID, issue.ID) + if err != nil { + return err + } + if circular { + return ErrCircularDependency{issue.ID, dep.ID} + } + + if _, err := sess.Insert(&IssueDependency{ + UserID: user.ID, + IssueID: issue.ID, + DependencyID: dep.ID, + }); err != nil { + return err + } + + // Add comment referencing the new dependency + if err = createIssueDependencyComment(sess, user, issue, dep, true); err != nil { + return err + } + + return sess.Commit() +} + +// RemoveIssueDependency removes a dependency from an issue +func RemoveIssueDependency(user *User, issue *Issue, dep *Issue, depType DependencyType) (err error) { + sess := x.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return err + } + + var issueDepToDelete IssueDependency + + switch depType { + case DependencyTypeBlockedBy: + issueDepToDelete = IssueDependency{IssueID: issue.ID, DependencyID: dep.ID} + case DependencyTypeBlocking: + issueDepToDelete = IssueDependency{IssueID: dep.ID, DependencyID: issue.ID} + default: + return ErrUnknownDependencyType{depType} + } + + affected, err := sess.Delete(&issueDepToDelete) + if err != nil { + return err + } + + // If we deleted nothing, the dependency did not exist + if affected <= 0 { + return ErrDependencyNotExists{issue.ID, dep.ID} + } + + // Add comment referencing the removed dependency + if err = createIssueDependencyComment(sess, user, issue, dep, false); err != nil { + return err + } + return sess.Commit() +} + +// Check if the dependency already exists +func issueDepExists(e Engine, issueID int64, depID int64) (bool, error) { + return e.Where("(issue_id = ? AND dependency_id = ?)", issueID, depID).Exist(&IssueDependency{}) +} + +// IssueNoDependenciesLeft checks if issue can be closed +func IssueNoDependenciesLeft(issue *Issue) (bool, error) { + + exists, err := x. + Table("issue_dependency"). + Select("issue.*"). + Join("INNER", "issue", "issue.id = issue_dependency.dependency_id"). + Where("issue_dependency.issue_id = ?", issue.ID). + And("issue.is_closed = ?", "0"). + Exist(&Issue{}) + + return !exists, err +} + +// IsDependenciesEnabled returns if dependecies are enabled and returns the default setting if not set. +func (repo *Repository) IsDependenciesEnabled() bool { + var u *RepoUnit + var err error + if u, err = repo.GetUnit(UnitTypeIssues); err != nil { + log.Trace("%s", err) + return setting.Service.DefaultEnableDependencies + } + return u.IssuesConfig().EnableDependencies +} |