Skip to content

Commit

Permalink
feat: initial commit regex based commit analyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
fitz7 committed Mar 2, 2023
0 parents commit cdeaac6
Show file tree
Hide file tree
Showing 9 changed files with 968 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea/
dist
21 changes: 21 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
builds:
- env:
- CGO_ENABLED=0
targets:
- linux_amd64
- linux_arm64
- darwin_amd64
- darwin_arm64
- linux_arm
- windows_amd64
main: ./cmd/commit-analyzer-regex
ldflags:
- -extldflags '-static'
- -s -w -X github.com/faceit/commit-analyzer-regex/pkg/analyzer.CAVERSION={{.Version}}

archives:
- format: binary
name_template: '{{ .Binary }}_v{{ .Version }}_{{ .Os }}_{{ .Arch }}'

checksum:
name_template: '{{ .ProjectName }}_v{{ .Version }}_checksums.txt'
4 changes: 4 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@Library('faceit-shared-libs') _
goCommandLinePipeline(
projectName : 'commit-analyzer-regex'
)
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# :bulb: commit-analyzer-regex

A Regex based commit analyzer for [go-semantic-release](https://github.com/go-semantic-release/semantic-release).

This is a largely based on go semantic releases [commit-analyzer-cz](https://github.com/go-semantic-release/commit-analyzer-cz).
With one major difference in that it takes regex to decide which commit types correspond to kind of version bump is used


## How the commit messages are analyzed

### Bump major version (0.1.2 -> 1.0.0)
- By adding `BREAKING CHANGE` or `BREAKING CHANGES` in the commit message footer, e.g.:
```
feat: allow provided config object to extend other configs
BREAKING CHANGE: `extends` key in config file is now used for extending other config files
```
- By adding `!` at the end of the commit type, e.g.:
```
refactor!: drop support for Node 6
```

### Bump minor version (0.1.2 -> 0.2.0)
- By using type `feat`, e.g.:
```
feat(lang): add polish language
```

### Bump patch version (0.1.2 -> 0.1.3)
- By using type `fix`, e.g.:
```
fix: correct minor typos in code
see the issue for details
on typos fixed.
Reviewed-by: Z
Refs #133
```

## References
- [Conventional Commit v1.0.0 - Examples](https://www.conventionalcommits.org/en/v1.0.0/#examples)
16 changes: 16 additions & 0 deletions cmd/commit-analyzer-regex/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

import (
"github.com/go-semantic-release/semantic-release/v2/pkg/analyzer"
"github.com/go-semantic-release/semantic-release/v2/pkg/plugin"

defaultAnalyzer "github.com/faceit/commit-analyzer-regex/pkg/analyzer"
)

func main() {
plugin.Serve(&plugin.ServeOpts{
CommitAnalyzer: func() analyzer.CommitAnalyzer {
return &defaultAnalyzer.DefaultCommitAnalyzer{}
},
})
}
46 changes: 46 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module github.com/faceit/commit-analyzer-regex

go 1.19

require (
github.com/go-semantic-release/semantic-release/v2 v2.25.0
github.com/stretchr/testify v1.8.1
)

require (
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/hashicorp/go-hclog v1.4.0 // indirect
github.com/hashicorp/go-plugin v1.4.8 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.6.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.14.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect
google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9 // indirect
google.golang.org/grpc v1.52.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
534 changes: 534 additions & 0 deletions go.sum

Large diffs are not rendered by default.

115 changes: 115 additions & 0 deletions pkg/analyzer/commit_analyzer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package analyzer

import (
"regexp"
"strings"

"github.com/go-semantic-release/semantic-release/v2/pkg/semrel"
)

var (
CAVERSION = "dev"
commitPattern = regexp.MustCompile(`^(\w*)(?:\((.*)\))?(\!)?\: (.*)$`)
breakingPattern = regexp.MustCompile("BREAKING CHANGES?")
mentionedIssuesPattern = regexp.MustCompile(`#(\d+)`)
mentionedUsersPattern = regexp.MustCompile(`(?i)@([a-z\d]([a-z\d]|-[a-z\d])+)`)
)

func extractMentions(re *regexp.Regexp, s string) string {
ret := make([]string, 0)
for _, m := range re.FindAllStringSubmatch(s, -1) {
ret = append(ret, m[1])
}
return strings.Join(ret, ",")
}

type DefaultCommitAnalyzer struct {
MinorRegexp *regexp.Regexp
PatchRegexp *regexp.Regexp
}

func (da *DefaultCommitAnalyzer) Init(config map[string]string) error {
for k, v := range config {
println(k)
println(v)
}
minorPattern := config["minor"]
println(minorPattern)
if minorPattern != "" {
println("using new minor pattern")
minorRegexp, err := regexp.Compile(minorPattern)
if err != nil {
return err
}
da.MinorRegexp = minorRegexp
} else {
da.MinorRegexp = regexp.MustCompile("feat")
}

patchPattern := config["patch"]
println(patchPattern)
if patchPattern != "" {
patchRegexp, err := regexp.Compile(patchPattern)
if err != nil {
return err
}
da.PatchRegexp = patchRegexp
} else {
da.PatchRegexp = regexp.MustCompile("fix")
}

return nil
}

func (da *DefaultCommitAnalyzer) Name() string {
return "commit-analyzer-regex"
}

func (da *DefaultCommitAnalyzer) Version() string {
return CAVERSION
}

func (da *DefaultCommitAnalyzer) analyzeSingleCommit(rawCommit *semrel.RawCommit) *semrel.Commit {
c := &semrel.Commit{
SHA: rawCommit.SHA,
Raw: strings.Split(rawCommit.RawMessage, "\n"),
Change: &semrel.Change{},
Annotations: rawCommit.Annotations,
}
c.Annotations["mentioned_issues"] = extractMentions(mentionedIssuesPattern, rawCommit.RawMessage)
c.Annotations["mentioned_users"] = extractMentions(mentionedUsersPattern, rawCommit.RawMessage)

found := commitPattern.FindAllStringSubmatch(c.Raw[0], -1)
if len(found) < 1 {
return c
}
c.Type = strings.ToLower(found[0][1])
c.Scope = found[0][2]
breakingChange := found[0][3]
c.Message = found[0][4]

isMajorChange := breakingPattern.MatchString(rawCommit.RawMessage)
isMinorChange := da.MinorRegexp.MatchString(c.Type)
isPatchChange := da.PatchRegexp.MatchString(c.Type)

if len(breakingChange) > 0 {
isMajorChange = true
isMinorChange = false
isPatchChange = false
}

c.Change = &semrel.Change{
Major: isMajorChange,
Minor: isMinorChange,
Patch: isPatchChange,
}
return c
}

func (da *DefaultCommitAnalyzer) Analyze(rawCommits []*semrel.RawCommit) []*semrel.Commit {
ret := make([]*semrel.Commit, len(rawCommits))
for i, c := range rawCommits {
ret[i] = da.analyzeSingleCommit(c)
}
return ret
}
Loading

0 comments on commit cdeaac6

Please sign in to comment.