Add doctor command, minor changes

pull/184/head
Simon Let 3 years ago
parent dd573cac03
commit 668308a528
  1. 2
      README.md
  2. 55
      cmd/cli/main.go
  3. 4
      cmd/collect/main.go
  4. 151
      cmd/control/cmd/doctor.go
  5. 11
      cmd/control/cmd/root.go
  6. 4
      cmd/control/cmd/update.go
  7. 2
      cmd/control/cmd/version.go
  8. 4
      cmd/install-utils/main.go
  9. 30
      cmd/install-utils/migrate.go
  10. 4
      cmd/postcollect/main.go
  11. 90
      internal/check/check.go
  12. 8
      internal/collect/collect.go
  13. 15
      internal/device/device.go
  14. 64
      internal/output/output.go
  15. 9
      scripts/install.sh

@ -23,8 +23,6 @@ Context-based replacement/enhancement for zsh and bash shell history
### Prerequisites
Nohup
Standard stuff: `bash(4.3+)`, `curl`, `tar`, ...
MacOS: `coreutils` (`brew install coreutils`)

@ -62,34 +62,31 @@ func runReshCli(out *output.Output, config cfg.Config) (string, int) {
pwd := flags.String("pwd", "", "$PWD - present working directory")
gitOriginRemote := flags.String("git-origin-remote", "<<<MISSING>>>", "> git origin remote")
query := flags.String("query", "", "Search query")
// TODO: Do we still need this?
testHistory := flags.String("test-history", "", "Load history from a file instead from the daemon (for testing purposes only!)")
testHistoryLines := flags.Int("test-lines", 0, "The number of lines to load from a file passed with --test-history (for testing purposes only!)")
flags.Parse(args)
// TODO: These errors should tell the user that they should not be running the command directly
errMsg := "Failed to get required command-line arguments"
if *sessionID == "" {
out.Fatal(errMsg, errors.New("missing required option --session-id"))
out.FatalE(errMsg, errors.New("missing required option --session-id"))
}
if *pwd == "" {
out.Fatal(errMsg, errors.New("missing required option --pwd"))
out.FatalE(errMsg, errors.New("missing required option --pwd"))
}
if *gitOriginRemote == "<<<MISSING>>>" {
out.Fatal(errMsg, errors.New("missing required option --git-origin-remote"))
out.FatalE(errMsg, errors.New("missing required option --git-origin-remote"))
}
dataDir, err := datadir.GetPath()
if err != nil {
out.Fatal("Could not get user data directory", err)
out.FatalE("Could not get user data directory", err)
}
deviceName, err := device.GetName(dataDir)
if err != nil {
out.Fatal("Could not get device name", err)
out.FatalE("Could not get device name", err)
}
g, err := gocui.NewGui(gocui.OutputNormal, false)
if err != nil {
out.Fatal("Failed to launch TUI", err)
out.FatalE("Failed to launch TUI", err)
}
defer g.Close()
@ -99,15 +96,11 @@ func runReshCli(out *output.Output, config cfg.Config) (string, int) {
g.Highlight = true
var resp msg.CliResponse
if *testHistory == "" {
mess := msg.CliMsg{
SessionID: *sessionID,
PWD: *pwd,
}
resp = SendCliMsg(out, mess, strconv.Itoa(config.Port))
} else {
resp = searchapp.LoadHistoryFromFile(out.Logger.Sugar(), *testHistory, *testHistoryLines)
}
st := state{
// lock sync.Mutex
@ -129,46 +122,46 @@ func runReshCli(out *output.Output, config cfg.Config) (string, int) {
errMsg = "Failed to set keybindings"
if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, layout.Next); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyArrowDown, gocui.ModNone, layout.Next); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyCtrlN, gocui.ModNone, layout.Next); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyArrowUp, gocui.ModNone, layout.Prev); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyCtrlP, gocui.ModNone, layout.Prev); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyArrowRight, gocui.ModNone, layout.SelectPaste); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyEnter, gocui.ModNone, layout.SelectExecute); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyCtrlG, gocui.ModNone, layout.AbortPaste); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyCtrlD, gocui.ModNone, quit); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
if err := g.SetKeybinding("", gocui.KeyCtrlR, gocui.ModNone, layout.SwitchModes); err != nil {
out.Fatal(errMsg, err)
out.FatalE(errMsg, err)
}
layout.UpdateData(*query)
layout.UpdateRawData(*query)
err = g.MainLoop()
if err != nil && !errors.Is(err, gocui.ErrQuit) {
out.Fatal("Main application loop finished with error", err)
out.FatalE("Main application loop finished with error", err)
}
return layout.s.output, layout.s.exitCode
}
@ -393,7 +386,7 @@ func (m manager) Layout(g *gocui.Gui) error {
v, err := g.SetView("input", 0, 0, maxX-1, 2, b)
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
m.out.Fatal("Failed to set view 'input'", err)
m.out.FatalE("Failed to set view 'input'", err)
}
v.Editable = true
@ -416,7 +409,7 @@ func (m manager) Layout(g *gocui.Gui) error {
v, err = g.SetView("body", 0, 2, maxX-1, maxY, b)
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
m.out.Fatal("Failed to set view 'body'", err)
m.out.FatalE("Failed to set view 'body'", err)
}
v.Frame = false
v.Autoscroll = false
@ -579,7 +572,7 @@ func SendCliMsg(out *output.Output, m msg.CliMsg, port string) msg.CliResponse {
sugar := out.Logger.Sugar()
recJSON, err := json.Marshal(m)
if err != nil {
out.Fatal("Failed to marshal message", err)
out.FatalE("Failed to marshal message", err)
}
req, err := http.NewRequest(
@ -587,7 +580,7 @@ func SendCliMsg(out *output.Output, m msg.CliMsg, port string) msg.CliResponse {
"http://localhost:"+port+"/dump",
bytes.NewBuffer(recJSON))
if err != nil {
out.Fatal("Failed to build request", err)
out.FatalE("Failed to build request", err)
}
req.Header.Set("Content-Type", "application/json")
@ -602,13 +595,13 @@ func SendCliMsg(out *output.Output, m msg.CliMsg, port string) msg.CliResponse {
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
out.Fatal("Failed read response", err)
out.FatalE("Failed read response", err)
}
// sugar.Println(string(body))
response := msg.CliResponse{}
err = json.Unmarshal(body, &response)
if err != nil {
out.Fatal("Failed decode response", err)
out.FatalE("Failed decode response", err)
}
sugar.Debugw("Received records from daemon",
"recordCount", len(response.Records),

@ -52,12 +52,12 @@ func main() {
time, err := strconv.ParseFloat(*timeStr, 64)
if err != nil {
out.Fatal("Error while parsing flag --time", err)
out.FatalE("Error while parsing flag --time", err)
}
realPwd, err := filepath.EvalSymlinks(*pwd)
if err != nil {
out.Error("Error while evaluating symlinks in PWD", err)
out.ErrorE("Error while evaluating symlinks in PWD", err)
realPwd = ""
}

@ -0,0 +1,151 @@
package cmd
import (
"fmt"
"os"
"os/exec"
"time"
"github.com/curusarn/resh/internal/cfg"
"github.com/curusarn/resh/internal/check"
"github.com/curusarn/resh/internal/msg"
"github.com/curusarn/resh/internal/status"
"github.com/spf13/cobra"
"go.uber.org/zap"
)
func doctorCmdFunc(config cfg.Config) func(*cobra.Command, []string) {
return func(cmd *cobra.Command, args []string) {
allOK := true
if !checkDaemon(config) {
allOK = false
printDivider()
}
if !checkShellSession() {
allOK = false
printDivider()
}
if !checkShells() {
allOK = false
printDivider()
}
if allOK {
out.Info("Everything looks good.")
}
}
}
func printDivider() {
fmt.Printf("\n")
}
var msgFailedDaemonStart = `Failed to start RESH daemon.
-> Start RESH daemon manually - run: resh-daemon-start
-> Or restart this terminal window to bring RESH daemon back up
-> You can check logs: ~/.local/share/resh/log.json (or ~/$XDG_DATA_HOME/resh/log.json)
-> You can create an issue at: https://github.com/curusarn/resh/issues
`
func checkDaemon(config cfg.Config) bool {
ok := true
resp, err := status.GetDaemonStatus(config.Port)
if err != nil {
out.InfoE("RESH Daemon is not running", err)
out.Info("Attempting to start RESH daemon ...")
resp, err = startDaemon(config.Port, 5, 200*time.Millisecond)
if err != nil {
out.InfoE(msgFailedDaemonStart, err)
return false
}
ok = false
out.Info("Successfully started daemon.")
}
if version != resp.Version {
out.InfoDaemonVersionMismatch(version, resp.Version)
return false
}
return ok
}
func startDaemon(port int, maxRetries int, backoff time.Duration) (*msg.StatusResponse, error) {
err := exec.Command("resh-daemon-start").Run()
if err != nil {
return nil, err
}
var resp *msg.StatusResponse
retry := 0
for {
time.Sleep(backoff)
resp, err = status.GetDaemonStatus(port)
if err == nil {
break
}
if retry == maxRetries {
return nil, err
}
out.Logger.Error("Failed to get daemon status - retrying", zap.Error(err), zap.Int("retry", retry))
retry++
continue
}
return resp, nil
}
var msgShellFilesNotLoaded = `RESH shell files were not properly loaded in this terminal.
-> Try restarting this terminal to see if the issue persists
-> Check your shell rc files (e.g. .zshrc, .bashrc, ...)
-> You can create an issue at: https://github.com/curusarn/resh/issues
`
func checkShellSession() bool {
versionEnv, found := os.LookupEnv("__RESH_VERSION")
if !found {
out.Info(msgShellFilesNotLoaded)
return false
}
if version != versionEnv {
out.InfoTerminalVersionMismatch(version, versionEnv)
return false
}
return true
}
func checkShells() bool {
allOK := true
msg, err := check.LoginShell()
if err != nil {
out.InfoE("Failed to get login shell", err)
allOK = false
}
if msg != "" {
out.Info(msg)
allOK = false
}
msg, err = check.ZshVersion()
if err != nil {
out.InfoE("Failed to check zsh version", err)
allOK = false
}
if msg != "" {
out.Info(msg)
allOK = false
}
msg, err = check.BashVersion()
if err != nil {
out.InfoE("Failed to check bash version", err)
allOK = false
}
if msg != "" {
out.Info(msg)
allOK = false
}
return allOK
}

@ -33,7 +33,7 @@ func Execute(ver, com, development string) {
defer logger.Sync() // flushes buffer, if any
out = output.New(logger, "ERROR")
if errCfg != nil {
out.Error("Error while getting configuration", errCfg)
out.ErrorE("Error while getting configuration", errCfg)
}
var versionCmd = cobra.Command{
@ -43,10 +43,17 @@ func Execute(ver, com, development string) {
}
rootCmd.AddCommand(&versionCmd)
doctorCmd := cobra.Command{
Use: "doctor",
Short: "check common problems",
Run: doctorCmdFunc(config),
}
rootCmd.AddCommand(&doctorCmd)
updateCmd.Flags().BoolVar(&betaFlag, "beta", false, "Update to latest version even if it's beta.")
rootCmd.AddCommand(updateCmd)
if err := rootCmd.Execute(); err != nil {
out.Fatal("Command ended with error", err)
out.FatalE("Command ended with error", err)
}
}

@ -15,7 +15,7 @@ var updateCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
homeDir, err := os.UserHomeDir()
if err != nil {
out.Fatal("Could not get user home dir", err)
out.FatalE("Could not get user home dir", err)
}
rawinstallPath := filepath.Join(homeDir, ".resh/rawinstall.sh")
execArgs := []string{rawinstallPath}
@ -27,7 +27,7 @@ var updateCmd = &cobra.Command{
execCmd.Stderr = os.Stderr
err = execCmd.Run()
if err != nil {
out.Fatal("Update ended with error", err)
out.FatalE("Update ended with error", err)
}
},
}

@ -11,6 +11,7 @@ import (
func versionCmdFunc(config cfg.Config) func(*cobra.Command, []string) {
return func(cmd *cobra.Command, args []string) {
fmt.Printf("Installed: %s\n", version)
versionEnv := getEnvVarWithDefault("__RESH_VERSION", "<unknown>")
@ -18,6 +19,7 @@ func versionCmdFunc(config cfg.Config) func(*cobra.Command, []string) {
resp, err := status.GetDaemonStatus(config.Port)
if err != nil {
fmt.Printf("Running checks: %s\n", version)
out.ErrorDaemonNotRunning(err)
return
}

@ -33,7 +33,7 @@ func main() {
out := output.New(logger, "install-utils ERROR")
if len(os.Args) < 2 {
out.ErrorWOErr("ERROR: Not enough arguments\n")
out.Error("ERROR: Not enough arguments\n")
printUsage(os.Stderr)
os.Exit(1)
}
@ -52,7 +52,7 @@ func main() {
case "help":
printUsage(os.Stdout)
default:
out.ErrorWOErr(fmt.Sprintf("ERROR: Unknown command: %s\n", command))
out.Error(fmt.Sprintf("ERROR: Unknown command: %s\n", command))
printUsage(os.Stderr)
os.Exit(1)
}

@ -15,11 +15,11 @@ import (
func migrateConfig(out *output.Output) {
err := cfg.Touch()
if err != nil {
out.Fatal("ERROR: Failed to touch config file", err)
out.FatalE("ERROR: Failed to touch config file", err)
}
changes, err := cfg.Migrate()
if err != nil {
out.Fatal("ERROR: Failed to update config file", err)
out.FatalE("ERROR: Failed to update config file", err)
}
if changes {
out.Info("RESH config file format has changed since last update - your config was updated to reflect the changes.")
@ -36,14 +36,14 @@ func migrateHistory(out *output.Output) {
func migrateHistoryLocation(out *output.Output) {
dataDir, err := datadir.MakePath()
if err != nil {
out.Fatal("ERROR: Failed to get data directory", err)
out.FatalE("ERROR: Failed to get data directory", err)
}
// TODO: de-hardcode this
historyPath := path.Join(dataDir, "resh/history.reshjson")
exists, err := futil.FileExists(historyPath)
if err != nil {
out.Fatal("ERROR: Failed to check history file", err)
out.FatalE("ERROR: Failed to check history file", err)
}
if exists {
out.Info(fmt.Sprintf("Found history file in '%s'", historyPath))
@ -52,7 +52,7 @@ func migrateHistoryLocation(out *output.Output) {
homeDir, err := os.UserHomeDir()
if err != nil {
out.Fatal("ERROR: Failed to get user home directory", err)
out.FatalE("ERROR: Failed to get user home directory", err)
}
legacyHistoryPaths := []string{
@ -62,13 +62,13 @@ func migrateHistoryLocation(out *output.Output) {
for _, path := range legacyHistoryPaths {
exists, err = futil.FileExists(path)
if err != nil {
out.Fatal("ERROR: Failed to check legacy history file", err)
out.FatalE("ERROR: Failed to check legacy history file", err)
}
if exists {
out.Info(fmt.Sprintf("Copying history file to new location: '%s' -> '%s' ...", path, historyPath))
err = futil.CopyFile(path, historyPath)
if err != nil {
out.Fatal("ERROR: Failed to copy history file", err)
out.FatalE("ERROR: Failed to copy history file", err)
}
out.Info("History file copied successfully")
return
@ -79,7 +79,7 @@ func migrateHistoryLocation(out *output.Output) {
func migrateHistoryFormat(out *output.Output) {
dataDir, err := datadir.MakePath()
if err != nil {
out.Fatal("ERROR: Could not get user data directory", err)
out.FatalE("ERROR: Could not get user data directory", err)
}
// TODO: de-hardcode this
historyPath := path.Join(dataDir, "history.reshjson")
@ -87,35 +87,35 @@ func migrateHistoryFormat(out *output.Output) {
exists, err := futil.FileExists(historyPath)
if err != nil {
out.Fatal("ERROR: Failed to check existence of history file", err)
out.FatalE("ERROR: Failed to check existence of history file", err)
}
if !exists {
out.ErrorWOErr("There is no history file - this is normal if you are installing RESH for the first time on this device")
out.Error("There is no history file - this is normal if you are installing RESH for the first time on this device")
err = futil.TouchFile(historyPath)
if err != nil {
out.Fatal("ERROR: Failed to touch history file", err)
out.FatalE("ERROR: Failed to touch history file", err)
}
os.Exit(0)
}
err = futil.CopyFile(historyPath, historyPathBak)
if err != nil {
out.Fatal("ERROR: Could not back up history file", err)
out.FatalE("ERROR: Could not back up history file", err)
}
rio := recio.New(out.Logger.Sugar())
recs, err := rio.ReadAndFixFile(historyPath, 3)
if err != nil {
out.Fatal("ERROR: Could not load history file", err)
out.FatalE("ERROR: Could not load history file", err)
}
err = rio.OverwriteFile(historyPath, recs)
if err != nil {
out.Error("ERROR: Could not update format of history file", err)
out.ErrorE("ERROR: Could not update format of history file", err)
err = futil.CopyFile(historyPathBak, historyPath)
if err != nil {
out.Fatal("ERROR: Could not restore history file from backup!", err)
out.FatalE("ERROR: Could not restore history file from backup!", err)
// TODO: history restoration tutorial
}
out.Info("History file was restored to the original form")

@ -47,11 +47,11 @@ func main() {
timeAfter, err := strconv.ParseFloat(*rta, 64)
if err != nil {
out.Fatal("Error while parsing flag --time-after", err)
out.FatalE("Error while parsing flag --time-after", err)
}
timeBefore, err := strconv.ParseFloat(*rtb, 64)
if err != nil {
out.Fatal("Error while parsing flag --time-before", err)
out.FatalE("Error while parsing flag --time-before", err)
}
duration := timeAfter - timeBefore

@ -0,0 +1,90 @@
package check
import (
"fmt"
"os"
"os/exec"
"strconv"
"strings"
)
func LoginShell() (string, error) {
shellPath, found := os.LookupEnv("SHELL")
if !found {
return "", fmt.Errorf("env variable $SHELL is not set")
}
parts := strings.Split(shellPath, "/")
shell := parts[len(parts)-1]
if shell != "bash" && shell != "zsh" {
return fmt.Sprintf("Current shell (%s) is unsupported\n", shell), nil
}
return "", nil
}
func msgShellVersion(shell, expectedVer, actualVer string) string {
return fmt.Sprintf(`Minimal supported %s version is %s. You have %s.
-> Update your %s if you want to use RESH with it.
`, shell, expectedVer, actualVer, shell)
}
func BashVersion() (string, error) {
out, err := exec.Command("bash", "-c", "echo $BASH_VERSION").Output()
if err != nil {
return "", fmt.Errorf("command failed: %w", err)
}
verStr := strings.TrimSuffix(string(out), "\n")
ver, err := parseVersion(verStr)
if err != nil {
return "", fmt.Errorf("failed to parse version: %w", err)
}
if ver.Major < 4 || (ver.Major == 4 && ver.Minor < 3) {
return msgShellVersion("bash", "4.3", verStr), nil
}
return "", nil
}
func ZshVersion() (string, error) {
out, err := exec.Command("zsh", "-c", "echo $ZSH_VERSION").Output()
if err != nil {
return "", fmt.Errorf("command failed: %w", err)
}
verStr := strings.TrimSuffix(string(out), "\n")
ver, err := parseVersion(string(out))
if err != nil {
return "", fmt.Errorf("failed to parse version: %w", err)
}
if ver.Major < 5 {
return msgShellVersion("zsh", "5.0", verStr), nil
}
return "", nil
}
type version struct {
Major int
Minor int
Rest string
}
func parseVersion(str string) (version, error) {
parts := strings.SplitN(str, ".", 3)
if len(parts) < 3 {
return version{}, fmt.Errorf("not enough parts")
}
major, err := strconv.Atoi(parts[0])
if err != nil {
return version{}, fmt.Errorf("failed to parse major version: %w", err)
}
minor, err := strconv.Atoi(parts[1])
if err != nil {
return version{}, fmt.Errorf("failed to parse minor version: %w", err)
}
ver := version{
Major: major,
Minor: minor,
Rest: parts[2],
}
return ver, nil
}

@ -23,13 +23,13 @@ func SendRecord(out *output.Output, r recordint.Collect, port, path string) {
)
recJSON, err := json.Marshal(r)
if err != nil {
out.Fatal("Error while encoding record", err)
out.FatalE("Error while encoding record", err)
}
req, err := http.NewRequest("POST", "http://localhost:"+port+path,
bytes.NewBuffer(recJSON))
if err != nil {
out.Fatal("Error while sending record", err)
out.FatalE("Error while sending record", err)
}
req.Header.Set("Content-Type", "application/json")
@ -50,13 +50,13 @@ func SendSessionInit(out *output.Output, r recordint.SessionInit, port string) {
)
recJSON, err := json.Marshal(r)
if err != nil {
out.Fatal("Error while encoding record", err)
out.FatalE("Error while encoding record", err)
}
req, err := http.NewRequest("POST", "http://localhost:"+port+"/session_init",
bytes.NewBuffer(recJSON))
if err != nil {
out.Fatal("Error while sending record", err)
out.FatalE("Error while sending record", err)
}
req.Header.Set("Content-Type", "application/json")

@ -2,6 +2,7 @@
package device
import (
"bufio"
"fmt"
"os"
"path"
@ -127,12 +128,16 @@ func promptForName(out *output.Output, fpath string) (string, error) {
hostStub := strings.Split(host, ".")[0]
fmt.Printf("\nPlease choose a short name for this device (default: '%s'): ", hostStub)
var input string
n, err := fmt.Scanln(&input)
if n != 1 {
return "", fmt.Errorf("expected 1 value from prompt got %d", n)
scanner := bufio.NewScanner(os.Stdin)
if scanner.Scan() {
input = scanner.Text()
}
if err != nil {
return "", fmt.Errorf("scanln error: %w", err)
if err = scanner.Err(); err != nil {
return "", fmt.Errorf("scanner error: %w", err)
}
if input == "" {
out.Info("Got no input - using default ...")
input = hostStub
}
out.Info(fmt.Sprintf("Device name set to '%s'", input))
fmt.Printf("You can change the device name at any time by editing '%s' file\n", fpath)

@ -21,48 +21,72 @@ func New(logger *zap.Logger, prefix string) *Output {
}
}
// Info outputs string to stdout and to log (as info)
// This is how we write output to users from interactive commands
// This way we have full record in logs
func (f *Output) Info(msg string) {
fmt.Printf("%s\n", msg)
f.Logger.Info(msg)
}
func (f *Output) Error(msg string, err error) {
fmt.Fprintf(os.Stderr, "%s: %s: %v\n", f.ErrPrefix, msg, err)
// InfoE outputs string to stdout and to log (as error)
// Passed error is only written to log
// This is how we output errors to users from interactive commands
// This way we have errors in logs
func (f *Output) InfoE(msg string, err error) {
fmt.Printf("%s\n", msg)
f.Logger.Error(msg, zap.Error(err))
}
func (f *Output) ErrorWOErr(msg string) {
// Error outputs string to stderr and to log (as error)
// This is how we output errors from non-interactive commands
func (f *Output) Error(msg string) {
fmt.Fprintf(os.Stderr, "%s: %s\n", f.ErrPrefix, msg)
f.Logger.Error(msg)
}
func (f *Output) Fatal(msg string, err error) {
// ErrorE outputs string and error to stderr and to log (as error)
// This is how we output errors from non-interactive commands
func (f *Output) ErrorE(msg string, err error) {
fmt.Fprintf(os.Stderr, "%s: %s: %v\n", f.ErrPrefix, msg, err)
f.Logger.Error(msg, zap.Error(err))
}
// FatalE outputs string and error to stderr and to log (as fatal)
// This is how we raise fatal errors from non-interactive commands
func (f *Output) FatalE(msg string, err error) {
fmt.Fprintf(os.Stderr, "%s: %s: %v\n", f.ErrPrefix, msg, err)
f.Logger.Fatal(msg, zap.Error(err))
}
var msgDaemonNotRunning = `Resh-daemon didn't respond - it's probably not running.
var msgDaemonNotRunning = `RESH daemon didn't respond - it's probably not running.
-> Try restarting this terminal window to bring resh-daemon back up
-> If the problem persists you can check resh-daemon logs: ~/.local/share/resh/log.json (or ~/$XDG_DATA_HOME/resh/log.json)
-> Start RESH daemon manually - run: resh-daemon-start
-> Or restart this terminal window to bring RESH daemon back up
-> You can check logs: ~/.local/share/resh/log.json (or ~/$XDG_DATA_HOME/resh/log.json)
-> You can create an issue at: https://github.com/curusarn/resh/issues
`
var msgTerminalVersionMismatch = `This terminal session was started with different resh version than is installed now.
It looks like you updated resh and didn't restart this terminal.
var msgTerminalVersionMismatch = `This terminal session was started with different RESH version than is installed now.
It looks like you updated RESH and didn't restart this terminal.
-> Restart this terminal window to fix that
`
var msgDaemonVersionMismatch = `Resh-daemon is running in different version than is installed now.
It looks like something went wrong during resh update.
var msgDaemonVersionMismatch = `RESH daemon is running in different version than is installed now.
It looks like something went wrong during RESH update.
-> Kill resh-daemon and then launch a new terminal window to fix that: pkill resh-daemon
-> Kill resh-daemon and then launch a new terminal window to fix that: killall resh-daemon
-> You can create an issue at: https://github.com/curusarn/resh/issues
`
func (f *Output) InfoDaemonNotRunning(err error) {
fmt.Printf("%s", msgDaemonNotRunning)
f.Logger.Error("Daemon is not running", zap.Error(err))
}
func (f *Output) ErrorDaemonNotRunning(err error) {
fmt.Fprintf(os.Stderr, "%s: %s", f.ErrPrefix, msgDaemonNotRunning)
f.Logger.Error("Daemon is not running", zap.Error(err))
@ -73,6 +97,14 @@ func (f *Output) FatalDaemonNotRunning(err error) {
f.Logger.Fatal("Daemon is not running", zap.Error(err))
}
func (f *Output) InfoTerminalVersionMismatch(installedVer, terminalVer string) {
fmt.Printf("%s(installed version: %s, this terminal version: %s)\n\n",
msgTerminalVersionMismatch, installedVer, terminalVer)
f.Logger.Fatal("Version mismatch",
zap.String("installed", installedVer),
zap.String("terminal", terminalVer))
}
func (f *Output) ErrorTerminalVersionMismatch(installedVer, terminalVer string) {
fmt.Fprintf(os.Stderr, "%s: %s(installed version: %s, this terminal version: %s)\n\n",
f.ErrPrefix, msgTerminalVersionMismatch, installedVer, terminalVer)
@ -89,6 +121,14 @@ func (f *Output) FatalTerminalVersionMismatch(installedVer, terminalVer string)
zap.String("terminal", terminalVer))
}
func (f *Output) InfoDaemonVersionMismatch(installedVer, daemonVer string) {
fmt.Printf("%s(installed version: %s, running daemon version: %s)\n\n",
msgDaemonVersionMismatch, installedVer, daemonVer)
f.Logger.Error("Version mismatch",
zap.String("installed", installedVer),
zap.String("daemon", daemonVer))
}
func (f *Output) ErrorDaemonVersionMismatch(installedVer, daemonVer string) {
fmt.Fprintf(os.Stderr, "%s: %s(installed version: %s, running daemon version: %s)\n\n",
f.ErrPrefix, msgDaemonVersionMismatch, installedVer, daemonVer)

@ -115,10 +115,10 @@ failed_to_kill() {
}
if [ -f "$pid_file" ]; then
kill -SIGKILL "$pid_file" || failed_to_kill
kill -SIGTERM "$pid_file" || failed_to_kill
rm "$pid_file"
else
pkill -SIGKILL "resh-daemon" || failed_to_kill
killall -SIGTERM resh-daemon || failed_to_kill
fi
echo "Creating/updating config file ..."
@ -152,6 +152,9 @@ fi
echo "Launching resh daemon ..."
~/.resh/bin/resh-daemon-start
# FIXME: Figure out how to give people enough time to read everything
# sleep 1
info="---- Scroll down using arrow keys ----
#####################################
# ____ _____ ____ _ _ #
@ -188,6 +191,7 @@ ISSUES & FEEDBACK
Please report issues to: https://github.com/curusarn/resh/issues
Feedback and suggestions are very welcome!
"
# Show banner if RESH is not loaded in the terminal
if [ -z "${__RESH_VERSION:-}" ]; then info="$info
##############################################################
# #
@ -206,6 +210,7 @@ echo "Thank you for using RESH"
echo "Report issues here: https://github.com/curusarn/resh/issues"
echo "Ctrl+R launches the RESH SEARCH app"
# Show banner if RESH is not loaded in the terminal
if [ -z "${__RESH_VERSION:-}" ]; then printf "
##############################################################
# #

Loading…
Cancel
Save