Update the upgrade timestamp on successful update

This commit is contained in:
Sung Won Cho 2017-04-07 14:47:45 +10:00
commit e45f853ded
3 changed files with 139 additions and 76 deletions

73
main.go
View file

@ -4,10 +4,10 @@ import (
"fmt"
"io/ioutil"
"os"
"os/user"
"sort"
"github.com/dnote-io/cli/upgrade"
"github.com/dnote-io/cli/utils"
"gopkg.in/yaml.v2"
)
@ -18,72 +18,39 @@ type Config struct {
type Note map[string][]string
const configFilename = ".dnoterc"
const dnoteFilename = ".dnote"
func getConfigPath() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s", usr.HomeDir, configFilename), nil
}
func getDnotePath() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s", usr.HomeDir, dnoteFilename), nil
}
func generateConfigFile() error {
content := []byte("book: general\n")
configPath, err := getConfigPath()
if err != nil {
return err
}
err = ioutil.WriteFile(configPath, content, 0644)
return err
}
func touchDnoteFile() error {
dnotePath, err := getDnotePath()
if err != nil {
return err
}
err = ioutil.WriteFile(dnotePath, []byte{}, 0644)
return err
}
// initDnote creates a config file if one does not exist
func initDnote() error {
configPath, err := getConfigPath()
configPath, err := utils.GetConfigPath()
if err != nil {
return err
}
dnotePath, err := getDnotePath()
dnotePath, err := utils.GetDnotePath()
if err != nil {
return err
}
dnoteUpdatePath, err := utils.GetDnoteUpdatePath()
if err != nil {
return err
}
if !checkFileExists(configPath) {
err := generateConfigFile()
err := utils.GenerateConfigFile()
if err != nil {
return err
}
}
if !checkFileExists(dnotePath) {
err := touchDnoteFile()
err := utils.TouchDnoteFile()
if err != nil {
return err
}
}
if !checkFileExists(dnoteUpdatePath) {
err := utils.TouchDnoteUpgradeFile()
if err != nil {
return err
}
}
return nil
}
@ -96,7 +63,7 @@ func check(e error) {
func readConfig() (Config, error) {
var ret Config
configPath, err := getConfigPath()
configPath, err := utils.GetConfigPath()
if err != nil {
return ret, err
}
@ -129,7 +96,7 @@ func writeConfig(config Config) error {
return err
}
configPath, err := getConfigPath()
configPath, err := utils.GetConfigPath()
if err != nil {
return err
}
@ -162,7 +129,7 @@ func changeBook(bookName string) error {
func readNote() (Note, error) {
ret := Note{}
notePath, err := getDnotePath()
notePath, err := utils.GetDnotePath()
if err != nil {
return ret, err
}
@ -202,7 +169,7 @@ func writeNote(content string) error {
return err
}
notePath, err := getDnotePath()
notePath, err := utils.GetDnotePath()
if err != nil {
return err
}
@ -241,7 +208,7 @@ func main() {
check(err)
err = upgrade.AutoUpdate()
if err != nil {
fmt.Println("Warning: Failed to check for update", err)
fmt.Println("Warning - Failed to check for update:", err)
}
if len(os.Args) < 2 {

View file

@ -1,9 +1,8 @@
package upgrade
import (
"bytes"
"context"
"encoding/binary"
"errors"
"fmt"
"io"
"io/ioutil"
@ -12,15 +11,26 @@ import (
"os/exec"
"os/user"
"path"
"regexp"
"runtime"
"strconv"
"time"
"github.com/dnote-io/cli/utils"
"github.com/google/go-github/github"
)
const dnoteUpdateFilename = ".dnote-update"
const version = "0.0.3"
func GetDnoteUpdatePath() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s", usr.HomeDir, utils.DnoteUpdateFilename), nil
}
// 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)
@ -33,37 +43,46 @@ func getAsset(release *github.RepositoryRelease) *github.ReleaseAsset {
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()
// getLastUpdateEpoch reads and parses the last update epoch
func getLastUpdateEpoch() (int64, error) {
updatePath, err := utils.GetDnoteUpdatePath()
if err != nil {
return false, err
return 0, err
}
b, err := ioutil.ReadFile(updatePath)
if err != nil {
return false, err
return 0, err
}
buf := bytes.NewBuffer(b)
lastEpoch, err := binary.ReadVarint(buf)
re := regexp.MustCompile(`LAST_UPDATE_EPOCH: (\d+)\n`)
match := re.FindStringSubmatch(string(b))
if len(match) != 2 {
msg := fmt.Sprintf("Error parsing %s", utils.DnoteUpdateFilename)
return 0, errors.New(msg)
}
lastEpoch, err := strconv.ParseInt(match[1], 10, 64)
if err != nil {
return 0, err
}
return lastEpoch, nil
}
// shouldCheckUpdate checks if update should be checked
func shouldCheckUpdate() (bool, error) {
var updatePeriod int64 = 86400 * 7
now := time.Now().Unix()
lastEpoch, err := getLastUpdateEpoch()
if err != nil {
return false, err
}
now := time.Now().Unix()
var epochTarget int64 = 86400 * 7 // 7 days
return now-lastEpoch > epochTarget, nil
return now-lastEpoch > updatePeriod, nil
}
// AutoUpdate triggers update if needed
@ -74,13 +93,15 @@ func AutoUpdate() error {
}
if shouldCheck {
Update()
tryUpgrade()
}
return nil
}
func Update() error {
func tryUpgrade() error {
defer utils.TouchDnoteUpgradeFile()
// Fetch the latest version
gh := github.NewClient(nil)
releases, _, err := gh.Repositories.ListReleases(context.Background(), "dnote-io", "cli", nil)
@ -139,6 +160,6 @@ func Update() error {
}
fmt.Printf("Updated: v%s -> v%s", version, latestVersion)
fmt.Println("Change note: https://github.com/dnote-io/cli/releases")
fmt.Println("Changelog: https://github.com/dnote-io/cli/releases")
return nil
}

75
utils/utils.go Normal file
View file

@ -0,0 +1,75 @@
package utils
import (
"fmt"
"io/ioutil"
"os/user"
"strconv"
"time"
)
const configFilename = ".dnoterc"
const DnoteUpdateFilename = ".dnote-update"
const dnoteFilename = ".dnote"
func GetConfigPath() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s", usr.HomeDir, configFilename), nil
}
func GetDnotePath() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s", usr.HomeDir, dnoteFilename), nil
}
func GenerateConfigFile() error {
content := []byte("book: general\n")
configPath, err := GetConfigPath()
if err != nil {
return err
}
err = ioutil.WriteFile(configPath, content, 0644)
return err
}
func TouchDnoteFile() error {
dnotePath, err := GetDnotePath()
if err != nil {
return err
}
err = ioutil.WriteFile(dnotePath, []byte{}, 0644)
return err
}
func TouchDnoteUpgradeFile() error {
fmt.Println("toching dnoteupdate")
dnoteUpdatePath, err := GetDnoteUpdatePath()
if err != nil {
return err
}
epoch := strconv.FormatInt(time.Now().Unix(), 10)
content := []byte(fmt.Sprintf("LAST_UPGRADE_EPOCH: %s\n", epoch))
err = ioutil.WriteFile(dnoteUpdatePath, content, 0644)
return err
}
func GetDnoteUpdatePath() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/%s", usr.HomeDir, DnoteUpdateFilename), nil
}