release.go 6.1 KB

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