From 175b6f3be4fa5094c8b917d07c86bf6ff72a6e54 Mon Sep 17 00:00:00 2001 From: Khalifah Khalil Shabazz Date: Sun, 3 Oct 2021 08:50:40 -0400 Subject: [PATCH] feat: Add Commits To Unreleased Even When No Tags When there are commits but no tags, then insert those commits under the unreleased section of the change log output. This requires get an updated CHANGELOG.md.tpl file. Includig the template footer to account for the unreleased line there that used .Versions. resolves #76 BREAKING CHANGE: * No longer throw the error "no tags" when: * No tag query entered * There are commits to tag * Requires an update to the changelog template --- chglog.go | 27 +++-- chglog_test.go | 111 +++++++++++++++++++- cmd/git-chglog/kac_template_builder.go | 18 ++-- cmd/git-chglog/kac_template_builder_test.go | 11 +- testdata/commits_and_next_tag.md | 52 +++++++++ testdata/commits_and_no_tags.md | 52 +++++++++ testdata/no_tags.md | 54 ++++++++++ 7 files changed, 303 insertions(+), 22 deletions(-) create mode 100644 testdata/commits_and_next_tag.md create mode 100644 testdata/commits_and_no_tags.md create mode 100644 testdata/no_tags.md diff --git a/chglog.go b/chglog.go index 1a084c8a..f4d93e9d 100644 --- a/chglog.go +++ b/chglog.go @@ -54,9 +54,10 @@ type Info struct { // RenderData is the data passed to the template type RenderData struct { - Info *Info - Unreleased *Unreleased - Versions []*Version + Info *Info + Unreleased *Unreleased + Versions []*Version + UnreleasedHash *Hash } // Config for generating CHANGELOG @@ -162,7 +163,7 @@ func (gen *Generator) Generate(w io.Writer, query string) error { return err } - if len(versions) == 0 { + if len(versions) == 0 && query != "" { return fmt.Errorf("commits corresponding to \"%s\" was not found", query) } @@ -284,7 +285,8 @@ func (gen *Generator) getTags(query string) ([]*Tag, string, error) { }, tags...) } - if len(tags) == 0 { + // Error only when you explicitly set a query + if len(tags) == 0 && query != "" { return nil, "", errors.New("git-tag does not exist") } @@ -353,9 +355,18 @@ func (gen *Generator) render(w io.Writer, unreleased *Unreleased, versions []*Ve t := template.Must(template.New(fname).Funcs(sprig.TxtFuncMap()).Funcs(fmap).ParseFiles(gen.config.Template)) + unreleasedHash := &Hash{} + + if unreleased.CommitGroups != nil && len(unreleased.CommitGroups) > 0 { + unreleasedHash = unreleased.CommitGroups[0].Commits[0].Hash + } else if unreleased.Commits != nil && len(unreleased.Commits) > 0 { + unreleasedHash = unreleased.Commits[0].Hash + } + return t.Execute(w, &RenderData{ - Info: gen.config.Info, - Unreleased: unreleased, - Versions: versions, + Info: gen.config.Info, + Unreleased: unreleased, + Versions: versions, + UnreleasedHash: unreleasedHash, }) } diff --git a/chglog_test.go b/chglog_test.go index a00359bb..da61ddfe 100644 --- a/chglog_test.go +++ b/chglog_test.go @@ -70,7 +70,7 @@ func cleanup() { func TestGeneratorNotFoundTags(t *testing.T) { assert := assert.New(t) - testName := "not_found" + testName := "no_tags" setup(testName, func(commit commitFunc, _ tagFunc, _ gitcmd.Client) { commit("2018-01-01 00:00:00", "feat(*): New feature", "") @@ -91,9 +91,8 @@ func TestGeneratorNotFoundTags(t *testing.T) { err := gen.Generate(buf, "") expected := strings.TrimSpace(buf.String()) - assert.Error(err) - assert.Contains(err.Error(), "git-tag does not exist") - assert.Equal("", expected) + assert.Nil(err) + assert.Contains(expected, "\n## [Unreleased]") } func TestGeneratorNotFoundCommits(t *testing.T) { @@ -629,3 +628,107 @@ func TestGeneratorWithSprig(t *testing.T) { [2.0.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...2.0.0`, expected) } + +var ( + styleGitHub = "github" + fmtTypeScopeSubject = "(): " + tplKeepAChangelog = "keep-a-changelog" +) + +func TestNewRepoUnreleasedCommitsButNoTags(t *testing.T) { + asrt := assert.New(t) + testName := "commits_and_no_tags" + + setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { + commit("2023-06-25 00:00:00", "feat: Second Feature", "") + commit("2023-06-24 00:00:00", "feat: First Feature", "") + }) + + gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), + &Config{ + Bin: "git", + WorkingDir: filepath.Join(testRepoRoot, testName), + Template: filepath.Join(cwd, "testdata", testName+".md"), + Info: &Info{ + Title: "CHANGELOG Example", + RepositoryURL: "https://github.com/git-chglog/git-chglog", + }, + Options: &Options{ + CommitGroupBy: "Type", + CommitGroupTitleMaps: map[string]string{ + "feat": "Features", + }, + HeaderPattern: "^(\\w*)\\:\\s(.*)$", + HeaderPatternMaps: []string{ + "Type", + "Subject", + }}, + }) + + buf := &bytes.Buffer{} + err := gen.Generate(buf, "") + actual := strings.TrimSpace(buf.String()) + + asrt.NoError(err) + asrt.Contains(actual, ` +## [Unreleased] + +### Features +- First Feature +- Second Feature + + +[Unreleased]: https://github.com/git-chglog/git-chglog/compare/`) + +} + +func TestNewRepoUnreleasedCommitsWithNextTag(t *testing.T) { + asrt := assert.New(t) + testName := "commits_and_next_tag" + + setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { + commit("2023-06-25 00:00:00", "feat: Second Feature", "") + commit("2023-06-24 00:00:00", "feat: First Feature", "") + }) + + gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), + &Config{ + Bin: "git", + WorkingDir: filepath.Join(testRepoRoot, testName), + Template: filepath.Join(cwd, "testdata", testName+".md"), + Info: &Info{ + Title: "CHANGELOG Example", + RepositoryURL: "https://github.com/git-chglog/git-chglog", + }, + Options: &Options{ + NextTag: "0.1.0", + CommitGroupBy: "Type", + CommitGroupTitleMaps: map[string]string{ + "feat": "Features", + }, + HeaderPattern: "^(\\w*)\\:\\s(.*)$", + HeaderPatternMaps: []string{ + "Type", + "Subject", + }}, + }) + + buf := &bytes.Buffer{} + err := gen.Generate(buf, "") + actual := strings.TrimSpace(buf.String()) + + asrt.NoError(err) + asrt.Equal(` +## [Unreleased] + + + +## 0.1.0 - 2023-06-24 +### Features +- First Feature +- Second Feature + + +[Unreleased]: https://github.com/git-chglog/git-chglog/compare/0.1.0...HEAD`, actual) + +} diff --git a/cmd/git-chglog/kac_template_builder.go b/cmd/git-chglog/kac_template_builder.go index e0956d2f..e7d50c97 100644 --- a/cmd/git-chglog/kac_template_builder.go +++ b/cmd/git-chglog/kac_template_builder.go @@ -57,7 +57,7 @@ func (t *kacTemplateBuilderImpl) unreleased(style, format string) string { title = fmt.Sprintf("[%s]", title) } - return fmt.Sprintf(`{{ if .Versions -}} + return fmt.Sprintf(`{{ if .Unreleased -}} %s## %s {{ if .Unreleased.CommitGroups -}} @@ -156,24 +156,30 @@ func (*kacTemplateBuilderImpl) footer(style string) string { case styleGitHub, styleGitLab: return ` -{{- if .Versions }} +{{ if .UnreleasedHash.Short -}} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ .UnreleasedHash.Short }}...HEAD +{{ end -}} +{{ if .Versions -}} [Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD +{{ end -}} {{ range .Versions -}} {{ if .Tag.Previous -}} [{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} {{ end -}} -{{ end -}} {{ end -}}` case styleBitbucket: return ` -{{- if .Versions }} -[Unreleased]: {{ .Info.RepositoryURL }}/compare/HEAD..{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }} +{{ if .UnreleasedHash.Short -}} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ .UnreleasedHash.Short }}...HEAD +{{ end -}} +{{ if .Versions -}} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD +{{ end -}} {{ range .Versions -}} {{ if .Tag.Previous -}} [{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Name }}..{{ .Tag.Previous.Name }} {{ end -}} -{{ end -}} {{ end -}}` default: return "" diff --git a/cmd/git-chglog/kac_template_builder_test.go b/cmd/git-chglog/kac_template_builder_test.go index 70170aac..666de0d9 100644 --- a/cmd/git-chglog/kac_template_builder_test.go +++ b/cmd/git-chglog/kac_template_builder_test.go @@ -19,7 +19,7 @@ func TestKACTemplateBuilderDefault(t *testing.T) { }) assert.Nil(err) - assert.Equal(`{{ if .Versions -}} + assert.Equal(`{{ if .Unreleased -}} ## [Unreleased] @@ -67,13 +67,16 @@ func TestKACTemplateBuilderDefault(t *testing.T) { {{ end -}} {{ end -}} +{{- if .UnreleasedHash.Short }} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ .UnreleasedHash.Short }}...HEAD +{{ end -}} {{- if .Versions }} [Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD +{{ end -}} {{ range .Versions -}} {{ if .Tag.Previous -}} [{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} {{ end -}} -{{ end -}} {{ end -}}`, out) } @@ -90,7 +93,7 @@ func TestKACTemplateBuilderNone(t *testing.T) { }) assert.Nil(err) - assert.Equal(`{{ if .Versions -}} + assert.Equal(`{{ if .Unreleased -}} ## Unreleased {{ if .Unreleased.CommitGroups -}} @@ -150,7 +153,7 @@ func TestKACTemplateBuilderSubject(t *testing.T) { }) assert.Nil(err) - assert.Equal(`{{ if .Versions -}} + assert.Equal(`{{ if .Unreleased -}} ## Unreleased {{ if .Unreleased.CommitGroups -}} diff --git a/testdata/commits_and_next_tag.md b/testdata/commits_and_next_tag.md new file mode 100644 index 00000000..ea9b5fa7 --- /dev/null +++ b/testdata/commits_and_next_tag.md @@ -0,0 +1,52 @@ +{{ if .Unreleased -}} + +## [Unreleased] + +{{ if .Unreleased.CommitGroups -}} +{{ range .Unreleased.CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{ range .Versions }} + +## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }} +{{ range .CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} + +{{- if .RevertCommits -}} +### Reverts +{{ range .RevertCommits -}} +- {{ .Revert.Header }} +{{ end }} +{{ end -}} + +{{- if .NoteGroups -}} +{{ range .NoteGroups -}} +### {{ .Title }} +{{ range .Notes }} +{{ .Body }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{- if .UnreleasedHash.Short }} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ .UnreleasedHash.Short }}...HEAD +{{ end -}} +{{- if .Versions }} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD +{{ end -}} +{{ range .Versions -}} +{{ if .Tag.Previous -}} +[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} +{{ end -}} +{{ end -}} \ No newline at end of file diff --git a/testdata/commits_and_no_tags.md b/testdata/commits_and_no_tags.md new file mode 100644 index 00000000..ea9b5fa7 --- /dev/null +++ b/testdata/commits_and_no_tags.md @@ -0,0 +1,52 @@ +{{ if .Unreleased -}} + +## [Unreleased] + +{{ if .Unreleased.CommitGroups -}} +{{ range .Unreleased.CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{ range .Versions }} + +## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }} +{{ range .CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} + +{{- if .RevertCommits -}} +### Reverts +{{ range .RevertCommits -}} +- {{ .Revert.Header }} +{{ end }} +{{ end -}} + +{{- if .NoteGroups -}} +{{ range .NoteGroups -}} +### {{ .Title }} +{{ range .Notes }} +{{ .Body }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{- if .UnreleasedHash.Short }} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ .UnreleasedHash.Short }}...HEAD +{{ end -}} +{{- if .Versions }} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD +{{ end -}} +{{ range .Versions -}} +{{ if .Tag.Previous -}} +[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} +{{ end -}} +{{ end -}} \ No newline at end of file diff --git a/testdata/no_tags.md b/testdata/no_tags.md new file mode 100644 index 00000000..f809cfef --- /dev/null +++ b/testdata/no_tags.md @@ -0,0 +1,54 @@ +{{ if .Unreleased -}} + +## [Unreleased] + +{{ if .Unreleased.CommitGroups -}} +{{ range .Unreleased.CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{ range .Versions }} + +## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }} +{{ range .CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} + +{{- if .RevertCommits -}} +### Reverts +{{ range .RevertCommits -}} +- {{ .Revert.Header }} +{{ end }} +{{ end -}} + +{{- if .NoteGroups -}} +{{ range .NoteGroups -}} +### {{ .Title }} +{{ range .Notes }} +{{ .Body }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{- if .Unreleased -}} +{{- $latest := index .Unreleased.Commits 0 -}} +{{- if .Unreleased.CommitGroups -}} +{{- $group = index .Unreleased.CommitGroups 0 -}} +{{- $latest = index $group.Commits 0 -}} +{{- end }} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest.Hash }}...HEAD +{{ end -}} +{{ range .Versions -}} +{{ if .Tag.Previous -}} +[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} +{{ end -}} +{{ end -}} \ No newline at end of file