Files
gluetun/internal/version/version.go

81 lines
2.4 KiB
Go
Raw Normal View History

2020-08-30 14:48:57 +00:00
package version
import (
2020-10-17 21:54:09 +00:00
"context"
2021-05-30 16:14:08 +00:00
"errors"
2020-08-30 14:48:57 +00:00
"fmt"
"net/http"
"sort"
2020-08-30 14:48:57 +00:00
"time"
"github.com/qdm12/gluetun/internal/format"
2020-11-04 14:07:04 +00:00
"github.com/qdm12/gluetun/internal/models"
2020-08-30 14:48:57 +00:00
)
// GetMessage returns a message for the user describing if there is a newer version
// available. It should only be called once the tunnel is established.
2020-11-04 14:07:04 +00:00
func GetMessage(ctx context.Context, buildInfo models.BuildInformation,
client *http.Client) (message string, err error) {
if buildInfo.Version == "latest" {
2020-08-30 14:48:57 +00:00
// Find # of commits between current commit and latest commit
2020-11-04 14:07:04 +00:00
commitsSince, err := getCommitsSince(ctx, client, buildInfo.Commit)
2020-08-30 14:48:57 +00:00
if err != nil {
2021-05-30 16:14:08 +00:00
return "", err
2020-08-30 14:48:57 +00:00
} else if commitsSince == 0 {
2020-11-04 14:07:04 +00:00
return fmt.Sprintf("You are running on the bleeding edge of %s!", buildInfo.Version), nil
2020-08-30 14:48:57 +00:00
}
commits := "commits"
if commitsSince == 1 {
commits = "commit"
}
2020-11-04 14:07:04 +00:00
return fmt.Sprintf("You are running %d %s behind the most recent %s", commitsSince, commits, buildInfo.Version), nil
2020-08-30 14:48:57 +00:00
}
2020-10-17 21:54:09 +00:00
tagName, name, releaseTime, err := getLatestRelease(ctx, client)
2020-08-30 14:48:57 +00:00
if err != nil {
2021-05-30 16:14:08 +00:00
return "", err
2020-08-30 14:48:57 +00:00
}
2020-11-04 14:07:04 +00:00
if tagName == buildInfo.Version {
return fmt.Sprintf("You are running the latest release %s", buildInfo.Version), nil
2020-08-30 14:48:57 +00:00
}
timeSinceRelease := format.FriendlyDuration(time.Since(releaseTime))
2020-08-30 14:48:57 +00:00
return fmt.Sprintf("There is a new release %s (%s) created %s ago",
tagName, name, timeSinceRelease),
nil
}
2021-05-30 16:14:08 +00:00
var errReleaseNotFound = errors.New("release not found")
2020-10-17 21:54:09 +00:00
func getLatestRelease(ctx context.Context, client *http.Client) (tagName, name string, time time.Time, err error) {
releases, err := getGithubReleases(ctx, client)
2020-08-30 14:48:57 +00:00
if err != nil {
return "", "", time, err
}
// Sort releases by tag names (semver)
sort.Slice(releases, func(i, j int) bool {
return releases[i].TagName > releases[j].TagName
})
2020-08-30 14:48:57 +00:00
for _, release := range releases {
if release.Prerelease {
continue
}
return release.TagName, release.Name, release.PublishedAt, nil
}
return "", "", time, fmt.Errorf("%w", errReleaseNotFound)
2020-08-30 14:48:57 +00:00
}
2021-05-30 16:14:08 +00:00
var errCommitNotFound = errors.New("commit not found")
2020-10-17 21:54:09 +00:00
func getCommitsSince(ctx context.Context, client *http.Client, commitShort string) (n int, err error) {
commits, err := getGithubCommits(ctx, client)
2020-08-30 14:48:57 +00:00
if err != nil {
return 0, err
}
for i := range commits {
if commits[i].Sha[:7] == commitShort {
return n, nil
}
n++
}
2021-05-30 16:14:08 +00:00
return 0, fmt.Errorf("%w: %s", errCommitNotFound, commitShort)
2020-08-30 14:48:57 +00:00
}