From fc465926e37af3c9372a78c1087071968b64c961 Mon Sep 17 00:00:00 2001 From: hau Date: Mon, 9 Nov 2020 15:46:42 +0700 Subject: [PATCH] feat: add conventional commits --- cmd/main.go | 18 ++++++++++- pkg/convention/commit.go | 67 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 pkg/convention/commit.go diff --git a/cmd/main.go b/cmd/main.go index d0cf1a3..f595b89 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,6 +4,7 @@ import ( "log" "os" + "github.com/haunt98/changeloguru/pkg/convention" "github.com/haunt98/changeloguru/pkg/git" "github.com/urfave/cli/v2" ) @@ -73,10 +74,25 @@ func action(c *cli.Context) error { if err != nil { return err } - if verbose { log.Printf("commits %+v", commits) } + conventionalCommits := make([]convention.Commit, 0, len(commits)) + for _, commit := range commits { + conventionalCommit, err := convention.NewCommit(commit) + if err != nil { + if verbose { + log.Printf("failed to new conventional commits %+v: %s", commit, err) + } + continue + } + + conventionalCommits = append(conventionalCommits, conventionalCommit) + } + if verbose { + log.Printf("conventional commits %+v", conventionalCommits) + } + return nil } diff --git a/pkg/convention/commit.go b/pkg/convention/commit.go new file mode 100644 index 0000000..98709ff --- /dev/null +++ b/pkg/convention/commit.go @@ -0,0 +1,67 @@ +package convention + +import ( + "errors" + "regexp" + "strings" + + "github.com/haunt98/changeloguru/pkg/git" +) + +// https://www.conventionalcommits.org/en/v1.0.0/ +// [optional scope]: +// [optional body] +// [optional footer(s)] + +var ( + headerRegex = regexp.MustCompile(`(?P[a-zA-Z]+)(?P\([a-zA-Z]+\))?(?P!)?:\s(?P.+)`) +) + +type Commit struct { + Type string + Scope string + Description string + BodyAndFooters string +} + +func NewCommit(c git.Commit) (result Commit, err error) { + messages := strings.Split(c.Message, "\n") + if len(messages) == 0 { + err = errors.New("empty commit") + return + } + + header := messages[0] + if err = parseHeader(header, &result); err != nil { + return + } + + bodyAndFooters := c.Message[len(header):] + parseBodyAndFooters(bodyAndFooters, &result) + + return +} + +func parseHeader(header string, commit *Commit) error { + if !headerRegex.MatchString(header) { + return errors.New("wrong header format") + } + + headerSubmatches := headerRegex.FindStringSubmatch(header) + + commit.Type = headerSubmatches[1] + + commit.Scope = headerSubmatches[2] + commit.Scope = strings.TrimPrefix(commit.Scope, "(") + commit.Scope = strings.TrimSuffix(commit.Scope, ")") + + commit.Description = headerSubmatches[4] + + return nil +} + +func parseBodyAndFooters(bodyAndFooters string, commit *Commit) { + bodyAndFooters = strings.TrimSpace(bodyAndFooters) + + commit.BodyAndFooters = bodyAndFooters +}