作者:林冠巨集 / 指尖下的幽靈
掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8
部落格:http://www.cnblogs.com/linguanh/
GitHub : https://github.com/af913337456/
騰訊雲專欄: https://cloud.tencent.com/developer/user/1148436/activities
原始碼--GitHub:github.com/af913337456…
如果你是一個後端Server程式
開發人員。你應該知道,在你寫完API
之後,是需要給客戶端
的同學提供呼叫
文件的。
例如下面一個api handler
,建立一個使用者
。
func HandleCreateUser(w http.ResponseWriter,r *http.Request) map[string]interface{} {
if r.Body == nil {
return util.GetCommonErr(23,"create user req body is fucking null?")
}
....
....
return util.GetCommonSuccess("success")
}
複製程式碼
上面有一行錯誤資訊輸出的程式碼
util.GetCommonErr(23,"create user req body is fucking null?")
複製程式碼
假設我們要寫成markDown風格的
文件,上面的可能是這樣一種對應
錯誤碼 | 含義 | 提示 |
---|---|---|
23 | create user req body is fucking null? | 暫無 |
Ok,這只是一個錯誤資訊的情況,我們很輕鬆就手動
寫完了。
如果有幾百上千個
呢?一個完整的服務端程式,肯定會有很多這種錯誤資訊輸出
的程式碼。在幾百上千個
的時候,還要手動寫?這是多麼低效率
,且浪費時間
的令人窒息
的操作。
而我這篇文章要介紹的就是一個幫你自動檢索並生成API輸出錯誤資訊文件
的開源程式
ErrorDocAutoPrinter
它,具備下面的特點
- 自定義程式碼資料夾路徑
Json
配置檔案形式匯入設定,避免反覆編譯程式- 按照給定的
程式碼方法名稱
自動檢索對應的程式碼行 - 按照給定的
切割引數規則
,自動切割組合 - 按照給定的
列名描述
,自動組合成新的文字 - 介面化的設計邏輯,高度自定義
- 自動按照
code
從小到大排序輸出,可控! - 自動提示
重複出現過
的錯誤資訊。 - 自動按照設定生成輸出檔案
- 可設定
符合目標
的檔案字尾
- 可設定
需要過濾
的檔名,符合就不處理 - 自定義輸出風格,
markDown
?txt
?html
? - 自行定義輸出的邏輯,可以對映到很多情況的文字玩法
- 總之:‘為所欲為’
我,提供了兩種風格的輸出
簡單文字
風格markDown
風格
使用步驟
- 配置好
json
檔案DefaultConfig.json
{
"TargetFileSuffix":[".go"],
"TargetErrorFuncName":["util.GetCommonErr","util.GetErrWithTips"],
"FilterFileName":["core"],
"ParamsColumnNames":[" 錯 誤 碼 "," 含 義 ","提 示"],
"ParamsSplitChar":","
}
複製程式碼
- 輸入你的
程式碼資料夾路徑
並執行程式
func TestDocPrinter(t *testing.T) {
p := NewDefaultErrorDocPrinter(NewDefaultMarkDownErrorDocPrinter())
if p == nil {
return
}
fmt.Println(p.printErrorDoc("../../errorDocPrinter"))
}
複製程式碼
- 複製貼上
結果
錯誤碼 | 含義 | 提示 |
---|---|---|
-9 | invalid create user | --空缺-- |
-4 | invalid create user | --空缺-- |
-1 | create user failed | 建立使用者失敗 |
88 | 建立評論失敗 | --空缺-- |
3110 | error params | --空缺-- |
3111 | update failed | --空缺-- |
3112 | yellow 內容涉黃 | --空缺-- |
3113 | forbid 禁止訪問 | --空缺-- |
3114 | empty id | --空缺-- |
3115 | 服務端開啟事務失敗 | --空缺-- |
3116 | 服務端事務提交失敗 | --空缺-- |
3117 | update effect row <= 0 | --空缺-- |
3118 | RowsAffected 失敗 | --空缺-- |
3119 | 更新只有部分成功 | --空缺-- |
3120 | empty userId | --空缺-- |
3121 | too lager | --空缺-- |
3122 | user not exits | --空缺-- |
3123 | 非法更新 | --空缺-- |
3124 | 引數個數長度限制 | --空缺-- |
3126 | 服務端事務提交失敗 | --空缺-- |
3127 | invalid money | --空缺-- |
3128 | money not enough | --空缺-- |
3129 | 建立消費記錄失敗 | --空缺-- |
基本說完了,原始碼見上面的開源連結,去玩吧。
簡單分析下 markDown
風格的生成
介面
type IErrorDocPrinter interface {
FindLines(printer *ErrorDocPrinter,reader *bufio.Reader,fileName,currentSuffix string,handleLine func(line string)) []string
BuildACell(printer ErrorDocPrinter,columns,size int,prefixName,param string) string
ResultLine(line string)
EndOfAFile(printer ErrorDocPrinter,aFileRetLines []string)
EndOfAllFile(printer ErrorDocPrinter,allRetLines []string)
}
複製程式碼
找到一個檔案所有行
func (p MarkDownErrorDocPrinter) FindLines(
printer *ErrorDocPrinter,reader *bufio.Reader,fileName,currentSuffix string,handleLine func(line string)) []string {
// 正則匹配 todo
var lines []string
printer.currentLineNum = 0
for {
byt, _, err := reader.ReadLine()
if err != nil {
// 讀完一個檔案
break
}
line := string(byt)
// 排除註釋
printer.currentLineNum++
if startWith(line,"//") {
continue
}
if startWith(line,"/*") {
continue
}
if startWith(line,"*") {
continue
}
for _,value := range printer.TargetErrorFuncName {
if strings.Contains(line,value) {
// hit,準備生成
handleLine(line)
lines = append(lines,line)
}
}
}
return lines
}
複製程式碼
處理一個單元格
func (p MarkDownErrorDocPrinter) BuildACell(
printer ErrorDocPrinter,columns,size int,prefixName,param string) string {
/**
| Name | Academy | score |
| - | - | - |
| Harry Potter | Gryffindor| 90 |
| Hermione Granger | Gryffindor | 100 |
| Draco Malfoy | Slytherin | 90 |
*/
if columns == 0 {
code,err := strconv.ParseInt(param,10,64)
if err == nil {
codeArr = append(codeArr,code)
}
return "|" + param
}
count := tipsMap[param]
if columns == 1 {
// 儲存提示列
if count != 0 {
count++
diffMap[fmt.Sprintf("param: -- %s -- times:%d",param,count-1)] =
fmt.Sprintf(" 與 %s 的第 %d 行提示重複",printer.currentFileName,printer.currentLineNum)
}else{
count = 1
}
tipsMap[param] = count
}
if columns == size - 1 {
return "|" + param + "|"
}
// 找出提示一樣,但是 code 不一樣的
return "|" + param
}
複製程式碼
從小到大排序--code
func quickSort(arr *[]int64,left,right int) {
if arr == nil {
return
}
if right == len(*arr) {
right--
}
if left < 0 || left >= len(*arr) {
return
}
hight := right
low := left
base := (*arr)[left]
if low < hight {
for ;low < hight; {
for ;low < hight && base <= (*arr)[hight]; {
hight--
break
}
(*arr)[low] = (*arr)[hight]
for ;low < hight && base >= (*arr)[low]; {
low++
break
}
(*arr)[hight] = (*arr)[low]
}
(*arr)[low] = base
quickSort(arr,left,low-1)
quickSort(arr,low+1,right)
}
}
複製程式碼
組裝
quickSort(&codeArr,0,len(codeArr))
codeArrSize := len(codeArr)
for i:=0; i<codeArrSize ;i++ {
codeAtr := strconv.Itoa((int)(codeArr[i]))
index := 0
for _,line := range allRetLines {
if strings.Contains(line,"|"+codeAtr+"|") {
final = append(final,line)
// 減去一個,減少迴圈次數
//retLines = append(retLines[:index],retLines[index+1:]...)
index--
break
}
index++
}
}
// 生成檔案
fileName := "errorInfo.md"
file,err := os.Create(fileName)
defer file.Close()
if err!=nil {
fmt.Println(err)
}
for _,line := range final {
fmt.Println(line)
file.WriteString(line+"\n")
}
複製程式碼