diff --git a/.gopmfile b/.gopmfile index 590eab7b59..12c4287b18 100644 --- a/.gopmfile +++ b/.gopmfile @@ -19,7 +19,7 @@ github.com/go-xorm/xorm = commit:c6c7056 github.com/gogits/chardet = commit:2404f77 github.com/gogits/cron = commit:7f3990a github.com/gogits/git-module = commit:f78bf3b -github.com/gogits/go-gogs-client = commit:e363d3f +github.com/gogits/go-gogs-client = commit:51c4df8 github.com/issue9/identicon = commit:d36b545 github.com/jaytaylor/html2text = commit:52d9b78 github.com/kardianos/minwinsvc = commit:cad6b2b diff --git a/README.md b/README.md index 89069f1e5c..a9443aa852 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra ![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true) -##### Current tip version: 0.9.81 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions) +##### Current tip version: 0.9.82 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions) | Web | UI | Preview | |:-------------:|:-------:|:-------:| diff --git a/cmd/web.go b/cmd/web.go index b581f95836..b211e97c22 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -88,8 +88,8 @@ func checkVersion() { {"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"}, {"gopkg.in/ini.v1", ini.Version, "1.8.4"}, {"gopkg.in/macaron.v1", macaron.Version, "1.1.7"}, - {"github.com/gogits/git-module", git.Version, "0.3.6"}, - {"github.com/gogits/go-gogs-client", gogs.Version, "0.12.0"}, + {"github.com/gogits/git-module", git.Version, "0.3.7"}, + {"github.com/gogits/go-gogs-client", gogs.Version, "0.12.1"}, } for _, c := range checkers { if !version.Compare(c.Version(), c.Expected, ">=") { diff --git a/glide.lock b/glide.lock index 7dae885254..0b21f0c4b1 100644 --- a/glide.lock +++ b/glide.lock @@ -43,7 +43,7 @@ imports: - name: github.com/gogits/git-module version: f78bf3bf703cb3eb0e85a9475d26826939feda4f - name: github.com/gogits/go-gogs-client - version: e363d3ff8f70d0fe813324eedf228684af41c29c + version: 51c4df8c350b32f095c8eb236aae2e306025eead - name: github.com/issue9/identicon version: d36b54562f4cf70c83653e13dc95c220c79ef521 - name: github.com/jaytaylor/html2text diff --git a/gogs.go b/gogs.go index 5455eb2cd1..2c3686321e 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.9.81.0816" +const APP_VER = "0.9.82.0816" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/action.go b/models/action.go index f28aef9b5d..8ac599c0e1 100644 --- a/models/action.go +++ b/models/action.go @@ -520,7 +520,7 @@ func CommitRepoAction( Before: oldCommitID, After: newCommitID, CompareURL: setting.AppUrl + commit.CompareURL, - Commits: commit.ToApiPayloadCommits(repo.FullLink()), + Commits: commit.ToApiPayloadCommits(repo.HTMLURL()), Repo: apiRepo, Pusher: apiPusher, Sender: apiPusher, diff --git a/models/issue.go b/models/issue.go index 9b9dedb693..53f5b04f85 100644 --- a/models/issue.go +++ b/models/issue.go @@ -32,23 +32,23 @@ var ( type Issue struct { ID int64 `xorm:"pk autoincr"` RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"` - Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository. - Title string `xorm:"name"` Repo *Repository `xorm:"-"` + Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository. PosterID int64 Poster *User `xorm:"-"` + Title string `xorm:"name"` + Content string `xorm:"TEXT"` + RenderedContent string `xorm:"-"` Labels []*Label `xorm:"-"` MilestoneID int64 Milestone *Milestone `xorm:"-"` + Priority int AssigneeID int64 Assignee *User `xorm:"-"` - IsRead bool `xorm:"-"` - IsPull bool // Indicates whether is a pull request or not. - *PullRequest `xorm:"-"` IsClosed bool - Content string `xorm:"TEXT"` - RenderedContent string `xorm:"-"` - Priority int + IsRead bool `xorm:"-"` + IsPull bool // Indicates whether is a pull request or not. + PullRequest *PullRequest `xorm:"-"` NumComments int Deadline time.Time `xorm:"-"` @@ -155,6 +155,16 @@ func (issue *Issue) LoadAttributes() error { return issue.loadAttributes(x) } +func (issue *Issue) HTMLURL() string { + var path string + if issue.IsPull { + path = "pulls" + } else { + path = "issues" + } + return fmt.Sprintf("%s/%s/%d", issue.Repo.HTMLURL(), path, issue.Index) +} + // State returns string representation of issue status. func (i *Issue) State() api.StateType { if i.IsClosed { @@ -175,11 +185,11 @@ func (issue *Issue) APIFormat() *api.Issue { apiIssue := &api.Issue{ ID: issue.ID, Index: issue.Index, - State: issue.State(), + Poster: issue.Poster.APIFormat(), Title: issue.Title, Body: issue.Content, - User: issue.Poster.APIFormat(), Labels: apiLabels, + State: issue.State(), Comments: issue.NumComments, Created: issue.Created, Updated: issue.Updated, @@ -208,16 +218,6 @@ func (i *Issue) HashTag() string { return "issue-" + com.ToStr(i.ID) } -func (issue *Issue) FullLink() string { - var path string - if issue.IsPull { - path = "pulls" - } else { - path = "issues" - } - return fmt.Sprintf("%s/%s/%d", issue.Repo.FullLink(), path, issue.Index) -} - // IsPoster returns true if given user by ID is the poster. func (i *Issue) IsPoster(uid int64) bool { return i.PosterID == uid @@ -591,16 +591,44 @@ func newIssue(e *xorm.Session, opts NewIssueOptions) (err error) { opts.Issue.Title = strings.TrimSpace(opts.Issue.Title) opts.Issue.Index = opts.Repo.NextIssueIndex() - if opts.Issue.AssigneeID > 0 { - // Silently drop invalid assignee. - valid, err := hasAccess(e, &User{ID: opts.Issue.AssigneeID}, opts.Repo, ACCESS_MODE_WRITE) - if err != nil { - return fmt.Errorf("hasAccess [user_id: %d, repo_id: %d]: %v", opts.Issue.AssigneeID, opts.Repo.ID, err) - } else if !valid { - opts.Issue.AssigneeID = 0 + if opts.Issue.MilestoneID > 0 { + milestone, err := getMilestoneByID(e, opts.Issue.MilestoneID) + if err != nil && !IsErrMilestoneNotExist(err) { + return fmt.Errorf("getMilestoneByID: %v", err) + } + + // Assume milestone is invalid and drop silently. + opts.Issue.MilestoneID = 0 + if milestone != nil { + opts.Issue.MilestoneID = milestone.ID + opts.Issue.Milestone = milestone + if err = changeMilestoneAssign(e, opts.Issue, -1); err != nil { + return err + } } } + if opts.Issue.AssigneeID > 0 { + assignee, err := getUserByID(e, opts.Issue.AssigneeID) + if err != nil && !IsErrUserNotExist(err) { + return fmt.Errorf("getUserByID: %v", err) + } + + // Assume assignee is invalid and drop silently. + opts.Issue.AssigneeID = 0 + if assignee != nil { + valid, err := hasAccess(e, assignee, opts.Repo, ACCESS_MODE_WRITE) + if err != nil { + return fmt.Errorf("hasAccess [user_id: %d, repo_id: %d]: %v", assignee.ID, opts.Repo.ID, err) + } + if valid { + opts.Issue.AssigneeID = assignee.ID + opts.Issue.Assignee = assignee + } + } + } + + // Milestone and assignee validation should happen before insert actual object. if _, err = e.Insert(opts.Issue); err != nil { return err } @@ -634,12 +662,6 @@ func newIssue(e *xorm.Session, opts NewIssueOptions) (err error) { } } - if opts.Issue.MilestoneID > 0 { - if err = changeMilestoneAssign(e, opts.Issue, -1); err != nil { - return err - } - } - if err = newIssueUsers(e, opts.Repo, opts.Issue); err != nil { return err } diff --git a/models/mail.go b/models/mail.go index 8e7f4bba40..0db21355a8 100644 --- a/models/mail.go +++ b/models/mail.go @@ -129,7 +129,7 @@ func SendCollaboratorMail(u, doer *User, repo *Repository) { data := map[string]interface{}{ "Subject": subject, "RepoName": repoName, - "Link": repo.FullLink(), + "Link": repo.HTMLURL(), } body, err := mailRender.HTMLString(string(MAIL_NOTIFY_COLLABORATOR), data) if err != nil { @@ -153,8 +153,8 @@ func composeTplData(subject, body, link string) map[string]interface{} { func composeIssueMessage(issue *Issue, doer *User, tplName base.TplName, tos []string, info string) *mailer.Message { subject := issue.MailSubject() - body := string(markdown.RenderSpecialLink([]byte(issue.Content), issue.Repo.FullLink(), issue.Repo.ComposeMetas())) - data := composeTplData(subject, body, issue.FullLink()) + body := string(markdown.RenderSpecialLink([]byte(issue.Content), issue.Repo.HTMLURL(), issue.Repo.ComposeMetas())) + data := composeTplData(subject, body, issue.HTMLURL()) data["Doer"] = doer content, err := mailRender.HTMLString(string(tplName), data) if err != nil { diff --git a/models/pull.go b/models/pull.go index fb967cd306..472c87b52b 100644 --- a/models/pull.go +++ b/models/pull.go @@ -100,6 +100,10 @@ func (pr *PullRequest) LoadAttributes() error { } func (pr *PullRequest) LoadIssue() (err error) { + if pr.Issue != nil { + return nil + } + pr.Issue, err = GetIssueByID(pr.IssueID) return err } @@ -112,14 +116,15 @@ func (pr *PullRequest) APIFormat() *api.PullRequest { apiPullRequest := &api.PullRequest{ ID: pr.ID, Index: pr.Index, - State: apiIssue.State, + Poster: apiIssue.Poster, Title: apiIssue.Title, Body: apiIssue.Body, - User: apiIssue.User, Labels: apiIssue.Labels, Milestone: apiIssue.Milestone, Assignee: apiIssue.Assignee, + State: apiIssue.State, Comments: apiIssue.Comments, + HTMLURL: pr.Issue.HTMLURL(), HasMerged: pr.HasMerged, } @@ -312,7 +317,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error Before: pr.MergeBase, After: pr.MergedCommitID, CompareURL: setting.AppUrl + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID), - Commits: ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.FullLink()), + Commits: ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.HTMLURL()), Repo: pr.BaseRepo.APIFormat(nil), Pusher: pr.HeadRepo.MustOwner().APIFormat(), Sender: doer.APIFormat(), diff --git a/models/repo.go b/models/repo.go index 6c427f92ec..e7c218a5f3 100644 --- a/models/repo.go +++ b/models/repo.go @@ -233,7 +233,7 @@ func (repo *Repository) FullName() string { return repo.MustOwner().Name + "/" + repo.Name } -func (repo *Repository) FullLink() string { +func (repo *Repository) HTMLURL() string { return setting.AppUrl + repo.FullName() } @@ -248,7 +248,7 @@ func (repo *Repository) APIFormat(permission *api.Permission) *api.Repository { Description: repo.Description, Private: repo.IsPrivate, Fork: repo.IsFork, - HTMLURL: repo.FullLink(), + HTMLURL: repo.HTMLURL(), SSHURL: cloneLink.SSH, CloneURL: cloneLink.HTTPS, Website: repo.Website, diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 3b36556c00..37731e5ee6 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -538,8 +538,8 @@ func ViewIssue(ctx *context.Context) { // Get more information if it's a pull request. if issue.IsPull { - if issue.HasMerged { - ctx.Data["DisableStatusChange"] = issue.HasMerged + if issue.PullRequest.HasMerged { + ctx.Data["DisableStatusChange"] = issue.PullRequest.HasMerged PrepareMergedViewPullInfo(ctx, issue) } else { PrepareViewPullInfo(ctx, issue) @@ -822,7 +822,7 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) { // Check if issue admin/poster changes the status of issue. if (ctx.Repo.IsWriter() || (ctx.IsSigned && issue.IsPoster(ctx.User.ID))) && (form.Status == "reopen" || form.Status == "close") && - !(issue.IsPull && issue.HasMerged) { + !(issue.IsPull && issue.PullRequest.HasMerged) { // Duplication and conflict check should apply to reopen pull request. var pr *models.PullRequest @@ -839,12 +839,12 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) { // Regenerate patch and test conflict. if pr == nil { - if err = issue.UpdatePatch(); err != nil { + if err = issue.PullRequest.UpdatePatch(); err != nil { ctx.Handle(500, "UpdatePatch", err) return } - issue.AddToTaskQueue() + issue.PullRequest.AddToTaskQueue() } } diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 87bc7bc217..d5d9bc9b07 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -156,7 +156,7 @@ func checkPullInfo(ctx *context.Context) *models.Issue { return nil } - if err = issue.GetHeadRepo(); err != nil { + if err = issue.PullRequest.GetHeadRepo(); err != nil { ctx.Handle(500, "GetHeadRepo", err) return nil } @@ -172,9 +172,10 @@ func checkPullInfo(ctx *context.Context) *models.Issue { return issue } -func PrepareMergedViewPullInfo(ctx *context.Context, pull *models.Issue) { +func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) { + pull := issue.PullRequest ctx.Data["HasMerged"] = true - ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBranch + ctx.Data["HeadTarget"] = issue.PullRequest.HeadUserName + "/" + pull.HeadBranch ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch var err error @@ -190,8 +191,9 @@ func PrepareMergedViewPullInfo(ctx *context.Context, pull *models.Issue) { } } -func PrepareViewPullInfo(ctx *context.Context, pull *models.Issue) *git.PullRequestInfo { +func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.PullRequestInfo { repo := ctx.Repo.Repository + pull := issue.PullRequest ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBranch ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch @@ -245,16 +247,17 @@ func ViewPullCommits(ctx *context.Context) { ctx.Data["PageIsPullList"] = true ctx.Data["PageIsPullCommits"] = true - pull := checkPullInfo(ctx) + issue := checkPullInfo(ctx) if ctx.Written() { return } + pull := issue.PullRequest ctx.Data["Username"] = pull.HeadUserName ctx.Data["Reponame"] = pull.HeadRepo.Name var commits *list.List if pull.HasMerged { - PrepareMergedViewPullInfo(ctx, pull) + PrepareMergedViewPullInfo(ctx, issue) if ctx.Written() { return } @@ -275,7 +278,7 @@ func ViewPullCommits(ctx *context.Context) { } } else { - prInfo := PrepareViewPullInfo(ctx, pull) + prInfo := PrepareViewPullInfo(ctx, issue) if ctx.Written() { return } else if prInfo == nil { @@ -296,10 +299,11 @@ func ViewPullFiles(ctx *context.Context) { ctx.Data["PageIsPullList"] = true ctx.Data["PageIsPullFiles"] = true - pull := checkPullInfo(ctx) + issue := checkPullInfo(ctx) if ctx.Written() { return } + pull := issue.PullRequest var ( diffRepoPath string @@ -309,7 +313,7 @@ func ViewPullFiles(ctx *context.Context) { ) if pull.HasMerged { - PrepareMergedViewPullInfo(ctx, pull) + PrepareMergedViewPullInfo(ctx, issue) if ctx.Written() { return } @@ -319,7 +323,7 @@ func ViewPullFiles(ctx *context.Context) { endCommitID = pull.MergedCommitID gitRepo = ctx.Repo.GitRepo } else { - prInfo := PrepareViewPullInfo(ctx, pull) + prInfo := PrepareViewPullInfo(ctx, issue) if ctx.Written() { return } else if prInfo == nil { diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 85878e7d1e..d3605b2a42 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -368,7 +368,7 @@ func TestWebhook(ctx *context.Context) { { ID: commit.ID.String(), Message: commit.Message(), - URL: ctx.Repo.Repository.FullLink() + "/commit/" + commit.ID.String(), + URL: ctx.Repo.Repository.HTMLURL() + "/commit/" + commit.ID.String(), Author: &api.PayloadUser{ Name: commit.Author.Name, Email: commit.Author.Email, diff --git a/templates/.VERSION b/templates/.VERSION index d381c8cafc..3aa00ff9dc 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.9.81.0816 \ No newline at end of file +0.9.82.0816 \ No newline at end of file diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index ebd737c381..3911059141 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -151,15 +151,15 @@ {{if .Issue.IsPull}}