project.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package project
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "regexp"
  8. "strings"
  9. "github.com/tal-tech/go-zero/tools/goctl/rpc/execx"
  10. )
  11. const (
  12. constGo = "go"
  13. constProtoC = "protoc"
  14. constGoMod = "go env GOMOD"
  15. constGoPath = "go env GOPATH"
  16. constProtoCGenGo = "protoc-gen-go"
  17. )
  18. type (
  19. Project struct {
  20. Path string
  21. Name string
  22. GoMod GoMod
  23. }
  24. GoMod struct {
  25. Module string
  26. }
  27. )
  28. func Prepare(projectDir string, checkGrpcEnv bool) (*Project, error) {
  29. _, err := exec.LookPath(constGo)
  30. if err != nil {
  31. return nil, err
  32. }
  33. if checkGrpcEnv {
  34. _, err = exec.LookPath(constProtoC)
  35. if err != nil {
  36. return nil, err
  37. }
  38. _, err = exec.LookPath(constProtoCGenGo)
  39. if err != nil {
  40. return nil, err
  41. }
  42. }
  43. var (
  44. goMod, module string
  45. goPath string
  46. name, path string
  47. )
  48. ret, err := execx.Run(constGoMod)
  49. if err != nil {
  50. return nil, err
  51. }
  52. goMod = strings.TrimSpace(ret)
  53. ret, err = execx.Run(constGoPath)
  54. if err != nil {
  55. return nil, err
  56. }
  57. goPath = strings.TrimSpace(ret)
  58. src := filepath.Join(goPath, "src")
  59. if len(goMod) > 0 {
  60. path = filepath.Dir(goMod)
  61. name = filepath.Base(path)
  62. data, err := ioutil.ReadFile(goMod)
  63. if err != nil {
  64. return nil, err
  65. }
  66. module, err = matchModule(data)
  67. if err != nil {
  68. return nil, err
  69. }
  70. } else {
  71. pwd, err := os.Getwd()
  72. if err != nil {
  73. return nil, err
  74. }
  75. if !strings.HasPrefix(pwd, src) {
  76. absPath, err := filepath.Abs(projectDir)
  77. if err != nil {
  78. return nil, err
  79. }
  80. name = filepath.Clean(filepath.Base(absPath))
  81. path = projectDir
  82. } else {
  83. r := strings.TrimPrefix(pwd, src+string(filepath.Separator))
  84. name = filepath.Dir(r)
  85. if name == "." {
  86. name = r
  87. }
  88. path = filepath.Join(src, name)
  89. }
  90. module = name
  91. }
  92. return &Project{
  93. Name: name,
  94. Path: path,
  95. GoMod: GoMod{
  96. Module: module,
  97. },
  98. }, nil
  99. }
  100. func matchModule(data []byte) (string, error) {
  101. text := string(data)
  102. re := regexp.MustCompile(`(?m)^\s*module\s+[a-z0-9/\-.]+$`)
  103. matches := re.FindAllString(text, -1)
  104. if len(matches) == 1 {
  105. target := matches[0]
  106. index := strings.Index(target, "module")
  107. return strings.TrimSpace(target[index+6:]), nil
  108. }
  109. return "", nil
  110. }