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.

repo_generate.go 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Copyright 2019 The Gitea 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 models
  5. import (
  6. "strconv"
  7. "strings"
  8. "code.gitea.io/gitea/modules/git"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/util"
  11. "github.com/gobwas/glob"
  12. "github.com/unknwon/com"
  13. )
  14. // GenerateRepoOptions contains the template units to generate
  15. type GenerateRepoOptions struct {
  16. Name string
  17. Description string
  18. Private bool
  19. GitContent bool
  20. Topics bool
  21. GitHooks bool
  22. Webhooks bool
  23. Avatar bool
  24. IssueLabels bool
  25. }
  26. // IsValid checks whether at least one option is chosen for generation
  27. func (gro GenerateRepoOptions) IsValid() bool {
  28. return gro.GitContent || gro.Topics || gro.GitHooks || gro.Webhooks || gro.Avatar || gro.IssueLabels // or other items as they are added
  29. }
  30. // GiteaTemplate holds information about a .gitea/template file
  31. type GiteaTemplate struct {
  32. Path string
  33. Content []byte
  34. globs []glob.Glob
  35. }
  36. // Globs parses the .gitea/template globs or returns them if they were already parsed
  37. func (gt GiteaTemplate) Globs() []glob.Glob {
  38. if gt.globs != nil {
  39. return gt.globs
  40. }
  41. gt.globs = make([]glob.Glob, 0)
  42. lines := strings.Split(string(util.NormalizeEOL(gt.Content)), "\n")
  43. for _, line := range lines {
  44. line = strings.TrimSpace(line)
  45. if line == "" || strings.HasPrefix(line, "#") {
  46. continue
  47. }
  48. g, err := glob.Compile(line, '/')
  49. if err != nil {
  50. log.Info("Invalid glob expression '%s' (skipped): %v", line, err)
  51. continue
  52. }
  53. gt.globs = append(gt.globs, g)
  54. }
  55. return gt.globs
  56. }
  57. // GenerateTopics generates topics from a template repository
  58. func GenerateTopics(ctx DBContext, templateRepo, generateRepo *Repository) error {
  59. for _, topic := range templateRepo.Topics {
  60. if _, err := addTopicByNameToRepo(ctx.e, generateRepo.ID, topic); err != nil {
  61. return err
  62. }
  63. }
  64. return nil
  65. }
  66. // GenerateGitHooks generates git hooks from a template repository
  67. func GenerateGitHooks(ctx DBContext, templateRepo, generateRepo *Repository) error {
  68. generateGitRepo, err := git.OpenRepository(generateRepo.RepoPath())
  69. if err != nil {
  70. return err
  71. }
  72. defer generateGitRepo.Close()
  73. templateGitRepo, err := git.OpenRepository(templateRepo.RepoPath())
  74. if err != nil {
  75. return err
  76. }
  77. defer templateGitRepo.Close()
  78. templateHooks, err := templateGitRepo.Hooks()
  79. if err != nil {
  80. return err
  81. }
  82. for _, templateHook := range templateHooks {
  83. generateHook, err := generateGitRepo.GetHook(templateHook.Name())
  84. if err != nil {
  85. return err
  86. }
  87. generateHook.Content = templateHook.Content
  88. if err := generateHook.Update(); err != nil {
  89. return err
  90. }
  91. }
  92. return nil
  93. }
  94. // GenerateWebhooks generates webhooks from a template repository
  95. func GenerateWebhooks(ctx DBContext, templateRepo, generateRepo *Repository) error {
  96. templateWebhooks, err := GetWebhooksByRepoID(templateRepo.ID, ListOptions{})
  97. if err != nil {
  98. return err
  99. }
  100. for _, templateWebhook := range templateWebhooks {
  101. generateWebhook := &Webhook{
  102. RepoID: generateRepo.ID,
  103. URL: templateWebhook.URL,
  104. HTTPMethod: templateWebhook.HTTPMethod,
  105. ContentType: templateWebhook.ContentType,
  106. Secret: templateWebhook.Secret,
  107. HookEvent: templateWebhook.HookEvent,
  108. IsActive: templateWebhook.IsActive,
  109. HookTaskType: templateWebhook.HookTaskType,
  110. OrgID: templateWebhook.OrgID,
  111. Events: templateWebhook.Events,
  112. Meta: templateWebhook.Meta,
  113. }
  114. if err := createWebhook(ctx.e, generateWebhook); err != nil {
  115. return err
  116. }
  117. }
  118. return nil
  119. }
  120. // GenerateAvatar generates the avatar from a template repository
  121. func GenerateAvatar(ctx DBContext, templateRepo, generateRepo *Repository) error {
  122. generateRepo.Avatar = strings.Replace(templateRepo.Avatar, strconv.FormatInt(templateRepo.ID, 10), strconv.FormatInt(generateRepo.ID, 10), 1)
  123. if err := com.Copy(templateRepo.CustomAvatarPath(), generateRepo.CustomAvatarPath()); err != nil {
  124. return err
  125. }
  126. return updateRepositoryCols(ctx.e, generateRepo, "avatar")
  127. }
  128. // GenerateIssueLabels generates issue labels from a template repository
  129. func GenerateIssueLabels(ctx DBContext, templateRepo, generateRepo *Repository) error {
  130. templateLabels, err := getLabelsByRepoID(ctx.e, templateRepo.ID, "", ListOptions{})
  131. if err != nil {
  132. return err
  133. }
  134. for _, templateLabel := range templateLabels {
  135. generateLabel := &Label{
  136. RepoID: generateRepo.ID,
  137. Name: templateLabel.Name,
  138. Description: templateLabel.Description,
  139. Color: templateLabel.Color,
  140. }
  141. if err := newLabel(ctx.e, generateLabel); err != nil {
  142. return err
  143. }
  144. }
  145. return nil
  146. }