Add avatar and issue labels to template repositories (#9149)

* Add avatar and issue labels

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Fix redundant if-err

Signed-off-by: jolheiser <john.olheiser@gmail.com>
This commit is contained in:
John Olheiser 2019-11-24 23:17:51 -06:00 committed by Lunny Xiao
parent 95c3dc856a
commit 62bcb2b7f1
8 changed files with 95 additions and 22 deletions

View file

@ -279,10 +279,9 @@ func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) {
Find(&labels) Find(&labels)
} }
// GetLabelsByRepoID returns all labels that belong to given repository by ID. func getLabelsByRepoID(e Engine, repoID int64, sortType string) ([]*Label, error) {
func GetLabelsByRepoID(repoID int64, sortType string) ([]*Label, error) {
labels := make([]*Label, 0, 10) labels := make([]*Label, 0, 10)
sess := x.Where("repo_id = ?", repoID) sess := e.Where("repo_id = ?", repoID)
switch sortType { switch sortType {
case "reversealphabetically": case "reversealphabetically":
@ -298,6 +297,11 @@ func GetLabelsByRepoID(repoID int64, sortType string) ([]*Label, error) {
return labels, sess.Find(&labels) return labels, sess.Find(&labels)
} }
// GetLabelsByRepoID returns all labels that belong to given repository by ID.
func GetLabelsByRepoID(repoID int64, sortType string) ([]*Label, error) {
return getLabelsByRepoID(x, repoID, sortType)
}
func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) { func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
var labels []*Label var labels []*Label
return labels, e.Where("issue_label.issue_id = ?", issueID). return labels, e.Where("issue_label.issue_id = ?", issueID).

View file

@ -1257,22 +1257,6 @@ type CreateRepoOptions struct {
Status RepositoryStatus Status RepositoryStatus
} }
// GenerateRepoOptions contains the template units to generate
type GenerateRepoOptions struct {
Name string
Description string
Private bool
GitContent bool
Topics bool
GitHooks bool
Webhooks 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 // or other items as they are added
}
func getRepoInitFile(tp, name string) ([]byte, error) { func getRepoInitFile(tp, name string) ([]byte, error) {
cleanedName := strings.TrimLeft(path.Clean("/"+name), "/") cleanedName := strings.TrimLeft(path.Clean("/"+name), "/")
relPath := path.Join("options", tp, cleanedName) relPath := path.Join("options", tp, cleanedName)
@ -2957,8 +2941,12 @@ func (repo *Repository) GetTreePathLock(treePath string) (*LFSLock, error) {
return nil, nil return nil, nil
} }
// UpdateRepositoryCols updates repository's columns func updateRepositoryCols(e Engine, repo *Repository, cols ...string) error {
func UpdateRepositoryCols(repo *Repository, cols ...string) error { _, err := e.ID(repo.ID).Cols(cols...).Update(repo)
_, err := x.ID(repo.ID).Cols(cols...).Update(repo)
return err return err
} }
// UpdateRepositoryCols updates repository's columns
func UpdateRepositoryCols(repo *Repository, cols ...string) error {
return updateRepositoryCols(x, repo, cols...)
}

View file

@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"time" "time"
@ -17,6 +18,24 @@ import (
"github.com/unknwon/com" "github.com/unknwon/com"
) )
// 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
}
// generateRepository initializes repository from template // generateRepository initializes repository from template
func generateRepository(e Engine, repo, templateRepo *Repository) (err error) { func generateRepository(e Engine, repo, templateRepo *Repository) (err error) {
tmpDir := filepath.Join(os.TempDir(), "gitea-"+repo.Name+"-"+com.ToStr(time.Now().Nanosecond())) tmpDir := filepath.Join(os.TempDir(), "gitea-"+repo.Name+"-"+com.ToStr(time.Now().Nanosecond()))
@ -160,3 +179,34 @@ func GenerateWebhooks(ctx DBContext, templateRepo, generateRepo *Repository) err
} }
return nil return nil
} }
// GenerateAvatar generates the avatar from a template repository
func GenerateAvatar(ctx DBContext, templateRepo, generateRepo *Repository) error {
generateRepo.Avatar = strings.Replace(templateRepo.Avatar, strconv.FormatInt(templateRepo.ID, 10), strconv.FormatInt(generateRepo.ID, 10), 1)
if err := com.Copy(templateRepo.CustomAvatarPath(), generateRepo.CustomAvatarPath()); err != nil {
return err
}
return updateRepositoryCols(ctx.e, generateRepo, "avatar")
}
// GenerateIssueLabels generates issue labels from a template repository
func GenerateIssueLabels(ctx DBContext, templateRepo, generateRepo *Repository) error {
templateLabels, err := getLabelsByRepoID(ctx.e, templateRepo.ID, "")
if err != nil {
return err
}
for _, templateLabel := range templateLabels {
generateLabel := &Label{
RepoID: generateRepo.ID,
Name: templateLabel.Name,
Description: templateLabel.Description,
Color: templateLabel.Color,
}
if err := newLabel(ctx.e, generateLabel); err != nil {
return err
}
}
return nil
}

View file

@ -42,6 +42,8 @@ type CreateRepoForm struct {
Topics bool Topics bool
GitHooks bool GitHooks bool
Webhooks bool Webhooks bool
Avatar bool
Labels bool
} }
// Validate validates the fields // Validate validates the fields

View file

@ -641,6 +641,8 @@ template.git_hooks = Git Hooks
template.git_hooks_tooltip = You are currently unable to modify or remove git hooks once added. Select this only if you trust the template repository. template.git_hooks_tooltip = You are currently unable to modify or remove git hooks once added. Select this only if you trust the template repository.
template.webhooks = Webhooks template.webhooks = Webhooks
template.topics = Topics template.topics = Topics
template.avatar = Avatar
template.issue_labels = Issue Labels
template.one_item = Must select at least one template item template.one_item = Must select at least one template item
template.invalid = Must select a template repository template.invalid = Must select a template repository

View file

@ -190,6 +190,8 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) {
Topics: form.Topics, Topics: form.Topics,
GitHooks: form.GitHooks, GitHooks: form.GitHooks,
Webhooks: form.Webhooks, Webhooks: form.Webhooks,
Avatar: form.Avatar,
IssueLabels: form.Labels,
} }
if !opts.IsValid() { if !opts.IsValid() {

View file

@ -47,6 +47,20 @@ func GenerateRepository(doer, owner *models.User, templateRepo *models.Repositor
} }
} }
// Avatar
if opts.Avatar && len(templateRepo.Avatar) > 0 {
if err = models.GenerateAvatar(ctx, templateRepo, generateRepo); err != nil {
return err
}
}
// Issue Labels
if opts.IssueLabels {
if err = models.GenerateIssueLabels(ctx, templateRepo, generateRepo); err != nil {
return err
}
}
return nil return nil
}); err != nil { }); err != nil {
if generateRepo != nil { if generateRepo != nil {

View file

@ -88,6 +88,17 @@
<label>{{.i18n.Tr "repo.template.topics"}}</label> <label>{{.i18n.Tr "repo.template.topics"}}</label>
</div> </div>
</div> </div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input class="hidden" name="avatar" type="checkbox" tabindex="0" {{if .avatar}}checked{{end}}>
<label>{{.i18n.Tr "repo.template.avatar"}}</label>
</div>
<div class="ui checkbox">
<input class="hidden" name="labels" type="checkbox" tabindex="0" {{if .labels}}checked{{end}}>
<label>{{.i18n.Tr "repo.template.issue_labels"}}</label>
</div>
</div>
</div> </div>
<div id="non_template"> <div id="non_template">