main.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "go/token"
  6. "io/ioutil"
  7. "log"
  8. "os"
  9. "strings"
  10. "unicode"
  11. "github.com/dave/dst"
  12. "github.com/dave/dst/decorator"
  13. )
  14. var handlerName string
  15. func init() {
  16. handler := flag.String("handler", "", "请输入需要生成的 handler 名称\n")
  17. flag.Parse()
  18. handlerName = strings.ToLower(*handler)
  19. }
  20. func main() {
  21. fs := token.NewFileSet()
  22. filePath := fmt.Sprintf("./internal/api/%s", handlerName)
  23. parsedFile, err := decorator.ParseFile(fs, filePath+"/handler.go", nil, 0)
  24. if err != nil {
  25. log.Fatalf("parsing package: %s: %s\n", filePath, err)
  26. }
  27. files, _ := ioutil.ReadDir(filePath)
  28. if len(files) > 1 {
  29. log.Fatalf("请先确保 %s 目录中,有且仅有 handler.go 一个文件。", filePath)
  30. }
  31. dst.Inspect(parsedFile, func(n dst.Node) bool {
  32. decl, ok := n.(*dst.GenDecl)
  33. if !ok || decl.Tok != token.TYPE {
  34. return true
  35. }
  36. for _, spec := range decl.Specs {
  37. typeSpec, _ok := spec.(*dst.TypeSpec)
  38. if !_ok {
  39. continue
  40. }
  41. var interfaceType *dst.InterfaceType
  42. if interfaceType, ok = typeSpec.Type.(*dst.InterfaceType); !ok {
  43. continue
  44. }
  45. for _, v := range interfaceType.Methods.List {
  46. if len(v.Names) > 0 {
  47. if v.Names[0].String() == "i" {
  48. continue
  49. }
  50. filepath := "./internal/api/" + handlerName
  51. filename := fmt.Sprintf("%s/func_%s.go", filepath, strings.ToLower(v.Names[0].String()))
  52. funcFile, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0766)
  53. if err != nil {
  54. fmt.Printf("create and open func file error %v\n", err.Error())
  55. continue
  56. }
  57. if funcFile == nil {
  58. fmt.Printf("func file is nil \n")
  59. continue
  60. }
  61. fmt.Println(" └── file : ", filename)
  62. funcContent := fmt.Sprintf("package %s\n\n", handlerName)
  63. funcContent += "import (\n"
  64. funcContent += `"github.com/xinliangnote/go-gin-api/internal/pkg/core"`
  65. funcContent += "\n)\n\n"
  66. funcContent += fmt.Sprintf("\n\ntype %sRequest struct {}\n\n", Lcfirst(v.Names[0].String()))
  67. funcContent += fmt.Sprintf("type %sResponse struct {}\n\n", Lcfirst(v.Names[0].String()))
  68. // 首行注释
  69. funcContent += fmt.Sprintf("%s\n", v.Decorations().Start.All()[0])
  70. nameArr := strings.Split(v.Decorations().Start.All()[0], v.Names[0].String())
  71. funcContent += fmt.Sprintf("// @Summary%s \n", nameArr[1])
  72. funcContent += fmt.Sprintf("// @Description%s \n", nameArr[1])
  73. // Tags
  74. funcContent += fmt.Sprintf("%s \n", v.Decorations().Start.All()[1])
  75. funcContent += fmt.Sprintf("// @Accept application/x-www-form-urlencoded \n")
  76. funcContent += fmt.Sprintf("// @Produce json \n")
  77. funcContent += fmt.Sprintf("// @Param Request body %sRequest true \"请求信息\" \n", Lcfirst(v.Names[0].String()))
  78. funcContent += fmt.Sprintf("// @Success 200 {object} %sResponse \n", Lcfirst(v.Names[0].String()))
  79. funcContent += fmt.Sprintf("// @Failure 400 {object} code.Failure \n")
  80. // Router
  81. funcContent += fmt.Sprintf("%s \n", v.Decorations().Start.All()[2])
  82. funcContent += fmt.Sprintf("func (h *handler) %s() core.HandlerFunc { \n return func(ctx core.Context) {\n\n}}", v.Names[0].String())
  83. funcFile.WriteString(funcContent)
  84. funcFile.Close()
  85. }
  86. }
  87. }
  88. return true
  89. })
  90. }
  91. func Lcfirst(str string) string {
  92. for i, v := range str {
  93. return string(unicode.ToLower(v)) + str[i+1:]
  94. }
  95. return ""
  96. }