|
|
@ -0,0 +1,399 @@ |
|
|
|
|
|
|
|
package main |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
|
|
|
"fmt" |
|
|
|
|
|
|
|
"github.com/AlecAivazis/survey/v2" |
|
|
|
|
|
|
|
"os" |
|
|
|
|
|
|
|
"os/exec" |
|
|
|
|
|
|
|
"strings" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Emoji string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
|
|
|
emojiTada = Emoji("🎉") // , "tada", "庆祝", "初次提交")
|
|
|
|
|
|
|
|
emojiNew = Emoji("🆕") // , "new", "全新", "引入新功能")
|
|
|
|
|
|
|
|
emojiBookmark = Emoji("🔖") // , "bookmark", "书签", "发行/版本标签")
|
|
|
|
|
|
|
|
emojiBug = Emoji("🐛") // , "bug", "bug", "修复 bug")
|
|
|
|
|
|
|
|
emojiAmbulance = Emoji("🚑") // , "ambulance", "急救车", "重要补丁")
|
|
|
|
|
|
|
|
emojiGlobeWithMeridians = Emoji("🌐") // , "globe_with_meridians", "地球", "国际化与本地化")
|
|
|
|
|
|
|
|
emojiLipstick = Emoji("💄") // , "lipstick", "口红", "更新 UI 和样式文件")
|
|
|
|
|
|
|
|
emojiClapper = Emoji("🎬") // , "clapper", "场记板", "更新演示/示例")
|
|
|
|
|
|
|
|
emojiRotatingLight = Emoji("🚨") // , "rotating_light", "警车灯", "移除 linter 警告")
|
|
|
|
|
|
|
|
emojiWrench = Emoji("🔧") // , "wrench", "扳手", "修改配置文件")
|
|
|
|
|
|
|
|
emojiHeavyPlusSign = Emoji("➕") // , "heavy_plus_sign", "加号", "增加一个依赖")
|
|
|
|
|
|
|
|
emojiHeavyMinusSign = Emoji("➖") // , "heavy_minus_sign", "减号", "减少一个依赖")
|
|
|
|
|
|
|
|
emojiArrowUp = Emoji("⬆️") // , "arrow_up", "上升箭头", "升级依赖")
|
|
|
|
|
|
|
|
emojiArrowDown = Emoji("⬇️") // , "arrow_down", "下降箭头", "降级依赖")
|
|
|
|
|
|
|
|
emojiZap = Emoji("⚡") // , "zap", "闪电", "提升性能")
|
|
|
|
|
|
|
|
emojiRacehorse = Emoji("🐎") // , "racehorse", "赛马", "提升性能")
|
|
|
|
|
|
|
|
emojiChartWithUpwardsTrend = Emoji("📈") // , "chart_with_upwards_trend", "上升趋势图", "添加分析或跟踪代码")
|
|
|
|
|
|
|
|
emojiRocket = Emoji("🚀") // , "rocket", "火箭", "部署功能")
|
|
|
|
|
|
|
|
emojiWhiteCheckMark = Emoji("✅") // , "white_check_mark", "白色复选框", "增加测试")
|
|
|
|
|
|
|
|
emojiMemo = Emoji("📝") // , "memo", "备忘录", "撰写文档")
|
|
|
|
|
|
|
|
emojiBook = Emoji("📖") // , "book", "书", "撰写文档")
|
|
|
|
|
|
|
|
emojiHammer = Emoji("🔨") // , "hammer", "锤子", "重大重构")
|
|
|
|
|
|
|
|
emojiArt = Emoji("🎨") // , "art", "调色板", "改进代码结构/代码格式")
|
|
|
|
|
|
|
|
emojiFire = Emoji("🔥") // , "fire", "火焰", "移除代码或文件")
|
|
|
|
|
|
|
|
emojiPencil2 = Emoji("✏️") // , "pencil2", "铅笔", "修复 typo")
|
|
|
|
|
|
|
|
emojiConstruction = Emoji("🚧") // , "construction", "施工", "工作进行中")
|
|
|
|
|
|
|
|
emojiWastebasket = Emoji("🗑️") // , "wastebasket", "垃圾桶", "废弃或删除")
|
|
|
|
|
|
|
|
emojiWheelchair = Emoji("♿") // , "wheelchair", "轮椅", "可访问性")
|
|
|
|
|
|
|
|
emojiConstructionWorker = Emoji("👷") // , "construction_worker", "工人", "添加 CI 构建系统")
|
|
|
|
|
|
|
|
emojiGreenHeart = Emoji("💚") // , "green_heart", "绿心", "修复 CI 构建问题")
|
|
|
|
|
|
|
|
emojiLock = Emoji("🔒") // , "lock", "锁", "修复安全问题")
|
|
|
|
|
|
|
|
emojiWhale = Emoji("🐳") // , "whale", "鲸鱼", "Docker 相关工作")
|
|
|
|
|
|
|
|
emojiApple = Emoji("🍎") // , "apple", "苹果", "修复在 MacOS 下的问题")
|
|
|
|
|
|
|
|
emojiGreenApple = Emoji("🍏") // , "green_apple", "IOS", "修复在 iOS 下的问题。")
|
|
|
|
|
|
|
|
emojiPenguin = Emoji("🐧") // , "penguin", "企鹅", "修复 Linux 下的问题")
|
|
|
|
|
|
|
|
emojiRobot = Emoji("🤖") // , "robot", "安卓", "修复 Android 下的问题")
|
|
|
|
|
|
|
|
emojiCheckeredFlag = Emoji("🏁") // , "checkered_flag", "旗帜", "修复 Windows 下的问题")
|
|
|
|
|
|
|
|
emojiTwistedRightwardsArrows = Emoji("🔀") // , "twisted_rightwards_arrows", "交叉箭头", "分支合并")
|
|
|
|
|
|
|
|
emojiSparkles = Emoji("✨") // , "sparkles", "新特性", "引入新特性")
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type emojiInfo struct { |
|
|
|
|
|
|
|
flag, title, desc string |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var emojiInfos map[Emoji]*emojiInfo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (e Emoji) Flag() string { |
|
|
|
|
|
|
|
if info, ok := emojiInfos[e]; ok { |
|
|
|
|
|
|
|
return info.flag |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return "" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (e Emoji) Title() string { |
|
|
|
|
|
|
|
if info, ok := emojiInfos[e]; ok { |
|
|
|
|
|
|
|
return info.title |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return "" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (e Emoji) Description() string { |
|
|
|
|
|
|
|
if info, ok := emojiInfos[e]; ok { |
|
|
|
|
|
|
|
return info.desc |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return "" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Type string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
|
|
|
typeFeat = Type("feat") // "新功能(feature)"
|
|
|
|
|
|
|
|
typeFix = Type("fix") // "自动修复问题 (适合于一次提交直接修复问题)"
|
|
|
|
|
|
|
|
typeTo = Type("to") // "不自动修复问题 (适合于多次提交,最终修复问题提交时使用fix)"
|
|
|
|
|
|
|
|
typeDocs = Type("docs") // "文档(documentation)"
|
|
|
|
|
|
|
|
typeStyle = Type("style") // "格式(不影响代码运行的变动)"
|
|
|
|
|
|
|
|
typeRefactor = Type("refactor") // "重构(即不是新增功能,也不是修改bug的代码变动)"
|
|
|
|
|
|
|
|
typePerf = Type("perf") // "优化相关,比如提升性能、体验"
|
|
|
|
|
|
|
|
typeTest = Type("test") // "增加测试"
|
|
|
|
|
|
|
|
typeChore = Type("chore") // "构建过程或辅助工具的变动"
|
|
|
|
|
|
|
|
typeRevert = Type("revert") // "回滚到上一个版本"
|
|
|
|
|
|
|
|
typeMerge = Type("merge") // "代码合并"
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var typeInfos map[Type]string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (e Type) Description() string { |
|
|
|
|
|
|
|
if desc, ok := typeInfos[e]; ok { |
|
|
|
|
|
|
|
return desc |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return "" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var emojisInType map[Type][]Emoji |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func init() { |
|
|
|
|
|
|
|
typeInfos = map[Type]string{ |
|
|
|
|
|
|
|
typeFeat: "新功能(feature)", |
|
|
|
|
|
|
|
typeFix: "自动修复问题 (适合于一次提交直接修复问题)", |
|
|
|
|
|
|
|
typeTo: "不自动修复问题 (适合于多次提交,最终修复问题提交时使用fix)", |
|
|
|
|
|
|
|
typeDocs: "文档(documentation)", |
|
|
|
|
|
|
|
typeStyle: "格式(不影响代码运行的变动)", |
|
|
|
|
|
|
|
typeRefactor: "重构(即不是新增功能,也不是修改bug的代码变动)", |
|
|
|
|
|
|
|
typePerf: "优化相关,比如提升性能、体验", |
|
|
|
|
|
|
|
typeTest: "增加测试", |
|
|
|
|
|
|
|
typeChore: "构建过程或辅助工具的变动", |
|
|
|
|
|
|
|
typeRevert: "回滚到上一个版本", |
|
|
|
|
|
|
|
typeMerge: "代码合并", |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emojiInfos = map[Emoji]*emojiInfo{ |
|
|
|
|
|
|
|
emojiTada: {"tada", "庆祝", "初次提交"}, |
|
|
|
|
|
|
|
emojiNew: {"new", "全新", "引入新功能"}, |
|
|
|
|
|
|
|
emojiBookmark: {"bookmark", "书签", "发行/版本标签"}, |
|
|
|
|
|
|
|
emojiBug: {"bug", "bug", "修复 bug"}, |
|
|
|
|
|
|
|
emojiAmbulance: {"ambulance", "急救车", "重要补丁"}, |
|
|
|
|
|
|
|
emojiGlobeWithMeridians: {"globe_with_meridians", "地球", "国际化与本地化"}, |
|
|
|
|
|
|
|
emojiLipstick: {"lipstick", "口红", "更新 UI 和样式文件"}, |
|
|
|
|
|
|
|
emojiClapper: {"clapper", "场记板", "更新演示/示例"}, |
|
|
|
|
|
|
|
emojiRotatingLight: {"rotating_light", "警车灯", "移除 linter 警告"}, |
|
|
|
|
|
|
|
emojiWrench: {"wrench", "扳手", "修改配置文件"}, |
|
|
|
|
|
|
|
emojiHeavyPlusSign: {"heavy_plus_sign", "加号", "增加一个依赖"}, |
|
|
|
|
|
|
|
emojiHeavyMinusSign: {"heavy_minus_sign", "减号", "减少一个依赖"}, |
|
|
|
|
|
|
|
emojiArrowUp: {"arrow_up", "上升箭头", "升级依赖"}, |
|
|
|
|
|
|
|
emojiArrowDown: {"arrow_down", "下降箭头", "降级依赖"}, |
|
|
|
|
|
|
|
emojiZap: {"zap", "闪电", "提升性能"}, |
|
|
|
|
|
|
|
emojiRacehorse: {"racehorse", "赛马", "提升性能"}, |
|
|
|
|
|
|
|
emojiChartWithUpwardsTrend: {"chart_with_upwards_trend", "上升趋势图", "添加分析或跟踪代码"}, |
|
|
|
|
|
|
|
emojiRocket: {"rocket", "火箭", "部署功能"}, |
|
|
|
|
|
|
|
emojiWhiteCheckMark: {"white_check_mark", "白色复选框", "增加测试"}, |
|
|
|
|
|
|
|
emojiMemo: {"memo", "备忘录", "撰写文档"}, |
|
|
|
|
|
|
|
emojiBook: {"book", "书", "撰写文档"}, |
|
|
|
|
|
|
|
emojiHammer: {"hammer", "锤子", "重大重构"}, |
|
|
|
|
|
|
|
emojiArt: {"art", "调色板", "改进代码结构/代码格式"}, |
|
|
|
|
|
|
|
emojiFire: {"fire", "火焰", "移除代码或文件"}, |
|
|
|
|
|
|
|
emojiPencil2: {"pencil2", "铅笔", "修复 typo"}, |
|
|
|
|
|
|
|
emojiConstruction: {"construction", "施工", "工作进行中"}, |
|
|
|
|
|
|
|
emojiWastebasket: {"wastebasket", "垃圾桶", "废弃或删除"}, |
|
|
|
|
|
|
|
emojiWheelchair: {"heelchair", "轮椅", "可访问性"}, |
|
|
|
|
|
|
|
emojiConstructionWorker: {"construction_worker", "工人", "添加 CI 构建系统"}, |
|
|
|
|
|
|
|
emojiGreenHeart: {"green_heart", "绿心", "修复 CI 构建问题"}, |
|
|
|
|
|
|
|
emojiLock: {"lock", "锁", "修复安全问题"}, |
|
|
|
|
|
|
|
emojiWhale: {"whale", "鲸鱼", "Docker 相关工作"}, |
|
|
|
|
|
|
|
emojiApple: {"apple", "苹果", "修复在 MacOS 下的问题"}, |
|
|
|
|
|
|
|
emojiGreenApple: {"green_apple", "IOS", "修复在 iOS 下的问题。"}, |
|
|
|
|
|
|
|
emojiPenguin: {"penguin", "企鹅", "修复 Linux 下的问题"}, |
|
|
|
|
|
|
|
emojiRobot: {"robot", "安卓", "修复 Android 下的问题"}, |
|
|
|
|
|
|
|
emojiCheckeredFlag: {"checkered_flag", "旗帜", "修复 Windows 下的问题"}, |
|
|
|
|
|
|
|
emojiTwistedRightwardsArrows: {"twisted_rightwards_arrows", "交叉箭头", "分支合并"}, |
|
|
|
|
|
|
|
emojiSparkles: {"sparkles", "新特性", "引入新特性"}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var platformEmojis = []Emoji{ |
|
|
|
|
|
|
|
emojiGreenHeart, |
|
|
|
|
|
|
|
emojiGreenApple, |
|
|
|
|
|
|
|
emojiLock, |
|
|
|
|
|
|
|
emojiWhale, |
|
|
|
|
|
|
|
emojiApple, |
|
|
|
|
|
|
|
emojiPenguin, |
|
|
|
|
|
|
|
emojiRobot, |
|
|
|
|
|
|
|
emojiCheckeredFlag, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
platform := func(res ...Emoji) []Emoji { |
|
|
|
|
|
|
|
return append(res, platformEmojis...) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emojisInType = map[Type][]Emoji{ |
|
|
|
|
|
|
|
typeFeat: {emojiNew, emojiSparkles}, |
|
|
|
|
|
|
|
typeFix: platform(emojiBug, emojiAmbulance, emojiGlobeWithMeridians, emojiWrench, emojiPencil2), |
|
|
|
|
|
|
|
typeTo: platform(emojiBug, emojiAmbulance, emojiGlobeWithMeridians, emojiWrench, emojiPencil2), |
|
|
|
|
|
|
|
typeDocs: {emojiGlobeWithMeridians, emojiLipstick, emojiClapper, emojiWrench, emojiHeavyPlusSign, emojiHeavyMinusSign, emojiZap, emojiRacehorse, emojiMemo, emojiBook, emojiConstruction, emojiSparkles}, |
|
|
|
|
|
|
|
typeStyle: platform(emojiTada, emojiGlobeWithMeridians, emojiLipstick, emojiClapper, emojiArt, emojiWheelchair), |
|
|
|
|
|
|
|
typeRefactor: platform(emojiRotatingLight, emojiHeavyPlusSign, emojiHeavyMinusSign, emojiArt, emojiWastebasket, emojiConstructionWorker), |
|
|
|
|
|
|
|
typePerf: platform(emojiGlobeWithMeridians, emojiLipstick, emojiArrowUp, emojiArrowDown, emojiZap, emojiRacehorse, emojiChartWithUpwardsTrend, emojiHammer, emojiConstructionWorker, emojiWheelchair), |
|
|
|
|
|
|
|
typeTest: platform(emojiGlobeWithMeridians, emojiWrench, emojiHeavyPlusSign, emojiHeavyMinusSign, emojiArrowUp, emojiArrowDown, emojiWheelchair, emojiConstructionWorker), |
|
|
|
|
|
|
|
typeChore: platform(emojiGlobeWithMeridians, emojiHeavyPlusSign, emojiHeavyMinusSign, emojiArrowUp, emojiArrowDown, emojiWheelchair), |
|
|
|
|
|
|
|
typeRevert: platform(emojiBookmark, emojiRotatingLight), |
|
|
|
|
|
|
|
typeMerge: {emojiBookmark, emojiTwistedRightwardsArrows}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Message struct { |
|
|
|
|
|
|
|
Type Type |
|
|
|
|
|
|
|
Emoji Emoji |
|
|
|
|
|
|
|
Scope string |
|
|
|
|
|
|
|
Subject string |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) String() string { |
|
|
|
|
|
|
|
var str string |
|
|
|
|
|
|
|
if len(m.Type) > 0 { |
|
|
|
|
|
|
|
str += string(m.Type) |
|
|
|
|
|
|
|
if len(m.Scope) > 0 { |
|
|
|
|
|
|
|
str += "(" + m.Scope + ")" |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
str += "(*)" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
str += ": " |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
str += m.Subject + "\n\n" |
|
|
|
|
|
|
|
return str |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) Preview() string { |
|
|
|
|
|
|
|
var str string |
|
|
|
|
|
|
|
for i, s := range strings.Split(m.String(), "\n") { |
|
|
|
|
|
|
|
if i > 0 { |
|
|
|
|
|
|
|
str += "\n" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
str += "\t" + s |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return str |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) Valid() bool { |
|
|
|
|
|
|
|
return len(m.Type) > 0 && len(m.Subject) > 0 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) AskType() error { |
|
|
|
|
|
|
|
var types []Type |
|
|
|
|
|
|
|
var options []string |
|
|
|
|
|
|
|
for entry, info := range typeInfos { |
|
|
|
|
|
|
|
types = append(types, entry) |
|
|
|
|
|
|
|
options = append(options, string(entry)+" "+info) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
qs := []*survey.Question{{ |
|
|
|
|
|
|
|
Name: "value", |
|
|
|
|
|
|
|
Prompt: &survey.Select{ |
|
|
|
|
|
|
|
Message: "请选择提交类型:", |
|
|
|
|
|
|
|
Options: options, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
var res = struct { |
|
|
|
|
|
|
|
Value int |
|
|
|
|
|
|
|
}{} |
|
|
|
|
|
|
|
err := survey.Ask(qs, &res, nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m.Type = types[res.Value] |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) AskScope() error { |
|
|
|
|
|
|
|
qs := []*survey.Question{ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Name: "value", |
|
|
|
|
|
|
|
Prompt: &survey.Input{Message: "影响范围:"}, |
|
|
|
|
|
|
|
Transform: survey.ToLower, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var res = struct { |
|
|
|
|
|
|
|
Value string |
|
|
|
|
|
|
|
}{} |
|
|
|
|
|
|
|
err := survey.Ask(qs, &res, nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m.Scope = res.Value |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) AskEmoji() error { |
|
|
|
|
|
|
|
if len(m.Type) == 0 { |
|
|
|
|
|
|
|
err := m.AskType() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
emojis, ok := emojisInType[m.Type] |
|
|
|
|
|
|
|
if !ok || len(emojis) == 0 { |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var es []Emoji |
|
|
|
|
|
|
|
var opts []string |
|
|
|
|
|
|
|
for _, e := range emojis { |
|
|
|
|
|
|
|
es = append(es, e) |
|
|
|
|
|
|
|
opts = append(opts, fmt.Sprintf("%s\x1b[36m (%s)\x1b[0m \x1b[2m- %s\x1b[0m", e, e.Title(), e.Description())) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// the questions to ask
|
|
|
|
|
|
|
|
var qs = []*survey.Question{{ |
|
|
|
|
|
|
|
Name: "value", |
|
|
|
|
|
|
|
Prompt: &survey.Select{ |
|
|
|
|
|
|
|
Message: "设置 Emoji 符号:", |
|
|
|
|
|
|
|
Options: opts, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
var res = struct { |
|
|
|
|
|
|
|
Value int |
|
|
|
|
|
|
|
}{} |
|
|
|
|
|
|
|
err := survey.Ask(qs, &res, nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m.Emoji = es[res.Value] |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) AskSubject() error { |
|
|
|
|
|
|
|
if len(m.Type) == 0 { |
|
|
|
|
|
|
|
err := m.AskType() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
qs := []*survey.Question{{ |
|
|
|
|
|
|
|
Name: "value", |
|
|
|
|
|
|
|
Prompt: &survey.Input{Message: "日志内容,不超过50个字符"}, |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
var res = struct { |
|
|
|
|
|
|
|
Value string |
|
|
|
|
|
|
|
}{} |
|
|
|
|
|
|
|
err := survey.Ask(qs, &res, nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(res.Value) == 0 { |
|
|
|
|
|
|
|
return m.AskSubject() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m.Subject = res.Value |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) Ask() error { |
|
|
|
|
|
|
|
if err := m.AskType(); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if err := m.AskScope(); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if err := m.AskEmoji(); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if err := m.AskSubject(); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) Confirm() (bool, error) { |
|
|
|
|
|
|
|
for !m.Valid() { |
|
|
|
|
|
|
|
err := m.Ask() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return false, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ok := false |
|
|
|
|
|
|
|
prompt := &survey.Confirm{ |
|
|
|
|
|
|
|
Message: "输入结果如下:\n\n" + m.Preview() + "\r立即提交?", |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
err := survey.AskOne(prompt, &ok) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return false, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if !ok { |
|
|
|
|
|
|
|
return false, nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return true, nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (m *Message) Commit() error { |
|
|
|
|
|
|
|
cmd := exec.Command("git", "commit", "-m", m.String()) |
|
|
|
|
|
|
|
cmd.Stdout = os.Stdout |
|
|
|
|
|
|
|
cmd.Stderr = os.Stderr |
|
|
|
|
|
|
|
return cmd.Run() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func main() { |
|
|
|
|
|
|
|
var msg Message |
|
|
|
|
|
|
|
ok, err := msg.Confirm() |
|
|
|
|
|
|
|
if err == nil && ok { |
|
|
|
|
|
|
|
err = msg.Commit() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
if err.Error() == "interrupt" { |
|
|
|
|
|
|
|
fmt.Println("\nCtrl+C pressed in Terminal") |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
fmt.Println(err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |