Skip to content

Commit 8c9376f

Browse files
committed
feat: normalize output and fix some bugs
1 parent fd7cec7 commit 8c9376f

1 file changed

Lines changed: 124 additions & 29 deletions

File tree

commit-msg.go

Lines changed: 124 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,125 @@ const (
1515
BODY_REQUIRED = false
1616
)
1717

18+
type MsgState int
19+
20+
const (
21+
// normal state
22+
Validated MsgState = iota
23+
Merge
24+
// non format error
25+
ArgumentMissing
26+
FileMissing
27+
ReadError
28+
// format error
29+
EmptyMessage
30+
EmptyHeader
31+
BadHeaderFormat
32+
WrongType
33+
BodyMissing
34+
NoBlankLineBeforeBody
35+
LineOverLong
36+
UndefindedError
37+
)
38+
1839
var (
40+
msgStates = [...]string{
41+
"Validated",
42+
"Merge",
43+
"ArgumentMissing",
44+
"FileMissing",
45+
"ReadError",
46+
"EmptyMessage",
47+
"EmptyHeader",
48+
"BadHeaderFormat",
49+
"WrongType",
50+
"BodyMissing",
51+
"NoBlankLineBeforeBody",
52+
"LineOverLong",
53+
"UndefindedError",
54+
}
55+
stateHint = [...]string{
56+
"%s: commit message meet the rule.\n",
57+
"%s: merge commit detected,skip check.\n",
58+
"Error %s: commit message file argument missing.\n",
59+
"Error %s: file %s not exists.\n",
60+
"Error %s: read file %s error.\n",
61+
"Error %s: commit message has no content except whitespaces.\n",
62+
"Error %s: header (first line) has no content except whitespaces.\n",
63+
`Error %s: header (first line) not following the rule:
64+
%s
65+
if you can not find any error after check, maybe you use Chinese colon, or lack of whitespace after the colon.`,
66+
"Error %s: %s, should be one of the keywords:\n%s\n",
67+
"Error %s: body has no content except whitespaces.\n",
68+
"Error %s: no empty line between header and body.\n",
69+
"Error %s: the length of line is %d, exceed %d:\n%s\n",
70+
"Error %s: unexpected error occurs, please raise an issue.",
71+
}
1972
typeList = [...]string{
20-
"feat", // 新功能(feature
21-
"fix", // 修补bug
22-
"docs", // 文档(documentation
23-
"style", // 格式(不影响代码运行的变动)
73+
"feat", // new feature 新功能
74+
"fix", // fix bug 修复
75+
"docs", // documentation 文档
76+
"style", // changes not affect logic 格式(不影响代码运行的变动)
2477
"refactor", // 重构(既不是新增功能,也不是修改bug的代码变动)
25-
"perf", // 提升性能(performance
78+
"perf", // performance 提升性能
2679
"test", // 增加测试
2780
"chore", // 构建过程或辅助工具的变动'
2881
"revert", // 撤销以前的 commit
29-
"Revert"} // 有些版本的工具生成的revert message首字母大写
82+
"Revert", // 有些工具生成的 revert 首字母大写
83+
}
84+
ruleHint = `Commit message rule as follow:
85+
<type>(<scope>): <subject>
86+
// empty line
87+
<body>
88+
// empty line
89+
<footer>
90+
91+
(<scope>), <body> and <footer> are optional
92+
<type> must be one of %s
93+
more specific instructions, please refer to https://github.com/JayceChant/commit-msg.go`
3094
)
3195

