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

Merge pull request #22 from bvieira/issue-prefix

Feature: add issue value prefix
This commit is contained in:
Beatriz Vieira 2021-07-18 18:15:21 -03:00 committed by GitHub
commit 7de1784bc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 24 deletions

View File

@ -17,5 +17,6 @@ commit-message:
footer: footer:
issue: issue:
key: issue key: issue
add-value-prefix: '#'
issue: issue:
regex: '#[0-9]+' regex: '#?[0-9]+'

View File

@ -1,4 +1,4 @@
.PHONY: usage build test run tidy release release-all .PHONY: usage build test test-coverage test-show-coverage run tidy release release-all
OK_COLOR=\033[32;01m OK_COLOR=\033[32;01m
NO_COLOR=\033[0m NO_COLOR=\033[0m
@ -18,6 +18,8 @@ BUILDARCH ?= amd64
BUILDENVS ?= CGO_ENABLED=0 GOOS=$(BUILDOS) GOARCH=$(BUILDARCH) BUILDENVS ?= CGO_ENABLED=0 GOOS=$(BUILDOS) GOARCH=$(BUILDARCH)
BUILDFLAGS ?= -a -installsuffix cgo --ldflags '-X main.Version=$(VERSION) -extldflags "-lm -lstdc++ -static"' BUILDFLAGS ?= -a -installsuffix cgo --ldflags '-X main.Version=$(VERSION) -extldflags "-lm -lstdc++ -static"'
COMPRESS_TYPE ?= targz
usage: Makefile usage: Makefile
@echo $(ECHOFLAGS) "to use make call:" @echo $(ECHOFLAGS) "to use make call:"
@echo $(ECHOFLAGS) " make <action>" @echo $(ECHOFLAGS) " make <action>"
@ -35,6 +37,16 @@ test:
@echo $(ECHOFLAGS) "$(OK_COLOR)==> Running tests...$(NO_COLOR)" @echo $(ECHOFLAGS) "$(OK_COLOR)==> Running tests...$(NO_COLOR)"
@go test $(PKGS) @go test $(PKGS)
## test-coverage: run tests with coverage
test-coverage:
@echo $(ECHOFLAGS) "$(OK_COLOR)==> Running tests with coverage...$(NO_COLOR)"
@go test -race -covermode=atomic -coverprofile coverage.out ./...
## test-show-coverage: show coverage
test-show-coverage: test-coverage
@echo $(ECHOFLAGS) "$(OK_COLOR)==> Show test coverage...$(NO_COLOR)"
@go tool cover -html coverage.out
## run: run git-sv ## run: run git-sv
run: run:
@echo $(ECHOFLAGS) "$(OK_COLOR)==> Running bin/$(BUILDOS)_$(BUILDARCH)/$(BIN)...$(NO_COLOR)" @echo $(ECHOFLAGS) "$(OK_COLOR)==> Running bin/$(BUILDOS)_$(BUILDARCH)/$(BIN)...$(NO_COLOR)"
@ -48,7 +60,11 @@ tidy:
## release: prepare binary for release ## release: prepare binary for release
release: release:
make build make build
ifeq ($(COMPRESS_TYPE), zip)
@zip -j bin/git-sv_$(VERSION)_$(BUILDOS)_$(BUILDARCH).zip bin/$(BUILDOS)_$(BUILDARCH)/$(BIN) @zip -j bin/git-sv_$(VERSION)_$(BUILDOS)_$(BUILDARCH).zip bin/$(BUILDOS)_$(BUILDARCH)/$(BIN)
else
@tar -czf bin/git-sv_$(VERSION)_$(BUILDOS)_$(BUILDARCH).tar.gz -C bin/$(BUILDOS)_$(BUILDARCH)/ $(BIN)
endif
## release-all: prepare linux, darwin and windows binary for release (requires sv4git) ## release-all: prepare linux, darwin and windows binary for release (requires sv4git)
release-all: release-all:
@ -56,4 +72,4 @@ release-all:
VERSION=$(shell git sv nv) BUILDOS=linux make release VERSION=$(shell git sv nv) BUILDOS=linux make release
VERSION=$(shell git sv nv) BUILDOS=darwin make release VERSION=$(shell git sv nv) BUILDOS=darwin make release
VERSION=$(shell git sv nv) BUILDOS=windows make release VERSION=$(shell git sv nv) COMPRESS_TYPE=zip BUILDOS=windows make release

View File

@ -127,6 +127,7 @@ commit-message:
- Jira - Jira
- JIRA - JIRA
use-hash: false # If false, use :<space> separator. If true, use <space># separator. use-hash: false # If false, use :<space> separator. If true, use <space># separator.
add-value-prefix: '' # Add a prefix to issue value.
issue: issue:
regex: '[A-Z]+-[0-9]+' # Regex for issue id. regex: '[A-Z]+-[0-9]+' # Regex for issue id.
``` ```

View File

@ -28,6 +28,7 @@ type CommitMessageFooterConfig struct {
Key string `yaml:"key"` Key string `yaml:"key"`
KeySynonyms []string `yaml:"key-synonyms"` KeySynonyms []string `yaml:"key-synonyms"`
UseHash bool `yaml:"use-hash"` UseHash bool `yaml:"use-hash"`
AddValuePrefix string `yaml:"add-value-prefix"`
} }
// CommitMessageIssueConfig issue preferences. // CommitMessageIssueConfig issue preferences.

View File

@ -108,8 +108,7 @@ func (p MessageProcessorImpl) Enhance(branch string, message string) (string, er
return "", fmt.Errorf("could not find issue id using configured regex") return "", fmt.Errorf("could not find issue id using configured regex")
} }
footer := fmt.Sprintf("%s: %s", p.messageCfg.IssueFooterConfig().Key, issue) footer := formatIssueFooter(p.messageCfg.IssueFooterConfig(), issue)
if !hasFooter(message) { if !hasFooter(message) {
return "\n" + footer, nil return "\n" + footer, nil
} }
@ -117,6 +116,16 @@ func (p MessageProcessorImpl) Enhance(branch string, message string) (string, er
return footer, nil return footer, nil
} }
func formatIssueFooter(cfg CommitMessageFooterConfig, issue string) string {
if !strings.HasPrefix(issue, cfg.AddValuePrefix) {
issue = cfg.AddValuePrefix + issue
}
if cfg.UseHash {
return fmt.Sprintf("%s #%s", cfg.Key, strings.TrimPrefix(issue, "#"))
}
return fmt.Sprintf("%s: %s", cfg.Key, issue)
}
// IssueID try to extract issue id from branch, return empty if not found. // IssueID try to extract issue id from branch, return empty if not found.
func (p MessageProcessorImpl) IssueID(branch string) (string, error) { func (p MessageProcessorImpl) IssueID(branch string) (string, error) {
if p.branchesCfg.DisableIssue || p.messageCfg.Issue.Regex == "" { if p.branchesCfg.DisableIssue || p.messageCfg.Issue.Regex == "" {
@ -154,11 +163,7 @@ func (p MessageProcessorImpl) Format(msg CommitMessage) (string, string, string)
if footer.Len() > 0 { if footer.Len() > 0 {
footer.WriteString("\n") footer.WriteString("\n")
} }
if p.messageCfg.IssueFooterConfig().UseHash { footer.WriteString(formatIssueFooter(p.messageCfg.IssueFooterConfig(), issue))
footer.WriteString(fmt.Sprintf("%s #%s", p.messageCfg.IssueFooterConfig().Key, strings.TrimPrefix(issue, "#")))
} else {
footer.WriteString(fmt.Sprintf("%s: %s", p.messageCfg.IssueFooterConfig().Key, issue))
}
} }
return header.String(), msg.Body, footer.String() return header.String(), msg.Body, footer.String()

View File

@ -15,6 +15,25 @@ var ccfg = CommitMessageConfig{
Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"}, Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"},
} }
var ccfgHash = CommitMessageConfig{
Types: []string{"feat", "fix"},
Scope: CommitMessageScopeConfig{},
Footer: map[string]CommitMessageFooterConfig{
"issue": {Key: "jira", KeySynonyms: []string{"Jira"}, UseHash: true},
"refs": {Key: "Refs", UseHash: true},
},
Issue: CommitMessageIssueConfig{Regex: "[A-Z]+-[0-9]+"},
}
var ccfgGitIssue = CommitMessageConfig{
Types: []string{"feat", "fix"},
Scope: CommitMessageScopeConfig{},
Footer: map[string]CommitMessageFooterConfig{
"issue": {Key: "issue", KeySynonyms: []string{"Issue"}, UseHash: false, AddValuePrefix: "#"},
},
Issue: CommitMessageIssueConfig{Regex: "#?[0-9]+"},
}
var ccfgEmptyIssue = CommitMessageConfig{ var ccfgEmptyIssue = CommitMessageConfig{
Types: []string{"feat", "fix"}, Types: []string{"feat", "fix"},
Scope: CommitMessageScopeConfig{}, Scope: CommitMessageScopeConfig{},
@ -139,27 +158,30 @@ func TestMessageProcessorImpl_Validate(t *testing.T) {
} }
func TestMessageProcessorImpl_Enhance(t *testing.T) { func TestMessageProcessorImpl_Enhance(t *testing.T) {
p := NewMessageProcessor(ccfg, newBranchCfg(false))
tests := []struct { tests := []struct {
name string name string
cfg CommitMessageConfig
branch string branch string
message string message string
want string want string
wantErr bool wantErr bool
}{ }{
{"issue on branch name", "JIRA-123", "fix: fix something", "\njira: JIRA-123", false}, {"issue on branch name", ccfg, "JIRA-123", "fix: fix something", "\njira: JIRA-123", false},
{"issue on branch name with description", "JIRA-123-some-description", "fix: fix something", "\njira: JIRA-123", false}, {"issue on branch name with description", ccfg, "JIRA-123-some-description", "fix: fix something", "\njira: JIRA-123", false},
{"issue on branch name with prefix", "feature/JIRA-123", "fix: fix something", "\njira: JIRA-123", false}, {"issue on branch name with prefix", ccfg, "feature/JIRA-123", "fix: fix something", "\njira: JIRA-123", false},
{"with footer", "JIRA-123", fullMessage, "jira: JIRA-123", false}, {"with footer", ccfg, "JIRA-123", fullMessage, "jira: JIRA-123", false},
{"with issue on footer", "JIRA-123", fullMessageWithJira, "", false}, {"with issue on footer", ccfg, "JIRA-123", fullMessageWithJira, "", false},
{"issue on branch name with prefix and description", "feature/JIRA-123-some-description", "fix: fix something", "\njira: JIRA-123", false}, {"issue on branch name with prefix and description", ccfg, "feature/JIRA-123-some-description", "fix: fix something", "\njira: JIRA-123", false},
{"no issue on branch name", "branch", "fix: fix something", "", true}, {"no issue on branch name", ccfg, "branch", "fix: fix something", "", true},
{"unexpected branch name", "feature /JIRA-123", "fix: fix something", "", true}, {"unexpected branch name", ccfg, "feature /JIRA-123", "fix: fix something", "", true},
{"issue on branch name using hash", ccfgHash, "JIRA-123-some-description", "fix: fix something", "\njira #JIRA-123", false},
{"numeric issue on branch name", ccfgGitIssue, "#13", "fix: fix something", "\nissue: #13", false},
{"numeric issue on branch name without hash", ccfgGitIssue, "13", "fix: fix something", "\nissue: #13", false},
{"numeric issue on branch name with description without hash", ccfgGitIssue, "13-some-fix", "fix: fix something", "\nissue: #13", false},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got, err := p.Enhance(tt.branch, tt.message) got, err := NewMessageProcessor(tt.cfg, newBranchCfg(false)).Enhance(tt.branch, tt.message)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("MessageProcessorImpl.Enhance() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("MessageProcessorImpl.Enhance() error = %v, wantErr %v", err, tt.wantErr)
return return
@ -325,12 +347,16 @@ func TestMessageProcessorImpl_Format(t *testing.T) {
}{ }{
{"simple message", ccfg, NewCommitMessage("feat", "", "something", "", "", ""), "feat: something", "", ""}, {"simple message", ccfg, NewCommitMessage("feat", "", "something", "", "", ""), "feat: something", "", ""},
{"with issue", ccfg, NewCommitMessage("feat", "", "something", "", "JIRA-123", ""), "feat: something", "", "jira: JIRA-123"}, {"with issue", ccfg, NewCommitMessage("feat", "", "something", "", "JIRA-123", ""), "feat: something", "", "jira: JIRA-123"},
{"with issue using hash", ccfgHash, NewCommitMessage("feat", "", "something", "", "JIRA-123", ""), "feat: something", "", "jira #JIRA-123"},
{"with issue using double hash", ccfgHash, NewCommitMessage("feat", "", "something", "", "#JIRA-123", ""), "feat: something", "", "jira #JIRA-123"},
{"with breaking change", ccfg, NewCommitMessage("feat", "", "something", "", "", "breaks"), "feat: something", "", "BREAKING CHANGE: breaks"}, {"with breaking change", ccfg, NewCommitMessage("feat", "", "something", "", "", "breaks"), "feat: something", "", "BREAKING CHANGE: breaks"},
{"with scope", ccfg, NewCommitMessage("feat", "scope", "something", "", "", ""), "feat(scope): something", "", ""}, {"with scope", ccfg, NewCommitMessage("feat", "scope", "something", "", "", ""), "feat(scope): something", "", ""},
{"with body", ccfg, NewCommitMessage("feat", "", "something", "body", "", ""), "feat: something", "body", ""}, {"with body", ccfg, NewCommitMessage("feat", "", "something", "body", "", ""), "feat: something", "body", ""},
{"with multiline body", ccfg, NewCommitMessage("feat", "", "something", multilineBody, "", ""), "feat: something", multilineBody, ""}, {"with multiline body", ccfg, NewCommitMessage("feat", "", "something", multilineBody, "", ""), "feat: something", multilineBody, ""},
{"full message", ccfg, NewCommitMessage("feat", "scope", "something", multilineBody, "JIRA-123", "breaks"), "feat(scope): something", multilineBody, fullFooter}, {"full message", ccfg, NewCommitMessage("feat", "scope", "something", multilineBody, "JIRA-123", "breaks"), "feat(scope): something", multilineBody, fullFooter},
{"config without issue key", ccfgEmptyIssue, NewCommitMessage("feat", "", "something", "", "JIRA-123", ""), "feat: something", "", ""}, {"config without issue key", ccfgEmptyIssue, NewCommitMessage("feat", "", "something", "", "JIRA-123", ""), "feat: something", "", ""},
{"with issue and issue prefix", ccfgGitIssue, NewCommitMessage("feat", "", "something", "", "123", ""), "feat: something", "", "issue: #123"},
{"with #issue and issue prefix", ccfgGitIssue, NewCommitMessage("feat", "", "something", "", "#123", ""), "feat: something", "", "issue: #123"},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {