2019-11-24 11:57:52 -06:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
2021-04-20 06:25:08 +08:00
"bufio"
"bytes"
2021-09-23 16:45:36 +01:00
"context"
2019-11-24 23:17:51 -06:00
"strconv"
2019-11-24 11:57:52 -06:00
"strings"
2021-09-19 19:49:59 +08:00
"code.gitea.io/gitea/models/db"
2019-11-24 11:57:52 -06:00
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
2020-10-14 21:07:51 +08:00
"code.gitea.io/gitea/modules/storage"
2019-11-24 11:57:52 -06:00
2019-11-30 00:54:47 -06:00
"github.com/gobwas/glob"
2019-11-24 11:57:52 -06:00
)
2019-11-24 23:17:51 -06:00
// GenerateRepoOptions contains the template units to generate
type GenerateRepoOptions struct {
Name string
Description string
Private bool
GitContent bool
Topics bool
GitHooks bool
Webhooks bool
Avatar bool
IssueLabels bool
}
// IsValid checks whether at least one option is chosen for generation
func ( gro GenerateRepoOptions ) IsValid ( ) bool {
return gro . GitContent || gro . Topics || gro . GitHooks || gro . Webhooks || gro . Avatar || gro . IssueLabels // or other items as they are added
}
2019-11-30 00:54:47 -06:00
// GiteaTemplate holds information about a .gitea/template file
type GiteaTemplate struct {
Path string
Content [ ] byte
globs [ ] glob . Glob
}
// Globs parses the .gitea/template globs or returns them if they were already parsed
func ( gt GiteaTemplate ) Globs ( ) [ ] glob . Glob {
if gt . globs != nil {
return gt . globs
}
gt . globs = make ( [ ] glob . Glob , 0 )
2021-04-20 06:25:08 +08:00
scanner := bufio . NewScanner ( bytes . NewReader ( gt . Content ) )
for scanner . Scan ( ) {
line := strings . TrimSpace ( scanner . Text ( ) )
2019-11-30 00:54:47 -06:00
if line == "" || strings . HasPrefix ( line , "#" ) {
continue
}
g , err := glob . Compile ( line , '/' )
if err != nil {
log . Info ( "Invalid glob expression '%s' (skipped): %v" , line , err )
continue
}
gt . globs = append ( gt . globs , g )
}
return gt . globs
}
2019-11-24 11:57:52 -06:00
// GenerateTopics generates topics from a template repository
2021-09-23 16:45:36 +01:00
func GenerateTopics ( ctx context . Context , templateRepo , generateRepo * Repository ) error {
2019-11-24 11:57:52 -06:00
for _ , topic := range templateRepo . Topics {
2021-09-23 16:45:36 +01:00
if _ , err := addTopicByNameToRepo ( db . GetEngine ( ctx ) , generateRepo . ID , topic ) ; err != nil {
2019-11-24 11:57:52 -06:00
return err
}
}
return nil
}
// GenerateGitHooks generates git hooks from a template repository
2021-09-23 16:45:36 +01:00
func GenerateGitHooks ( ctx context . Context , templateRepo , generateRepo * Repository ) error {
2020-01-12 17:36:21 +08:00
generateGitRepo , err := git . OpenRepository ( generateRepo . RepoPath ( ) )
2019-11-24 11:57:52 -06:00
if err != nil {
return err
}
defer generateGitRepo . Close ( )
2020-01-12 17:36:21 +08:00
templateGitRepo , err := git . OpenRepository ( templateRepo . RepoPath ( ) )
2019-11-24 11:57:52 -06:00
if err != nil {
return err
}
defer templateGitRepo . Close ( )
templateHooks , err := templateGitRepo . Hooks ( )
if err != nil {
return err
}
for _ , templateHook := range templateHooks {
generateHook , err := generateGitRepo . GetHook ( templateHook . Name ( ) )
if err != nil {
return err
}
generateHook . Content = templateHook . Content
if err := generateHook . Update ( ) ; err != nil {
return err
}
}
return nil
}
// GenerateWebhooks generates webhooks from a template repository
2021-09-23 16:45:36 +01:00
func GenerateWebhooks ( ctx context . Context , templateRepo , generateRepo * Repository ) error {
2021-08-12 14:43:08 +02:00
templateWebhooks , err := ListWebhooksByOpts ( & ListWebhookOptions { RepoID : templateRepo . ID } )
2019-11-24 11:57:52 -06:00
if err != nil {
return err
}
for _ , templateWebhook := range templateWebhooks {
generateWebhook := & Webhook {
2020-12-10 01:20:13 +08:00
RepoID : generateRepo . ID ,
URL : templateWebhook . URL ,
HTTPMethod : templateWebhook . HTTPMethod ,
ContentType : templateWebhook . ContentType ,
Secret : templateWebhook . Secret ,
HookEvent : templateWebhook . HookEvent ,
IsActive : templateWebhook . IsActive ,
Type : templateWebhook . Type ,
OrgID : templateWebhook . OrgID ,
Events : templateWebhook . Events ,
Meta : templateWebhook . Meta ,
2019-11-24 11:57:52 -06:00
}
2021-09-23 16:45:36 +01:00
if err := createWebhook ( db . GetEngine ( ctx ) , generateWebhook ) ; err != nil {
2019-11-24 11:57:52 -06:00
return err
}
}
return nil
}
2019-11-24 23:17:51 -06:00
// GenerateAvatar generates the avatar from a template repository
2021-09-23 16:45:36 +01:00
func GenerateAvatar ( ctx context . Context , templateRepo , generateRepo * Repository ) error {
2019-11-24 23:17:51 -06:00
generateRepo . Avatar = strings . Replace ( templateRepo . Avatar , strconv . FormatInt ( templateRepo . ID , 10 ) , strconv . FormatInt ( generateRepo . ID , 10 ) , 1 )
2020-10-14 21:07:51 +08:00
if _ , err := storage . Copy ( storage . RepoAvatars , generateRepo . CustomAvatarRelativePath ( ) , storage . RepoAvatars , templateRepo . CustomAvatarRelativePath ( ) ) ; err != nil {
2019-11-24 23:17:51 -06:00
return err
}
2021-09-23 16:45:36 +01:00
return updateRepositoryCols ( db . GetEngine ( ctx ) , generateRepo , "avatar" )
2019-11-24 23:17:51 -06:00
}
// GenerateIssueLabels generates issue labels from a template repository
2021-09-23 16:45:36 +01:00
func GenerateIssueLabels ( ctx context . Context , templateRepo , generateRepo * Repository ) error {
2021-09-24 19:32:56 +08:00
templateLabels , err := getLabelsByRepoID ( db . GetEngine ( ctx ) , templateRepo . ID , "" , db . ListOptions { } )
2019-11-24 23:17:51 -06:00
if err != nil {
return err
}
for _ , templateLabel := range templateLabels {
generateLabel := & Label {
RepoID : generateRepo . ID ,
Name : templateLabel . Name ,
Description : templateLabel . Description ,
Color : templateLabel . Color ,
}
2021-09-23 16:45:36 +01:00
if err := newLabel ( db . GetEngine ( ctx ) , generateLabel ) ; err != nil {
2019-11-24 23:17:51 -06:00
return err
}
}
return nil
}