aboutsummaryrefslogtreecommitdiffstats
path: root/modules/structs
diff options
context:
space:
mode:
authorJason Song <i@wolfogre.com>2022-11-19 23:22:15 +0800
committerGitHub <noreply@github.com>2022-11-19 15:22:15 +0000
commitd3f850cc0e791fa5ee5b25d824c475505fc12444 (patch)
tree67dd48f57356446fb2de93ca149e2c04f2ccc74f /modules/structs
parentc8f3eb6acbf16b9f2e74fa2bfabb384359fbadd8 (diff)
downloadgitea-d3f850cc0e791fa5ee5b25d824c475505fc12444.tar.gz
gitea-d3f850cc0e791fa5ee5b25d824c475505fc12444.zip
Support comma-delimited string as labels in issue template (#21831)
The [labels in issue YAML templates](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms#top-level-syntax) can be a string array or a comma-delimited string, so a single string should be valid labels. The old codes committed in #20987 ignore this, that's why the warning is displayed: <img width="618" alt="image" src="https://user-images.githubusercontent.com/9418365/202112642-93dc72d0-71c3-40a2-9720-30fc2d48c97c.png"> Fixes #17877.
Diffstat (limited to 'modules/structs')
-rw-r--r--modules/structs/issue.go53
-rw-r--r--modules/structs/issue_test.go63
2 files changed, 108 insertions, 8 deletions
diff --git a/modules/structs/issue.go b/modules/structs/issue.go
index 25c6251fbf..45c3f6294a 100644
--- a/modules/structs/issue.go
+++ b/modules/structs/issue.go
@@ -5,8 +5,12 @@
package structs
import (
+ "fmt"
"path"
+ "strings"
"time"
+
+ "gopkg.in/yaml.v3"
)
// StateType issue state type
@@ -143,14 +147,47 @@ type IssueFormField struct {
// IssueTemplate represents an issue template for a repository
// swagger:model
type IssueTemplate struct {
- Name string `json:"name" yaml:"name"`
- Title string `json:"title" yaml:"title"`
- About string `json:"about" yaml:"about"` // Using "description" in a template file is compatible
- Labels []string `json:"labels" yaml:"labels"`
- Ref string `json:"ref" yaml:"ref"`
- Content string `json:"content" yaml:"-"`
- Fields []*IssueFormField `json:"body" yaml:"body"`
- FileName string `json:"file_name" yaml:"-"`
+ Name string `json:"name" yaml:"name"`
+ Title string `json:"title" yaml:"title"`
+ About string `json:"about" yaml:"about"` // Using "description" in a template file is compatible
+ Labels IssueTemplateLabels `json:"labels" yaml:"labels"`
+ Ref string `json:"ref" yaml:"ref"`
+ Content string `json:"content" yaml:"-"`
+ Fields []*IssueFormField `json:"body" yaml:"body"`
+ FileName string `json:"file_name" yaml:"-"`
+}
+
+type IssueTemplateLabels []string
+
+func (l *IssueTemplateLabels) UnmarshalYAML(value *yaml.Node) error {
+ var labels []string
+ if value.IsZero() {
+ *l = labels
+ return nil
+ }
+ switch value.Kind {
+ case yaml.ScalarNode:
+ str := ""
+ err := value.Decode(&str)
+ if err != nil {
+ return err
+ }
+ for _, v := range strings.Split(str, ",") {
+ if v = strings.TrimSpace(v); v == "" {
+ continue
+ }
+ labels = append(labels, v)
+ }
+ *l = labels
+ return nil
+ case yaml.SequenceNode:
+ if err := value.Decode(&labels); err != nil {
+ return err
+ }
+ *l = labels
+ return nil
+ }
+ return fmt.Errorf("line %d: cannot unmarshal %s into IssueTemplateLabels", value.Line, value.ShortTag())
}
// IssueTemplateType defines issue template type
diff --git a/modules/structs/issue_test.go b/modules/structs/issue_test.go
index 5312585d0f..72b40f7cf2 100644
--- a/modules/structs/issue_test.go
+++ b/modules/structs/issue_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "gopkg.in/yaml.v3"
)
func TestIssueTemplate_Type(t *testing.T) {
@@ -41,3 +42,65 @@ func TestIssueTemplate_Type(t *testing.T) {
})
}
}
+
+func TestIssueTemplateLabels_UnmarshalYAML(t *testing.T) {
+ tests := []struct {
+ name string
+ content string
+ tmpl *IssueTemplate
+ want *IssueTemplate
+ wantErr string
+ }{
+ {
+ name: "array",
+ content: `labels: ["a", "b", "c"]`,
+ tmpl: &IssueTemplate{
+ Labels: []string{"should_be_overwrote"},
+ },
+ want: &IssueTemplate{
+ Labels: []string{"a", "b", "c"},
+ },
+ },
+ {
+ name: "string",
+ content: `labels: "a,b,c"`,
+ tmpl: &IssueTemplate{
+ Labels: []string{"should_be_overwrote"},
+ },
+ want: &IssueTemplate{
+ Labels: []string{"a", "b", "c"},
+ },
+ },
+ {
+ name: "empty",
+ content: `labels:`,
+ tmpl: &IssueTemplate{
+ Labels: []string{"should_be_overwrote"},
+ },
+ want: &IssueTemplate{
+ Labels: nil,
+ },
+ },
+ {
+ name: "error",
+ content: `
+labels:
+ a: aa
+ b: bb
+`,
+ tmpl: &IssueTemplate{},
+ wantErr: "line 3: cannot unmarshal !!map into IssueTemplateLabels",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ err := yaml.Unmarshal([]byte(tt.content), tt.tmpl)
+ if tt.wantErr != "" {
+ assert.EqualError(t, err, tt.wantErr)
+ } else {
+ assert.NoError(t, err)
+ assert.Equal(t, tt.want, tt.tmpl)
+ }
+ })
+ }
+}