feat: Supports annotated git-tag and adds Tag.Subject field #3

This commit is contained in:
tsuyoshiwada 2018-02-25 15:57:15 +09:00
parent d165ea884a
commit 114b7d6fc8
3 changed files with 106 additions and 79 deletions

View file

@ -80,13 +80,15 @@ type CommitGroup struct {
// If you give `Tag`, the reference hierarchy will be deepened.
// This struct is used to minimize the hierarchy of references
type RelateTag struct {
Name string
Date time.Time
Name string
Subject string
Date time.Time
}
// Tag is data of git-tag
type Tag struct {
Name string
Subject string
Date time.Time
Next *RelateTag
Previous *RelateTag

View file

@ -2,8 +2,7 @@ package chglog
import (
"fmt"
"regexp"
"strconv"
"sort"
"strings"
"time"
@ -11,24 +10,24 @@ import (
)
type tagReader struct {
client gitcmd.Client
format string
reTag *regexp.Regexp
client gitcmd.Client
format string
separator string
}
func newTagReader(client gitcmd.Client) *tagReader {
return &tagReader{
client: client,
reTag: regexp.MustCompile("tag: ([\\w\\.\\-_]+),?"),
client: client,
separator: "@@__CHGLOG__@@",
}
}
func (r *tagReader) ReadAll() ([]*Tag, error) {
out, err := r.client.Exec(
"log",
"--tags",
"--simplify-by-decoration",
"--pretty=%D\t%at",
"for-each-ref",
"--format",
"%(refname)"+r.separator+"%(subject)"+r.separator+"%(taggerdate)"+r.separator+"%(authordate)",
"refs/tags",
)
tags := []*Tag{}
@ -40,28 +39,49 @@ func (r *tagReader) ReadAll() ([]*Tag, error) {
lines := strings.Split(out, "\n")
for _, line := range lines {
if line == "" {
tokens := strings.Split(line, r.separator)
if len(tokens) != 4 {
continue
}
tokens := strings.Split(line, "\t")
res := r.reTag.FindAllStringSubmatch(tokens[0], -1)
if len(res) == 0 {
continue
}
ts, err := strconv.Atoi(tokens[1])
name := r.parseRefname(tokens[0])
subject := r.parseSubject(tokens[1])
date, err := r.parseDate(tokens[2])
if err != nil {
continue
t, err2 := r.parseDate(tokens[3])
if err2 != nil {
return nil, err2
}
date = t
}
tags = append(tags, &Tag{
Name: res[0][1],
Date: time.Unix(int64(ts), 0),
Name: name,
Subject: subject,
Date: date,
})
}
r.sortTags(tags)
r.assignPreviousAndNextTag(tags)
return tags, nil
}
func (*tagReader) parseRefname(input string) string {
return strings.Replace(input, "refs/tags/", "", 1)
}
func (*tagReader) parseSubject(input string) string {
return strings.TrimSpace(input)
}
func (*tagReader) parseDate(input string) (time.Time, error) {
return time.Parse("Mon Jan 2 15:04:05 2006 -0700", input)
}
func (*tagReader) assignPreviousAndNextTag(tags []*Tag) {
total := len(tags)
for i, tag := range tags {
@ -72,21 +92,27 @@ func (r *tagReader) ReadAll() ([]*Tag, error) {
if i > 0 {
next = &RelateTag{
Name: tags[i-1].Name,
Date: tags[i-1].Date,
Name: tags[i-1].Name,
Subject: tags[i-1].Subject,
Date: tags[i-1].Date,
}
}
if i+1 < total {
prev = &RelateTag{
Name: tags[i+1].Name,
Date: tags[i+1].Date,
Name: tags[i+1].Name,
Subject: tags[i+1].Subject,
Date: tags[i+1].Date,
}
}
tag.Next = next
tag.Previous = prev
}
return tags, nil
}
func (*tagReader) sortTags(tags []*Tag) {
sort.Slice(tags, func(i, j int) bool {
return !tags[i].Date.Before(tags[j].Date)
})
}

View file

@ -13,19 +13,17 @@ func TestTagReader(t *testing.T) {
assert := assert.New(t)
client := &mockClient{
ReturnExec: func(subcmd string, args ...string) (string, error) {
if subcmd != "log" {
if subcmd != "for-each-ref" {
return "", errors.New("")
}
return strings.Join([]string{
"",
"tag: v5.2.0-beta.1, origin/labs/router\t1518023112",
"tag: 2.0.0\t1517875200",
"tag: v2.0.4-rc.1\t1517788800",
"tag: 2.0.4-beta.1\t1517702400",
"tag: hoge_fuga\t1517616000",
"tag: 1.9.29-alpha.0\t1517529600",
"hoge\t0",
"foo\t0",
"refs/tags/v2.0.4-beta.1@@__CHGLOG__@@Release v2.0.4-beta.1@@__CHGLOG__@@Thu Feb 1 00:00:00 2018 +0000@@__CHGLOG__@@",
"refs/tags/4.4.3@@__CHGLOG__@@This is tag subject@@__CHGLOG__@@@@__CHGLOG__@@Fri Feb 2 00:00:00 2018 +0000",
"refs/tags/4.4.4@@__CHGLOG__@@Release 4.4.4@@__CHGLOG__@@Fri Feb 2 10:00:40 2018 +0000@@__CHGLOG__@@",
"refs/tags/5.0.0-rc.0@@__CHGLOG__@@Release 5.0.0-rc.0@@__CHGLOG__@@Sat Feb 3 12:30:10 2018 +0000@@__CHGLOG__@@",
"refs/tags/hoge_fuga@@__CHGLOG__@@Invalid semver tag name@@__CHGLOG__@@Mon Mar 12 12:30:10 2018 +0000@@__CHGLOG__@@",
"hoge@@__CHGLOG__@@",
}, "\n"), nil
},
}
@ -36,68 +34,69 @@ func TestTagReader(t *testing.T) {
assert.Equal(
[]*Tag{
&Tag{
Name: "v5.2.0-beta.1",
Date: time.Unix(1518023112, 0),
Next: nil,
Name: "hoge_fuga",
Subject: "Invalid semver tag name",
Date: time.Date(2018, 3, 12, 12, 30, 10, 0, time.UTC),
Next: nil,
Previous: &RelateTag{
Name: "2.0.0",
Date: time.Unix(1517875200, 0),
Name: "5.0.0-rc.0",
Subject: "Release 5.0.0-rc.0",
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
},
},
&Tag{
Name: "2.0.0",
Date: time.Unix(1517875200, 0),
Name: "5.0.0-rc.0",
Subject: "Release 5.0.0-rc.0",
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
Next: &RelateTag{
Name: "v5.2.0-beta.1",
Date: time.Unix(1518023112, 0),
Name: "hoge_fuga",
Subject: "Invalid semver tag name",
Date: time.Date(2018, 3, 12, 12, 30, 10, 0, time.UTC),
},
Previous: &RelateTag{
Name: "v2.0.4-rc.1",
Date: time.Unix(1517788800, 0),
Name: "4.4.4",
Subject: "Release 4.4.4",
Date: time.Date(2018, 2, 2, 10, 0, 40, 0, time.UTC),
},
},
&Tag{
Name: "v2.0.4-rc.1",
Date: time.Unix(1517788800, 0),
Name: "4.4.4",
Subject: "Release 4.4.4",
Date: time.Date(2018, 2, 2, 10, 0, 40, 0, time.UTC),
Next: &RelateTag{
Name: "2.0.0",
Date: time.Unix(1517875200, 0),
Name: "5.0.0-rc.0",
Subject: "Release 5.0.0-rc.0",
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
},
Previous: &RelateTag{
Name: "2.0.4-beta.1",
Date: time.Unix(1517702400, 0),
Name: "4.4.3",
Subject: "This is tag subject",
Date: time.Date(2018, 2, 2, 0, 0, 0, 0, time.UTC),
},
},
&Tag{
Name: "2.0.4-beta.1",
Date: time.Unix(1517702400, 0),
Name: "4.4.3",
Subject: "This is tag subject",
Date: time.Date(2018, 2, 2, 0, 0, 0, 0, time.UTC),
Next: &RelateTag{
Name: "v2.0.4-rc.1",
Date: time.Unix(1517788800, 0),
Name: "4.4.4",
Subject: "Release 4.4.4",
Date: time.Date(2018, 2, 2, 10, 0, 40, 0, time.UTC),
},
Previous: &RelateTag{
Name: "hoge_fuga",
Date: time.Unix(1517616000, 0),
Name: "v2.0.4-beta.1",
Subject: "Release v2.0.4-beta.1",
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
},
},
&Tag{
Name: "hoge_fuga",
Date: time.Unix(1517616000, 0),
Name: "v2.0.4-beta.1",
Subject: "Release v2.0.4-beta.1",
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
Next: &RelateTag{
Name: "2.0.4-beta.1",
Date: time.Unix(1517702400, 0),
},
Previous: &RelateTag{
Name: "1.9.29-alpha.0",
Date: time.Unix(1517529600, 0),
},
},
&Tag{
Name: "1.9.29-alpha.0",
Date: time.Unix(1517529600, 0),
Next: &RelateTag{
Name: "hoge_fuga",
Date: time.Unix(1517616000, 0),
Name: "4.4.3",
Subject: "This is tag subject",
Date: time.Date(2018, 2, 2, 0, 0, 0, 0, time.UTC),
},
Previous: nil,
},