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  }