96+
func (state MsgState) Name() string {
97+
return msgStates[state]
98+
}
99+
100+
func (state MsgState) Hint() string {
101+
return stateHint[state]
102+
}
103+
104+
func logAndExit(state MsgState, v ...interface{}) {
105+
a := append([]interface{}{state.Name()}, v...)
106+
if state <= Merge {
107+
log.Printf(state.Hint(), a...)
108+
os.Exit(0)
109+
} else if state <= FileMissing {
110+
log.Fatalf(state.Hint(), a...)
111+
} else {
112+
log.Printf(state.Hint(), a...)
113+
log.Fatalf(ruleHint, strings.Join(typeList[:], ", "))
114+
}
115+
}
116+
32117
func getMsg(path string) string {
33118
if path == "" {
34-
log.Fatalln("Arg missing.")
119+
logAndExit(ArgumentMissing)
35120
}
36121

37122
f, err := os.Stat(path)
38123
if err != nil {
39-
log.Fatalln(err)
124+
log.Println(err)
125+
logAndExit(FileMissing, path)
40126
}
41127

42128
if f.IsDir() {
43-
log.Fatalln(path, "is not a file.")
129+
log.Println(path, "is not a file.")
130+
logAndExit(FileMissing, path)
44131
}
45132

46133
buf, err := ioutil.ReadFile(path)
47134
if err != nil {
48-
log.Fatalln(err)
135+
log.Println(err)
136+
logAndExit(ReadError, path)
49137
}
50138

51139
return string(buf)
@@ -61,64 +149,69 @@ func checkType(type_ string) {
61149
return
62150
}
63151
}
64-
log.Fatalln("Wrong type.")
152+
logAndExit(WrongType, type_, strings.Join(typeList[:], ", "))
65153
}
66154

67155
func checkHeader(header string) {
68156
if checkEmpty(header) {
69-
log.Fatalln("Empty header.")
157+
logAndExit(EmptyHeader)
70158
}
71159

72160
re := regexp.MustCompile(HEADER_PATTERN)
73161
groups := re.FindStringSubmatch(header)
74162

75-
isFixupOrSquash := (groups[2] != "")
163+
if groups == nil || checkEmpty(groups[5]) {
164+
logAndExit(BadHeaderFormat, header)
165+
}
76166

77167
type_ := groups[3]
78-
// scope = groups[4] // TODO: 根据配置对scope检查
79-
// subject = (groups[5] != "") // TODO: 根据规则对subject检查
80168
checkType(type_)
81169

170+
isFixupOrSquash := (groups[2] != "")
171+
// scope := groups[4] // TODO: 根据配置对scope检查
172+
// subject := groups[5] // TODO: 根据规则对subject检查
173+
82174
length := len(header)
83-
if length > LINE_LIMIT && !(isFixupOrSquash || type_ == "revert") {
84-
log.Fatalln("Line overlong.")
175+
if length > LINE_LIMIT &&
176+
!(isFixupOrSquash || type_ == "revert" || type_ == "Revert") {
177+
logAndExit(LineOverLong, length, LINE_LIMIT, header)
85178
}
86179
}
87180

88181
func checkBody(body string) {
89182
if checkEmpty(body) {
90183
if BODY_REQUIRED {
91-
log.Fatalln("Empty body.")
184+
logAndExit(BodyMissing)
92185
} else {
93-
return
186+
logAndExit(Validated)
94187
}
95188
}
96189

97190
if !checkEmpty(strings.SplitN(body, "\n", 2)[0]) {
98-
log.Fatalln("Blank line lacking between header and body.")
191+
logAndExit(NoBlankLineBeforeBody)
99192
}
100193

101194
for _, line := range strings.Split(body, "\n") {
102-
if len(line) > LINE_LIMIT {
103-
log.Fatalln("Line overlong.")
195+
length := len(line)
196+
if length > LINE_LIMIT {
197+
logAndExit(LineOverLong, length, LINE_LIMIT, line)
104198
}
105199
}
106200
}
107201

108202
func validateMsg(msg string) {
109-
msg = strings.TrimSpace(msg)
110-
if msg == "" {
111-
log.Fatalln("Empty Message.")
203+
if checkEmpty(msg) {
204+
logAndExit(EmptyMessage)
112205
}
113206

114207
isMerge, err := regexp.MatchString(MERGE_PATTERN, msg)
115208
if err != nil {
116-
log.Fatalln(err)
209+
log.Println(err)
210+
logAndExit(UndefindedError)
117211
}
118212

119213
if isMerge {
120-
log.Println("Merge message, skip check.")
121-
os.Exit(0)
214+
logAndExit(Merge)
122215
}
123216

124217
sections := strings.SplitN(msg, "\n", 2)
@@ -127,8 +220,10 @@ func validateMsg(msg string) {
127220
if len(sections) == 2 {
128221
checkBody(sections[1])
129222
} else if BODY_REQUIRED {
130-
log.Fatalln("Body missing. Maybe a new line is lacking.")
223+
logAndExit(BodyMissing)
131224
}
225+
226+
logAndExit(Validated)
132227
}
133228

134229
func main() {

0 commit comments

Comments
 (0)