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

405 lines
11 KiB

10 years ago
10 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
Template Repositories (#8768) * Start work on templates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Continue work Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix IsTemplate vs IsGenerated Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tabs vs spaces * Tabs vs Spaces * Add templates to API & start adding tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix integration tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove unused User Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move template tests to existing repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Minor re-check updates and cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix optionalbool Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test fixes and icon change Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add new user and repo for tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests (finally) Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update meta repo with env variables Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move generation to create page Combine with repo create template Modify API search to prioritize owner for repo Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests and coverage Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix swagger and JS lint Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix API searching for own private repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Change wording Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix repo search test. User had a private repo that didn't show up Signed-off-by: jolheiser <john.olheiser@gmail.com> * Another search test fix Signed-off-by: jolheiser <john.olheiser@gmail.com> * Clarify git content Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Feedback updates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add topics WIP Signed-off-by: jolheiser <john.olheiser@gmail.com> * Finish adding topics Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update locale Signed-off-by: jolheiser <john.olheiser@gmail.com>
4 years ago
10 years ago
10 years ago
8 years ago
Template Repositories (#8768) * Start work on templates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Continue work Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix IsTemplate vs IsGenerated Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tabs vs spaces * Tabs vs Spaces * Add templates to API & start adding tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix integration tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove unused User Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move template tests to existing repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Minor re-check updates and cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix optionalbool Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test fixes and icon change Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add new user and repo for tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests (finally) Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update meta repo with env variables Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move generation to create page Combine with repo create template Modify API search to prioritize owner for repo Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests and coverage Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix swagger and JS lint Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix API searching for own private repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Change wording Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix repo search test. User had a private repo that didn't show up Signed-off-by: jolheiser <john.olheiser@gmail.com> * Another search test fix Signed-off-by: jolheiser <john.olheiser@gmail.com> * Clarify git content Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Feedback updates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add topics WIP Signed-off-by: jolheiser <john.olheiser@gmail.com> * Finish adding topics Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update locale Signed-off-by: jolheiser <john.olheiser@gmail.com>
4 years ago
Template Repositories (#8768) * Start work on templates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Continue work Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix IsTemplate vs IsGenerated Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tabs vs spaces * Tabs vs Spaces * Add templates to API & start adding tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix integration tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove unused User Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move template tests to existing repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Minor re-check updates and cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix optionalbool Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test fixes and icon change Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add new user and repo for tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests (finally) Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update meta repo with env variables Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move generation to create page Combine with repo create template Modify API search to prioritize owner for repo Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests and coverage Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix swagger and JS lint Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix API searching for own private repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Change wording Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix repo search test. User had a private repo that didn't show up Signed-off-by: jolheiser <john.olheiser@gmail.com> * Another search test fix Signed-off-by: jolheiser <john.olheiser@gmail.com> * Clarify git content Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Feedback updates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add topics WIP Signed-off-by: jolheiser <john.olheiser@gmail.com> * Finish adding topics Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update locale Signed-off-by: jolheiser <john.olheiser@gmail.com>
4 years ago
Template Repositories (#8768) * Start work on templates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Continue work Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix IsTemplate vs IsGenerated Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tabs vs spaces * Tabs vs Spaces * Add templates to API & start adding tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix integration tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove unused User Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move template tests to existing repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Minor re-check updates and cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix optionalbool Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test fixes and icon change Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add new user and repo for tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests (finally) Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update meta repo with env variables Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move generation to create page Combine with repo create template Modify API search to prioritize owner for repo Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests and coverage Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix swagger and JS lint Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix API searching for own private repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Change wording Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix repo search test. User had a private repo that didn't show up Signed-off-by: jolheiser <john.olheiser@gmail.com> * Another search test fix Signed-off-by: jolheiser <john.olheiser@gmail.com> * Clarify git content Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Feedback updates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add topics WIP Signed-off-by: jolheiser <john.olheiser@gmail.com> * Finish adding topics Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update locale Signed-off-by: jolheiser <john.olheiser@gmail.com>
4 years ago
Template Repositories (#8768) * Start work on templates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Continue work Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix IsTemplate vs IsGenerated Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tabs vs spaces * Tabs vs Spaces * Add templates to API & start adding tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix integration tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove unused User Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move template tests to existing repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Minor re-check updates and cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix optionalbool Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test fixes and icon change Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add new user and repo for tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests (finally) Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update meta repo with env variables Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move generation to create page Combine with repo create template Modify API search to prioritize owner for repo Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests and coverage Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix swagger and JS lint Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix API searching for own private repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Change wording Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix repo search test. User had a private repo that didn't show up Signed-off-by: jolheiser <john.olheiser@gmail.com> * Another search test fix Signed-off-by: jolheiser <john.olheiser@gmail.com> * Clarify git content Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Feedback updates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add topics WIP Signed-off-by: jolheiser <john.olheiser@gmail.com> * Finish adding topics Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update locale Signed-off-by: jolheiser <john.olheiser@gmail.com>
4 years ago
10 years ago
9 years ago
9 years ago
9 years ago
8 years ago
10 years ago
10 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2020 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package repo
  6. import (
  7. "fmt"
  8. "os"
  9. "path"
  10. "strings"
  11. "code.gitea.io/gitea/models"
  12. "code.gitea.io/gitea/modules/auth"
  13. "code.gitea.io/gitea/modules/base"
  14. "code.gitea.io/gitea/modules/context"
  15. "code.gitea.io/gitea/modules/git"
  16. "code.gitea.io/gitea/modules/log"
  17. "code.gitea.io/gitea/modules/setting"
  18. repo_service "code.gitea.io/gitea/services/repository"
  19. "github.com/unknwon/com"
  20. )
  21. const (
  22. tplCreate base.TplName = "repo/create"
  23. )
  24. // MustBeNotEmpty render when a repo is a empty git dir
  25. func MustBeNotEmpty(ctx *context.Context) {
  26. if ctx.Repo.Repository.IsEmpty {
  27. ctx.NotFound("MustBeNotEmpty", nil)
  28. }
  29. }
  30. // MustBeEditable check that repo can be edited
  31. func MustBeEditable(ctx *context.Context) {
  32. if !ctx.Repo.Repository.CanEnableEditor() || ctx.Repo.IsViewCommit {
  33. ctx.NotFound("", nil)
  34. return
  35. }
  36. }
  37. // MustBeAbleToUpload check that repo can be uploaded to
  38. func MustBeAbleToUpload(ctx *context.Context) {
  39. if !setting.Repository.Upload.Enabled {
  40. ctx.NotFound("", nil)
  41. }
  42. }
  43. func checkContextUser(ctx *context.Context, uid int64) *models.User {
  44. orgs, err := models.GetOrgsCanCreateRepoByUserID(ctx.User.ID)
  45. if err != nil {
  46. ctx.ServerError("GetOrgsCanCreateRepoByUserID", err)
  47. return nil
  48. }
  49. if !ctx.User.IsAdmin {
  50. orgsAvailable := []*models.User{}
  51. for i := 0; i < len(orgs); i++ {
  52. if orgs[i].CanCreateRepo() {
  53. orgsAvailable = append(orgsAvailable, orgs[i])
  54. }
  55. }
  56. ctx.Data["Orgs"] = orgsAvailable
  57. } else {
  58. ctx.Data["Orgs"] = orgs
  59. }
  60. // Not equal means current user is an organization.
  61. if uid == ctx.User.ID || uid == 0 {
  62. return ctx.User
  63. }
  64. org, err := models.GetUserByID(uid)
  65. if models.IsErrUserNotExist(err) {
  66. return ctx.User
  67. }
  68. if err != nil {
  69. ctx.ServerError("GetUserByID", fmt.Errorf("[%d]: %v", uid, err))
  70. return nil
  71. }
  72. // Check ownership of organization.
  73. if !org.IsOrganization() {
  74. ctx.Error(403)
  75. return nil
  76. }
  77. if !ctx.User.IsAdmin {
  78. canCreate, err := org.CanCreateOrgRepo(ctx.User.ID)
  79. if err != nil {
  80. ctx.ServerError("CanCreateOrgRepo", err)
  81. return nil
  82. } else if !canCreate {
  83. ctx.Error(403)
  84. return nil
  85. }
  86. } else {
  87. ctx.Data["Orgs"] = orgs
  88. }
  89. return org
  90. }
  91. func getRepoPrivate(ctx *context.Context) bool {
  92. switch strings.ToLower(setting.Repository.DefaultPrivate) {
  93. case setting.RepoCreatingLastUserVisibility:
  94. return ctx.User.LastRepoVisibility
  95. case setting.RepoCreatingPrivate:
  96. return true
  97. case setting.RepoCreatingPublic:
  98. return false
  99. default:
  100. return ctx.User.LastRepoVisibility
  101. }
  102. }
  103. // Create render creating repository page
  104. func Create(ctx *context.Context) {
  105. ctx.Data["Title"] = ctx.Tr("new_repo")
  106. // Give default value for template to render.
  107. ctx.Data["Gitignores"] = models.Gitignores
  108. ctx.Data["LabelTemplates"] = models.LabelTemplates
  109. ctx.Data["Licenses"] = models.Licenses
  110. ctx.Data["Readmes"] = models.Readmes
  111. ctx.Data["readme"] = "Default"
  112. ctx.Data["private"] = getRepoPrivate(ctx)
  113. ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
  114. ctx.Data["default_branch"] = setting.Repository.DefaultBranch
  115. ctxUser := checkContextUser(ctx, ctx.QueryInt64("org"))
  116. if ctx.Written() {
  117. return
  118. }
  119. ctx.Data["ContextUser"] = ctxUser
  120. ctx.Data["repo_template_name"] = ctx.Tr("repo.template_select")
  121. templateID := ctx.QueryInt64("template_id")
  122. if templateID > 0 {
  123. templateRepo, err := models.GetRepositoryByID(templateID)
  124. if err == nil && templateRepo.CheckUnitUser(ctxUser.ID, ctxUser.IsAdmin, models.UnitTypeCode) {
  125. ctx.Data["repo_template"] = templateID
  126. ctx.Data["repo_template_name"] = templateRepo.Name
  127. }
  128. }
  129. if !ctx.User.CanCreateRepo() {
  130. ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", ctx.User.MaxCreationLimit()), tplCreate, nil)
  131. } else {
  132. ctx.HTML(200, tplCreate)
  133. }
  134. }
  135. func handleCreateError(ctx *context.Context, owner *models.User, err error, name string, tpl base.TplName, form interface{}) {
  136. switch {
  137. case models.IsErrReachLimitOfRepo(err):
  138. ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", owner.MaxCreationLimit()), tpl, form)
  139. case models.IsErrRepoAlreadyExist(err):
  140. ctx.Data["Err_RepoName"] = true
  141. ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tpl, form)
  142. case models.IsErrNameReserved(err):
  143. ctx.Data["Err_RepoName"] = true
  144. ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tpl, form)
  145. case models.IsErrNamePatternNotAllowed(err):
  146. ctx.Data["Err_RepoName"] = true
  147. ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tpl, form)
  148. default:
  149. ctx.ServerError(name, err)
  150. }
  151. }
  152. // CreatePost response for creating repository
  153. func CreatePost(ctx *context.Context, form auth.CreateRepoForm) {
  154. ctx.Data["Title"] = ctx.Tr("new_repo")
  155. ctx.Data["Gitignores"] = models.Gitignores
  156. ctx.Data["LabelTemplates"] = models.LabelTemplates
  157. ctx.Data["Licenses"] = models.Licenses
  158. ctx.Data["Readmes"] = models.Readmes
  159. ctxUser := checkContextUser(ctx, form.UID)
  160. if ctx.Written() {
  161. return
  162. }
  163. ctx.Data["ContextUser"] = ctxUser
  164. if ctx.HasError() {
  165. ctx.HTML(200, tplCreate)
  166. return
  167. }
  168. var repo *models.Repository
  169. var err error
  170. if form.RepoTemplate > 0 {
  171. opts := models.GenerateRepoOptions{
  172. Name: form.RepoName,
  173. Description: form.Description,
  174. Private: form.Private,
  175. GitContent: form.GitContent,
  176. Topics: form.Topics,
  177. GitHooks: form.GitHooks,
  178. Webhooks: form.Webhooks,
  179. Avatar: form.Avatar,
  180. IssueLabels: form.Labels,
  181. }
  182. if !opts.IsValid() {
  183. ctx.RenderWithErr(ctx.Tr("repo.template.one_item"), tplCreate, form)
  184. return
  185. }
  186. templateRepo := getRepository(ctx, form.RepoTemplate)
  187. if ctx.Written() {
  188. return
  189. }
  190. if !templateRepo.IsTemplate {
  191. ctx.RenderWithErr(ctx.Tr("repo.template.invalid"), tplCreate, form)
  192. return
  193. }
  194. repo, err = repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, opts)
  195. if err == nil {
  196. log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
  197. ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name)
  198. return
  199. }
  200. } else {
  201. repo, err = repo_service.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
  202. Name: form.RepoName,
  203. Description: form.Description,
  204. Gitignores: form.Gitignores,
  205. IssueLabels: form.IssueLabels,
  206. License: form.License,
  207. Readme: form.Readme,
  208. IsPrivate: form.Private || setting.Repository.ForcePrivate,
  209. DefaultBranch: form.DefaultBranch,
  210. AutoInit: form.AutoInit,
  211. })
  212. if err == nil {
  213. log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
  214. ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name)
  215. return
  216. }
  217. }
  218. handleCreateError(ctx, ctxUser, err, "CreatePost", tplCreate, &form)
  219. }
  220. // Action response for actions to a repository
  221. func Action(ctx *context.Context) {
  222. var err error
  223. switch ctx.Params(":action") {
  224. case "watch":
  225. err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true)
  226. case "unwatch":
  227. err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false)
  228. case "star":
  229. err = models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true)
  230. case "unstar":
  231. err = models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false)
  232. case "desc": // FIXME: this is not used
  233. if !ctx.Repo.IsOwner() {
  234. ctx.Error(404)
  235. return
  236. }
  237. ctx.Repo.Repository.Description = ctx.Query("desc")
  238. ctx.Repo.Repository.Website = ctx.Query("site")
  239. err = models.UpdateRepository(ctx.Repo.Repository, false)
  240. }
  241. if err != nil {
  242. ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
  243. return
  244. }
  245. ctx.RedirectToFirst(ctx.Query("redirect_to"), ctx.Repo.RepoLink)
  246. }
  247. // RedirectDownload return a file based on the following infos:
  248. func RedirectDownload(ctx *context.Context) {
  249. var (
  250. vTag = ctx.Params("vTag")
  251. fileName = ctx.Params("fileName")
  252. )
  253. tagNames := []string{vTag}
  254. curRepo := ctx.Repo.Repository
  255. releases, err := models.GetReleasesByRepoIDAndNames(models.DefaultDBContext(), curRepo.ID, tagNames)
  256. if err != nil {
  257. if models.IsErrAttachmentNotExist(err) {
  258. ctx.Error(404)
  259. return
  260. }
  261. ctx.ServerError("RedirectDownload", err)
  262. return
  263. }
  264. if len(releases) == 1 {
  265. release := releases[0]
  266. att, err := models.GetAttachmentByReleaseIDFileName(release.ID, fileName)
  267. if err != nil {
  268. ctx.Error(404)
  269. return
  270. }
  271. if att != nil {
  272. ctx.Redirect(att.DownloadURL())
  273. return
  274. }
  275. }
  276. ctx.Error(404)
  277. }
  278. // Download download an archive of a repository
  279. func Download(ctx *context.Context) {
  280. var (
  281. uri = ctx.Params("*")
  282. refName string
  283. ext string
  284. archivePath string
  285. archiveType git.ArchiveType
  286. )
  287. switch {
  288. case strings.HasSuffix(uri, ".zip"):
  289. ext = ".zip"
  290. archivePath = path.Join(ctx.Repo.GitRepo.Path, "archives/zip")
  291. archiveType = git.ZIP
  292. case strings.HasSuffix(uri, ".tar.gz"):
  293. ext = ".tar.gz"
  294. archivePath = path.Join(ctx.Repo.GitRepo.Path, "archives/targz")
  295. archiveType = git.TARGZ
  296. default:
  297. log.Trace("Unknown format: %s", uri)
  298. ctx.Error(404)
  299. return
  300. }
  301. refName = strings.TrimSuffix(uri, ext)
  302. if !com.IsDir(archivePath) {
  303. if err := os.MkdirAll(archivePath, os.ModePerm); err != nil {
  304. ctx.ServerError("Download -> os.MkdirAll(archivePath)", err)
  305. return
  306. }
  307. }
  308. // Get corresponding commit.
  309. var (
  310. commit *git.Commit
  311. err error
  312. )
  313. gitRepo := ctx.Repo.GitRepo
  314. if gitRepo.IsBranchExist(refName) {
  315. commit, err = gitRepo.GetBranchCommit(refName)
  316. if err != nil {
  317. ctx.ServerError("GetBranchCommit", err)
  318. return
  319. }
  320. } else if gitRepo.IsTagExist(refName) {
  321. commit, err = gitRepo.GetTagCommit(refName)
  322. if err != nil {
  323. ctx.ServerError("GetTagCommit", err)
  324. return
  325. }
  326. } else if len(refName) >= 4 && len(refName) <= 40 {
  327. commit, err = gitRepo.GetCommit(refName)
  328. if err != nil {
  329. ctx.NotFound("GetCommit", nil)
  330. return
  331. }
  332. } else {
  333. ctx.NotFound("Download", nil)
  334. return
  335. }
  336. archivePath = path.Join(archivePath, base.ShortSha(commit.ID.String())+ext)
  337. if !com.IsFile(archivePath) {
  338. if err := commit.CreateArchive(ctx.Req.Context(), archivePath, git.CreateArchiveOpts{
  339. Format: archiveType,
  340. Prefix: setting.Repository.PrefixArchiveFiles,
  341. }); err != nil {
  342. ctx.ServerError("Download -> CreateArchive "+archivePath, err)
  343. return
  344. }
  345. }
  346. ctx.ServeFile(archivePath, ctx.Repo.Repository.Name+"-"+refName+ext)
  347. }
  348. // Status returns repository's status
  349. func Status(ctx *context.Context) {
  350. task, err := models.GetMigratingTask(ctx.Repo.Repository.ID)
  351. if err != nil {
  352. ctx.JSON(500, map[string]interface{}{
  353. "err": err,
  354. })
  355. return
  356. }
  357. ctx.JSON(200, map[string]interface{}{
  358. "status": ctx.Repo.Repository.Status,
  359. "err": task.Errors,
  360. })
  361. }