From 0118b6aaf8ada3edd67cb975c776f6f124178ad2 Mon Sep 17 00:00:00 2001 From: John Olheiser <42128690+jolheiser@users.noreply.github.com> Date: Sun, 8 Sep 2019 03:28:40 -0500 Subject: [PATCH] Add option to initialize repository with labels (#6061) * Add optional label sets on repo creation * Fix CRLF * Instead of hardcoding default, make it the helper * Move label set init out of repo init Add a new error for the router Combine router label init with repo creation label init Signed-off-by: jolheiser * Add issue labels to Swagger for repo creation Signed-off-by: jolheiser * Update models/issue_label.go Co-Authored-By: Lauris BH * Update models/issue_label.go Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> --- models/error.go | 16 ++++++++++++++++ models/issue_label.go | 28 ++++++++++++++++++++++++++++ models/repo.go | 8 ++++++++ modules/auth/repo_form.go | 1 + modules/structs/repo.go | 2 ++ options/locale/locale_en-US.ini | 2 ++ routers/api/v1/repo/repo.go | 1 + routers/repo/issue_label.go | 23 +++++++---------------- routers/repo/repo.go | 3 +++ templates/repo/create.tmpl | 14 ++++++++++++++ templates/swagger/v1_json.tmpl | 5 +++++ 11 files changed, 87 insertions(+), 16 deletions(-) diff --git a/models/error.go b/models/error.go index 11ca6e686..cecd03f99 100644 --- a/models/error.go +++ b/models/error.go @@ -1058,6 +1058,22 @@ func (err ErrIssueNotExist) Error() string { return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) } +// ErrIssueLabelTemplateLoad represents a "ErrIssueLabelTemplateLoad" kind of error. +type ErrIssueLabelTemplateLoad struct { + TemplateFile string + OriginalError error +} + +// IsErrIssueLabelTemplateLoad checks if an error is a ErrIssueLabelTemplateLoad. +func IsErrIssueLabelTemplateLoad(err error) bool { + _, ok := err.(ErrIssueLabelTemplateLoad) + return ok +} + +func (err ErrIssueLabelTemplateLoad) Error() string { + return fmt.Sprintf("Failed to load label template file '%s': %v", err.TemplateFile, err.OriginalError) +} + // __________ .__ .__ __________ __ // \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_ // | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\ diff --git a/models/issue_label.go b/models/issue_label.go index 686897f63..f378f62e6 100644 --- a/models/issue_label.go +++ b/models/issue_label.go @@ -127,6 +127,34 @@ func (label *Label) ForegroundColor() template.CSS { return template.CSS("#000") } +func initalizeLabels(e Engine, repoID int64, labelTemplate string) error { + list, err := GetLabelTemplateFile(labelTemplate) + if err != nil { + return ErrIssueLabelTemplateLoad{labelTemplate, err} + } + + labels := make([]*Label, len(list)) + for i := 0; i < len(list); i++ { + labels[i] = &Label{ + RepoID: repoID, + Name: list[i][0], + Description: list[i][2], + Color: list[i][1], + } + } + for _, label := range labels { + if err = newLabel(e, label); err != nil { + return err + } + } + return nil +} + +// InitalizeLabels adds a label set to a repository using a template +func InitalizeLabels(repoID int64, labelTemplate string) error { + return initalizeLabels(x, repoID, labelTemplate) +} + func newLabel(e Engine, label *Label) error { _, err := e.Insert(label) return err diff --git a/models/repo.go b/models/repo.go index 507521357..3e593ce4e 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1098,6 +1098,7 @@ type CreateRepoOptions struct { Description string OriginalURL string Gitignores string + IssueLabels string License string Readme string IsPrivate bool @@ -1394,6 +1395,13 @@ func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err return nil, fmt.Errorf("initRepository: %v", err) } + // Initialize Issue Labels if selected + if len(opts.IssueLabels) > 0 { + if err = initalizeLabels(sess, repo.ID, opts.IssueLabels); err != nil { + return nil, fmt.Errorf("initalizeLabels: %v", err) + } + } + _, stderr, err := process.GetManager().ExecDir(-1, repoPath, fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath), git.GitExecutable, "update-server-info") diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index bb9be70e8..418f6d387 100644 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -33,6 +33,7 @@ type CreateRepoForm struct { Description string `binding:"MaxSize(255)"` AutoInit bool Gitignores string + IssueLabels string License string Readme string } diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 81203319e..d94980fca 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -67,6 +67,8 @@ type CreateRepoOption struct { Description string `json:"description" binding:"MaxSize(255)"` // Whether the repository is private Private bool `json:"private"` + // Issue Label set to use + IssueLabels string `json:"issue_labels"` // Whether the repository should be auto-intialized? AutoInit bool `json:"auto_init"` // Gitignores to use diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index e57772731..a72263d08 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -578,6 +578,8 @@ fork_visibility_helper = The visibility of a forked repository cannot be changed repo_desc = Description repo_lang = Language repo_gitignore_helper = Select .gitignore templates. +issue_labels = Issue Labels +issue_labels_helper = Select an issue label set. license = License license_helper = Select a license file. readme = README diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 82bfa58b7..c838ba727 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -206,6 +206,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR repo, err := models.CreateRepository(ctx.User, owner, models.CreateRepoOptions{ Name: opt.Name, Description: opt.Description, + IssueLabels: opt.IssueLabels, Gitignores: opt.Gitignores, License: opt.License, Readme: opt.Readme, diff --git a/routers/repo/issue_label.go b/routers/repo/issue_label.go index cae6535c7..452a0a4c0 100644 --- a/routers/repo/issue_label.go +++ b/routers/repo/issue_label.go @@ -33,24 +33,15 @@ func InitializeLabels(ctx *context.Context, form auth.InitializeLabelsForm) { ctx.Redirect(ctx.Repo.RepoLink + "/labels") return } - list, err := models.GetLabelTemplateFile(form.TemplateName) - if err != nil { - ctx.Flash.Error(ctx.Tr("repo.issues.label_templates.fail_to_load_file", form.TemplateName, err)) - ctx.Redirect(ctx.Repo.RepoLink + "/labels") - return - } - labels := make([]*models.Label, len(list)) - for i := 0; i < len(list); i++ { - labels[i] = &models.Label{ - RepoID: ctx.Repo.Repository.ID, - Name: list[i][0], - Description: list[i][2], - Color: list[i][1], + if err := models.InitalizeLabels(ctx.Repo.Repository.ID, form.TemplateName); err != nil { + if models.IsErrIssueLabelTemplateLoad(err) { + originalErr := err.(models.ErrIssueLabelTemplateLoad).OriginalError + ctx.Flash.Error(ctx.Tr("repo.issues.label_templates.fail_to_load_file", form.TemplateName, originalErr)) + ctx.Redirect(ctx.Repo.RepoLink + "/labels") + return } - } - if err := models.NewLabels(labels...); err != nil { - ctx.ServerError("NewLabels", err) + ctx.ServerError("InitalizeLabels", err) return } ctx.Redirect(ctx.Repo.RepoLink + "/labels") diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 53244f304..b67384d72 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -115,6 +115,7 @@ func Create(ctx *context.Context) { // Give default value for template to render. ctx.Data["Gitignores"] = models.Gitignores + ctx.Data["LabelTemplates"] = models.LabelTemplates ctx.Data["Licenses"] = models.Licenses ctx.Data["Readmes"] = models.Readmes ctx.Data["readme"] = "Default" @@ -155,6 +156,7 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) { ctx.Data["Title"] = ctx.Tr("new_repo") ctx.Data["Gitignores"] = models.Gitignores + ctx.Data["LabelTemplates"] = models.LabelTemplates ctx.Data["Licenses"] = models.Licenses ctx.Data["Readmes"] = models.Readmes @@ -173,6 +175,7 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) { Name: form.RepoName, Description: form.Description, Gitignores: form.Gitignores, + IssueLabels: form.IssueLabels, License: form.License, Readme: form.Readme, IsPrivate: form.Private || setting.Repository.ForcePrivate, diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index 8163aaefa..1a53e3c89 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -56,6 +56,20 @@ +
+ + +
+
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 8cf22251a..33c0c38f8 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -7843,6 +7843,11 @@ "type": "string", "x-go-name": "Gitignores" }, + "issue_labels": { + "description": "Issue Label set to use", + "type": "string", + "x-go-name": "IssueLabels" + }, "license": { "description": "License to use", "type": "string",