Go 实现 自动检索 API 错误码代码行 并 打印成文档,例 markDown 形式等

af913337456 · · 959 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

#### 源码--GitHub:<a href="https://github.com/af913337456/ErrorDocAutoPrinter">https://github.com/af913337456/ErrorDocAutoPrinter</a> 如果你是一个`后端Server程序`开发人员。你应该知道,在你写完`API`之后,是需要给`客户端`的同学提供`调用`文档的。 例如下面一个`api handler`,`创建一个用户`。 ```golang 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") } ``` 上面有一行`错误信息输出的代码` ```golang 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` 风格 ### 使用步骤 1. 配置好`json`文件 `DefaultConfig.json` ```json { "TargetFileSuffix":[".go"], "TargetErrorFuncName":["util.GetCommonErr","util.GetErrWithTips"], "FilterFileName":["core"], "ParamsColumnNames":[" 错 误 码 "," 含 义 ","提 示"], "ParamsSplitChar":"," } ``` 2. 输入你的`代码文件夹路径`并运行程序 ```golang func TestDocPrinter(t *testing.T) { p := NewDefaultErrorDocPrinter(NewDefaultMarkDownErrorDocPrinter()) if p == nil { return } fmt.Println(p.printErrorDoc("../../errorDocPrinter")) } ``` 3. 复制粘贴`结果` | 错误码 | 含义 |提示| | - | - | - | |-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` 风格的生成 接口 ```golang 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) } ``` #### 找到一个文件所有行 ```golang 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 } ``` #### 处理一个单元格 ```golang 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 ```golang 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) } } ``` #### 组装 ```golang 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") } ``` ## 如果编程不是为了让复杂的问题简单化,那和机械学习有什么区别?

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

959 次点击  ∙  3 赞  
加入收藏 微博
1 回复  |  直到 2018-05-26 11:22:29
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传