gomod.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package ctx
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "github.com/zeromicro/go-zero/tools/goctl/rpc/execx"
  11. "github.com/zeromicro/go-zero/tools/goctl/util/pathx"
  12. )
  13. // Module contains the relative data of go module,
  14. // which is the result of the command go list
  15. type Module struct {
  16. Path string
  17. Main bool
  18. Dir string
  19. GoMod string
  20. GoVersion string
  21. }
  22. // projectFromGoMod is used to find the go module and project file path
  23. // the workDir flag specifies which folder we need to detect based on
  24. // only valid for go mod project
  25. func projectFromGoMod(workDir string) (*ProjectContext, error) {
  26. if len(workDir) == 0 {
  27. return nil, errors.New("the work directory is not found")
  28. }
  29. if _, err := os.Stat(workDir); err != nil {
  30. return nil, err
  31. }
  32. workDir, err := pathx.ReadLink(workDir)
  33. if err != nil {
  34. return nil, err
  35. }
  36. m, err := getRealModule(workDir, execx.Run)
  37. if err != nil {
  38. return nil, err
  39. }
  40. var ret ProjectContext
  41. ret.WorkDir = workDir
  42. ret.Name = filepath.Base(m.Dir)
  43. dir, err := pathx.ReadLink(m.Dir)
  44. if err != nil {
  45. return nil, err
  46. }
  47. ret.Dir = dir
  48. ret.Path = m.Path
  49. return &ret, nil
  50. }
  51. func getRealModule(workDir string, execRun execx.RunFunc) (*Module, error) {
  52. data, err := execRun("go list -json -m", workDir)
  53. if err != nil {
  54. return nil, err
  55. }
  56. modules, err := decodePackages(strings.NewReader(data))
  57. if err != nil {
  58. return nil, err
  59. }
  60. for _, m := range modules {
  61. if strings.HasPrefix(workDir, m.Dir) {
  62. return &m, nil
  63. }
  64. }
  65. return nil, errors.New("no matched module")
  66. }
  67. func decodePackages(rc io.Reader) ([]Module, error) {
  68. var modules []Module
  69. decoder := json.NewDecoder(rc)
  70. for decoder.More() {
  71. var m Module
  72. if err := decoder.Decode(&m); err != nil {
  73. return nil, fmt.Errorf("invalid module: %v", err)
  74. }
  75. modules = append(modules, m)
  76. }
  77. return modules, nil
  78. }