github.com/autonomy/conform@v0.1.0-alpha.16/internal/policy/commit/check_imperative_verb.go (about) 1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 package commit 6 7 import ( 8 "strings" 9 10 "github.com/autonomy/conform/internal/policy" 11 "github.com/pkg/errors" 12 "gopkg.in/jdkato/prose.v2" 13 ) 14 15 // ImperativeCheck enforces that the first word of a commit message header is 16 // and imperative verb. 17 type ImperativeCheck struct { 18 errors []error 19 } 20 21 // Name returns the name of the check. 22 func (i ImperativeCheck) Name() string { 23 return "Imperative Mood" 24 } 25 26 // Message returns to check message. 27 func (i ImperativeCheck) Message() string { 28 if len(i.errors) != 0 { 29 return i.errors[0].Error() 30 } 31 return "Commit begins with imperative verb" 32 } 33 34 // Errors returns any violations of the check. 35 func (i ImperativeCheck) Errors() []error { 36 return i.errors 37 } 38 39 // ValidateImperative checks the commit message for a GPG signature. 40 func (c Commit) ValidateImperative() policy.Check { 41 check := &ImperativeCheck{} 42 var ( 43 word string 44 err error 45 ) 46 if word, err = c.firstWord(); err != nil { 47 check.errors = append(check.errors, err) 48 return check 49 } 50 doc, err := prose.NewDocument("I " + strings.ToLower(word)) 51 if err != nil { 52 check.errors = append(check.errors, errors.Errorf("Failed to create document: %v", err)) 53 return check 54 } 55 if len(doc.Tokens()) != 2 { 56 check.errors = append(check.errors, errors.Errorf("Expected 2 tokens, got %d", len(doc.Tokens()))) 57 return check 58 } 59 tokens := doc.Tokens() 60 tok := tokens[1] 61 for _, tag := range []string{"VBD", "VBG", "VBZ"} { 62 if tok.Tag == tag { 63 check.errors = append(check.errors, errors.Errorf("First word of commit must be an imperative verb: %q is invalid", word)) 64 } 65 } 66 67 return check 68 }