release.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package version
  2. import (
  3. "encoding/json"
  4. "io"
  5. "net/http"
  6. "time"
  7. "github.com/pkg/errors"
  8. )
  9. type ReleaseType string
  10. const (
  11. ReleaseTypeStable ReleaseType = "stable"
  12. ReleaseTypePrerelease ReleaseType = "prerelease"
  13. ReleaseTypeDev ReleaseType = "dev"
  14. )
  15. type TReleaseAsset struct {
  16. Name string `json:"name"`
  17. BrowserDownloadUrl string `json:"browser_download_url"`
  18. Size uint `json:"size"`
  19. }
  20. type TRelease struct {
  21. TagName string `json:"tag_name"`
  22. Name string `json:"name"`
  23. PublishedAt time.Time `json:"published_at"`
  24. Body string `json:"body"`
  25. Prerelease bool `json:"prerelease"`
  26. Type ReleaseType `json:"type"`
  27. Assets []TReleaseAsset `json:"assets"`
  28. }
  29. func (t *TRelease) GetAssetsMap() (m map[string]TReleaseAsset) {
  30. m = make(map[string]TReleaseAsset)
  31. for _, v := range t.Assets {
  32. m[v.Name] = v
  33. }
  34. return
  35. }
  36. func getLatestRelease() (data TRelease, err error) {
  37. resp, err := http.Get(GetGithubLatestReleaseAPIUrl())
  38. if err != nil {
  39. err = errors.Wrap(err, "service.getLatestRelease http.Get err")
  40. return
  41. }
  42. body, err := io.ReadAll(resp.Body)
  43. if err != nil {
  44. err = errors.Wrap(err, "service.getLatestRelease io.ReadAll err")
  45. return
  46. }
  47. defer resp.Body.Close()
  48. if resp.StatusCode != 200 {
  49. err = errors.New(string(body))
  50. return
  51. }
  52. err = json.Unmarshal(body, &data)
  53. if err != nil {
  54. err = errors.Wrap(err, "service.getLatestRelease json.Unmarshal err")
  55. return
  56. }
  57. data.Type = ReleaseTypeStable
  58. return
  59. }
  60. func getLatestPrerelease() (data TRelease, err error) {
  61. resp, err := http.Get(GetGithubReleasesListAPIUrl())
  62. if err != nil {
  63. err = errors.Wrap(err, "service.getLatestPrerelease http.Get err")
  64. return
  65. }
  66. body, err := io.ReadAll(resp.Body)
  67. if err != nil {
  68. err = errors.Wrap(err, "service.getLatestPrerelease io.ReadAll err")
  69. return
  70. }
  71. defer resp.Body.Close()
  72. if resp.StatusCode != 200 {
  73. err = errors.New(string(body))
  74. return
  75. }
  76. var releaseList []TRelease
  77. err = json.Unmarshal(body, &releaseList)
  78. if err != nil {
  79. err = errors.Wrap(err, "service.getLatestPrerelease json.Unmarshal err")
  80. return
  81. }
  82. latestDate := time.Time{}
  83. for _, release := range releaseList {
  84. if release.Prerelease && release.PublishedAt.After(latestDate) {
  85. data = release
  86. latestDate = release.PublishedAt
  87. data.Type = ReleaseTypePrerelease
  88. }
  89. }
  90. return
  91. }
  92. func GetRelease(channel string) (data TRelease, err error) {
  93. stableRelease, err := getLatestRelease()
  94. if err != nil {
  95. return TRelease{}, err
  96. }
  97. switch ReleaseType(channel) {
  98. default:
  99. fallthrough
  100. case ReleaseTypeStable:
  101. return stableRelease, nil
  102. case ReleaseTypePrerelease:
  103. preRelease, err := getLatestPrerelease()
  104. if err != nil {
  105. return TRelease{}, err
  106. }
  107. // if preRelease is newer than stableRelease, return preRelease
  108. // otherwise return stableRelease
  109. if preRelease.PublishedAt.After(stableRelease.PublishedAt) {
  110. return preRelease, nil
  111. }
  112. return stableRelease, nil
  113. case ReleaseTypeDev:
  114. devRelease, err := getDevBuild()
  115. if err != nil {
  116. return TRelease{}, err
  117. }
  118. return devRelease, nil
  119. }
  120. }