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