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.8KB

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