gomod.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. const goModuleWithoutGoFiles = "command-line-arguments"
  14. var errInvalidGoMod = errors.New("invalid go module")
  15. // Module contains the relative data of go module,
  16. // which is the result of the command go list
  17. type Module struct {
  18. Path string
  19. Main bool
  20. Dir string
  21. GoMod string
  22. GoVersion string
  23. }
  24. func (m *Module) validate() error {
  25. if m.Path == goModuleWithoutGoFiles || m.Dir == "" {
  26. return errInvalidGoMod
  27. }
  28. return nil
  29. }
  30. // projectFromGoMod is used to find the go module and project file path
  31. // the workDir flag specifies which folder we need to detect based on
  32. // only valid for go mod project
  33. func projectFromGoMod(workDir string) (*ProjectContext, error) {
  34. if len(workDir) == 0 {
  35. return nil, errors.New("the work directory is not found")
  36. }
  37. if _, err := os.Stat(workDir); err != nil {
  38. return nil, err
  39. }
  40. workDir, err := pathx.ReadLink(workDir)
  41. if err != nil {
  42. return nil, err
  43. }
  44. m, err := getRealModule(workDir, execx.Run)
  45. if err != nil {
  46. return nil, err
  47. }
  48. if err := m.validate(); err != nil {
  49. return nil, err
  50. }
  51. var ret ProjectContext
  52. ret.WorkDir = workDir
  53. ret.Name = filepath.Base(m.Dir)
  54. dir, err := pathx.ReadLink(m.Dir)
  55. if err != nil {
  56. return nil, err
  57. }
  58. ret.Dir = dir
  59. ret.Path = m.Path
  60. return &ret, nil
  61. }
  62. func getRealModule(workDir string, execRun execx.RunFunc) (*Module, error) {
  63. data, err := execRun("go list -json -m", workDir)
  64. if err != nil {
  65. return nil, err
  66. }
  67. modules, err := decodePackages(strings.NewReader(data))
  68. if err != nil {
  69. return nil, err
  70. }
  71. for _, m := range modules {
  72. if strings.HasPrefix(workDir, m.Dir) {
  73. return &m, nil
  74. }
  75. }
  76. return nil, errors.New("no matched module")
  77. }
  78. func decodePackages(rc io.Reader) ([]Module, error) {
  79. var modules []Module
  80. decoder := json.NewDecoder(rc)
  81. for decoder.More() {
  82. var m Module
  83. if err := decoder.Decode(&m); err != nil {
  84. return nil, fmt.Errorf("invalid module: %v", err)
  85. }
  86. modules = append(modules, m)
  87. }
  88. return modules, nil
  89. }