// 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 }