// Package version implements functions to fetch information from // Github on newer version of the program available. package version import ( "context" "errors" "fmt" "net/http" "time" "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/golibs/format" ) // 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. func GetMessage(ctx context.Context, buildInfo models.BuildInformation, client *http.Client) (message string, err error) { if buildInfo.Version == "latest" { // Find # of commits between current commit and latest commit commitsSince, err := getCommitsSince(ctx, client, buildInfo.Commit) if err != nil { return "", err } else if commitsSince == 0 { return fmt.Sprintf("You are running on the bleeding edge of %s!", buildInfo.Version), nil } commits := "commits" if commitsSince == 1 { commits = "commit" } return fmt.Sprintf("You are running %d %s behind the most recent %s", commitsSince, commits, buildInfo.Version), nil } tagName, name, releaseTime, err := getLatestRelease(ctx, client) if err != nil { return "", err } if tagName == buildInfo.Version { return fmt.Sprintf("You are running the latest release %s", buildInfo.Version), nil } timeSinceRelease := format.FriendlyDuration(time.Since(releaseTime)) return fmt.Sprintf("There is a new release %s (%s) created %s ago", tagName, name, timeSinceRelease), nil } var errReleaseNotFound = errors.New("release not found") func getLatestRelease(ctx context.Context, client *http.Client) (tagName, name string, time time.Time, err error) { releases, err := getGithubReleases(ctx, client) if err != nil { return "", "", time, err } for _, release := range releases { if release.Prerelease { continue } return release.TagName, release.Name, release.PublishedAt, nil } return "", "", time, errReleaseNotFound } var errCommitNotFound = errors.New("commit not found") func getCommitsSince(ctx context.Context, client *http.Client, commitShort string) (n int, err error) { commits, err := getGithubCommits(ctx, client) if err != nil { return 0, err } for i := range commits { if commits[i].Sha[:7] == commitShort { return n, nil } n++ } return 0, fmt.Errorf("%w: %s", errCommitNotFound, commitShort) }