From b5d9f9c535bb418aa0b65f4b4f9a5d5f4f7a95f8 Mon Sep 17 00:00:00 2001 From: Beatriz Vieira Date: Sun, 30 Jan 2022 18:45:16 -0300 Subject: [PATCH] refactor: extract templates from code and use go:embed issue: #40 --- sv/formatter.go | 53 +++------------ sv/formatter_test.go | 68 +++++++++++++++++++ sv/resources/templates/changelog-md.tpl | 6 ++ sv/resources/templates/releasenotes-md.tpl | 6 ++ .../rn-md-section-breaking-changes.tpl | 7 ++ sv/resources/templates/rn-md-section-item.tpl | 1 + sv/resources/templates/rn-md-section.tpl | 7 ++ 7 files changed, 104 insertions(+), 44 deletions(-) create mode 100644 sv/resources/templates/changelog-md.tpl create mode 100644 sv/resources/templates/releasenotes-md.tpl create mode 100644 sv/resources/templates/rn-md-section-breaking-changes.tpl create mode 100644 sv/resources/templates/rn-md-section-item.tpl create mode 100644 sv/resources/templates/rn-md-section.tpl diff --git a/sv/formatter.go b/sv/formatter.go index 9d93367..896de9f 100644 --- a/sv/formatter.go +++ b/sv/formatter.go @@ -2,6 +2,7 @@ package sv import ( "bytes" + "embed" "text/template" ) @@ -13,40 +14,9 @@ type releaseNoteTemplateVariables struct { BreakingChanges BreakingChangeSection } -const ( - cglTemplate = `# Changelog -{{- range .}} - -{{template "rnTemplate" .}} ---- -{{- end}} -` - - rnSectionItem = "- {{if .Message.Scope}}**{{.Message.Scope}}:** {{end}}{{.Message.Description}} ({{.Hash}}){{if .Message.Metadata.issue}} ({{.Message.Metadata.issue}}){{end}}" - - rnSection = `{{- if .}}{{- if ne .Name ""}} - -### {{.Name}} -{{range $k,$v := .Items}} -{{template "rnSectionItem" $v}} -{{- end}} -{{- end}}{{- end}}` - - rnSectionBreakingChanges = `{{- if ne .Name ""}} - -### {{.Name}} -{{range $k,$v := .Messages}} -- {{$v}} -{{- end}} -{{- end}}` - - rnTemplate = `## {{if .Release}}{{.Release}}{{end}}{{if and .Date .Release}} ({{end}}{{.Date}}{{if and .Date .Release}}){{end}} -{{- $sections := .Sections }} -{{- range $key := .Order }} -{{- template "rnSection" (index $sections $key) }} -{{- end}} -{{- template "rnSectionBreakingChanges" .BreakingChanges}} -` +var ( + //go:embed resources/templates/* + defaultTemplatesFS embed.FS ) // OutputFormatter output formatter interface. @@ -57,24 +27,19 @@ type OutputFormatter interface { // OutputFormatterImpl formater for release note and changelog. type OutputFormatterImpl struct { - releasenoteTemplate *template.Template - changelogTemplate *template.Template + templates *template.Template } // NewOutputFormatter TemplateProcessor constructor. func NewOutputFormatter() *OutputFormatterImpl { - cgl := template.Must(template.New("cglTemplate").Parse(cglTemplate)) - rn := template.Must(cgl.New("rnTemplate").Parse(rnTemplate)) - template.Must(rn.New("rnSectionItem").Parse(rnSectionItem)) - template.Must(rn.New("rnSection").Parse(rnSection)) - template.Must(rn.New("rnSectionBreakingChanges").Parse(rnSectionBreakingChanges)) - return &OutputFormatterImpl{releasenoteTemplate: rn, changelogTemplate: cgl} + tpls := template.Must(template.New("templates").ParseFS(defaultTemplatesFS, "resources/templates/*")) + return &OutputFormatterImpl{templates: tpls} } // FormatReleaseNote format a release note. func (p OutputFormatterImpl) FormatReleaseNote(releasenote ReleaseNote) (string, error) { var b bytes.Buffer - if err := p.releasenoteTemplate.Execute(&b, releaseNoteVariables(releasenote)); err != nil { + if err := p.templates.ExecuteTemplate(&b, "releasenotes-md.tpl", releaseNoteVariables(releasenote)); err != nil { return "", err } return b.String(), nil @@ -88,7 +53,7 @@ func (p OutputFormatterImpl) FormatChangelog(releasenotes []ReleaseNote) (string } var b bytes.Buffer - if err := p.changelogTemplate.Execute(&b, templateVars); err != nil { + if err := p.templates.ExecuteTemplate(&b, "changelog-md.tpl", templateVars); err != nil { return "", err } return b.String(), nil diff --git a/sv/formatter_test.go b/sv/formatter_test.go index 73a5104..eabf4f5 100644 --- a/sv/formatter_test.go +++ b/sv/formatter_test.go @@ -1,7 +1,9 @@ package sv import ( + "bytes" "testing" + "text/template" "time" "github.com/Masterminds/semver/v3" @@ -85,3 +87,69 @@ func fullReleaseNote(tag string, date time.Time) ReleaseNote { } return releaseNote(v, tag, date, sections, []string{"break change message"}) } + +func releaseNotesVariables(release string) releaseNoteTemplateVariables { + return releaseNoteTemplateVariables{ + Release: release, + Date: "2006-01-02", + Sections: map[string]ReleaseNoteSection{ + "build": newReleaseNoteSection("Build", []GitCommitLog{commitlog("build", map[string]string{})}), + "feat": newReleaseNoteSection("Features", []GitCommitLog{commitlog("feat", map[string]string{})}), + "fix": newReleaseNoteSection("Bug Fixes", []GitCommitLog{commitlog("fix", map[string]string{})}), + }, + Order: []string{"feat", "fix", "refactor", "perf", "test", "build", "ci", "chore", "docs", "style"}, + BreakingChanges: BreakingChangeSection{"Breaking Changes", []string{"break change message"}}, + } +} + +func changelogVariables(releases ...string) []releaseNoteTemplateVariables { + var variables []releaseNoteTemplateVariables + for _, r := range releases { + variables = append(variables, releaseNotesVariables(r)) + } + return variables + +} + +func Test_checkTemplatesFiles(t *testing.T) { + tests := []string{ + "resources/templates/changelog-md.tpl", + "resources/templates/releasenotes-md.tpl", + } + for _, tt := range tests { + t.Run(tt, func(t *testing.T) { + got, err := defaultTemplatesFS.ReadFile(tt) + if err != nil { + t.Errorf("missing template error = %v", err) + return + } + if len(got) <= 0 { + t.Errorf("empty template") + } + }) + } +} + +func Test_checkTemplatesExecution(t *testing.T) { + tpls := template.Must(template.New("templates").ParseFS(defaultTemplatesFS, "resources/templates/*")) + tests := []struct { + template string + variables interface{} + }{ + {"changelog-md.tpl", changelogVariables("v1.0.0", "v1.0.1")}, + {"releasenotes-md.tpl", releaseNotesVariables("v1.0.0")}, + } + for _, tt := range tests { + t.Run(tt.template, func(t *testing.T) { + var b bytes.Buffer + err := tpls.ExecuteTemplate(&b, tt.template, tt.variables) + if err != nil { + t.Errorf("invalid template err = %v", err) + return + } + if len(b.Bytes()) <= 0 { + t.Errorf("empty template") + } + }) + } +} diff --git a/sv/resources/templates/changelog-md.tpl b/sv/resources/templates/changelog-md.tpl new file mode 100644 index 0000000..d478272 --- /dev/null +++ b/sv/resources/templates/changelog-md.tpl @@ -0,0 +1,6 @@ +# Changelog +{{- range .}} + +{{template "releasenotes-md.tpl" .}} +--- +{{- end}} \ No newline at end of file diff --git a/sv/resources/templates/releasenotes-md.tpl b/sv/resources/templates/releasenotes-md.tpl new file mode 100644 index 0000000..440cb6b --- /dev/null +++ b/sv/resources/templates/releasenotes-md.tpl @@ -0,0 +1,6 @@ +## {{if .Release}}{{.Release}}{{end}}{{if and .Date .Release}} ({{end}}{{.Date}}{{if and .Date .Release}}){{end}} +{{- $sections := .Sections }} +{{- range $key := .Order }} +{{- template "rn-md-section.tpl" (index $sections $key) }} +{{- end}} +{{- template "rn-md-section-breaking-changes.tpl" .BreakingChanges}} diff --git a/sv/resources/templates/rn-md-section-breaking-changes.tpl b/sv/resources/templates/rn-md-section-breaking-changes.tpl new file mode 100644 index 0000000..862b1dc --- /dev/null +++ b/sv/resources/templates/rn-md-section-breaking-changes.tpl @@ -0,0 +1,7 @@ +{{- if ne .Name ""}} + +### {{.Name}} +{{range $k,$v := .Messages}} +- {{$v}} +{{- end}} +{{- end}} \ No newline at end of file diff --git a/sv/resources/templates/rn-md-section-item.tpl b/sv/resources/templates/rn-md-section-item.tpl new file mode 100644 index 0000000..f0783a3 --- /dev/null +++ b/sv/resources/templates/rn-md-section-item.tpl @@ -0,0 +1 @@ +- {{if .Message.Scope}}**{{.Message.Scope}}:** {{end}}{{.Message.Description}} ({{.Hash}}){{if .Message.Metadata.issue}} ({{.Message.Metadata.issue}}){{end}} \ No newline at end of file diff --git a/sv/resources/templates/rn-md-section.tpl b/sv/resources/templates/rn-md-section.tpl new file mode 100644 index 0000000..32c7759 --- /dev/null +++ b/sv/resources/templates/rn-md-section.tpl @@ -0,0 +1,7 @@ +{{- if .}}{{- if ne .Name ""}} + +### {{.Name}} +{{range $k,$v := .Items}} +{{template "rn-md-section-item.tpl" $v}} +{{- end}} +{{- end}}{{- end}} \ No newline at end of file