mirror of
https://github.com/vbatts/git-validation.git
synced 2024-11-22 16:15:40 +00:00
message_regexp: regular expression rule for messages
Fixes: #30 now you can add a regular expression to the rules to be run i.e. `git-validation -run "dco,message_regexp='^JIRA-[0-9]+ [A-Z].*$'"` Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
parent
d9bf419b44
commit
00823a324b
8 changed files with 89 additions and 10 deletions
|
@ -30,7 +30,9 @@ Usage of git-validation:
|
|||
The entire default rule set is run by default:
|
||||
```console
|
||||
vbatts@valse ~/src/vb/git-validation (master) $ git-validation -list-rules
|
||||
"dangling-whitespace" -- checking the presence of dangling whitespaces on line endings
|
||||
"DCO" -- makes sure the commits are signed
|
||||
"message_regexp" -- checks the commit message for a user provided regular expression
|
||||
"short-subject" -- commit subjects are strictly less than 90 (github ellipsis length)
|
||||
```
|
||||
|
||||
|
@ -92,6 +94,7 @@ vbatts@valse ~/src/vb/git-validation (master) $ GIT_CHECK_EXCLUDE="./vendor" git
|
|||
```
|
||||
using the `GIT_CHECK_EXCLUDE` environment variable
|
||||
|
||||
|
||||
## Rules
|
||||
|
||||
Default rules are added by registering them to the `validate` package.
|
||||
|
|
17
main.go
17
main.go
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
_ "github.com/vbatts/git-validation/rules/danglingwhitespace"
|
||||
_ "github.com/vbatts/git-validation/rules/dco"
|
||||
_ "github.com/vbatts/git-validation/rules/messageregexp"
|
||||
_ "github.com/vbatts/git-validation/rules/shortsubject"
|
||||
"github.com/vbatts/git-validation/validate"
|
||||
)
|
||||
|
@ -47,10 +48,20 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
// reduce the set being run
|
||||
rules := validate.RegisteredRules
|
||||
// rules to be used
|
||||
var rules []validate.Rule
|
||||
for _, r := range validate.RegisteredRules {
|
||||
// only those that are Default
|
||||
if r.Default {
|
||||
rules = append(rules, r)
|
||||
}
|
||||
}
|
||||
// or reduce the set being run to what the user provided
|
||||
if *flRun != "" {
|
||||
rules = validate.FilterRules(rules, validate.SanitizeFilters(*flRun))
|
||||
rules = validate.FilterRules(validate.RegisteredRules, validate.SanitizeFilters(*flRun))
|
||||
}
|
||||
if os.Getenv("DEBUG") != "" {
|
||||
log.Printf("%#v", rules) // XXX maybe reduce this list
|
||||
}
|
||||
|
||||
var commitRange = *flCommitRange
|
||||
|
|
|
@ -12,6 +12,7 @@ var (
|
|||
Name: "dangling-whitespace",
|
||||
Description: "checking the presence of dangling whitespaces on line endings",
|
||||
Run: ValidateDanglingWhitespace,
|
||||
Default: true,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -20,7 +21,7 @@ func init() {
|
|||
}
|
||||
|
||||
// ValidateDanglingWhitespace runs Git's check to look for whitespace errors.
|
||||
func ValidateDanglingWhitespace(c git.CommitEntry) (vr validate.Result) {
|
||||
func ValidateDanglingWhitespace(r validate.Rule, c git.CommitEntry) (vr validate.Result) {
|
||||
vr.CommitEntry = c
|
||||
vr.Msg = "commit does not have any whitespace errors"
|
||||
vr.Pass = true
|
||||
|
|
|
@ -20,11 +20,12 @@ var (
|
|||
Name: "DCO",
|
||||
Description: "makes sure the commits are signed",
|
||||
Run: ValidateDCO,
|
||||
Default: true,
|
||||
}
|
||||
)
|
||||
|
||||
// ValidateDCO checks that the commit has been signed off, per the DCO process
|
||||
func ValidateDCO(c git.CommitEntry) (vr validate.Result) {
|
||||
func ValidateDCO(r validate.Rule, c git.CommitEntry) (vr validate.Result) {
|
||||
vr.CommitEntry = c
|
||||
if len(strings.Split(c["parent"], " ")) > 1 {
|
||||
vr.Pass = true
|
||||
|
|
61
rules/messageregexp/rule.go
Normal file
61
rules/messageregexp/rule.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
package messageregexp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/vbatts/git-validation/git"
|
||||
"github.com/vbatts/git-validation/validate"
|
||||
)
|
||||
|
||||
func init() {
|
||||
validate.RegisterRule(RegexpRule)
|
||||
}
|
||||
|
||||
var (
|
||||
// RegexpRule for validating a user provided regex on the commit messages
|
||||
RegexpRule = validate.Rule{
|
||||
Name: "message_regexp",
|
||||
Description: "checks the commit message for a user provided regular expression",
|
||||
Run: ValidateMessageRegexp,
|
||||
Default: false, // only for users specifically calling it through -run ...
|
||||
}
|
||||
)
|
||||
|
||||
// ValidateMessageRegexp is the message regex func to run
|
||||
func ValidateMessageRegexp(r validate.Rule, c git.CommitEntry) (vr validate.Result) {
|
||||
if r.Value == "" {
|
||||
vr.Pass = true
|
||||
vr.Msg = "noop: message_regexp value is blank"
|
||||
return vr
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(r.Value)
|
||||
vr.CommitEntry = c
|
||||
if len(strings.Split(c["parent"], " ")) > 1 {
|
||||
vr.Pass = true
|
||||
vr.Msg = "merge commits are not checked for message_regexp"
|
||||
return vr
|
||||
}
|
||||
|
||||
hasValid := false
|
||||
for _, line := range strings.Split(c["subject"], "\n") {
|
||||
if re.MatchString(line) {
|
||||
hasValid = true
|
||||
}
|
||||
}
|
||||
for _, line := range strings.Split(c["body"], "\n") {
|
||||
if re.MatchString(line) {
|
||||
hasValid = true
|
||||
}
|
||||
}
|
||||
if !hasValid {
|
||||
vr.Pass = false
|
||||
vr.Msg = fmt.Sprintf("commit message does not match %q", r.Value)
|
||||
} else {
|
||||
vr.Pass = true
|
||||
vr.Msg = fmt.Sprintf("commit message matches %q", r.Value)
|
||||
}
|
||||
return vr
|
||||
}
|
|
@ -11,6 +11,7 @@ var (
|
|||
Name: "short-subject",
|
||||
Description: "commit subjects are strictly less than 90 (github ellipsis length)",
|
||||
Run: ValidateShortSubject,
|
||||
Default: true,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -20,7 +21,7 @@ func init() {
|
|||
|
||||
// ValidateShortSubject checks that the commit's subject is strictly less than
|
||||
// 90 characters (preferably not more than 72 chars).
|
||||
func ValidateShortSubject(c git.CommitEntry) (vr validate.Result) {
|
||||
func ValidateShortSubject(r validate.Rule, c git.CommitEntry) (vr validate.Result) {
|
||||
if len(c["subject"]) >= 90 {
|
||||
vr.Pass = false
|
||||
vr.Msg = "commit subject exceeds 90 characters"
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
// RegisteredRules are the standard validation to perform on git commits
|
||||
// RegisteredRules are the avaible validation to perform on git commits
|
||||
RegisteredRules = []Rule{}
|
||||
registerRuleLock = sync.Mutex{}
|
||||
)
|
||||
|
@ -26,14 +26,15 @@ type Rule struct {
|
|||
Name string // short name for reference in in the `-run=...` flag
|
||||
Value string // value to configure for the rule (i.e. a regexp to check for in the commit message)
|
||||
Description string // longer Description for readability
|
||||
Run func(git.CommitEntry) Result
|
||||
Run func(Rule, git.CommitEntry) Result
|
||||
Default bool // whether the registered rule is run by default
|
||||
}
|
||||
|
||||
// Commit processes the given rules on the provided commit, and returns the result set.
|
||||
func Commit(c git.CommitEntry, rules []Rule) Results {
|
||||
results := Results{}
|
||||
for _, r := range rules {
|
||||
results = append(results, r.Run(c))
|
||||
results = append(results, r.Run(r, c))
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ func TestSliceHelpers(t *testing.T) {
|
|||
for i := range set {
|
||||
got := StringsSliceEqual(set[i].A, set[i].B)
|
||||
if got != set[i].Equal {
|
||||
t.Errorf("expected %d A and B comparison to be %q, but got %q", i, set[i].Equal, got)
|
||||
t.Errorf("expected %d A and B comparison to be %t, but got %t", i, set[i].Equal, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue