From 0e9ba05c825444c80c58eade69dabc967fbacc99 Mon Sep 17 00:00:00 2001 From: George Antoniadis Date: Thu, 29 Oct 2020 23:30:27 +0000 Subject: [PATCH] feat(changelog): add changelog template --- go.mod | 1 + go.sum | 3 ++ main.go | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 99 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 4eaf45b..921f05f 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/octago/sflags v0.2.0 github.com/pkg/errors v0.9.1 // indirect github.com/stretchr/testify v1.5.1 // indirect + github.com/wfscheper/convcom v0.0.0-20200418012201-7aa0e60ba66c golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee // indirect golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 // indirect ) diff --git a/go.sum b/go.sum index 21e9550..0bd935c 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= @@ -56,6 +57,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/wfscheper/convcom v0.0.0-20200418012201-7aa0e60ba66c h1:M/EIb5XC69hSpwpKpMq1ToIOFmsEPhJgAa/CzJC9+iA= +github.com/wfscheper/convcom v0.0.0-20200418012201-7aa0e60ba66c/go.mod h1:NC6MKsvA67myGLL8ykKy7/4fllTn6au88QZygMSfR/s= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/main.go b/main.go index 3d1cbea..56de5c7 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,11 @@ package main import ( + "bytes" "errors" "flag" "fmt" + "html/template" "io/ioutil" "log" "strings" @@ -13,8 +15,32 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/octago/sflags/gen/gflag" + convcom "github.com/wfscheper/convcom" ) +const changelogTemplate = ` +## {{ .Version }} + +{{- range $commit := .Commits }} + +### {{ $commit.Git.Hash }} + +{{ $commit.Git.Message }} +* Type: {{ $commit.Conv.Type }} +* Scope: {{ $commit.Conv.Scope }} +* Description: {{ $commit.Conv.Description }} +* Header: {{ $commit.Conv.Header }} +* MergeHeader: {{ $commit.Conv.MergeHeader }} +* Body: {{ $commit.Conv.Body }} +* Footers: {{ $commit.Conv.Footers }} +* Mentions: {{ $commit.Conv.Mentions }} +* References: {{ $commit.Conv.References }} +* Notes: {{ $commit.Conv.Notes }} +* Reverts: {{ $commit.Conv.Reverts }} +* IsBreaking: {{ $commit.Conv.IsBreaking }} +{{ end }} +` + type ( config struct { // action @@ -34,8 +60,16 @@ type ( VersionPrefix string `flag:"version-prefix" desc:"Version prefix"` // changelog config - ChangelogUpdate bool - ChangelogTemplatePath string + ChangelogUpdate bool `flag:"changelog-update" desc:"Update changelog"` + ChangelogPath string `flag:"changelog-path" desc:"Changelog file path"` + } + changelogEntry struct { + Version string + Commits []*changelogCommit + } + changelogCommit struct { + Git *object.Commit + Conv *convcom.Commit } ) @@ -176,8 +210,6 @@ func gitTagUpdate(c *config) error { return err } - fmt.Println(latestTagName, newVersion) - // create new tag repo.CreateTag(newVersion, head.Hash(), &git.CreateTagOptions{ Message: "chore(version): bump version to " + newVersion, @@ -244,11 +276,64 @@ func changelogUpdate(c *config) error { fmt.Println(latestTagName, newVersion) - // create new tag - repo.CreateTag(newVersion, head.Hash(), &git.CreateTagOptions{ - Message: "chore(version): bump version to " + newVersion, + convComParser, err := convcom.New(&convcom.Config{}) + if err != nil { + return err + } + + // find commits since the latest tag + commitsSinceTag := []*changelogCommit{} + commitIter, err := repo.Log(&git.LogOptions{}) + err = commitIter.ForEach(func(commit *object.Commit) error { + // once we reach the commit of the latest tag, we're done + if commit.Hash == latestTagCommit.Hash { + return errDone + } + convCommit, err := convComParser.Parse(commit.Message) + if err != nil { + return err + } + commitsSinceTag = append(commitsSinceTag, &changelogCommit{ + Git: commit, + Conv: convCommit, + }) + return nil }) - return nil + if err != nil && err != errDone { + return err + } + + // check current head is the latest tag + if latestTagCommit.Hash == head.Hash() { + return errors.New("head is already tagged") + } + + // go through the commits and figure out what we need to bump + tmpl, err := template.New("changelog").Parse(changelogTemplate) + if err != nil { + return err + } + + // render template + var newBody bytes.Buffer + if err := tmpl.Execute(&newBody, &changelogEntry{ + Version: newVersion, + Commits: commitsSinceTag, + }); err != nil { + return err + } + + // get existing file contents + changelogBody, err := ioutil.ReadFile(c.ChangelogPath) + if err != nil { + return err + } + + // merge existing changelog with new + mergedBody := append(newBody.Bytes(), changelogBody...) + + // and update file + return ioutil.WriteFile(c.ChangelogPath, mergedBody, 0644) } func fileUpdate(c *config) error { @@ -301,6 +386,7 @@ func main() { c := &config{ FilePath: "VERSION", VersionPrefix: "v", + ChangelogPath: "CHANGELOG", } err := gflag.ParseToDef(c) if err != nil { @@ -311,6 +397,7 @@ func main() { actions := []func(*config) error{ autodetectBump, bumpAtLeastMinor, + changelogUpdate, fileUpdate, gitTagUpdate, }