Skip to content

Commit deac6da

Browse files
committed
Add state yml
1 parent 5949ca4 commit deac6da

File tree

1 file changed

+84
-5
lines changed

1 file changed

+84
-5
lines changed

update/update.go

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,111 @@ package update
22

33
import (
44
"fmt"
5+
"io/ioutil"
6+
"time"
57

68
"github.com/github/gh-cli/api"
79
"github.com/hashicorp/go-version"
10+
"github.com/mitchellh/go-homedir"
11+
"gopkg.in/yaml.v3"
812
)
913

1014
// ReleaseInfo stores information about a release
1115
type ReleaseInfo struct {
12-
Version string `json:"tag_name"`
13-
URL string `json:"html_url"`
16+
Version string
17+
URL string
18+
}
19+
20+
type StateEntry struct {
21+
CheckedForUpdateAt time.Time `yaml:"checked_for_update_at"`
22+
LatestRelease ReleaseInfo `yaml:"latest_release"`
1423
}
1524

1625
// CheckForUpdate checks whether this software has had a newer relase on GitHub
1726
func CheckForUpdate(client *api.Client, repo, currentVersion string) (*ReleaseInfo, error) {
18-
latestRelease := ReleaseInfo{}
19-
err := client.REST("GET", fmt.Sprintf("repos/%s/releases/latest", repo), nil, &latestRelease)
27+
latestRelease, err := getLatestReleaseInfo(client, repo, currentVersion)
2028
if err != nil {
2129
return nil, err
2230
}
2331

2432
if versionGreaterThan(latestRelease.Version, currentVersion) {
25-
return &latestRelease, nil
33+
return latestRelease, nil
2634
}
2735

2836
return nil, nil
2937
}
3038

39+
func getLatestReleaseInfo(client *api.Client, repo, currentVersion string) (*ReleaseInfo, error) {
40+
stateEntry, err := getStateEntry()
41+
if err != nil {
42+
return nil, err
43+
}
44+
45+
checkedRecently := time.Since(stateEntry.CheckedForUpdateAt).Hours() < 24
46+
if checkedRecently {
47+
return &stateEntry.LatestRelease, nil
48+
}
49+
50+
latestRelease := ReleaseInfo{}
51+
err = client.REST("GET", fmt.Sprintf("repos/%s/releases/latest", repo), nil, &latestRelease)
52+
if err != nil {
53+
return nil, err
54+
}
55+
56+
err = setStateEntry(time.Now(), latestRelease)
57+
if err != nil {
58+
return nil, err
59+
}
60+
61+
return &latestRelease, nil
62+
}
63+
64+
func stateFileName() string {
65+
f, _ := homedir.Expand("~/.config/gh/state.yml")
66+
return f
67+
}
68+
69+
func getStateEntry() (*StateEntry, error) {
70+
f := stateFileName()
71+
content, err := ioutil.ReadFile(f)
72+
if err != nil {
73+
data := StateEntry{
74+
CheckedForUpdateAt: time.Now(),
75+
LatestRelease: ReleaseInfo{
76+
Version: "v0.0.0",
77+
URL: "<?>",
78+
},
79+
}
80+
content, err = yaml.Marshal(data)
81+
if err != nil {
82+
return nil, err
83+
}
84+
ioutil.WriteFile(f, content, 0600)
85+
}
86+
87+
var stateEntry StateEntry
88+
err = yaml.Unmarshal(content, &stateEntry)
89+
if err != nil {
90+
return nil, err
91+
}
92+
93+
return &stateEntry, nil
94+
}
95+
96+
func setStateEntry(t time.Time, r ReleaseInfo) error {
97+
data := StateEntry{
98+
CheckedForUpdateAt: t,
99+
LatestRelease: r,
100+
}
101+
content, err := yaml.Marshal(data)
102+
if err != nil {
103+
return err
104+
}
105+
ioutil.WriteFile(stateFileName(), content, 0600)
106+
107+
return nil
108+
}
109+
31110
func versionGreaterThan(v, w string) bool {
32111
vv, ve := version.NewVersion(v)
33112
vw, we := version.NewVersion(w)

0 commit comments

Comments
 (0)