package update import ( "errors" "time" ) const StateIdle = "idle" var ( ErrNoRelease = errors.New("no release found") ErrInvalidVersion = errors.New("invalid version") ErrFeedUnavailable = errors.New("release feed unavailable") ) type ReleaseNotes struct { Version string `json:"version"` ReleasedAt time.Time `json:"released_at"` Items []string `json:"items"` } type Asset struct { Name string `json:"name"` URL string `json:"url"` Size int64 `json:"size"` } type Release struct { Tag string URL string PublishedAt time.Time Notes ReleaseNotes Assets []Asset } type CheckResult struct { Latest string `json:"latest"` ReleaseURL string `json:"release_url"` Notes ReleaseNotes `json:"notes"` Assets []Asset `json:"assets"` CheckedAt time.Time `json:"checked_at"` } type Progress struct { Percent int `json:"percent"` DownloadedBytes int64 `json:"downloaded_bytes"` TotalBytes int64 `json:"total_bytes"` } type UpdateStatus struct { Current string `json:"current"` Latest string `json:"latest"` Available bool `json:"available"` ReleaseURL *string `json:"release_url"` Notes *ReleaseNotes `json:"notes"` CheckedAt *time.Time `json:"checked_at"` CanApply bool `json:"can_apply"` State string `json:"state"` Progress *Progress `json:"progress"` Error *string `json:"error"` StartedAt *time.Time `json:"started_at"` FinishedAt *time.Time `json:"finished_at"` Container bool `json:"container"` } func NewResult(release Release, checkedAt time.Time) CheckResult { return CheckResult{ Latest: release.Tag, ReleaseURL: release.URL, Notes: release.Notes, Assets: release.Assets, CheckedAt: checkedAt.UTC(), } } func NewStatus(current string, result *CheckResult) UpdateStatus { status := UpdateStatus{Current: current, State: StateIdle} if result == nil { return status } releaseURL := result.ReleaseURL notes := result.Notes notes.Items = nonNilItems(notes.Items) checkedAt := result.CheckedAt status.Latest = result.Latest status.Available = IsNewer(current, result.Latest) status.ReleaseURL = &releaseURL status.Notes = ¬es status.CheckedAt = &checkedAt return status } func nonNilItems(items []string) []string { if items == nil { return []string{} } return items } func Newest(releases []Release) (Release, error) { var newest Release found := false for _, release := range releases { if _, err := ParseVersion(release.Tag); err != nil { continue } if !found || IsNewer(newest.Tag, release.Tag) { newest = release found = true } } if !found { return Release{}, ErrNoRelease } return newest, nil }