commit-msg/main.go

102 lines
2.0 KiB
Go

package main
import (
"errors"
"fmt"
"io"
"log"
"os"
"regexp"
"strings"
)
var (
errCommitMsgSyntax = errors.New("commit msg syntax is wrong")
errCommitMsgInvalideType = errors.New("commit msg type is invalide")
)
var allowedTypes []string
func init() {
allowedTypes = append(allowedTypes, "fix", "feat", "build", "chore", "ci", "docs", "style", "refactor", "perf", "test")
}
func main() {
commitMsg, err := getCommitMessageFromFile(os.Args[1])
if err != nil {
log.Fatal("Error parsing commitMsg: ", err)
}
firstLine, err := getFirstLine(commitMsg)
if err != nil {
log.Fatal("Error getting first line of commitMsg: ", err)
}
err = checkCommitMsg(firstLine)
if err != nil {
fmt.Println("### COMMIT MESSAGES dont match conventions")
fmt.Println(err)
fmt.Println("")
fmt.Println("A valid example is:")
fmt.Println("feat(lang): add Polish language")
fmt.Println("valide types are: ", strings.Join(allowedTypes, ", "))
fmt.Println("see more at: https://www.conventionalcommits.org/en/v1.0.0/")
os.Exit(1)
}
fmt.Println("Commit Message ok")
}
func checkCommitMsg(firstLine string) error {
r, _ := regexp.Compile("^([a-z]*)(\\([^\\)]*\\))?!?:")
results := r.FindStringSubmatch(firstLine)
if len(results) < 3 {
return errCommitMsgSyntax
}
if !CheckTyp(results[1]) {
return errCommitMsgInvalideType
}
return nil
}
func CheckTyp(ty string) bool {
for _, t := range allowedTypes {
if t == ty {
return true
}
}
return false
}
func getFirstLine(commitMsg string) (string, error) {
lines := strings.Split(commitMsg, "\n")
return lines[0], nil
}
func getCommitMessageFromFile(path string) (string, error) {
f, err := os.Open(path)
if err != nil {
return "", fmt.Errorf("cant open commit msg file: %w", err)
}
defer f.Close()
buf := make([]byte, 1024)
commitmsg := ""
for {
n, err := f.Read(buf)
if err == io.EOF {
break
}
if err != nil {
return "", fmt.Errorf("cant read from commit-msg file: %w", err)
}
if n > 0 {
commitmsg += string(buf[:n])
}
}
return commitmsg, nil
}