You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

repo.go 6.3 kB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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 middleware
  5. import (
  6. "errors"
  7. "fmt"
  8. "strings"
  9. "github.com/go-martini/martini"
  10. "github.com/gogits/git"
  11. "github.com/gogits/gogs/models"
  12. "github.com/gogits/gogs/modules/base"
  13. "github.com/gogits/gogs/modules/log"
  14. )
  15. func RepoAssignment(redirect bool, args ...bool) martini.Handler {
  16. return func(ctx *Context, params martini.Params) {
  17. // valid brachname
  18. var validBranch bool
  19. // display bare quick start if it is a bare repo
  20. var displayBare bool
  21. if len(args) >= 1 {
  22. // Note: argument has wrong value in Go1.3 martini.
  23. // validBranch = args[0]
  24. validBranch = true
  25. }
  26. if len(args) >= 2 {
  27. // displayBare = args[1]
  28. displayBare = true
  29. }
  30. var (
  31. user *models.User
  32. err error
  33. )
  34. userName := params["username"]
  35. repoName := params["reponame"]
  36. refName := params["branchname"]
  37. // get repository owner
  38. ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName)
  39. if !ctx.Repo.IsOwner {
  40. user, err = models.GetUserByName(params["username"])
  41. if err != nil {
  42. if err == models.ErrUserNotExist {
  43. ctx.Handle(404, "RepoAssignment", err)
  44. return
  45. } else if redirect {
  46. ctx.Redirect("/")
  47. return
  48. }
  49. ctx.Handle(500, "RepoAssignment", err)
  50. return
  51. }
  52. } else {
  53. user = ctx.User
  54. }
  55. if user == nil {
  56. if redirect {
  57. ctx.Redirect("/")
  58. return
  59. }
  60. ctx.Handle(403, "RepoAssignment", errors.New("invliad user account for single repository"))
  61. return
  62. }
  63. ctx.Repo.Owner = user
  64. // get repository
  65. repo, err := models.GetRepositoryByName(user.Id, repoName)
  66. if err != nil {
  67. if err == models.ErrRepoNotExist {
  68. ctx.Handle(404, "RepoAssignment", err)
  69. return
  70. } else if redirect {
  71. ctx.Redirect("/")
  72. return
  73. }
  74. ctx.Handle(500, "RepoAssignment", err)
  75. return
  76. }
  77. // Check access.
  78. if repo.IsPrivate {
  79. if ctx.User == nil {
  80. ctx.Handle(404, "RepoAssignment(HasAccess)", nil)
  81. return
  82. }
  83. hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.AU_READABLE)
  84. if err != nil {
  85. ctx.Handle(500, "RepoAssignment(HasAccess)", err)
  86. return
  87. } else if !hasAccess {
  88. ctx.Handle(404, "RepoAssignment(HasAccess)", nil)
  89. return
  90. }
  91. }
  92. ctx.Repo.HasAccess = true
  93. ctx.Data["HasAccess"] = true
  94. if repo.IsMirror {
  95. ctx.Repo.Mirror, err = models.GetMirror(repo.Id)
  96. if err != nil {
  97. ctx.Handle(500, "RepoAssignment(GetMirror)", err)
  98. return
  99. }
  100. ctx.Data["MirrorInterval"] = ctx.Repo.Mirror.Interval
  101. }
  102. repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
  103. ctx.Repo.Repository = repo
  104. ctx.Data["IsBareRepo"] = ctx.Repo.Repository.IsBare
  105. gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName))
  106. if err != nil {
  107. ctx.Handle(500, "RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err)
  108. return
  109. }
  110. ctx.Repo.GitRepo = gitRepo
  111. ctx.Repo.RepoLink = "/" + user.Name + "/" + repo.Name
  112. tags, err := ctx.Repo.GitRepo.GetTags()
  113. if err != nil {
  114. ctx.Handle(500, "RepoAssignment(GetTags))", err)
  115. return
  116. }
  117. ctx.Repo.Repository.NumTags = len(tags)
  118. ctx.Data["Title"] = user.Name + "/" + repo.Name
  119. ctx.Data["Repository"] = repo
  120. ctx.Data["Owner"] = user
  121. ctx.Data["RepoLink"] = ctx.Repo.RepoLink
  122. ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
  123. ctx.Data["BranchName"] = ""
  124. ctx.Repo.CloneLink.SSH = fmt.Sprintf("%s@%s:%s/%s.git", base.RunUser, base.Domain, user.LowerName, repo.LowerName)
  125. ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("%s%s/%s.git", base.AppUrl, user.LowerName, repo.LowerName)
  126. ctx.Data["CloneLink"] = ctx.Repo.CloneLink
  127. if ctx.Repo.Repository.IsGoget {
  128. ctx.Data["GoGetLink"] = fmt.Sprintf("%s%s/%s", base.AppUrl, user.LowerName, repo.LowerName)
  129. ctx.Data["GoGetImport"] = fmt.Sprintf("%s/%s/%s", base.Domain, user.LowerName, repo.LowerName)
  130. }
  131. // when repo is bare, not valid branch
  132. if !ctx.Repo.Repository.IsBare && validBranch {
  133. detect:
  134. if len(refName) > 0 {
  135. if gitRepo.IsBranchExist(refName) {
  136. ctx.Repo.IsBranch = true
  137. ctx.Repo.BranchName = refName
  138. ctx.Repo.Commit, err = gitRepo.GetCommitOfBranch(refName)
  139. if err != nil {
  140. ctx.Handle(404, "RepoAssignment invalid branch", nil)
  141. return
  142. }
  143. ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
  144. } else if gitRepo.IsTagExist(refName) {
  145. ctx.Repo.IsBranch = true
  146. ctx.Repo.BranchName = refName
  147. ctx.Repo.Commit, err = gitRepo.GetCommitOfTag(refName)
  148. if err != nil {
  149. ctx.Handle(404, "RepoAssignment invalid tag", nil)
  150. return
  151. }
  152. ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
  153. } else if len(refName) == 40 {
  154. ctx.Repo.IsCommit = true
  155. ctx.Repo.CommitId = refName
  156. ctx.Repo.BranchName = refName
  157. ctx.Repo.Commit, err = gitRepo.GetCommit(refName)
  158. if err != nil {
  159. ctx.Handle(404, "RepoAssignment invalid commit", nil)
  160. return
  161. }
  162. } else {
  163. ctx.Handle(404, "RepoAssignment invalid repo", nil)
  164. return
  165. }
  166. } else {
  167. if len(refName) == 0 {
  168. if gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
  169. refName = ctx.Repo.Repository.DefaultBranch
  170. } else {
  171. brs, err := gitRepo.GetBranches()
  172. if err != nil {
  173. ctx.Handle(500, "RepoAssignment(GetBranches))", err)
  174. return
  175. }
  176. refName = brs[0]
  177. }
  178. }
  179. goto detect
  180. }
  181. ctx.Data["IsBranch"] = ctx.Repo.IsBranch
  182. ctx.Data["IsCommit"] = ctx.Repo.IsCommit
  183. log.Debug("Repo.Commit: %v", ctx.Repo.Commit)
  184. }
  185. log.Debug("displayBare: %v; IsBare: %v", displayBare, ctx.Repo.Repository.IsBare)
  186. // repo is bare and display enable
  187. if displayBare && ctx.Repo.Repository.IsBare {
  188. log.Debug("Bare repository: %s", ctx.Repo.RepoLink)
  189. ctx.HTML(200, "repo/single_bare")
  190. return
  191. }
  192. if ctx.IsSigned {
  193. ctx.Repo.IsWatching = models.IsWatching(ctx.User.Id, repo.Id)
  194. }
  195. ctx.Data["BranchName"] = ctx.Repo.BranchName
  196. brs, err := ctx.Repo.GitRepo.GetBranches()
  197. if err != nil {
  198. log.Error("RepoAssignment(GetBranches): %v", err)
  199. }
  200. ctx.Data["Branches"] = brs
  201. ctx.Data["CommitId"] = ctx.Repo.CommitId
  202. ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching
  203. }
  204. }