@@ -24,71 +24,109 @@ func CheckForUpdate(currentVersion string) {
2424 return
2525 }
2626
27- lastUpdate , _ := LastUpdateCheckTime ()
27+ updateInfo , _ := getUpdateInfo ()
2828
29- if time .Since (lastUpdate ) < 24 * time .Hour {
29+ if updateInfo .UpdateAvailable && updateInfo .CurrentVersion == currentVersion {
30+ printVersionNotice (updateInfo .CurrentVersion , updateInfo .AvailableVersion )
3031 return
3132 }
3233
33- defer func () {
34- _ = StoreUpdateCheckTime (time .Now ().UTC ())
35- }()
34+ if time .Since (updateInfo .LastChecked ) < time .Hour {
35+ return
36+ }
37+
38+ latestVersion := getLatestVersion ()
39+
40+ if latestVersion != "" && latestVersion != currentVersion {
41+ updateInfo .CurrentVersion = currentVersion
42+ updateInfo .AvailableVersion = latestVersion
43+ updateInfo .UpdateAvailable = true
44+
45+ printVersionNotice (currentVersion , latestVersion )
46+ } else {
47+ updateInfo .CurrentVersion = currentVersion
48+ updateInfo .AvailableVersion = ""
49+ updateInfo .UpdateAvailable = false
50+ }
51+
52+ updateInfo .LastChecked = time .Now ()
53+
54+ _ = storeUpdateInfo (updateInfo )
55+ }
56+
57+ func printVersionNotice (currentVersion string , availableVersion string ) {
58+ c := color .New (color .FgHiYellow )
59+ _ , _ = c .Printf ("A new version of the CLI is available: %s (current: %s)\n " , availableVersion , currentVersion )
60+ _ , _ = c .Printf ("Some features may not work correctly. Please update ASAP!\n " )
61+ _ , _ = c .Printf ("See instructions at: %v\n " , repoURL )
62+ fmt .Println ()
63+ }
3664
65+ func getLatestVersion () string {
3766 ctx , cancel := context .WithTimeout (context .Background (), 3 * time .Second )
3867 defer cancel ()
3968
4069 req , err := http .NewRequestWithContext (ctx , http .MethodGet , releasesURL , nil )
4170 if err != nil {
42- return
71+ return ""
4372 }
4473
4574 resp , err := http .DefaultClient .Do (req )
4675 if err != nil {
47- return
76+ return ""
4877 }
4978 defer func () {
5079 _ = resp .Body .Close ()
5180 }()
5281
5382 var release releaseResponse
5483 if err := json .NewDecoder (resp .Body ).Decode (& release ); err != nil {
55- return
84+ return ""
5685 }
5786
58- latestVersion := strings .TrimLeft (release .TagName , "v" )
87+ return strings .TrimLeft (release .TagName , "v" )
88+ }
5989
60- if latestVersion != currentVersion {
61- c := color .New (color .FgHiYellow )
62- _ , _ = c .Printf ("A new version is available: %s (current: %s)\n " , release .TagName , currentVersion )
63- _ , _ = c .Printf ("Visit %v to update\n " , repoURL )
64- fmt .Println ()
65- }
90+ func updateInfoPath () string {
91+ return path .Join (GlobalConfigDir (), "update" )
6692}
6793
68- func lastUpdateCheckPath () string {
69- return path .Join (GlobalConfigDir (), "last-update-check" )
94+ type UpdateInfo struct {
95+ CurrentVersion string `json:"current_version"`
96+ AvailableVersion string `json:"available_version"`
97+ UpdateAvailable bool `json:"update_available"`
98+ LastChecked time.Time `json:"last_checked"`
7099}
71100
72- func LastUpdateCheckTime () (time. Time , error ) {
73- if ! fileExists (lastUpdateCheckPath ()) {
74- return time. Time {}, nil
101+ func getUpdateInfo () (UpdateInfo , error ) {
102+ if ! fileExists (updateInfoPath ()) {
103+ return UpdateInfo {}, nil
75104 }
76105
77- content , err := os .ReadFile (lastUpdateCheckPath ())
106+ content , err := os .ReadFile (updateInfoPath ())
78107 if err != nil {
79- return time. Time {}, err
108+ return UpdateInfo {}, fmt . Errorf ( "failed to read update file: %w" , err )
80109 }
81110
82- t , err := time . Parse ( time . RFC3339 , string ( content ))
83- if err != nil {
84- return time. Time {}, err
111+ var info UpdateInfo
112+ if err := json . Unmarshal ( content , & info ); err != nil {
113+ return UpdateInfo {}, fmt . Errorf ( "failed to unmarshal update info: %w" , err )
85114 }
86115
87- return t , nil
116+ return info , nil
88117}
89118
90- func StoreUpdateCheckTime (t time.Time ) error {
91- return os .WriteFile (lastUpdateCheckPath (), []byte (t .Format (time .RFC3339 )), 0644 )
119+ func storeUpdateInfo (info UpdateInfo ) error {
120+ content , err := json .Marshal (info )
121+ if err != nil {
122+ return fmt .Errorf ("failed to marshal update info: %w" , err )
123+ }
124+
125+ if err := os .WriteFile (updateInfoPath (), content , 0644 ); err != nil {
126+ return fmt .Errorf ("failed to write update info file: %w" , err )
127+ }
128+
129+ return nil
92130}
93131
94132func fileExists (path string ) bool {
0 commit comments