golang的私有化定制自动更新插件
shenwc
2024-11-26 5a1d99989fa32be1684b9290b4a58e8418b7b92d
stores/apex/apex.go
New file
@@ -0,0 +1,123 @@
// Package apex provides an Apex release store.
package apex
import (
   "encoding/json"
   "fmt"
   "net/http"
   "time"
   "github.com/pkg/errors"
   update "github.com/zan8in/goupdate"
)
// Store is the store implementation.
type Store struct {
   URL       string
   Product   string
   Plan      string
   Version   string
   AccessKey string
}
// Release model.
type Release struct {
   Version   string    `json:"version"`
   Notes     string    `json:"notes"`
   Files     []*File   `json:"files"`
   CreatedAt time.Time `json:"created_at"`
}
// File model.
type File struct {
   Name string `json:"name"`
   Key  string `json:"key"`
   Size int64  `json:"size"`
   URL  string `json:"url"`
}
// GetRelease returns the specified release or ErrNotFound.
func (s *Store) GetRelease(version string) (*update.Release, error) {
   releases, err := s.releases()
   if err != nil {
      return nil, err
   }
   for _, r := range releases {
      if r.Version == version {
         return r, nil
      }
   }
   return nil, update.ErrNotFound
}
// LatestReleases returns releases newer than Version, or nil.
func (s *Store) LatestReleases() (latest []*update.Release, err error) {
   releases, err := s.releases()
   if err != nil {
      return
   }
   for _, r := range releases {
      if r.Version == s.Version {
         break
      }
      latest = append(latest, r)
   }
   return
}
// releases returns all releases.
func (s *Store) releases() (all []*update.Release, err error) {
   url := fmt.Sprintf("%s/%s/%s", s.URL, s.Product, s.Plan)
   req, err := http.NewRequest("GET", url, nil)
   if err != nil {
      return nil, errors.Wrap(err, "creating request")
   }
   req.Header.Set("Authorization", "Bearer "+s.AccessKey)
   res, err := http.DefaultClient.Do(req)
   if err != nil {
      return nil, errors.Wrap(err, "requesting")
   }
   defer res.Body.Close()
   if res.StatusCode >= 400 {
      return nil, errors.Errorf("response status code is %d", res.StatusCode)
   }
   var releases []*Release
   if err := json.NewDecoder(res.Body).Decode(&releases); err != nil {
      return nil, errors.Wrap(err, "unmarshaling")
   }
   for _, r := range releases {
      all = append(all, toRelease(r))
   }
   return
}
// toRelease returns a Release.
func toRelease(r *Release) *update.Release {
   out := &update.Release{
      Version:     r.Version,
      Notes:       r.Notes,
      PublishedAt: r.CreatedAt,
   }
   for _, f := range r.Files {
      out.Assets = append(out.Assets, &update.Asset{
         Name: f.Name,
         Size: int(f.Size),
         URL:  f.URL,
      })
   }
   return out
}