-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Fix markdown meta parsing #12817
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix markdown meta parsing #12817
Changes from all commits
5c3b10a
a4e85b1
9961cca
ee8e0a6
33b28af
8e02820
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,20 +25,22 @@ func isYAMLSeparator(line string) bool { | |
| // and returns the frontmatter metadata separated from the markdown content | ||
| func ExtractMetadata(contents string, out interface{}) (string, error) { | ||
| var front, body []string | ||
| var seps int | ||
| lines := strings.Split(contents, "\n") | ||
| for idx, line := range lines { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's better to use scanner := bufio.NewScanner(strings.NewReader(contents))
var idx = 0
for scanner.Scan() {
line := scanner.Text()
...
idx++
}
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the advantage in this case?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Less CPU and memory usage. But since it should be a small file, it's not necessary. |
||
| if seps == 2 { | ||
| front, body = lines[:idx], lines[idx:] | ||
| break | ||
| if idx == 0 { | ||
| // First line has to be a separator | ||
| if !isYAMLSeparator(line) { | ||
| return "", errors.New("frontmatter must start with a separator line") | ||
| } | ||
| continue | ||
| } | ||
| if isYAMLSeparator(line) { | ||
| seps++ | ||
| continue | ||
| front, body = lines[1:idx], lines[idx+1:] | ||
| break | ||
| } | ||
| } | ||
|
|
||
| if len(front) == 0 && len(body) == 0 { | ||
| if len(front) == 0 { | ||
| return "", errors.New("could not determine metadata") | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| // Copyright 2020 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 markdown | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "testing" | ||
|
|
||
| "code.gitea.io/gitea/modules/structs" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| func TestExtractMetadata(t *testing.T) { | ||
| t.Run("ValidFrontAndBody", func(t *testing.T) { | ||
| var meta structs.IssueTemplate | ||
| body, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s\n%s", sepTest, frontTest, sepTest, bodyTest), &meta) | ||
| assert.NoError(t, err) | ||
| assert.Equal(t, body, bodyTest) | ||
| assert.Equal(t, metaTest, meta) | ||
| assert.True(t, meta.Valid()) | ||
| }) | ||
|
|
||
| t.Run("NoFirstSeparator", func(t *testing.T) { | ||
| var meta structs.IssueTemplate | ||
| _, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", frontTest, sepTest, bodyTest), &meta) | ||
| assert.Error(t, err) | ||
| }) | ||
|
|
||
| t.Run("NoLastSeparator", func(t *testing.T) { | ||
| var meta structs.IssueTemplate | ||
| _, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, bodyTest), &meta) | ||
| assert.Error(t, err) | ||
| }) | ||
|
|
||
| t.Run("NoBody", func(t *testing.T) { | ||
| var meta structs.IssueTemplate | ||
| body, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, sepTest), &meta) | ||
| assert.NoError(t, err) | ||
| assert.Equal(t, body, "") | ||
| assert.Equal(t, metaTest, meta) | ||
| assert.True(t, meta.Valid()) | ||
| }) | ||
| } | ||
|
|
||
| var ( | ||
| sepTest = "-----" | ||
| frontTest = `name: Test | ||
| about: "A Test" | ||
| title: "Test Title" | ||
| labels: | ||
| - bug | ||
| - "test label"` | ||
| bodyTest = "This is the body" | ||
| metaTest = structs.IssueTemplate{ | ||
| Name: "Test", | ||
| About: "A Test", | ||
| Title: "Test Title", | ||
| Labels: []string{"bug", "test label"}, | ||
| } | ||
| ) |
Uh oh!
There was an error while loading. Please reload this page.