github.com/nuvolaris/nuv@v0.0.0-20240511174247-a74e3a52bfd8/updates_check.go (about) 1 // Licensed to the Apache Software Foundation (ASF) under one 2 // or more contributor license agreements. See the NOTICE file 3 // distributed with this work for additional information 4 // regarding copyright ownership. The ASF licenses this file 5 // to you under the Apache License, Version 2.0 (the 6 // "License"); you may not use this file except in compliance 7 // with the License. You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 package main 19 20 import ( 21 "errors" 22 "fmt" 23 "io/fs" 24 "os" 25 "time" 26 27 "github.com/go-git/go-git/v5" 28 ) 29 30 const LATESTCHECK = ".latestcheck" 31 32 func checkUpdated(base string, timeInterval time.Duration) { 33 trace("checkUpdated", base) 34 olaris_base := joinpath(base, getNuvBranch()) 35 latest_check_path := joinpath(olaris_base, LATESTCHECK) 36 olaris_path := joinpath(olaris_base, "olaris") 37 38 // if no olaris dir, no update check 39 if !isDir(olaris_path) { 40 return 41 } 42 43 // get info on latest_check file 44 file, ok := checkLatestFile(latest_check_path) 45 if !ok { 46 return 47 } 48 49 mtime := file.ModTime() 50 now := time.Now().Local() 51 diff := now.Sub(mtime) 52 53 if diff >= timeInterval { 54 fmt.Println("Checking for updates...") 55 // touch latest_check file ONLY if enough time has passed 56 touchLatestCheckFile(latest_check_path) 57 58 // check if remote olaris is newer 59 if checkRemoteOlarisNewer(olaris_path) { 60 fmt.Print("New tasks available! Use 'nuv -update' to update.\n\n") 61 } else { 62 fmt.Print("Tasks up to date!\n\n") 63 } 64 } 65 } 66 67 func checkLatestFile(path string) (fs.FileInfo, bool) { 68 file, err := os.Stat(path) 69 if errors.Is(err, os.ErrNotExist) { 70 debug("latestcheck file not found, skipping update check") 71 return nil, false 72 } else if err != nil { 73 debug("failed to access .latestcheck file info", err) 74 return nil, false 75 } 76 77 return file, true 78 } 79 80 func createLatestCheckFile(base string) { 81 // create latest_check file 82 _, err := os.Create(joinpath(base, LATESTCHECK)) 83 if err != nil { 84 warn("failed to set latest_check file", err) 85 } 86 } 87 88 func touchLatestCheckFile(latest_check_path string) { 89 trace("touch latest_check file", latest_check_path) 90 currentTime := time.Now().Local() 91 err := os.Chtimes(latest_check_path, currentTime, currentTime) 92 if err != nil { 93 warn("failed to set latest update check", err) 94 } 95 } 96 97 func checkRemoteOlarisNewer(olaris_path string) bool { 98 trace("checkRemoteOlarisNewer", olaris_path) 99 repo, err := git.PlainOpen(olaris_path) 100 if err != nil { 101 warn("failed to check olaris folder", err) 102 return false 103 } 104 105 localRef, err := repo.Head() 106 if err != nil { 107 warn("failed to check olaris folder", err) 108 return false 109 } 110 111 remote, err := repo.Remote("origin") 112 if err != nil { 113 warn("failed to check remote olaris", err) 114 return false 115 } 116 _ = remote.Fetch(&git.FetchOptions{}) 117 remoteRefs, err := remote.List(&git.ListOptions{}) 118 if err != nil { 119 warn("failed to check remote olaris", err) 120 return false 121 } 122 123 // check ref is in refs 124 for _, remoteRef := range remoteRefs { 125 if localRef.Name().String() == remoteRef.Name().String() { 126 // is hash different? 127 if localRef.Hash().String() != remoteRef.Hash().String() { 128 return true 129 } 130 } 131 } 132 return false 133 }