diff --git a/README.md b/README.md index f643b68d..1a2c1ff9 100644 --- a/README.md +++ b/README.md @@ -38,5 +38,3 @@ Please refer to [commands](/COMMANDS.md). MIT [![Build Status](https://travis-ci.org/dnote-io/cli.svg?branch=master)](https://travis-ci.org/dnote-io/cli) -[![Go Report Card](https://goreportcard.com/badge/github.com/dnote-io/cli)](https://goreportcard.com/report/github.com/dnote-io/cli) -[![GolangCI](https://golangci.com/badges/github.com/dnote-io/cli.svg)](https://golangci.com) diff --git a/cmd/login/login.go b/cmd/login/login.go index 03222d53..c941c2bb 100644 --- a/cmd/login/login.go +++ b/cmd/login/login.go @@ -32,7 +32,7 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc { log.Plain(" (_) (__)\n\n") log.Plain("Welcome to Dnote Cloud :)\n\n") log.Plain("A home for your engineering microlessons\n") - log.Plain("You can register at https://dnote.io\n\n") + log.Plain("You can register at https://dnote.io/cloud\n\n") log.Printf("API key: ") var apiKey string @@ -52,7 +52,7 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc { config.APIKey = apiKey err = core.WriteConfig(ctx, config) if err != nil { - return err + return errors.Wrap(err, "Failed to write to config file") } log.Success("configured\n") diff --git a/cmd/remove/remove.go b/cmd/remove/remove.go index 72ffb308..966161bf 100644 --- a/cmd/remove/remove.go +++ b/cmd/remove/remove.go @@ -85,7 +85,7 @@ func note(ctx infra.DnoteCtx, index int, bookName string) error { content := notes[index].Content log.Printf("content: \"%s\"\n", content) - ok, err := utils.AskConfirmation("remove this note?") + ok, err := utils.AskConfirmation("remove this note?", false) if err != nil { return errors.Wrap(err, "Failed to get confirmation") } @@ -113,7 +113,7 @@ func note(ctx infra.DnoteCtx, index int, bookName string) error { // book deletes a book with the given name func book(ctx infra.DnoteCtx, bookName string) error { - ok, err := utils.AskConfirmation(fmt.Sprintf("delete book '%s' and all its notes?", bookName)) + ok, err := utils.AskConfirmation(fmt.Sprintf("delete book '%s' and all its notes?", bookName), false) if err != nil { return err } diff --git a/cmd/sync/sync.go b/cmd/sync/sync.go index 85ad443b..d6907ae4 100644 --- a/cmd/sync/sync.go +++ b/cmd/sync/sync.go @@ -57,7 +57,7 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc { } if config.APIKey == "" { - fmt.Println("Login required. Please run `dnote login`") + log.Error("login required. please run `dnote login`\n") return nil } diff --git a/core/core.go b/core/core.go index ef8685e0..4363bd8a 100644 --- a/core/core.go +++ b/core/core.go @@ -18,7 +18,7 @@ import ( const ( // Version is the current version of dnote - Version = "0.2.0" + Version = "0.2.1" // TimestampFilename is the name of the file containing upgrade info TimestampFilename = "timestamps" @@ -79,15 +79,22 @@ func InitActionFile(ctx infra.DnoteCtx) error { func getEditorCommand() string { editor := os.Getenv("EDITOR") - if editor == "atom" { + switch editor { + case "atom": return "atom -w" - } else if editor == "subl" { + case "subl": return "subl -n -w" - } else if editor == "mate" { + case "mate": return "mate -w" + case "vim": + return "vim" + case "nano": + return "nano" + case "emacs": + return "emacs" + default: + return "vi" } - - return "vim" } // InitConfigFile populates a new config file if it does not exist yet @@ -242,7 +249,12 @@ func WriteDnote(ctx infra.DnoteCtx, dnote infra.Dnote) error { notePath := GetDnotePath(ctx) - return ioutil.WriteFile(notePath, d, 0644) + err = ioutil.WriteFile(notePath, d, 0644) + if err != nil { + errors.Wrap(err, "Failed to write to the dnote file") + } + + return nil } func WriteConfig(ctx infra.DnoteCtx, config infra.Config) error { @@ -253,7 +265,12 @@ func WriteConfig(ctx infra.DnoteCtx, config infra.Config) error { configPath := GetConfigPath(ctx) - return ioutil.WriteFile(configPath, d, 0644) + err = ioutil.WriteFile(configPath, d, 0644) + if err != nil { + errors.Wrap(err, "Failed to write to the config file") + } + + return nil } // LogAction appends the action to the action log and updates the last_action @@ -287,7 +304,12 @@ func WriteActionLog(ctx infra.DnoteCtx, actions []Action) error { return errors.Wrap(err, "Failed to marshal newly generated actions to JSON") } - return ioutil.WriteFile(path, d, 0644) + err = ioutil.WriteFile(path, d, 0644) + if err != nil { + return errors.Wrap(err, "Failed to write to the actions file") + } + + return nil } func ClearActionLog(ctx infra.DnoteCtx) error { @@ -321,7 +343,11 @@ func ReadActionLog(ctx infra.DnoteCtx) ([]Action, error) { } err = json.Unmarshal(b, &ret) - return ret, err + if err != nil { + return ret, errors.Wrap(err, "Failed to unmarshal action log JSON") + } + + return ret, nil } func ReadConfig(ctx infra.DnoteCtx) (infra.Config, error) { @@ -334,7 +360,11 @@ func ReadConfig(ctx infra.DnoteCtx) (infra.Config, error) { } err = yaml.Unmarshal(b, &ret) - return ret, err + if err != nil { + return ret, errors.Wrap(err, "Failed to unmarshal config YAML") + } + + return ret, nil } func UpdateLastActionTimestamp(ctx infra.DnoteCtx, val int64) error { diff --git a/log/log.go b/log/log.go index 0c72ae97..8451149b 100644 --- a/log/log.go +++ b/log/log.go @@ -17,11 +17,11 @@ var ( var indent = " " func Info(msg string) { - fmt.Fprintf(color.Output, "%s %s %s\n", indent, SprintfBlue("•"), msg) + fmt.Fprintf(color.Output, "%s%s %s", indent, SprintfBlue("•"), msg) } func Infof(msg string, v ...interface{}) { - fmt.Fprintf(color.Output, "%s %s %s", indent, SprintfBlue("•"), fmt.Sprintf(msg, v...)) + fmt.Fprintf(color.Output, "%s%s %s", indent, SprintfBlue("•"), fmt.Sprintf(msg, v...)) } func Success(msg string) { @@ -45,7 +45,11 @@ func Warnf(msg string, v ...interface{}) { } func Error(msg string) { - fmt.Fprintf(color.Output, "%s%s %s\n", indent, SprintfRed("⨯"), msg) + fmt.Fprintf(color.Output, "%s%s %s", indent, SprintfRed("⨯"), msg) +} + +func Errorf(msg string, v ...interface{}) { + fmt.Fprintf(color.Output, "%s%s %s", indent, SprintfRed("⨯"), fmt.Sprintf(msg, v...)) } func Printf(msg string, v ...interface{}) { diff --git a/main.go b/main.go index 9ed8ebac..8cb853d8 100644 --- a/main.go +++ b/main.go @@ -46,7 +46,7 @@ func main() { root.Register(upgrade.NewCmd(ctx)) if err := root.Execute(); err != nil { - log.Error(err.Error()) + log.Errorf("%s\n", err.Error()) os.Exit(1) } } diff --git a/migrate/migrate.go b/migrate/migrate.go index 98bbdb06..017823f3 100644 --- a/migrate/migrate.go +++ b/migrate/migrate.go @@ -186,7 +186,11 @@ func readSchema(ctx infra.DnoteCtx) (schema, error) { } err = yaml.Unmarshal(b, &ret) - return ret, err + if err != nil { + return ret, errors.Wrap(err, "Failed to unmarshal the schema JSON") + } + + return ret, nil } func writeSchema(ctx infra.DnoteCtx, s schema) error { diff --git a/migrate/migrations.go b/migrate/migrations.go index 3b04af56..1154bce2 100644 --- a/migrate/migrations.go +++ b/migrate/migrations.go @@ -148,15 +148,22 @@ func migrateToV3(ctx infra.DnoteCtx) error { func getEditorCommand() string { editor := os.Getenv("EDITOR") - if editor == "atom" { + switch editor { + case "atom": return "atom -w" - } else if editor == "subl" { + case "subl": return "subl -n -w" - } else if editor == "mate" { + case "mate": return "mate -w" + case "vim": + return "vim" + case "nano": + return "nano" + case "emacs": + return "emacs" + default: + return "vi" } - - return "vim" } func migrateToV4(ctx infra.DnoteCtx) error { diff --git a/upgrade/upgrade.go b/upgrade/upgrade.go index 4c5c6ab4..76399d63 100644 --- a/upgrade/upgrade.go +++ b/upgrade/upgrade.go @@ -19,6 +19,7 @@ import ( "github.com/pkg/errors" ) +// upgradeInterval is 7 days var upgradeInterval int64 = 86400 * 7 // getAsset finds the asset to download from the liast of assets in a release @@ -70,7 +71,7 @@ func AutoUpgrade(ctx infra.DnoteCtx) error { } if shouldCheck { - willCheck, err := utils.AskConfirmation("check for upgrade?") + willCheck, err := utils.AskConfirmation("check for upgrade?", true) if err != nil { return errors.Wrap(err, "Failed to get user confirmation for checking upgrade") } @@ -112,7 +113,7 @@ func Upgrade(ctx infra.DnoteCtx) error { // Check if up to date if latestVersion == core.Version { - log.Success("you are up-to-date\n") + log.Success("you are up-to-date\n\n") err = touchLastUpgrade(ctx) if err != nil { return errors.Wrap(err, "Failed to update the upgrade timestamp") @@ -132,7 +133,7 @@ func Upgrade(ctx infra.DnoteCtx) error { } // Download temporary file - log.Infof("Downloading: %s\n", latestVersion) + log.Infof("downloading: %s\n", latestVersion) tmpPath := path.Join(os.TempDir(), "dnote_update") out, err := os.Create(tmpPath) @@ -174,7 +175,7 @@ func Upgrade(ctx infra.DnoteCtx) error { return errors.Wrap(err, "Upgrade is done, but failed to update the last_upgrade timestamp.") } - log.Successf("Updated: v%s -> v%s\n", core.Version, latestVersion) - log.Info("Changelog: https://github.com/dnote-io/cli/releases\n") + log.Successf("updated: v%s -> v%s\n", core.Version, latestVersion) + log.Plain("changelog: https://github.com/dnote-io/cli/releases\n\n") return nil } diff --git a/utils/utils.go b/utils/utils.go index f8adeea6..00494ca4 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -33,8 +33,15 @@ func GetInput() (string, error) { return input, nil } -func AskConfirmation(question string) (bool, error) { - log.Printf("%s (y/N): ", question) +func AskConfirmation(question string, optimistic bool) (bool, error) { + var choices string + if optimistic { + choices = "(Y/n)" + } else { + choices = "(y/N)" + } + + log.Printf("%s %s: ", question, choices) res, err := GetInput() if err != nil { @@ -43,6 +50,10 @@ func AskConfirmation(question string) (bool, error) { confirmed := res == "y\n" || res == "y\r\n" + if optimistic { + confirmed = confirmed || res == "\n" || res == "\r\n" + } + return confirmed, nil }