project.go 2.5 KB

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