forked from zibuyu28/cmt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
193 lines (174 loc) · 5.54 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
package main
import (
"context"
"fmt"
"github.com/AlecAivazis/survey/v2"
"os"
"os/exec"
"reflect"
"regexp"
"strings"
"time"
)
var typeMap = map[string]string{
"feat": "A new feature",
"fix": "A bug fix",
"docs": "Documentation only changes",
"style": "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",
"refactor": "A code change that neither fixes a bug nor adds a feature",
"perf": "A code change that improves performance",
"test": "Adding missing tests",
"chore": "Changes to the build process or auxiliary tools and libraries such as documentation generation",
"revert": "Revert to a commit",
"WIP": "Work in progress",
}
var scopeReg = regexp.MustCompile("^[a-z0-9]{2,20}$")
type Answer struct {
Type string `survey:"type"`
Scope string `survey:"scope"`
Message string `survey:"message"`
Version string `survey:"version"`
TBNum string `survey:"tb_num"`
}
type simpleWriter struct {
cmdReturn string
}
func (s *simpleWriter) Write(p []byte) (n int, err error) {
s.cmdReturn = string(p)
return len(p), nil
}
func main() {
// the answers will be written to this struct
ans := &Answer{}
// get last commit message
lc, _ := lastCommit()
defaultConstruct(ans, lc)
qs := []*survey.Question{tpq, scopeq, messageq, versionq, tbnumq}
err := survey.Ask(qs, ans)
if err != nil {
return
}
commit(ans)
}
func commit(ans *Answer) {
var commitmsg string
switch {
case ans.Version == "" && ans.TBNum == "":
commitmsg = fmt.Sprintf("%s(%s): %s", ans.Type, ans.Scope, ans.Message)
case ans.Version == "" && ans.TBNum != "":
commitmsg = fmt.Sprintf("%s(%s): %s(%s)", ans.Type, ans.Scope, ans.Message, ans.TBNum)
case ans.Version != "" && ans.TBNum == "":
commitmsg = fmt.Sprintf("%s(%s): %s(%s)", ans.Type, ans.Scope, ans.Message, ans.Version)
default:
commitmsg = fmt.Sprintf("%s(%s): %s(%s-%s)", ans.Type, ans.Scope, ans.Message, ans.Version, ans.TBNum)
}
fmt.Printf("commit message : %s\n", commitmsg)
commandContext := exec.Command("git", "commit", "-m", fmt.Sprintf("%s", commitmsg))
commandContext.Stdout = os.Stdout
commandContext.Stderr = os.Stdout
err := commandContext.Run()
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
}
func defaultConstruct(ans *Answer, lastCommit string) {
commitReg := regexp.MustCompile("^([^(]*)\\(([^)]*)\\):\\s([^(]*)\\(([v\\.0-9]{6,15})-([^)]*)\\)$")
submatch := commitReg.FindAllStringSubmatch(lastCommit, -1)
if len(submatch) == 0 {
commitReg = regexp.MustCompile("^([^(]*)\\(([^)]*)\\):\\s([^(]*)")
submatch = commitReg.FindAllStringSubmatch(lastCommit, -1)
}
if len(submatch) == 1 && len(submatch[0]) == 4 {
ans.Type = submatch[0][1]
tpq.Prompt.(*survey.Select).Default = ans.Type
ans.Scope = submatch[0][2]
scopeq.Prompt.(*survey.Input).Default = ans.Scope
ans.Message = submatch[0][3]
messageq.Prompt.(*survey.Input).Default = ans.Message
}
if len(submatch) == 1 && len(submatch[0]) == 6 {
ans.Type = submatch[0][1]
tpq.Prompt.(*survey.Select).Default = ans.Type
ans.Scope = submatch[0][2]
scopeq.Prompt.(*survey.Input).Default = ans.Scope
ans.Message = submatch[0][3]
messageq.Prompt.(*survey.Input).Default = ans.Message
ans.Version = submatch[0][4]
versionq.Prompt.(*survey.Input).Default = ans.Version
ans.TBNum = submatch[0][5]
tbnumq.Prompt.(*survey.Input).Default = ans.TBNum
}
}
func lastCommit() (string, error) {
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*10)
defer cancelFunc()
sw := simpleWriter{}
commandContext := exec.CommandContext(ctx, "git", "log", "--pretty=format:\"%s\"", "--no-merges", "-1")
commandContext.Stdout = &sw
err := commandContext.Run()
if err != nil {
return "", err
}
resp := strings.TrimSpace(sw.cmdReturn)
resp = strings.TrimSuffix(resp, "\n")
resp = strings.TrimPrefix(resp, "\"")
resp = strings.TrimSuffix(resp, "\"")
return resp, nil
}
var tpq = &survey.Question{
Name: "type",
Prompt: &survey.Select{
Message: "Select the type of change you're committing",
//Options: []string{"feat", "fix", "docs", "style", "refactor", "perf", "test", "chore", "revert", "WIP"},
Options: []string{"feat", "fix", "docs", "style", "perf", "test", "chore"},
Description: func(value string, index int) string {
return typeMap[value]
},
},
Validate: survey.Required,
}
var scopeq = &survey.Question{
Name: "scope",
Prompt: &survey.Input{
Message: "Input the scope of impact of your current commit",
Help: "one word to describe the scope of influence, composed of lowercase letters and numbers, the length range is 2-20 characters",
},
Validate: func(ans interface{}) error {
if ans == nil {
return fmt.Errorf("input is empty")
}
if str, ok := ans.(string); ok {
if ans == "" {
return fmt.Errorf("input is empty")
}
if !scopeReg.MatchString(str) {
return fmt.Errorf("this input [%s] not in correct format, validate regular '[a-z0-9]{2,20}'", str)
}
// the input is fine
return nil
} else {
// otherwise we cannot convert the value into a string and cannot enforce length
return fmt.Errorf("cannot enforce length on response of type %v", reflect.TypeOf(ans).Name())
}
},
}
var messageq = &survey.Question{
Name: "message",
Prompt: &survey.Input{
Message: "Input message of your current commit",
},
Validate: survey.Required,
}
var versionq = &survey.Question{
Name: "version",
Prompt: &survey.Input{
Message: "Input repository version",
},
}
var tbnumq = &survey.Question{
Name: "tb_num",
Prompt: &survey.Input{
Message: "Input teambition number",
},
}