mirror of
https://github.com/romdo/go-conver.git
synced 2026-02-19 08:16:40 +00:00
wip: add parseHeader function
This commit is contained in:
@@ -3,11 +3,12 @@
|
||||
package commit
|
||||
|
||||
type Commit struct {
|
||||
Type string
|
||||
Scope string
|
||||
Description string
|
||||
Body string
|
||||
Footers []Footer
|
||||
Type string
|
||||
Scope string
|
||||
Subject string
|
||||
Body string
|
||||
Footers []*Footer
|
||||
IsBreaking bool
|
||||
}
|
||||
|
||||
type Footer struct {
|
||||
|
||||
@@ -1,21 +1,51 @@
|
||||
package commit
|
||||
|
||||
import "bytes"
|
||||
|
||||
const (
|
||||
cr = 13
|
||||
lf = 10
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func paragraphs(input []byte) [][]byte {
|
||||
cln := bytes.ReplaceAll(input, []byte{cr, lf}, []byte{lf})
|
||||
cln = bytes.ReplaceAll(cln, []byte{cr}, []byte{lf})
|
||||
const (
|
||||
cr = 13
|
||||
lf = 10
|
||||
crlf = "\r\n"
|
||||
)
|
||||
|
||||
ps := bytes.Split(cln, []byte{lf, lf})
|
||||
var rHeader = regexp.MustCompile(
|
||||
`^([\w\-]*)(?:\(([\w\$\.\/\-\* ]*)\))?(!)?\: (.*)$`,
|
||||
)
|
||||
|
||||
for i, p := range ps {
|
||||
ps[i] = bytes.Trim(p, "\r\n")
|
||||
func parseHeader(header []byte) (*Commit, error) {
|
||||
if bytes.ContainsAny(header, crlf) {
|
||||
return nil, errors.New("header cannot span multiple lines")
|
||||
}
|
||||
|
||||
return ps
|
||||
result := rHeader.FindSubmatch(header)
|
||||
if result == nil {
|
||||
return &Commit{Subject: string(header)}, nil
|
||||
}
|
||||
|
||||
return &Commit{
|
||||
Type: string(result[1]),
|
||||
Scope: string(result[2]),
|
||||
Subject: string(result[4]),
|
||||
IsBreaking: (string(result[3]) == "!"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func paragraphs(input []byte) [][]byte {
|
||||
paras := bytes.Split(normlizeLinefeeds(input), []byte{lf, lf})
|
||||
for i, p := range paras {
|
||||
paras[i] = bytes.Trim(p, crlf)
|
||||
}
|
||||
|
||||
return paras
|
||||
}
|
||||
|
||||
func normlizeLinefeeds(input []byte) []byte {
|
||||
return bytes.ReplaceAll(
|
||||
bytes.ReplaceAll(input, []byte{cr, lf}, []byte{lf}),
|
||||
[]byte{cr}, []byte{lf},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,175 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_parseHeader(t *testing.T) {
|
||||
type args struct {
|
||||
header []byte
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *Commit
|
||||
errStr string
|
||||
}{
|
||||
{
|
||||
name: "non-convention commit",
|
||||
args: args{header: []byte("add user sorting option")},
|
||||
want: &Commit{Subject: "add user sorting option"},
|
||||
},
|
||||
{
|
||||
name: "type only",
|
||||
args: args{header: []byte("feat: add user sorting option")},
|
||||
want: &Commit{Type: "feat", Subject: "add user sorting option"},
|
||||
},
|
||||
{
|
||||
name: "type and scope",
|
||||
args: args{header: []byte("feat(user): add user sorting option")},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "user",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "type and breaking",
|
||||
args: args{header: []byte("feat!: add user sorting option")},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Subject: "add user sorting option",
|
||||
IsBreaking: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "type, scope and breaking",
|
||||
args: args{header: []byte("feat(user)!: add user sorting option")},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "user",
|
||||
Subject: "add user sorting option",
|
||||
IsBreaking: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "type with underscore (_)",
|
||||
args: args{header: []byte("int_feat: add user sorting option")},
|
||||
want: &Commit{
|
||||
Type: "int_feat",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "type with hyphen (-)",
|
||||
args: args{header: []byte("int-feat: add user sorting option")},
|
||||
want: &Commit{
|
||||
Type: "int-feat",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scope with underscopre (_)",
|
||||
args: args{
|
||||
header: []byte("feat(user_sort): add user sorting option"),
|
||||
},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "user_sort",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scope with hyphen (-)",
|
||||
args: args{
|
||||
header: []byte("feat(user-sort): add user sorting option"),
|
||||
},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "user-sort",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scope with slash (/)",
|
||||
args: args{
|
||||
header: []byte("feat(user/sort): add user sorting option"),
|
||||
},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "user/sort",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scope with period (.)",
|
||||
args: args{
|
||||
header: []byte("feat(user.sort): add user sorting option"),
|
||||
},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "user.sort",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scope with dollar sign ($)",
|
||||
args: args{
|
||||
header: []byte("feat($user): add user sorting option"),
|
||||
},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "$user",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scope with star (*)",
|
||||
args: args{
|
||||
header: []byte("feat(user*): add user sorting option"),
|
||||
},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "user*",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scope with space ( )",
|
||||
args: args{
|
||||
header: []byte("feat(user sort): add user sorting option"),
|
||||
},
|
||||
want: &Commit{
|
||||
Type: "feat",
|
||||
Scope: "user sort",
|
||||
Subject: "add user sorting option",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multi-line header (LF)",
|
||||
args: args{
|
||||
header: []byte("feat(user)!: add usersorting\noption"),
|
||||
},
|
||||
errStr: "header cannot span multiple lines",
|
||||
},
|
||||
{
|
||||
name: "multi-line header (CR)",
|
||||
args: args{
|
||||
header: []byte("feat(user)!: add usersorting\roption"),
|
||||
},
|
||||
errStr: "header cannot span multiple lines",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := parseHeader(tt.args.header)
|
||||
|
||||
if tt.errStr != "" {
|
||||
assert.Error(t, err, tt.errStr)
|
||||
} else {
|
||||
assert.Equal(t, tt.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_paragraph(t *testing.T) {
|
||||
type args struct {
|
||||
input []byte
|
||||
|
||||
Reference in New Issue
Block a user