project.go 2.1 KB

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