genpb.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package genpb
  7. import (
  8. "context"
  9. "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
  10. "github.com/gogf/gf/v2/frame/g"
  11. "github.com/gogf/gf/v2/os/gfile"
  12. "github.com/gogf/gf/v2/os/gproc"
  13. "github.com/gogf/gf/v2/util/gtag"
  14. )
  15. type (
  16. CGenPb struct{}
  17. CGenPbInput struct {
  18. g.Meta `name:"pb" config:"{CGenPbConfig}" brief:"{CGenPbBrief}" eg:"{CGenPbEg}"`
  19. Path string `name:"path" short:"p" dc:"protobuf file folder path" d:"manifest/protobuf"`
  20. OutputApi string `name:"api" short:"a" dc:"output folder path storing generated go files of api" d:"api"`
  21. OutputCtrl string `name:"ctrl" short:"c" dc:"output folder path storing generated go files of controller" d:"internal/controller"`
  22. }
  23. CGenPbOutput struct{}
  24. )
  25. const (
  26. CGenPbConfig = `gfcli.gen.pb`
  27. CGenPbBrief = `parse proto files and generate protobuf go files`
  28. CGenPbEg = `
  29. gf gen pb
  30. gf gen pb -p . -a . -p .
  31. `
  32. )
  33. func init() {
  34. gtag.Sets(g.MapStrStr{
  35. `CGenPbEg`: CGenPbEg,
  36. `CGenPbBrief`: CGenPbBrief,
  37. `CGenPbConfig`: CGenPbConfig,
  38. })
  39. }
  40. func (c CGenPb) Pb(ctx context.Context, in CGenPbInput) (out *CGenPbOutput, err error) {
  41. // Necessary check.
  42. protoc := gproc.SearchBinary("protoc")
  43. if protoc == "" {
  44. mlog.Fatalf(`command "protoc" not found in your environment, please install protoc first: https://grpc.io/docs/languages/go/quickstart/`)
  45. }
  46. // protocol fold checks.
  47. var (
  48. protoPath = gfile.RealPath(in.Path)
  49. isParsingPWD bool
  50. )
  51. if protoPath == "" {
  52. // Use current working directory as protoPath if there are proto files under.
  53. currentPath := gfile.Pwd()
  54. currentFiles, _ := gfile.ScanDirFile(currentPath, "*.proto")
  55. if len(currentFiles) > 0 {
  56. protoPath = currentPath
  57. isParsingPWD = true
  58. } else {
  59. mlog.Fatalf(`proto files folder "%s" does not exist`, in.Path)
  60. }
  61. }
  62. // output path checks.
  63. outputApiPath := gfile.RealPath(in.OutputApi)
  64. if outputApiPath == "" {
  65. if isParsingPWD {
  66. outputApiPath = protoPath
  67. } else {
  68. mlog.Fatalf(`output api folder "%s" does not exist`, in.OutputApi)
  69. }
  70. }
  71. outputCtrlPath := gfile.RealPath(in.OutputCtrl)
  72. if outputCtrlPath == "" {
  73. if isParsingPWD {
  74. outputCtrlPath = ""
  75. } else {
  76. mlog.Fatalf(`output controller folder "%s" does not exist`, in.OutputCtrl)
  77. }
  78. }
  79. // folder scanning.
  80. files, err := gfile.ScanDirFile(protoPath, "*.proto", true)
  81. if err != nil {
  82. mlog.Fatal(err)
  83. }
  84. if len(files) == 0 {
  85. mlog.Fatalf(`no proto files found in folder "%s"`, in.Path)
  86. }
  87. if err = gfile.Chdir(protoPath); err != nil {
  88. mlog.Fatal(err)
  89. }
  90. for _, file := range files {
  91. var command = gproc.NewProcess(protoc, nil)
  92. command.Args = append(command.Args, "--proto_path="+gfile.Pwd())
  93. command.Args = append(command.Args, "--go_out=paths=source_relative:"+outputApiPath)
  94. command.Args = append(command.Args, "--go-grpc_out=paths=source_relative:"+outputApiPath)
  95. command.Args = append(command.Args, file)
  96. mlog.Print(command.String())
  97. if err = command.Run(ctx); err != nil {
  98. mlog.Fatal(err)
  99. }
  100. }
  101. // Generate struct tag according comment rules.
  102. err = c.generateStructTag(ctx, generateStructTagInput{OutputApiPath: outputApiPath})
  103. if err != nil {
  104. return
  105. }
  106. // Generate controllers according comment rules.
  107. if outputCtrlPath != "" {
  108. err = c.generateController(ctx, generateControllerInput{
  109. OutputApiPath: outputApiPath,
  110. OutputCtrlPath: outputCtrlPath,
  111. })
  112. if err != nil {
  113. return
  114. }
  115. }
  116. mlog.Print("done!")
  117. return
  118. }