117 lines
2.8 KiB
Go
117 lines
2.8 KiB
Go
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
|
|
}
|