mirror of
https://github.com/go-gitea/gitea.git
synced 2024-12-04 14:46:57 -05:00
Make commit trailer parsing public and add parameterized tests
This commit is contained in:
parent
25a9f121b5
commit
8e3209b09a
42
modules/util/commit_trailers.go
Normal file
42
modules/util/commit_trailers.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/mail"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrInvalidCommitTrailerValueSyntax = errors.New("syntax error occurred while parsing a commit trailer value")
|
||||||
|
|
||||||
|
// ParseCommitTrailerValueWithAuthor parses a commit trailer value that contains author data.
|
||||||
|
// Note that it only parses the value and does not consider the trailer key i.e. we just
|
||||||
|
// parse something like the following:
|
||||||
|
//
|
||||||
|
// Foo Bar <foobar@example.com>
|
||||||
|
func ParseCommitTrailerValueWithAuthor(value string) (name, email string, err error) {
|
||||||
|
value = strings.TrimSpace(value)
|
||||||
|
if !strings.HasSuffix(value, ">") {
|
||||||
|
return "", "", ErrInvalidCommitTrailerValueSyntax
|
||||||
|
}
|
||||||
|
|
||||||
|
closedBracketIdx := len(value) - 1
|
||||||
|
openBracketIdx := strings.LastIndex(value, "<")
|
||||||
|
if openBracketIdx == -1 {
|
||||||
|
return "", "", ErrInvalidCommitTrailerValueSyntax
|
||||||
|
}
|
||||||
|
|
||||||
|
email = value[openBracketIdx+1 : closedBracketIdx]
|
||||||
|
if _, err := mail.ParseAddress(email); err != nil {
|
||||||
|
return "", "", ErrInvalidCommitTrailerValueSyntax
|
||||||
|
}
|
||||||
|
|
||||||
|
name = strings.TrimSpace(value[:openBracketIdx])
|
||||||
|
if len(name) == 0 {
|
||||||
|
return "", "", ErrInvalidCommitTrailerValueSyntax
|
||||||
|
}
|
||||||
|
|
||||||
|
return name, email, nil
|
||||||
|
}
|
37
modules/util/commit_trailers_test.go
Normal file
37
modules/util/commit_trailers_test.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseCommitTrailerValueWithAuthor(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
input string
|
||||||
|
shouldBeError bool
|
||||||
|
expectedName string
|
||||||
|
expectedEmail string
|
||||||
|
}{
|
||||||
|
{"Foo Bar <foobar@example.com", true, "", ""},
|
||||||
|
{"Foo Bar foobar@example.com>", true, "", ""},
|
||||||
|
{"Foo Bar <>", true, "", ""},
|
||||||
|
{"Foo Bar <invalid-email-address>", true, "", ""},
|
||||||
|
{"<foobar@example.com>", true, "", ""},
|
||||||
|
{" <foobar@example.com>", true, "", ""},
|
||||||
|
{"Foo Bar <foobar@example.com>", false, "Foo Bar", "foobar@example.com"},
|
||||||
|
{" Foo Bar <foobar@example.com>", false, "Foo Bar", "foobar@example.com"},
|
||||||
|
// Account for edge case where name contains an open bracket.
|
||||||
|
{" Foo < Bar <foobar@example.com>", false, "Foo < Bar", "foobar@example.com"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for n, c := range cases {
|
||||||
|
name, email, err := ParseCommitTrailerValueWithAuthor(c.input)
|
||||||
|
if c.shouldBeError {
|
||||||
|
assert.Error(t, err, "case %d should be a syntax error", n)
|
||||||
|
} else {
|
||||||
|
assert.Equal(t, c.expectedName, name, "case %d should have correct name", n)
|
||||||
|
assert.Equal(t, c.expectedEmail, email, "case %d should have correct email", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/mail"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -24,6 +23,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -159,7 +159,7 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int
|
|||||||
// There should be an empty line before we read the commit stats line.
|
// There should be an empty line before we read the commit stats line.
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
coAuthorName, coAuthorEmail, err := parseCoAuthorTrailerValue(line)
|
coAuthorName, coAuthorEmail, err := util.ParseCommitTrailerValueWithAuthor(line)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -220,33 +220,6 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int
|
|||||||
return extendedCommitStats, nil
|
return extendedCommitStats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var errSyntax = errors.New("syntax error occurred")
|
|
||||||
|
|
||||||
func parseCoAuthorTrailerValue(value string) (name, email string, err error) {
|
|
||||||
value = strings.TrimSpace(value)
|
|
||||||
if !strings.HasSuffix(value, ">") {
|
|
||||||
return "", "", errSyntax
|
|
||||||
}
|
|
||||||
|
|
||||||
closedBracketIdx := len(value) - 1
|
|
||||||
openBracketIdx := strings.LastIndex(value, "<")
|
|
||||||
if openBracketIdx == -1 {
|
|
||||||
return "", "", errSyntax
|
|
||||||
}
|
|
||||||
|
|
||||||
email = value[openBracketIdx+1 : closedBracketIdx]
|
|
||||||
if _, err := mail.ParseAddress(email); err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
name = strings.TrimSpace(value[:openBracketIdx])
|
|
||||||
if len(name) == 0 {
|
|
||||||
return "", "", errSyntax
|
|
||||||
}
|
|
||||||
|
|
||||||
return name, email, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateContributorStats(genDone chan struct{}, cache cache.StringCache, cacheKey string, repo *repo_model.Repository, revision string) {
|
func generateContributorStats(genDone chan struct{}, cache cache.StringCache, cacheKey string, repo *repo_model.Repository, revision string) {
|
||||||
ctx := graceful.GetManager().HammerContext()
|
ctx := graceful.GetManager().HammerContext()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user