aboutsummaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorUnknwon <u@gogs.io>2015-09-01 19:07:02 -0400
committerUnknwon <u@gogs.io>2015-09-01 19:07:02 -0400
commit8c046073a891e3a192794869628763ef072002eb (patch)
treea5de325078531c330da64f8361d43184fee894d3 /models
parent63fecac537298109253bc00c256336e942f73481 (diff)
downloadgitea-8c046073a891e3a192794869628763ef072002eb.tar.gz
gitea-8c046073a891e3a192794869628763ef072002eb.zip
work on PR conversation
Diffstat (limited to 'models')
-rw-r--r--models/error.go21
-rw-r--r--models/issue.go190
-rw-r--r--models/models.go4
-rw-r--r--models/repo.go29
4 files changed, 182 insertions, 62 deletions
diff --git a/models/error.go b/models/error.go
index a7c8f5def3..4d888c870b 100644
--- a/models/error.go
+++ b/models/error.go
@@ -281,6 +281,27 @@ 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)
}
+// __________ .__ .__ __________ __
+// \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_
+// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
+// | | | | / |_| |_| | \ ___< <_| | | /\ ___/ \___ \ | |
+// |____| |____/|____/____/____|_ /\___ >__ |____/ \___ >____ > |__|
+// \/ \/ |__| \/ \/
+
+type ErrPullRepoNotExist struct {
+ ID int64
+ PullID int64
+}
+
+func IsErrPullRepoNotExist(err error) bool {
+ _, ok := err.(ErrPullRepoNotExist)
+ return ok
+}
+
+func (err ErrPullRepoNotExist) Error() string {
+ return fmt.Sprintf("pull repo does not exist [id: %d, pull_id: %d]", err.ID, err.PullID)
+}
+
// _________ __
// \_ ___ \ ____ _____ _____ ____ _____/ |_
// / \ \/ / _ \ / \ / \_/ __ \ / \ __\
diff --git a/models/issue.go b/models/issue.go
index 28f37bf82c..e9eeb4889e 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"io"
+ "io/ioutil"
"mime/multipart"
"os"
"path"
@@ -21,6 +22,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
+ "github.com/gogits/gogs/modules/process"
"github.com/gogits/gogs/modules/setting"
gouuid "github.com/gogits/gogs/modules/uuid"
)
@@ -44,9 +46,10 @@ type Issue struct {
MilestoneID int64
Milestone *Milestone `xorm:"-"`
AssigneeID int64
- Assignee *User `xorm:"-"`
- IsRead bool `xorm:"-"`
- IsPull bool // Indicates whether is a pull request or not.
+ Assignee *User `xorm:"-"`
+ IsRead bool `xorm:"-"`
+ IsPull bool // Indicates whether is a pull request or not.
+ PullRepo *PullRepo `xorm:"-"`
IsClosed bool
Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"`
@@ -92,6 +95,11 @@ func (i *Issue) AfterSet(colName string, _ xorm.Cell) {
if err != nil {
log.Error(3, "GetUserByID[%d]: %v", i.ID, err)
}
+ case "is_pull":
+ i.PullRepo, err = GetPullRepoByPullID(i.ID)
+ if err != nil {
+ log.Error(3, "GetPullRepoByPullID[%d]: %v", i.ID, err)
+ }
case "created":
i.Created = regulateTimeZone(i.Created)
}
@@ -273,30 +281,11 @@ func (i *Issue) ChangeStatus(doer *User, isClosed bool) (err error) {
return sess.Commit()
}
-// CreateIssue creates new issue with labels for repository.
-func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
- // Check attachments.
- attachments := make([]*Attachment, 0, len(uuids))
- for _, uuid := range uuids {
- attach, err := GetAttachmentByUUID(uuid)
- if err != nil {
- if IsErrAttachmentNotExist(err) {
- continue
- }
- return fmt.Errorf("GetAttachmentByUUID[%s]: %v", uuid, err)
- }
- attachments = append(attachments, attach)
- }
-
- sess := x.NewSession()
- defer sessionRelease(sess)
- if err = sess.Begin(); err != nil {
- return err
- }
-
- if _, err = sess.Insert(issue); err != nil {
+// It's caller's responsibility to create action.
+func newIssue(e *xorm.Session, repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
+ if _, err = e.Insert(issue); err != nil {
return err
- } else if _, err = sess.Exec("UPDATE `repository` SET num_issues=num_issues+1 WHERE id=?", issue.RepoID); err != nil {
+ } else if _, err = e.Exec("UPDATE `repository` SET num_issues=num_issues+1 WHERE id=?", issue.RepoID); err != nil {
return err
}
@@ -306,34 +295,62 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
continue
}
- label, err = getLabelByID(sess, id)
+ label, err = getLabelByID(e, id)
if err != nil {
return err
}
- if err = issue.addLabel(sess, label); err != nil {
+ if err = issue.addLabel(e, label); err != nil {
return fmt.Errorf("addLabel: %v", err)
}
}
if issue.MilestoneID > 0 {
- if err = changeMilestoneAssign(sess, 0, issue); err != nil {
+ if err = changeMilestoneAssign(e, 0, issue); err != nil {
return err
}
}
- if err = newIssueUsers(sess, repo, issue); err != nil {
+ if err = newIssueUsers(e, repo, issue); err != nil {
return err
}
+ // Check attachments.
+ attachments := make([]*Attachment, 0, len(uuids))
+ for _, uuid := range uuids {
+ attach, err := getAttachmentByUUID(e, uuid)
+ if err != nil {
+ if IsErrAttachmentNotExist(err) {
+ continue
+ }
+ return fmt.Errorf("getAttachmentByUUID[%s]: %v", uuid, err)
+ }
+ attachments = append(attachments, attach)
+ }
+
for i := range attachments {
attachments[i].IssueID = issue.ID
// No assign value could be 0, so ignore AllCols().
- if _, err = sess.Id(attachments[i].ID).Update(attachments[i]); err != nil {
+ if _, err = e.Id(attachments[i].ID).Update(attachments[i]); err != nil {
return fmt.Errorf("update attachment[%d]: %v", attachments[i].ID, err)
}
}
+ return nil
+}
+
+// NewIssue creates new issue with labels for repository.
+func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
+ sess := x.NewSession()
+ defer sessionRelease(sess)
+ if err = sess.Begin(); err != nil {
+ return err
+ }
+
+ if err = newIssue(sess, repo, issue, labelIDs, uuids); err != nil {
+ return fmt.Errorf("newIssue: %v", err)
+ }
+
// Notify watchers.
act := &Action{
ActUserID: issue.Poster.Id,
@@ -813,6 +830,117 @@ func UpdateIssueUsersByMentions(uids []int64, iid int64) error {
return nil
}
+// __________ .__ .__ __________ __
+// \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_
+// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
+// | | | | / |_| |_| | \ ___< <_| | | /\ ___/ \___ \ | |
+// |____| |____/|____/____/____|_ /\___ >__ |____/ \___ >____ > |__|
+// \/ \/ |__| \/ \/
+
+type PullRequestType int
+
+const (
+ PULL_REQUEST_GOGS = iota
+ PLLL_ERQUEST_GIT
+)
+
+// PullRepo represents relation between pull request and repositories.
+type PullRepo struct {
+ ID int64 `xorm:"pk autoincr"`
+ PullID int64 `xorm:"INDEX"`
+ HeadRepoID int64 `xorm:"UNIQUE(s)"`
+ HeadRepo *Repository `xorm:"-"`
+ BaseRepoID int64 `xorm:"UNIQUE(s)"`
+ HeadBarcnh string `xorm:"UNIQUE(s)"`
+ BaseBranch string `xorm:"UNIQUE(s)"`
+ MergeBase string `xorm:"VARCHAR(40)"`
+ Type PullRequestType
+ CanAutoMerge bool
+}
+
+func (pr *PullRepo) AfterSet(colName string, _ xorm.Cell) {
+ var err error
+ switch colName {
+ case "head_repo_id":
+ pr.HeadRepo, err = GetRepositoryByID(pr.HeadRepoID)
+ if err != nil {
+ log.Error(3, "GetRepositoryByID[%d]: %v", pr.ID, err)
+ }
+ }
+}
+
+// NewPullRequest creates new pull request with labels for repository.
+func NewPullRequest(repo *Repository, pr *Issue, labelIDs []int64, uuids []string, pullRepo *PullRepo, patch []byte) (err error) {
+
+ sess := x.NewSession()
+ defer sessionRelease(sess)
+ if err = sess.Begin(); err != nil {
+ return err
+ }
+
+ if err = newIssue(sess, repo, pr, labelIDs, uuids); err != nil {
+ return fmt.Errorf("newIssue: %v", err)
+ }
+
+ // Notify watchers.
+ act := &Action{
+ ActUserID: pr.Poster.Id,
+ ActUserName: pr.Poster.Name,
+ ActEmail: pr.Poster.Email,
+ OpType: PULL_REQUEST,
+ Content: fmt.Sprintf("%d|%s", pr.Index, pr.Name),
+ RepoID: repo.ID,
+ RepoUserName: repo.Owner.Name,
+ RepoName: repo.Name,
+ IsPrivate: repo.IsPrivate,
+ }
+ if err = notifyWatchers(sess, act); err != nil {
+ return err
+ }
+
+ // Test apply patch.
+ repoPath, err := repo.RepoPath()
+ if err != nil {
+ return fmt.Errorf("RepoPath: %v", err)
+ }
+ patchPath := path.Join(repoPath, "pulls", com.ToStr(pr.ID)+".patch")
+
+ os.MkdirAll(path.Dir(patchPath), os.ModePerm)
+ if err = ioutil.WriteFile(patchPath, patch, 0644); err != nil {
+ return fmt.Errorf("save patch: %v", err)
+ }
+ defer os.Remove(patchPath)
+
+ stdout, stderr, err := process.ExecDir(-1, repoPath,
+ fmt.Sprintf("NewPullRequest(git apply --check): %d", repo.ID),
+ "git", "apply", "--check", "-v", patchPath)
+ if err != nil {
+ if strings.Contains(stderr, "fatal:") {
+ return fmt.Errorf("git apply --check: %v - %s", err, stderr)
+ }
+ }
+ pullRepo.CanAutoMerge = !strings.Contains(stdout, "error: patch failed:")
+
+ pullRepo.PullID = pr.ID
+ if _, err = sess.Insert(pullRepo); err != nil {
+ return fmt.Errorf("insert pull repo: %v", err)
+ }
+
+ return sess.Commit()
+}
+
+// GetPullRepoByPullID returns pull repo by given pull ID.
+func GetPullRepoByPullID(pullID int64) (*PullRepo, error) {
+ pullRepo := new(PullRepo)
+ has, err := x.Where("pull_id=?", pullID).Get(pullRepo)
+ if err != nil {
+ return nil, err
+ } else if !has {
+ return nil, ErrPullRepoNotExist{0, pullID}
+ }
+ return pullRepo, nil
+}
+
// .____ ___. .__
// | | _____ \_ |__ ____ | |
// | | \__ \ | __ \_/ __ \| |
diff --git a/models/models.go b/models/models.go
index 55b8e01dec..791018f8e5 100644
--- a/models/models.go
+++ b/models/models.go
@@ -78,8 +78,8 @@ func init() {
tables = append(tables,
new(User), new(PublicKey), new(Oauth2), new(AccessToken),
new(Repository), new(DeployKey), new(Collaboration), new(Access),
- new(Watch), new(Star), new(ForkInfo), new(Follow), new(Action),
- new(Issue), new(Comment), new(Attachment), new(IssueUser),
+ new(Watch), new(Star), new(Follow), new(Action),
+ new(Issue), new(PullRepo), new(Comment), new(Attachment), new(IssueUser),
new(Label), new(IssueLabel), new(Milestone),
new(Mirror), new(Release), new(LoginSource), new(Webhook),
new(UpdateTask), new(HookTask),
diff --git a/models/repo.go b/models/repo.go
index 10854ab5e8..ec6dfbfcbf 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -160,7 +160,6 @@ type Repository struct {
IsFork bool `xorm:"NOT NULL DEFAULT false"`
ForkID int64
BaseRepo *Repository `xorm:"-"`
- ForkInfo *ForkInfo `xorm:"-"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
@@ -168,15 +167,6 @@ type Repository struct {
func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
switch colName {
- case "is_fork":
- forkInfo := new(ForkInfo)
- has, err := x.Where("repo_id=?", repo.ID).Get(forkInfo)
- if err != nil {
- log.Error(3, "get fork in[%d]: %v", repo.ID, err)
- return
- } else if has {
- repo.ForkInfo = forkInfo
- }
case "updated":
repo.Updated = regulateTimeZone(repo.Updated)
}
@@ -1047,8 +1037,6 @@ func DeleteRepository(uid, repoID int64) error {
if repo.IsFork {
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks-1 WHERE id=?", repo.ForkID); err != nil {
return fmt.Errorf("decrease fork count: %v", err)
- } else if _, err = sess.Delete(&ForkInfo{RepoID: repo.ID}); err != nil {
- return fmt.Errorf("delete fork info: %v", err)
}
}
@@ -1095,9 +1083,6 @@ func DeleteRepository(uid, repoID int64) error {
if _, err = x.Exec("UPDATE `repository` SET fork_id=0,is_fork=? WHERE fork_id=?", false, repo.ID); err != nil {
log.Error(4, "reset 'fork_id' and 'is_fork': %v", err)
}
- if _, err = x.Delete(&ForkInfo{ForkID: repo.ID}); err != nil {
- log.Error(4, "clear fork infos: %v", err)
- }
}
}
@@ -1669,13 +1654,6 @@ func IsStaring(uid, repoId int64) bool {
// \___ / \____/|__| |__|_ \
// \/ \/
-type ForkInfo struct {
- ID int64 `xorm:"pk autoincr"`
- ForkID int64
- RepoID int64 `xorm:"UNIQUE"`
- StartCommitID string `xorm:"VARCHAR(40)"`
-}
-
// HasForkedRepo checks if given user has already forked a repository with given ID.
func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
repo := new(Repository)
@@ -1709,13 +1687,6 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.ID); err != nil {
return nil, err
}
- // else if _, err = sess.Insert(&ForkInfo{
- // ForkID: oldRepo.ID,
- // RepoID: repo.ID,
- // StartCommitID: "",
- // }); err != nil {
- // return nil, fmt.Errorf("insert fork info: %v", err)
- // }
oldRepoPath, err := oldRepo.RepoPath()
if err != nil {