0
0
mirror of https://github.com/thegeeklab/git-sv.git synced 2024-11-24 21:20:40 +00:00

refactor: create branches config

BREAKING CHANGE: remove BRANCH_ISSUE_REGEX varenv
This commit is contained in:
Beatriz Vieira 2021-02-14 01:48:11 -03:00
parent 0e7438b3a9
commit f6debee45e
5 changed files with 56 additions and 33 deletions

View File

@ -20,7 +20,8 @@ type Config struct {
CommitMessageTypes []string `envconfig:"COMMIT_MESSAGE_TYPES" default:"build,ci,chore,docs,feat,fix,perf,refactor,revert,style,test"`
IssueKeyName string `envconfig:"ISSUE_KEY_NAME" default:"jira"`
IssueRegex string `envconfig:"ISSUE_REGEX" default:"[A-Z]+-[0-9]+"`
BranchIssueRegex string `envconfig:"BRANCH_ISSUE_REGEX" default:"^([a-z]+\\/)?([A-Z]+-[0-9]+)(-.*)?"` //TODO breaking change: use issue regex instead of duplicating issue regex
BranchIssuePrefixRegex string `envconfig:"BRANCH_ISSUE_PREFIX_REGEX" default:"([a-z]+\\/)?"`
BranchIssueSuffixRegex string `envconfig:"BRANCH_ISSUE_SUFFIX_REGEX" default:"(-.*)?"`
}
func loadConfig() Config {

View File

@ -21,13 +21,20 @@ func main() {
Types: cfg.CommitMessageTypes,
Scope: sv.CommitMessageScopeConfig{},
Footer: map[string]sv.CommitMessageFooterConfig{
"issue": {Key: cfg.IssueIDPrefixes[0], KeySynonyms: cfg.IssueIDPrefixes[1:], Regex: cfg.IssueRegex},
"issue": {Key: cfg.IssueIDPrefixes[0], KeySynonyms: cfg.IssueIDPrefixes[1:]},
"breaking-change": {Key: cfg.BreakingChangePrefixes[0], KeySynonyms: cfg.BreakingChangePrefixes[1:]},
},
Issue: sv.CommitMessageIssueConfig{Regex: cfg.IssueRegex},
}
branchesConfig := sv.BranchesConfig{
Skip: cfg.ValidateMessageSkipBranches,
ExpectIssue: true,
PrefixRegex: cfg.BranchIssuePrefixRegex,
SuffixRegex: cfg.BranchIssueSuffixRegex,
}
////
messageProcessor := sv.NewMessageProcessor(commitMessageCfg, cfg.ValidateMessageSkipBranches, cfg.BranchIssueRegex)
messageProcessor := sv.NewMessageProcessor(commitMessageCfg, branchesConfig)
git := sv.NewGit(messageProcessor, cfg.TagPattern)
semverProcessor := sv.NewSemVerCommitsProcessor(cfg.IncludeUnknownTypeAsPatch, cfg.MajorVersionTypes, cfg.MinorVersionTypes, cfg.PatchVersionTypes)
releasenotesProcessor := sv.NewReleaseNoteProcessor(cfg.ReleaseNotesTags)

View File

@ -5,6 +5,7 @@ type CommitMessageConfig struct {
Types []string
Scope CommitMessageScopeConfig
Footer map[string]CommitMessageFooterConfig
Issue CommitMessageIssueConfig
}
// IssueConfig config for issue.
@ -33,6 +34,18 @@ type CommitMessageScopeConfig struct {
type CommitMessageFooterConfig struct {
Key string
KeySynonyms []string
Regex string
UseHash bool
}
// CommitMessageIssueConfig issue preferences.
type CommitMessageIssueConfig struct {
Regex string
}
// BranchesConfig branches preferences.
type BranchesConfig struct {
PrefixRegex string
SuffixRegex string
ExpectIssue bool
Skip []string
}

View File

@ -56,41 +56,39 @@ type MessageProcessor interface {
}
// NewMessageProcessor MessageProcessorImpl constructor
func NewMessageProcessor(cfg CommitMessageConfig, skipBranches []string, branchIssueRegex string) *MessageProcessorImpl {
func NewMessageProcessor(mcfg CommitMessageConfig, bcfg BranchesConfig) *MessageProcessorImpl {
return &MessageProcessorImpl{
cfg: cfg,
skipBranches: skipBranches,
branchIssueRegex: branchIssueRegex,
messageCfg: mcfg,
branchesCfg: bcfg,
}
}
// MessageProcessorImpl process validate message hook.
type MessageProcessorImpl struct {
cfg CommitMessageConfig
skipBranches []string
branchIssueRegex string
messageCfg CommitMessageConfig
branchesCfg BranchesConfig
}
// SkipBranch check if branch should be ignored.
func (p MessageProcessorImpl) SkipBranch(branch string) bool {
return contains(branch, p.skipBranches)
return contains(branch, p.branchesCfg.Skip)
}
// Validate commit message.
func (p MessageProcessorImpl) Validate(message string) error {
valid, err := regexp.MatchString("^("+strings.Join(p.cfg.Types, "|")+")(\\(.+\\))?!?: .*$", firstLine(message))
valid, err := regexp.MatchString("^("+strings.Join(p.messageCfg.Types, "|")+")(\\(.+\\))?!?: .*$", firstLine(message))
if err != nil {
return err
}
if !valid {
return fmt.Errorf("message should contain type: %v, and should be valid according with conventional commits", p.cfg.Types)
return fmt.Errorf("message should contain type: %v, and should be valid according with conventional commits", p.messageCfg.Types)
}
return nil
}
// Enhance add metadata on commit message.
func (p MessageProcessorImpl) Enhance(branch string, message string) (string, error) {
if p.branchIssueRegex == "" || p.cfg.IssueConfig().Key == "" || hasIssueID(message, p.cfg.IssueConfig().Key) {
if !p.branchesCfg.ExpectIssue || p.messageCfg.IssueConfig().Key == "" || hasIssueID(message, p.messageCfg.IssueConfig().Key) {
return "", nil //enhance disabled
}
@ -102,9 +100,9 @@ func (p MessageProcessorImpl) Enhance(branch string, message string) (string, er
return "", fmt.Errorf("could not find issue id using configured regex")
}
footer := fmt.Sprintf("%s: %s", p.cfg.IssueConfig().Key, issue)
footer := fmt.Sprintf("%s: %s", p.messageCfg.IssueConfig().Key, issue)
if !hasFooter(message, p.cfg.Footer[breakingKey].Key) {
if !hasFooter(message, p.messageCfg.Footer[breakingKey].Key) {
return "\n" + footer, nil
}
@ -113,9 +111,10 @@ func (p MessageProcessorImpl) Enhance(branch string, message string) (string, er
// IssueID try to extract issue id from branch, return empty if not found.
func (p MessageProcessorImpl) IssueID(branch string) (string, error) {
r, err := regexp.Compile(p.branchIssueRegex)
rstr := fmt.Sprintf("^%s(%s)%s$", p.branchesCfg.PrefixRegex, p.messageCfg.Issue.Regex, p.branchesCfg.SuffixRegex)
r, err := regexp.Compile(rstr)
if err != nil {
return "", fmt.Errorf("could not compile issue regex: %s, error: %v", p.branchIssueRegex, err.Error())
return "", fmt.Errorf("could not compile issue regex: %s, error: %v", rstr, err.Error())
}
groups := r.FindStringSubmatch(branch)
@ -137,13 +136,13 @@ func (p MessageProcessorImpl) Format(msg CommitMessage) (string, string, string)
var footer strings.Builder
if msg.BreakingMessage() != "" {
footer.WriteString(fmt.Sprintf("%s: %s", p.cfg.BreakingChangeConfig().Key, msg.BreakingMessage()))
footer.WriteString(fmt.Sprintf("%s: %s", p.messageCfg.BreakingChangeConfig().Key, msg.BreakingMessage()))
}
if issue, exists := msg.Metadata[issueKey]; exists {
if footer.Len() > 0 {
footer.WriteString("\n")
}
footer.WriteString(fmt.Sprintf("%s: %s", p.cfg.IssueConfig().Key, issue))
footer.WriteString(fmt.Sprintf("%s: %s", p.messageCfg.IssueConfig().Key, issue))
}
return header.String(), msg.Body, footer.String()
@ -154,7 +153,7 @@ func (p MessageProcessorImpl) Parse(subject, body string) CommitMessage {
commitType, scope, description, hasBreakingChange := parseSubjectMessage(subject)
metadata := make(map[string]string)
for key, mdCfg := range p.cfg.Footer {
for key, mdCfg := range p.messageCfg.Footer {
prefixes := append([]string{mdCfg.Key}, mdCfg.KeySynonyms...)
for _, prefix := range prefixes {
if tagValue := extractFooterMetadata(prefix, body, mdCfg.UseHash); tagValue != "" {

View File

@ -5,20 +5,23 @@ import (
"testing"
)
var cfg = CommitMessageConfig{
var ccfg = CommitMessageConfig{
Types: []string{"feat", "fix"},
Scope: CommitMessageScopeConfig{},
Footer: map[string]CommitMessageFooterConfig{
"issue": {Key: "jira", KeySynonyms: []string{"Jira"}, Regex: "[A-Z]+-[0-9]+"},
"issue": {Key: "jira", KeySynonyms: []string{"Jira"}},
"breaking-change": {Key: "BREAKING CHANGE", KeySynonyms: []string{"BREAKING CHANGES"}},
"refs": {Key: "Refs", UseHash: true},
},
Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"},
}
const (
branchIssueRegex = "^([a-z]+\\/)?([A-Z]+-[0-9]+)(-.*)?"
issueRegex = "[A-Z]+-[0-9]+"
)
var bcfg = BranchesConfig{
ExpectIssue: true,
PrefixRegex: "([a-z]+\\/)?",
SuffixRegex: "(-.*)?",
Skip: []string{"develop", "master"},
}
// messages samples start
var fullMessage = `fix: correct minor typos in code
@ -57,7 +60,7 @@ BREAKING CHANGE: refactor to use JavaScript features not available in Node 6.`
// multiline samples end
func TestMessageProcessorImpl_Validate(t *testing.T) {
p := NewMessageProcessor(cfg, []string{"develop", "master"}, branchIssueRegex)
p := NewMessageProcessor(ccfg, bcfg)
tests := []struct {
name string
@ -90,7 +93,7 @@ func TestMessageProcessorImpl_Validate(t *testing.T) {
}
func TestMessageProcessorImpl_Enhance(t *testing.T) {
p := NewMessageProcessor(cfg, []string{"develop", "master"}, branchIssueRegex)
p := NewMessageProcessor(ccfg, bcfg)
tests := []struct {
name string
@ -123,7 +126,7 @@ func TestMessageProcessorImpl_Enhance(t *testing.T) {
}
func TestMessageProcessorImpl_IssueID(t *testing.T) {
p := NewMessageProcessor(cfg, []string{"develop", "master"}, branchIssueRegex)
p := NewMessageProcessor(ccfg, bcfg)
tests := []struct {
name string
@ -251,7 +254,7 @@ Jira: JIRA-999
Refs #123`
func TestMessageProcessorImpl_Parse(t *testing.T) {
p := NewMessageProcessor(cfg, []string{"develop", "master"}, branchIssueRegex)
p := NewMessageProcessor(ccfg, bcfg)
tests := []struct {
name string
@ -278,7 +281,7 @@ func TestMessageProcessorImpl_Parse(t *testing.T) {
}
func TestMessageProcessorImpl_Format(t *testing.T) {
p := NewMessageProcessor(cfg, []string{"develop", "master"}, branchIssueRegex)
p := NewMessageProcessor(ccfg, bcfg)
tests := []struct {
name string