mirror of
https://github.com/git-chglog/git-chglog.git
synced 2026-01-22 18:06:11 +00:00
fix: Fix parsing of revert and body
This commit is contained in:
parent
153727ed1a
commit
8869631aad
8 changed files with 160 additions and 30 deletions
|
|
@ -70,7 +70,7 @@ func TestGeneratorWithTypeScopeSubject(t *testing.T) {
|
|||
gen := NewGenerator(&Config{
|
||||
Bin: "git",
|
||||
WorkingDir: filepath.Join(testRepoRoot, testName),
|
||||
Template: filepath.Join("fixtures", testName+".md"),
|
||||
Template: filepath.Join("testdata", testName+".md"),
|
||||
Info: &Info{
|
||||
Title: "CHANGELOG Example",
|
||||
RepositoryURL: "https://github.com/git-chglog/git-chglog",
|
||||
|
|
|
|||
|
|
@ -73,9 +73,7 @@ func TestCommitExtractor(t *testing.T) {
|
|||
Header: "Revert1",
|
||||
Notes: []*Note{},
|
||||
Revert: &Revert{
|
||||
Raw: "revert1",
|
||||
Subject: "REVERT1",
|
||||
Hash: "1",
|
||||
Header: "REVERT1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,14 @@ var (
|
|||
}, delimiter)
|
||||
)
|
||||
|
||||
func joinAndQuoteMeta(list []string, sep string) string {
|
||||
arr := make([]string, len(list))
|
||||
for i, s := range list {
|
||||
arr[i] = regexp.QuoteMeta(s)
|
||||
}
|
||||
return strings.Join(arr, sep)
|
||||
}
|
||||
|
||||
type commitParser struct {
|
||||
client gitcmd.Client
|
||||
config *Config
|
||||
|
|
@ -53,9 +61,9 @@ type commitParser struct {
|
|||
func newCommitParser(client gitcmd.Client, config *Config) *commitParser {
|
||||
opts := config.Options
|
||||
|
||||
joinedRefActions := strings.Join(opts.RefActions, "|")
|
||||
joinedIssuePrefix := strings.Join(opts.IssuePrefix, "|")
|
||||
joinedNoteKeywords := strings.Join(opts.NoteKeywords, "|")
|
||||
joinedRefActions := joinAndQuoteMeta(opts.RefActions, "|")
|
||||
joinedIssuePrefix := joinAndQuoteMeta(opts.IssuePrefix, "|")
|
||||
joinedNoteKeywords := joinAndQuoteMeta(opts.NoteKeywords, "|")
|
||||
|
||||
return &commitParser{
|
||||
client: client,
|
||||
|
|
@ -65,7 +73,7 @@ func newCommitParser(client gitcmd.Client, config *Config) *commitParser {
|
|||
reRevert: regexp.MustCompile(opts.RevertPattern),
|
||||
reRef: regexp.MustCompile("(?i)(" + joinedRefActions + ")\\s?([\\w/\\.\\-]+)?(?:" + joinedIssuePrefix + ")(\\d+)"),
|
||||
reIssue: regexp.MustCompile("(?:" + joinedIssuePrefix + ")(\\d+)"),
|
||||
reNotes: regexp.MustCompile("^(?i)[\\s|*]*(" + joinedNoteKeywords + ")[:\\s]+(.*)"),
|
||||
reNotes: regexp.MustCompile("^(?i)\\s*(" + joinedNoteKeywords + ")[:\\s]+(.*)"),
|
||||
reMention: regexp.MustCompile("@([\\w-]+)"),
|
||||
}
|
||||
}
|
||||
|
|
@ -76,8 +84,6 @@ func (p *commitParser) Parse(rev string) ([]*Commit, error) {
|
|||
rev,
|
||||
"--no-decorate",
|
||||
"--pretty="+logFormat,
|
||||
"-n",
|
||||
"10",
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -203,25 +209,32 @@ func (p *commitParser) processHeader(commit *Commit, input string) {
|
|||
}
|
||||
|
||||
func (p *commitParser) processBody(commit *Commit, input string) {
|
||||
input = convNewline(input, "\n")
|
||||
|
||||
// body
|
||||
commit.Body = input
|
||||
|
||||
// notes & refs & mentions
|
||||
commit.Notes = []*Note{}
|
||||
inNote := false
|
||||
fenceDetector := newMdFenceDetector()
|
||||
lines := strings.Split(input, "\n")
|
||||
|
||||
for _, line := range lines {
|
||||
refs := p.parseRefs(line)
|
||||
if len(refs) > 0 {
|
||||
inNote = false
|
||||
commit.Refs = append(commit.Refs, refs...)
|
||||
}
|
||||
fenceDetector.Update(line)
|
||||
|
||||
mentions := p.parseMentions(line)
|
||||
if len(mentions) > 0 {
|
||||
inNote = false
|
||||
commit.Mentions = append(commit.Mentions, mentions...)
|
||||
if !fenceDetector.InCodeblock() {
|
||||
refs := p.parseRefs(line)
|
||||
if len(refs) > 0 {
|
||||
inNote = false
|
||||
commit.Refs = append(commit.Refs, refs...)
|
||||
}
|
||||
|
||||
mentions := p.parseMentions(line)
|
||||
if len(mentions) > 0 {
|
||||
inNote = false
|
||||
commit.Mentions = append(commit.Mentions, mentions...)
|
||||
}
|
||||
}
|
||||
|
||||
res := p.reNotes.FindAllStringSubmatch(line, -1)
|
||||
|
|
@ -240,6 +253,10 @@ func (p *commitParser) processBody(commit *Commit, input string) {
|
|||
}
|
||||
}
|
||||
|
||||
p.trimSpaceInNotes(commit)
|
||||
}
|
||||
|
||||
func (*commitParser) trimSpaceInNotes(commit *Commit) {
|
||||
for _, note := range commit.Notes {
|
||||
note.Body = strings.TrimSpace(note.Body)
|
||||
}
|
||||
|
|
@ -326,3 +343,42 @@ func (p *commitParser) uniqMentions(mentions []string) []string {
|
|||
|
||||
return arr
|
||||
}
|
||||
|
||||
var (
|
||||
fenceTypes = []string{
|
||||
"```",
|
||||
"~~~",
|
||||
" ",
|
||||
"\t",
|
||||
}
|
||||
)
|
||||
|
||||
type mdFenceDetector struct {
|
||||
fence int
|
||||
}
|
||||
|
||||
func newMdFenceDetector() *mdFenceDetector {
|
||||
return &mdFenceDetector{
|
||||
fence: -1,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *mdFenceDetector) InCodeblock() bool {
|
||||
return d.fence > -1
|
||||
}
|
||||
|
||||
func (d *mdFenceDetector) Update(input string) {
|
||||
for i, s := range fenceTypes {
|
||||
if d.fence < 0 {
|
||||
if strings.Index(input, s) == 0 {
|
||||
d.fence = i
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if strings.Index(input, s) == 0 && i == d.fence {
|
||||
d.fence = -1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package chglog
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
|
@ -20,7 +21,7 @@ func TestCommitParserParse(t *testing.T) {
|
|||
return "", errors.New("")
|
||||
}
|
||||
|
||||
bytes, _ := ioutil.ReadFile(filepath.Join("fixtures", "gitlog.txt"))
|
||||
bytes, _ := ioutil.ReadFile(filepath.Join("testdata", "gitlog.txt"))
|
||||
|
||||
return string(bytes), nil
|
||||
},
|
||||
|
|
@ -62,10 +63,9 @@ func TestCommitParserParse(t *testing.T) {
|
|||
"Ref",
|
||||
"Source",
|
||||
},
|
||||
RevertPattern: "^Revert\\s\"([\\s\\S]*)\"\\s*This reverts commit (\\w*)\\.",
|
||||
RevertPattern: "^Revert \"([\\s\\S]*)\"$",
|
||||
RevertPatternMaps: []string{
|
||||
"Subject",
|
||||
"Hash",
|
||||
"Header",
|
||||
},
|
||||
NoteKeywords: []string{
|
||||
"BREAKING CHANGE",
|
||||
|
|
@ -230,10 +230,23 @@ BREAKING CHANGE: This is breaking point message.`,
|
|||
Notes: []*Note{
|
||||
&Note{
|
||||
Title: "BREAKING CHANGE",
|
||||
Body: `This is multiline breaking change note.
|
||||
Body: fmt.Sprintf(`This is multiline breaking change note.
|
||||
It is treated as the body of the Note until a mention or reference appears.
|
||||
|
||||
We also allow blank lines :)`,
|
||||
We also allow blank lines :)
|
||||
|
||||
Example:
|
||||
|
||||
%sjavascript
|
||||
import { Controller } from 'hoge-fuga';
|
||||
|
||||
@autobind
|
||||
class MyController extends Controller {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
%s`, "```", "```"),
|
||||
},
|
||||
},
|
||||
Mentions: []string{},
|
||||
|
|
@ -241,7 +254,7 @@ We also allow blank lines :)`,
|
|||
Type: "fix",
|
||||
Scope: "model",
|
||||
Subject: "Remove hoge attributes",
|
||||
Body: `This mixed body message.
|
||||
Body: fmt.Sprintf(`This mixed body message.
|
||||
|
||||
BREAKING CHANGE:
|
||||
This is multiline breaking change note.
|
||||
|
|
@ -249,8 +262,49 @@ It is treated as the body of the Note until a mention or reference appears.
|
|||
|
||||
We also allow blank lines :)
|
||||
|
||||
Example:
|
||||
|
||||
%sjavascript
|
||||
import { Controller } from 'hoge-fuga';
|
||||
|
||||
@autobind
|
||||
class MyController extends Controller {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
%s
|
||||
|
||||
Fixes #123
|
||||
Closes username/repository#456`,
|
||||
Closes username/repository#456`, "```", "```"),
|
||||
},
|
||||
&Commit{
|
||||
Hash: &Hash{
|
||||
Long: "123456789735dcc4810dda3312b0792236c97c4e",
|
||||
Short: "12345678",
|
||||
},
|
||||
Author: &Author{
|
||||
Name: "tsuyoshi wada",
|
||||
Email: "mail@example.com",
|
||||
Date: time.Unix(int64(1517488587), 0),
|
||||
},
|
||||
Committer: &Committer{
|
||||
Name: "tsuyoshi wada",
|
||||
Email: "mail@example.com",
|
||||
Date: time.Unix(int64(1517488587), 0),
|
||||
},
|
||||
Merge: nil,
|
||||
Revert: &Revert{
|
||||
Header: "fix(core): commit message",
|
||||
},
|
||||
Refs: []*Ref{},
|
||||
Notes: []*Note{},
|
||||
Mentions: []string{},
|
||||
Header: "Revert \"fix(core): commit message\"",
|
||||
Type: "",
|
||||
Scope: "",
|
||||
Subject: "",
|
||||
Body: "This reverts commit f755db78dcdf461dc42e709b3ab728ceba353d1d.",
|
||||
},
|
||||
}, commits)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ type Merge struct {
|
|||
|
||||
// Revert ...
|
||||
type Revert struct {
|
||||
Raw string
|
||||
Subject string
|
||||
Hash string
|
||||
Header string
|
||||
}
|
||||
|
||||
// Ref ...
|
||||
|
|
@ -96,6 +94,7 @@ type Tag struct {
|
|||
type Version struct {
|
||||
Tag *Tag
|
||||
CommitGroups []*CommitGroup
|
||||
Commits []*Commit
|
||||
MergeCommits []*Commit
|
||||
RevertCommits []*Commit
|
||||
NoteGroups []*NoteGroup
|
||||
|
|
|
|||
15
fixtures/gitlog.txt → testdata/gitlog.txt
vendored
15
fixtures/gitlog.txt → testdata/gitlog.txt
vendored
|
|
@ -20,5 +20,20 @@ It is treated as the body of the Note until a mention or reference appears.
|
|||
|
||||
We also allow blank lines :)
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
import { Controller } from 'hoge-fuga';
|
||||
|
||||
@autobind
|
||||
class MyController extends Controller {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Fixes #123
|
||||
Closes username/repository#456
|
||||
|
||||
@@__CHGLOG__@@HASH:123456789735dcc4810dda3312b0792236c97c4e 12345678@@__CHGLOG_DELIMITER__@@AUTHOR:tsuyoshi wada mail@example.com 1517488587@@__CHGLOG_DELIMITER__@@COMMITTER:tsuyoshi wada mail@example.com 1517488587@@__CHGLOG_DELIMITER__@@SUBJECT:Revert "fix(core): commit message"@@__CHGLOG_DELIMITER__@@BODY:This reverts commit f755db78dcdf461dc42e709b3ab728ceba353d1d.
|
||||
8
utils.go
8
utils.go
|
|
@ -104,3 +104,11 @@ func compareTime(a time.Time, operator string, b time.Time) bool {
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func convNewline(str, nlcode string) string {
|
||||
return strings.NewReplacer(
|
||||
"\r\n", nlcode,
|
||||
"\r", nlcode,
|
||||
"\n", nlcode,
|
||||
).Replace(str)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue