Merge pull request #151 from github/less-aggressive-checking

Only check for new version once every 24 hours
This commit is contained in:
Mislav Marohnić 2019-12-13 17:09:26 +01:00 committed by GitHub
commit caa1c49c6c
3 changed files with 76 additions and 6 deletions

View file

@ -10,6 +10,7 @@ import (
"github.com/github/gh-cli/utils"
"github.com/mattn/go-isatty"
"github.com/mgutz/ansi"
"github.com/mitchellh/go-homedir"
)
var updaterEnabled = ""
@ -60,5 +61,9 @@ func checkForUpdate(currentVersion string) (*update.ReleaseInfo, error) {
}
repo := updaterEnabled
return update.CheckForUpdate(client, repo, currentVersion)
stateFilePath, err := homedir.Expand("~/.config/gh/state.yml")
if err != nil {
return nil, err
}
return update.CheckForUpdate(client, stateFilePath, repo, currentVersion)
}

View file

@ -2,9 +2,12 @@ package update
import (
"fmt"
"io/ioutil"
"time"
"github.com/github/gh-cli/api"
"github.com/hashicorp/go-version"
"gopkg.in/yaml.v3"
)
// ReleaseInfo stores information about a release
@ -13,21 +16,71 @@ type ReleaseInfo struct {
URL string `json:"html_url"`
}
type StateEntry struct {
CheckedForUpdateAt time.Time `yaml:"checked_for_update_at"`
LatestRelease ReleaseInfo `yaml:"latest_release"`
}
// CheckForUpdate checks whether this software has had a newer relase on GitHub
func CheckForUpdate(client *api.Client, repo, currentVersion string) (*ReleaseInfo, error) {
latestRelease := ReleaseInfo{}
err := client.REST("GET", fmt.Sprintf("repos/%s/releases/latest", repo), nil, &latestRelease)
func CheckForUpdate(client *api.Client, stateFilePath, repo, currentVersion string) (*ReleaseInfo, error) {
latestRelease, err := getLatestReleaseInfo(client, stateFilePath, repo, currentVersion)
if err != nil {
return nil, err
}
if versionGreaterThan(latestRelease.Version, currentVersion) {
return &latestRelease, nil
return latestRelease, nil
}
return nil, nil
}
func getLatestReleaseInfo(client *api.Client, stateFilePath, repo, currentVersion string) (*ReleaseInfo, error) {
stateEntry, err := getStateEntry(stateFilePath)
if err == nil && time.Since(stateEntry.CheckedForUpdateAt).Hours() < 24 {
return &stateEntry.LatestRelease, nil
}
latestRelease := ReleaseInfo{}
err = client.REST("GET", fmt.Sprintf("repos/%s/releases/latest", repo), nil, &latestRelease)
if err != nil {
return nil, err
}
err = setStateEntry(stateFilePath, time.Now(), latestRelease)
if err != nil {
return nil, err
}
return &latestRelease, nil
}
func getStateEntry(stateFilePath string) (*StateEntry, error) {
content, err := ioutil.ReadFile(stateFilePath)
if err != nil {
return nil, err
}
var stateEntry StateEntry
err = yaml.Unmarshal(content, &stateEntry)
if err != nil {
return nil, err
}
return &stateEntry, nil
}
func setStateEntry(stateFilePath string, t time.Time, r ReleaseInfo) error {
data := StateEntry{CheckedForUpdateAt: t, LatestRelease: r}
content, err := yaml.Marshal(data)
if err != nil {
return err
}
ioutil.WriteFile(stateFilePath, content, 0600)
return nil
}
func versionGreaterThan(v, w string) bool {
vv, ve := version.NewVersion(v)
vw, we := version.NewVersion(w)

View file

@ -3,6 +3,9 @@ package update
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"testing"
"github.com/github/gh-cli/api"
@ -55,7 +58,7 @@ func TestCheckForUpdate(t *testing.T) {
"html_url": "%s"
}`, s.LatestVersion, s.LatestURL)))
rel, err := CheckForUpdate(client, "OWNER/REPO", s.CurrentVersion)
rel, err := CheckForUpdate(client, tempFilePath(), "OWNER/REPO", s.CurrentVersion)
if err != nil {
t.Fatal(err)
}
@ -87,3 +90,12 @@ func TestCheckForUpdate(t *testing.T) {
})
}
}
func tempFilePath() string {
file, err := ioutil.TempFile("", "")
if err != nil {
log.Fatal(err)
}
os.Remove(file.Name())
return file.Name()
}