mirror of
https://github.com/dnote/dnote
synced 2026-03-15 06:55:49 +01:00
Stop heartbeat and autoudpate periodically
This commit is contained in:
parent
165e7e57f8
commit
d64eb8f2b7
2 changed files with 152 additions and 44 deletions
52
main.go
52
main.go
|
|
@ -1,14 +1,15 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/user"
|
||||
"sort"
|
||||
|
||||
"github.com/dnote-io/cli/upgrade"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
|
@ -19,7 +20,6 @@ type Note map[string][]string
|
|||
|
||||
const configFilename = ".dnoterc"
|
||||
const dnoteFilename = ".dnote"
|
||||
const version = "v0.0.1"
|
||||
|
||||
func getConfigPath() (string, error) {
|
||||
usr, err := user.Current()
|
||||
|
|
@ -236,49 +236,13 @@ func checkFileExists(filepath string) bool {
|
|||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
func checkUpdates() error {
|
||||
endpoint := "https://api.github.com/repos/dnote-io/cli/releases"
|
||||
resp, err := http.Get(endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
var x []map[string]interface{}
|
||||
err = json.NewDecoder(resp.Body).Decode(&x)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(x) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
latestRelease := x[0]
|
||||
latestVersion := latestRelease["tag_name"]
|
||||
|
||||
if version != latestVersion {
|
||||
fmt.Println("==")
|
||||
fmt.Printf("Update available: %s\n", latestVersion)
|
||||
fmt.Printf("See: %s\n", x[0]["html_url"])
|
||||
fmt.Println("==\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func heartbeat() {
|
||||
http.Get("http://api.dnote.io/heartbeat")
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := initDnote()
|
||||
check(err)
|
||||
err = checkUpdates()
|
||||
check(err)
|
||||
|
||||
heartbeat()
|
||||
err = upgrade.AutoUpdate()
|
||||
if err != nil {
|
||||
fmt.Println("Warning: Failed to check for update", err)
|
||||
}
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("Dnote - Spontaneously capture new engineering lessons\n")
|
||||
|
|
|
|||
144
upgrade/upgrade.go
Normal file
144
upgrade/upgrade.go
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
package upgrade
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/github"
|
||||
)
|
||||
|
||||
const dnoteUpdateFilename = ".dnote-update"
|
||||
const version = "0.0.3"
|
||||
|
||||
// getAsset finds the asset to download from the liast of assets in a release
|
||||
func getAsset(release *github.RepositoryRelease) *github.ReleaseAsset {
|
||||
filename := fmt.Sprintf("dnote-%s-%s", runtime.GOOS, runtime.GOARCH)
|
||||
|
||||
for _, asset := range release.Assets {
|
||||
if *asset.Name == filename {
|
||||
return &asset
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func getDnoteUpdatePath() (string, error) {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s", usr.HomeDir, dnoteUpdateFilename), nil
|
||||
}
|
||||
|
||||
// shouldCheckUpdate checks if update should be checked
|
||||
func shouldCheckUpdate() (bool, error) {
|
||||
updatePath, err := getDnoteUpdatePath()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(updatePath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(b)
|
||||
lastEpoch, err := binary.ReadVarint(buf)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
var epochTarget int64 = 86400 * 7 // 7 days
|
||||
|
||||
return now-lastEpoch > epochTarget, nil
|
||||
}
|
||||
|
||||
// AutoUpdate triggers update if needed
|
||||
func AutoUpdate() error {
|
||||
shouldCheck, err := shouldCheckUpdate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if shouldCheck {
|
||||
Update()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Update() error {
|
||||
// Fetch the latest version
|
||||
gh := github.NewClient(nil)
|
||||
releases, _, err := gh.Repositories.ListReleases(context.Background(), "dnote-io", "cli", nil)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
latest := releases[0]
|
||||
latestVersion := (*latest.TagName)[1:]
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if up to date
|
||||
if latestVersion == version {
|
||||
fmt.Printf("Up-to-date: %s", version)
|
||||
return nil
|
||||
}
|
||||
|
||||
asset := getAsset(latest)
|
||||
if asset == nil {
|
||||
fmt.Printf("Could not find the release for %s %s", runtime.GOOS, runtime.GOARCH)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Download temporary file
|
||||
tmpPath := path.Join(os.TempDir(), "dnote_update")
|
||||
out, err := os.Create(tmpPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
resp, err := http.Get(*asset.BrowserDownloadURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Override the binary
|
||||
cmdPath, err := exec.LookPath("dnote")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Rename(tmpPath, cmdPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Updated: v%s -> v%s", version, latestVersion)
|
||||
fmt.Println("Change note: https://github.com/dnote-io/cli/releases")
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue