release.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package repo
  5. import (
  6. "github.com/go-martini/martini"
  7. "github.com/gogits/gogs/models"
  8. "github.com/gogits/gogs/modules/auth"
  9. "github.com/gogits/gogs/modules/base"
  10. "github.com/gogits/gogs/modules/log"
  11. "github.com/gogits/gogs/modules/middleware"
  12. )
  13. func Releases(ctx *middleware.Context) {
  14. ctx.Data["Title"] = "Releases"
  15. ctx.Data["IsRepoToolbarReleases"] = true
  16. ctx.Data["IsRepoReleaseNew"] = false
  17. rawTags, err := ctx.Repo.GitRepo.GetTags()
  18. if err != nil {
  19. ctx.Handle(500, "release.Releases(GetTags)", err)
  20. return
  21. }
  22. rels, err := models.GetReleasesByRepoId(ctx.Repo.Repository.Id)
  23. if err != nil {
  24. ctx.Handle(500, "release.Releases(GetReleasesByRepoId)", err)
  25. return
  26. }
  27. commitsCount, err := ctx.Repo.Commit.CommitsCount()
  28. if err != nil {
  29. ctx.Handle(500, "release.Releases(CommitsCount)", err)
  30. return
  31. }
  32. // Temproray cache commits count of used branches to speed up.
  33. countCache := make(map[string]int)
  34. tags := make([]*models.Release, len(rawTags))
  35. for i, rawTag := range rawTags {
  36. for _, rel := range rels {
  37. if rel.IsDraft && !ctx.Repo.IsOwner {
  38. continue
  39. }
  40. if rel.TagName == rawTag {
  41. rel.Publisher, err = models.GetUserById(rel.PublisherId)
  42. if err != nil {
  43. ctx.Handle(500, "release.Releases(GetUserById)", err)
  44. return
  45. }
  46. // Get corresponding target if it's not the current branch.
  47. if ctx.Repo.BranchName != rel.Target {
  48. // Get count if not exists.
  49. if _, ok := countCache[rel.Target]; !ok {
  50. commit, err := ctx.Repo.GitRepo.GetCommitOfTag(rel.TagName)
  51. if err != nil {
  52. ctx.Handle(500, "release.Releases(GetCommitOfTag)", err)
  53. return
  54. }
  55. countCache[rel.Target], err = commit.CommitsCount()
  56. if err != nil {
  57. ctx.Handle(500, "release.Releases(CommitsCount2)", err)
  58. return
  59. }
  60. }
  61. rel.NumCommitsBehind = countCache[rel.Target] - rel.NumCommits
  62. } else {
  63. rel.NumCommitsBehind = commitsCount - rel.NumCommits
  64. }
  65. rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink)
  66. tags[i] = rel
  67. break
  68. }
  69. }
  70. if tags[i] == nil {
  71. commit, err := ctx.Repo.GitRepo.GetCommitOfTag(rawTag)
  72. if err != nil {
  73. ctx.Handle(500, "release.Releases(GetCommitOfTag2)", err)
  74. return
  75. }
  76. tags[i] = &models.Release{
  77. Title: rawTag,
  78. TagName: rawTag,
  79. Sha1: commit.Id.String(),
  80. }
  81. tags[i].NumCommits, err = ctx.Repo.GitRepo.CommitsCount(commit.Id.String())
  82. if err != nil {
  83. ctx.Handle(500, "release.Releases(CommitsCount)", err)
  84. return
  85. }
  86. tags[i].NumCommitsBehind = commitsCount - tags[i].NumCommits
  87. }
  88. }
  89. models.SortReleases(tags)
  90. ctx.Data["Releases"] = tags
  91. ctx.HTML(200, "release/list")
  92. }
  93. func NewRelease(ctx *middleware.Context) {
  94. if !ctx.Repo.IsOwner {
  95. ctx.Handle(403, "release.ReleasesNew", nil)
  96. return
  97. }
  98. ctx.Data["Title"] = "New Release"
  99. ctx.Data["IsRepoToolbarReleases"] = true
  100. ctx.Data["IsRepoReleaseNew"] = true
  101. ctx.HTML(200, "release/new")
  102. }
  103. func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) {
  104. if !ctx.Repo.IsOwner {
  105. ctx.Handle(403, "release.ReleasesNew", nil)
  106. return
  107. }
  108. ctx.Data["Title"] = "New Release"
  109. ctx.Data["IsRepoToolbarReleases"] = true
  110. ctx.Data["IsRepoReleaseNew"] = true
  111. if ctx.HasError() {
  112. ctx.HTML(200, "release/new")
  113. return
  114. }
  115. commitsCount, err := ctx.Repo.Commit.CommitsCount()
  116. if err != nil {
  117. ctx.Handle(500, "release.ReleasesNewPost(CommitsCount)", err)
  118. return
  119. }
  120. if !ctx.Repo.GitRepo.IsBranchExist(form.Target) {
  121. ctx.RenderWithErr("Target branch does not exist", "release/new", &form)
  122. return
  123. }
  124. rel := &models.Release{
  125. RepoId: ctx.Repo.Repository.Id,
  126. PublisherId: ctx.User.Id,
  127. Title: form.Title,
  128. TagName: form.TagName,
  129. Target: form.Target,
  130. Sha1: ctx.Repo.Commit.Id.String(),
  131. NumCommits: commitsCount,
  132. Note: form.Content,
  133. IsDraft: len(form.Draft) > 0,
  134. IsPrerelease: form.Prerelease,
  135. }
  136. if err = models.CreateRelease(ctx.Repo.GitRepo, rel); err != nil {
  137. if err == models.ErrReleaseAlreadyExist {
  138. ctx.RenderWithErr("Release with this tag name has already existed", "release/new", &form)
  139. } else {
  140. ctx.Handle(500, "release.ReleasesNewPost(IsReleaseExist)", err)
  141. }
  142. return
  143. }
  144. log.Trace("%s Release created: %s/%s:%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.Name, form.TagName)
  145. ctx.Redirect(ctx.Repo.RepoLink + "/releases")
  146. }
  147. func EditRelease(ctx *middleware.Context, params martini.Params) {
  148. if !ctx.Repo.IsOwner {
  149. ctx.Handle(403, "release.ReleasesEdit", nil)
  150. return
  151. }
  152. tagName := params["tagname"]
  153. rel, err := models.GetRelease(ctx.Repo.Repository.Id, tagName)
  154. if err != nil {
  155. if err == models.ErrReleaseNotExist {
  156. ctx.Handle(404, "release.ReleasesEdit(GetRelease)", err)
  157. } else {
  158. ctx.Handle(500, "release.ReleasesEdit(GetRelease)", err)
  159. }
  160. return
  161. }
  162. ctx.Data["Release"] = rel
  163. ctx.Data["Title"] = "Edit Release"
  164. ctx.Data["IsRepoToolbarReleases"] = true
  165. ctx.HTML(200, "release/edit")
  166. }
  167. func EditReleasePost(ctx *middleware.Context, params martini.Params, form auth.EditReleaseForm) {
  168. if !ctx.Repo.IsOwner {
  169. ctx.Handle(403, "release.EditReleasePost", nil)
  170. return
  171. }
  172. tagName := params["tagname"]
  173. rel, err := models.GetRelease(ctx.Repo.Repository.Id, tagName)
  174. if err != nil {
  175. if err == models.ErrReleaseNotExist {
  176. ctx.Handle(404, "release.EditReleasePost(GetRelease)", err)
  177. } else {
  178. ctx.Handle(500, "release.EditReleasePost(GetRelease)", err)
  179. }
  180. return
  181. }
  182. ctx.Data["Release"] = rel
  183. ctx.Data["Title"] = "Edit Release"
  184. ctx.Data["IsRepoToolbarReleases"] = true
  185. rel.Title = form.Title
  186. rel.Note = form.Content
  187. rel.IsDraft = len(form.Draft) > 0
  188. rel.IsPrerelease = form.Prerelease
  189. if err = models.UpdateRelease(ctx.Repo.GitRepo, rel); err != nil {
  190. ctx.Handle(500, "release.EditReleasePost(UpdateRelease)", err)
  191. return
  192. }
  193. ctx.Redirect(ctx.Repo.RepoLink + "/releases")
  194. }