gitcz/gitcz.go

250 lines
5.0 KiB
Go
Raw Normal View History

package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"os"
"os/exec"
"strconv"
"strings"
)
type CzType struct {
Type string
Message string
}
type CzCommit struct {
Type *CzType
Scope *string
Subject *string
Body *string
BreakingChange *string
Closes *string
}
var StdinInput = bufio.NewReader(os.Stdin)
var (
InputTypePrompt = "选择或输入一个提交类型(必填): "
InputScopePrompt = "说明本次提交的影响范围(必填): "
InputSubjectPrompt = "对本次提交进行简短描述(必填): "
InputBodyPrompt = "对本次提交进行完整描述(选填): "
InputBreakingChangePrompt = "如果当前代码版本与上一版本不兼容,对变动、变动的理由及迁移的方法进行描述(选填): "
InputClosesPrompt = "如果本次提交针对某个issue,列出关闭的issues(选填): "
)
var CzTypeList = []CzType{
{
Type: "feat",
Message: "新的功能",
},
{
Type: "fix",
Message: "修补错误",
},
{
Type: "docs",
Message: "文档修改",
},
{
Type: "style",
Message: "格式变化",
},
{
Type: "refactor",
Message: "重构代码",
},
{
Type: "perf",
Message: "性能提高",
},
{
Type: "test",
Message: "测试用例",
},
{
Type: "chore",
Message: "构建变动",
},
}
func main() {
amend := flag.Bool(
"amend",
false,
"覆盖上次提交信息",
)
sign := flag.Bool("S", false, "对commit进行签名")
author := flag.Bool(
"author",
false,
"关于本软件开发者",
)
flag.Parse()
if *author {
Author()
return
}
czCommit := &CzCommit{}
czCommit.Type = InputType()
czCommit.Scope = InputScope()
czCommit.Subject = InputSubject()
czCommit.Body = InputBody()
czCommit.BreakingChange = InputBreakingChange()
czCommit.Closes = InputCloses()
commit := GenerateCommit(czCommit)
if err := GitCommit(commit, *amend, *sign); err != nil {
fmt.Println(err)
}
}
func Author() {
fmt.Println("welcome to our website https://aite.xyz/")
fmt.Println("----------------------------------------")
fmt.Println("腾讯扣扣88966001")
fmt.Println("电子邮箱xiaoqidun@gmail.com")
fmt.Println("----------------------------------------")
fmt.Println("Copyright (c) 2020 xiaoqidun@gmail.com")
}
func NewLine() {
fmt.Println()
}
func GitCommit(commit string, amend bool, sign bool) (err error) {
tempFile, err := os.CreateTemp("", "git_commit_")
if err != nil {
return
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
if _, err = tempFile.WriteString(commit); err != nil {
return
}
args := []string{"commit"}
if amend {
args = append(args, "--amend")
}
if sign {
args = append(args, "-S")
}
args = append(args, "-F", tempFile.Name())
cmd := exec.Command("git", args...)
result, err := cmd.CombinedOutput()
if err != nil && !strings.ContainsAny(err.Error(), "exit status") {
return
} else {
fmt.Println(string(bytes.TrimSpace(result)))
}
return nil
}
func InputType() *CzType {
typeNum := len(CzTypeList)
for i := 0; i < typeNum; i++ {
fmt.Printf("[%d] %s:\t%s\n", i+1, CzTypeList[i].Type, CzTypeList[i].Message)
}
fmt.Print(InputTypePrompt)
text, _ := StdinInput.ReadString('\n')
text = strings.TrimSpace(text)
selectId, err := strconv.Atoi(text)
if err == nil && (selectId > 0 && selectId <= typeNum) {
NewLine()
return &CzTypeList[selectId-1]
}
for i := 0; i < typeNum; i++ {
if text == CzTypeList[i].Type {
NewLine()
return &CzTypeList[i]
}
}
NewLine()
return InputType()
}
func InputScope() *string {
fmt.Print(InputScopePrompt)
text, _ := StdinInput.ReadString('\n')
text = strings.TrimSpace(text)
if text != "" {
NewLine()
return &text
}
NewLine()
return InputScope()
}
func InputSubject() *string {
fmt.Print(InputSubjectPrompt)
text, _ := StdinInput.ReadString('\n')
text = strings.TrimSpace(text)
if text != "" {
NewLine()
return &text
}
NewLine()
return InputSubject()
}
func InputBody() *string {
fmt.Print(InputBodyPrompt)
text, _ := StdinInput.ReadString('\n')
text = strings.TrimSpace(text)
if text != "" {
NewLine()
return &text
}
NewLine()
return nil
}
func InputBreakingChange() *string {
fmt.Print(InputBreakingChangePrompt)
text, _ := StdinInput.ReadString('\n')
text = strings.TrimSpace(text)
if text != "" {
NewLine()
return &text
}
NewLine()
return nil
}
func InputCloses() *string {
fmt.Print(InputClosesPrompt)
text, _ := StdinInput.ReadString('\n')
text = strings.TrimSpace(text)
if text != "" {
NewLine()
return &text
}
NewLine()
return nil
}
func GenerateCommit(czCommit *CzCommit) string {
commit := fmt.Sprintf(
"%s(%s): %s\n\n",
czCommit.Type.Type,
*czCommit.Scope,
*czCommit.Subject,
)
if czCommit.Body != nil {
commit += *czCommit.Body
commit += "\n\n"
}
if czCommit.BreakingChange != nil {
2022-03-10 14:05:13 +08:00
commit += "BREAKING CHANGE: " + *czCommit.BreakingChange
commit += "\n\n"
}
if czCommit.Closes != nil {
2022-03-10 14:05:13 +08:00
commit += "Closes fix " + *czCommit.Closes
}
return commit
}