diff --git a/cmd/git-chglog/custom_template_builder.go b/cmd/git-chglog/custom_template_builder.go
new file mode 100644
index 00000000..90f7752f
--- /dev/null
+++ b/cmd/git-chglog/custom_template_builder.go
@@ -0,0 +1,136 @@
+package main
+
+import "fmt"
+
+type customTemplateBuilderImpl struct{}
+
+// NewCustomTemplateBuilder ...
+func NewCustomTemplateBuilder() TemplateBuilder {
+ return &customTemplateBuilderImpl{}
+}
+
+// Build ...
+func (t *customTemplateBuilderImpl) Build(ans *Answer) (string, error) {
+ // versions
+ tpl := "{{range .Versions}}\n"
+
+ // version header
+ tpl += t.versionHeader(ans.Style, ans.Template)
+
+ // commits
+ tpl += t.commits(ans.Template, ans.CommitMessageFormat)
+
+ // revert
+ if ans.IncludeReverts {
+ tpl += t.reverts()
+ }
+
+ // merges
+ if ans.IncludeMerges {
+ tpl += t.merges(ans.Style)
+ }
+
+ // notes
+ tpl += t.notes()
+
+ // versions end
+ tpl += "\n{{end}}"
+
+ return tpl, nil
+}
+
+func (*customTemplateBuilderImpl) versionHeader(style, template string) string {
+ var (
+ tpl string
+ tagName = "{{.Tag.Name}}"
+ date = "{{datetime \"2006-01-02\" .Tag.Date}}"
+ )
+
+ // parts
+ switch style {
+ case styleGitHub:
+ tpl = "\n"
+ tagName = "{{if .Tag.Previous}}[{{.Tag.Name}}]({{$.Info.RepositoryURL}}/compare/{{.Tag.Previous.Name}}...{{.Tag.Name}}){{else}}{{.Tag.Name}}{{end}}"
+ }
+
+ // format
+ switch template {
+ case tplStandard:
+ tpl = fmt.Sprintf("%s## %s (%s)\n",
+ tpl,
+ tagName,
+ date,
+ )
+ case tplCool:
+ tpl = fmt.Sprintf("%s## %s\n\n> %s\n",
+ tpl,
+ tagName,
+ date,
+ )
+ }
+
+ return tpl
+}
+
+func (*customTemplateBuilderImpl) commits(template, format string) string {
+ var (
+ header string
+ body string
+ )
+
+ switch format {
+ case fmtSubject.Display:
+ body = `{{range .Commits}}
+* {{.Header}}{{end}}
+`
+
+ default:
+ if format == fmtTypeScopeSubject.Display {
+ header = "{{if .Scope}}**{{.Scope}}:** {{end}}{{.Subject}}"
+ } else {
+ header = "{{.Subject}}"
+ }
+
+ body = fmt.Sprintf(`### {{.Title}}
+{{range .Commits}}
+* %s{{end}}
+`, header)
+ }
+
+ return fmt.Sprintf(`{{range .CommitGroups}}
+%s{{end}}`, body)
+}
+
+func (*customTemplateBuilderImpl) reverts() string {
+ return `{{if .RevertCommits}}
+### Reverts
+{{range .RevertCommits}}
+* {{.Revert.Header}}{{end}}
+{{end}}`
+}
+
+func (t *customTemplateBuilderImpl) merges(style string) string {
+ var title string
+
+ switch style {
+ case styleGitHub:
+ title = "Pull Requests"
+ default:
+ title = "Merges"
+ }
+
+ return fmt.Sprintf(`{{if .MergeCommits}}
+### %s
+{{range .MergeCommits}}
+* {{.Header}}{{end}}
+{{end}}`, title)
+}
+
+func (*customTemplateBuilderImpl) notes() string {
+ return `{{range .NoteGroups}}
+### {{.Title}}
+{{range .Notes}}
+{{.Body}}
+{{end}}
+{{end}}`
+}
diff --git a/cmd/git-chglog/template_builder_test.go b/cmd/git-chglog/custom_template_builder_test.go
similarity index 85%
rename from cmd/git-chglog/template_builder_test.go
rename to cmd/git-chglog/custom_template_builder_test.go
index 9d6449e0..a6251800 100644
--- a/cmd/git-chglog/template_builder_test.go
+++ b/cmd/git-chglog/custom_template_builder_test.go
@@ -6,9 +6,9 @@ import (
"github.com/stretchr/testify/assert"
)
-func TestTemplateBuilderDefault(t *testing.T) {
+func TestCustomTemplateBuilderDefault(t *testing.T) {
assert := assert.New(t)
- builder := NewTemplateBuilder()
+ builder := NewCustomTemplateBuilder()
out, err := builder.Build(&Answer{
Style: styleGitHub,
@@ -25,7 +25,7 @@ func TestTemplateBuilderDefault(t *testing.T) {
{{range .CommitGroups}}
### {{.Title}}
{{range .Commits}}
-* {{if ne .Scope ""}}**{{.Scope}}:** {{end}}{{.Subject}}{{end}}
+* {{if .Scope}}**{{.Scope}}:** {{end}}{{.Subject}}{{end}}
{{end}}{{if .RevertCommits}}
### Reverts
{{range .RevertCommits}}
@@ -43,9 +43,9 @@ func TestTemplateBuilderDefault(t *testing.T) {
{{end}}`, out)
}
-func TestTemplateBuilderNone(t *testing.T) {
+func TestCustomTemplateBuilderNone(t *testing.T) {
assert := assert.New(t)
- builder := NewTemplateBuilder()
+ builder := NewCustomTemplateBuilder()
out, err := builder.Build(&Answer{
Style: styleNone,
@@ -61,7 +61,7 @@ func TestTemplateBuilderNone(t *testing.T) {
{{range .CommitGroups}}
### {{.Title}}
{{range .Commits}}
-* {{if ne .Scope ""}}**{{.Scope}}:** {{end}}{{.Subject}}{{end}}
+* {{if .Scope}}**{{.Scope}}:** {{end}}{{.Subject}}{{end}}
{{end}}{{if .RevertCommits}}
### Reverts
{{range .RevertCommits}}
@@ -79,9 +79,9 @@ func TestTemplateBuilderNone(t *testing.T) {
{{end}}`, out)
}
-func TestTemplateBuilderCool(t *testing.T) {
+func TestCustomTemplateBuilderCool(t *testing.T) {
assert := assert.New(t)
- builder := NewTemplateBuilder()
+ builder := NewCustomTemplateBuilder()
out, err := builder.Build(&Answer{
Style: styleNone,
@@ -99,7 +99,7 @@ func TestTemplateBuilderCool(t *testing.T) {
{{range .CommitGroups}}
### {{.Title}}
{{range .Commits}}
-* {{if ne .Scope ""}}**{{.Scope}}:** {{end}}{{.Subject}}{{end}}
+* {{if .Scope}}**{{.Scope}}:** {{end}}{{.Subject}}{{end}}
{{end}}{{if .RevertCommits}}
### Reverts
{{range .RevertCommits}}
@@ -117,9 +117,9 @@ func TestTemplateBuilderCool(t *testing.T) {
{{end}}`, out)
}
-func TestTemplateBuilderSubjectOnly(t *testing.T) {
+func TestCustomTemplateBuilderSubjectOnly(t *testing.T) {
assert := assert.New(t)
- builder := NewTemplateBuilder()
+ builder := NewCustomTemplateBuilder()
out, err := builder.Build(&Answer{
Style: styleNone,
@@ -152,9 +152,9 @@ func TestTemplateBuilderSubjectOnly(t *testing.T) {
{{end}}`, out)
}
-func TestTemplateBuilderSubject(t *testing.T) {
+func TestCustomTemplateBuilderSubject(t *testing.T) {
assert := assert.New(t)
- builder := NewTemplateBuilder()
+ builder := NewCustomTemplateBuilder()
out, err := builder.Build(&Answer{
Style: styleNone,
@@ -188,9 +188,9 @@ func TestTemplateBuilderSubject(t *testing.T) {
{{end}}`, out)
}
-func TestTemplateBuilderIgnoreReverts(t *testing.T) {
+func TestCustomTemplateBuilderIgnoreReverts(t *testing.T) {
assert := assert.New(t)
- builder := NewTemplateBuilder()
+ builder := NewCustomTemplateBuilder()
out, err := builder.Build(&Answer{
Style: styleNone,
@@ -220,9 +220,9 @@ func TestTemplateBuilderIgnoreReverts(t *testing.T) {
{{end}}`, out)
}
-func TestTemplateBuilderIgnoreMerges(t *testing.T) {
+func TestCustomTemplateBuilderIgnoreMerges(t *testing.T) {
assert := assert.New(t)
- builder := NewTemplateBuilder()
+ builder := NewCustomTemplateBuilder()
out, err := builder.Build(&Answer{
Style: styleNone,
diff --git a/cmd/git-chglog/initializer.go b/cmd/git-chglog/initializer.go
index 920df14b..7356f8b0 100644
--- a/cmd/git-chglog/initializer.go
+++ b/cmd/git-chglog/initializer.go
@@ -10,13 +10,13 @@ import (
// Initializer ...
type Initializer struct {
- ctx *InitContext
- client gitcmd.Client
- fs FileSystem
- logger *Logger
- questioner Questioner
- configBuilder ConfigBuilder
- templateBuilder TemplateBuilder
+ ctx *InitContext
+ client gitcmd.Client
+ fs FileSystem
+ logger *Logger
+ questioner Questioner
+ configBuilder ConfigBuilder
+ templateBuilderFactory TemplateBuilderFactory
}
// NewInitializer ...
@@ -25,15 +25,14 @@ func NewInitializer(
fs FileSystem,
questioner Questioner,
configBuilder ConfigBuilder,
- templateBuilder TemplateBuilder,
-) *Initializer {
+ tplBuilderFactory TemplateBuilderFactory) *Initializer {
return &Initializer{
- ctx: ctx,
- fs: fs,
- logger: NewLogger(ctx.Stdout, ctx.Stderr, false, false),
- questioner: questioner,
- configBuilder: configBuilder,
- templateBuilder: templateBuilder,
+ ctx: ctx,
+ fs: fs,
+ logger: NewLogger(ctx.Stdout, ctx.Stderr, false, false),
+ questioner: questioner,
+ configBuilder: configBuilder,
+ templateBuilderFactory: tplBuilderFactory,
}
}
@@ -86,7 +85,8 @@ func (init *Initializer) generateConfig(ans *Answer) error {
}
func (init *Initializer) generateTemplate(ans *Answer) error {
- s, err := init.templateBuilder.Build(ans)
+ templateBuilder := init.templateBuilderFactory(ans.Template)
+ s, err := templateBuilder.Build(ans)
if err != nil {
return err
}
diff --git a/cmd/git-chglog/initializer_test.go b/cmd/git-chglog/initializer_test.go
index 5c4717c4..fb929f19 100644
--- a/cmd/git-chglog/initializer_test.go
+++ b/cmd/git-chglog/initializer_test.go
@@ -64,7 +64,9 @@ func TestInitializer(t *testing.T) {
mockFs,
questioner,
configBuilder,
- tplBuilder,
+ func(t string) TemplateBuilder {
+ return tplBuilder
+ },
)
assert.Equal(ExitCodeOK, init.Run())
diff --git a/cmd/git-chglog/kac_template_builder.go b/cmd/git-chglog/kac_template_builder.go
new file mode 100644
index 00000000..f31427cb
--- /dev/null
+++ b/cmd/git-chglog/kac_template_builder.go
@@ -0,0 +1,118 @@
+package main
+
+import "fmt"
+
+type kacTemplateBuilderImpl struct{}
+
+// NewKACTemplateBuilder ...
+func NewKACTemplateBuilder() TemplateBuilder {
+ return &kacTemplateBuilderImpl{}
+}
+
+// Build ...
+func (t *kacTemplateBuilderImpl) Build(ans *Answer) (string, error) {
+ // versions
+ tpl := "## {{if .Versions}}[Unreleased]{{end}}\n{{range .Versions}}\n"
+ tpl += t.versionHeader(ans.Style)
+
+ // commits
+ tpl += t.commits(ans.CommitMessageFormat)
+
+ // revert
+ if ans.IncludeReverts {
+ tpl += t.reverts()
+ }
+
+ // merges
+ if ans.IncludeMerges {
+ tpl += t.merges(ans.Style)
+ }
+
+ // notes
+ tpl += t.notes()
+
+ // versions end
+ tpl += "{{end}}"
+
+ // footer (links)
+ tpl += t.footer(ans.Style)
+
+ return tpl, nil
+}
+
+func (t *kacTemplateBuilderImpl) versionHeader(style string) string {
+ var (
+ tagName = "{{.Tag.Name}}"
+ date = "{{datetime \"2006-01-02\" .Tag.Date}}"
+ )
+
+ switch style {
+ case styleGitHub:
+ tagName = "{{if .Tag.Previous}}[{{.Tag.Name}}]{{else}}{{.Tag.Name}}{{end}}"
+ }
+
+ return fmt.Sprintf("## %s - %s", tagName, date)
+}
+
+func (t *kacTemplateBuilderImpl) commits(format string) string {
+ var (
+ body string
+ )
+
+ switch format {
+ case fmtSubject.Display:
+ body = `{{range .Commits}}
+- {{.Header}}{{end}}`
+
+ default:
+ body = `### {{.Title}}{{range .Commits}}
+- {{if .Scope}}**{{.Scope}}:** {{end}}{{.Subject}}{{end}}`
+ }
+
+ return fmt.Sprintf(`{{range .CommitGroups}}
+%s
+{{end}}`, body)
+}
+
+func (t *kacTemplateBuilderImpl) reverts() string {
+ return `{{if .RevertCommits}}
+### Reverts{{range .RevertCommits}}
+- {{.Revert.Header}}{{end}}
+{{end}}`
+}
+
+func (t *kacTemplateBuilderImpl) merges(style string) string {
+ var title string
+
+ switch style {
+ case styleGitHub:
+ title = "Pull Requests"
+ default:
+ title = "Merges"
+ }
+
+ return fmt.Sprintf(`{{if .MergeCommits}}
+### %s{{range .MergeCommits}}
+- {{.Header}}{{end}}
+{{end}}`, title)
+}
+
+func (*kacTemplateBuilderImpl) notes() string {
+ return `{{range .NoteGroups}}
+### {{.Title}}
+{{range .Notes}}
+{{.Body}}
+{{end}}
+{{end}}`
+}
+
+func (*kacTemplateBuilderImpl) footer(style string) string {
+ if style != styleGitHub {
+ return ""
+ }
+
+ return `{{if .Versions}}
+[Unreleased]: {{.Info.RepositoryURL}}/compare/{{$latest := index .Versions 0}}{{$latest.Tag.Name}}...HEAD{{range .Versions}}{{if .Tag.Previous}}
+[{{.Tag.Name}}]: {{$.Info.RepositoryURL}}/compare/{{.Tag.Previous.Name}}...{{.Tag.Name}}{{end}}{{end}}
+{{end}}`
+}
diff --git a/cmd/git-chglog/kac_template_builder_test.go b/cmd/git-chglog/kac_template_builder_test.go
new file mode 100644
index 00000000..2f46d53f
--- /dev/null
+++ b/cmd/git-chglog/kac_template_builder_test.go
@@ -0,0 +1,42 @@
+package main
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestKACTemplateBuilderDefault(t *testing.T) {
+ assert := assert.New(t)
+ builder := NewKACTemplateBuilder()
+
+ out, err := builder.Build(&Answer{
+ Style: styleGitHub,
+ CommitMessageFormat: fmtTypeScopeSubject.Display,
+ Template: tplKeepAChangelog,
+ IncludeMerges: true,
+ IncludeReverts: true,
+ })
+
+ assert.Nil(err)
+ assert.Equal(`## {{if .Versions}}[Unreleased]{{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 .MergeCommits}}
+### Pull Requests{{range .MergeCommits}}
+- {{.Header}}{{end}}
+{{end}}{{range .NoteGroups}}
+### {{.Title}}
+{{range .Notes}}
+{{.Body}}
+{{end}}
+{{end}}{{end}}{{if .Versions}}
+[Unreleased]: {{.Info.RepositoryURL}}/compare/{{$latest := index .Versions 0}}{{$latest.Tag.Name}}...HEAD{{range .Versions}}{{if .Tag.Previous}}
+[{{.Tag.Name}}]: {{$.Info.RepositoryURL}}/compare/{{.Tag.Previous.Name}}...{{.Tag.Name}}{{end}}{{end}}
+{{end}}`, out)
+}
diff --git a/cmd/git-chglog/main.go b/cmd/git-chglog/main.go
index fb8e0c21..cae9214d 100644
--- a/cmd/git-chglog/main.go
+++ b/cmd/git-chglog/main.go
@@ -132,7 +132,7 @@ func main() {
fs,
),
NewConfigBuilder(),
- NewTemplateBuilder(),
+ templateBuilderFactory,
)
os.Exit(initializer.Run())
diff --git a/cmd/git-chglog/template_builder.go b/cmd/git-chglog/template_builder.go
index 7154c0f3..963aab7c 100644
--- a/cmd/git-chglog/template_builder.go
+++ b/cmd/git-chglog/template_builder.go
@@ -1,143 +1,18 @@
package main
-import "fmt"
-
// TemplateBuilder ...
type TemplateBuilder interface {
Builder
}
-type templateBuilderImpl struct{}
+// TemplateBuilderFactory ...
+type TemplateBuilderFactory = func(string) TemplateBuilder
-// NewTemplateBuilder ...
-func NewTemplateBuilder() TemplateBuilder {
- return &templateBuilderImpl{}
-}
-
-// Build ...
-func (t *templateBuilderImpl) Build(ans *Answer) (string, error) {
- // versions
- tpl := "{{range .Versions}}\n"
-
- // version header
- tpl += t.versionHeader(ans.Style, ans.Template)
-
- // commits
- tpl += t.commits(ans.Template, ans.CommitMessageFormat)
-
- // revert
- if ans.IncludeReverts {
- tpl += t.reverts()
- }
-
- // merges
- if ans.IncludeMerges {
- tpl += t.merges(ans.Style)
- }
-
- // notes
- tpl += t.notes()
-
- // versions end
- tpl += "\n{{end}}"
-
- return tpl, nil
-}
-
-func (*templateBuilderImpl) versionHeader(style, template string) string {
- var (
- tpl string
- tagName string
- date = "{{datetime \"2006-01-02\" .Tag.Date}}"
- )
-
- // parts
- switch style {
- case styleGitHub:
- tpl = "\n"
- tagName = "{{if .Tag.Previous}}[{{.Tag.Name}}]({{$.Info.RepositoryURL}}/compare/{{.Tag.Previous.Name}}...{{.Tag.Name}}){{else}}{{.Tag.Name}}{{end}}"
- default:
- tagName = "{{.Tag.Name}}"
- }
-
- // format
+func templateBuilderFactory(template string) TemplateBuilder {
switch template {
- case tplStandard:
- tpl = fmt.Sprintf("%s## %s (%s)\n",
- tpl,
- tagName,
- date,
- )
- case tplCool:
- tpl = fmt.Sprintf("%s## %s\n\n> %s\n",
- tpl,
- tagName,
- date,
- )
- }
-
- return tpl
-}
-
-func (*templateBuilderImpl) commits(template, format string) string {
- var (
- header string
- body string
- )
-
- switch format {
- case fmtSubject.Display:
- body = `{{range .Commits}}
-* {{.Header}}{{end}}
-`
-
+ case tplKeepAChangelog:
+ return NewKACTemplateBuilder()
default:
- if format == fmtTypeScopeSubject.Display {
- header = "{{if ne .Scope \"\"}}**{{.Scope}}:** {{end}}{{.Subject}}"
- } else {
- header = "{{.Subject}}"
- }
-
- body = fmt.Sprintf(`### {{.Title}}
-{{range .Commits}}
-* %s{{end}}
-`, header)
+ return NewCustomTemplateBuilder()
}
-
- return fmt.Sprintf(`{{range .CommitGroups}}
-%s{{end}}`, body)
-}
-
-func (*templateBuilderImpl) reverts() string {
- return `{{if .RevertCommits}}
-### Reverts
-{{range .RevertCommits}}
-* {{.Revert.Header}}{{end}}
-{{end}}`
-}
-
-func (t *templateBuilderImpl) merges(style string) string {
- var title string
-
- switch style {
- case styleGitHub:
- title = "Pull Requests"
- default:
- title = "Merges"
- }
-
- return fmt.Sprintf(`{{if .MergeCommits}}
-### %s
-{{range .MergeCommits}}
-* {{.Header}}{{end}}
-{{end}}`, title)
-}
-
-func (*templateBuilderImpl) notes() string {
- return `{{range .NoteGroups}}
-### {{.Title}}
-{{range .Notes}}
-{{.Body}}
-{{end}}
-{{end}}`
}
diff --git a/cmd/git-chglog/variables.go b/cmd/git-chglog/variables.go
index 0253f10b..bcb63803 100644
--- a/cmd/git-chglog/variables.go
+++ b/cmd/git-chglog/variables.go
@@ -86,9 +86,11 @@ var (
// Templates
var (
- tplStandard = "standard"
- tplCool = "cool"
- templates = []string{
+ tplKeepAChangelog = "keep-a-changelog"
+ tplStandard = "standard"
+ tplCool = "cool"
+ templates = []string{
+ tplKeepAChangelog,
tplStandard,
tplCool,
}