Simplify shell hooks

Simplify reloading of shell files and make it more robust
Switch to proper GNU options
Don't expose revision anywhere. Keep it in binaries. Keep -revision option.
Drop revision from 'reshctl version'
Simplify shell hooks code
Don't instruct users to restart terminals - reloading should handle it fine now
Add clean_build to makefile
pull/184/head
Simon Let 3 years ago
parent 682b9599e8
commit 9b0c8b3149
  1. 14
      Makefile
  2. 67
      cmd/collect/main.go
  3. 11
      cmd/control/cmd/version.go
  4. 50
      cmd/postcollect/main.go
  5. 33
      cmd/session-init/main.go
  6. 2
      go.mod
  7. 35
      internal/opt/opt.go
  8. 14
      internal/output/output.go
  9. 4
      internal/signalhandler/signalhander.go
  10. 155
      scripts/hooks.sh
  11. 16
      scripts/install.sh
  12. 2
      scripts/reshctl.sh
  13. 14
      scripts/shellrc.sh

@ -1,19 +1,25 @@
SHELL=/bin/bash SHELL=/bin/bash
LATEST_TAG=$(shell git describe --tags) LATEST_TAG=$(shell git describe --tags)
COMMIT=$(shell [ -z "$(git status --untracked-files=no --porcelain)" ] && git rev-parse --short=12 HEAD || echo "no_commit") VERSION:="${LATEST_TAG}-$(shell date +%s)"
VERSION="${LATEST_TAG}-DEV" COMMIT:=$(shell [ -z "$(git status --untracked-files=no --porcelain)" ] && git rev-parse --short=12 HEAD || echo "no_commit")
GOFLAGS=-ldflags "-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.development=true" GOFLAGS=-ldflags "-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.development=true"
build: submodules bin/resh-session-init bin/resh-collect bin/resh-postcollect\ build: submodules bin/resh-session-init bin/resh-collect bin/resh-postcollect\
bin/resh-daemon bin/resh-control bin/resh-config bin/resh-cli\ bin/resh-daemon bin/resh-control bin/resh-config bin/resh-cli\
bin/resh-install-utils bin/resh-generate-uuid bin/resh-get-epochtime bin/resh-install-utils bin/resh-generate-uuid bin/resh-get-epochtime
# we disable jobserver for the actual installation because we want it to run serially # We disable jobserver for the actual installation because we want it to run serially
# Make waits to the daemon process we launch during install and hangs # Make waits to the daemon process we launch during install and hangs
install: build install: build
make -j1 _install make -j1 _install
# Rebuild binaries and install
# Very useful to ensure that all binaries get new VERSION variable which is used for shell config reloading
clean_install:
make clean
make build
make -j1 _install
_install: _install:
scripts/install.sh scripts/install.sh

@ -1,20 +1,19 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"os" "os"
"github.com/curusarn/resh/internal/cfg" "github.com/curusarn/resh/internal/cfg"
"github.com/curusarn/resh/internal/collect" "github.com/curusarn/resh/internal/collect"
"github.com/curusarn/resh/internal/logger" "github.com/curusarn/resh/internal/logger"
"github.com/curusarn/resh/internal/opt"
"github.com/curusarn/resh/internal/output" "github.com/curusarn/resh/internal/output"
"github.com/curusarn/resh/internal/recordint" "github.com/curusarn/resh/internal/recordint"
"github.com/curusarn/resh/record" "github.com/curusarn/resh/record"
"github.com/spf13/pflag"
"go.uber.org/zap" "go.uber.org/zap"
// "os/exec"
"path/filepath" "path/filepath"
"strconv" "strconv"
) )
@ -36,57 +35,29 @@ func main() {
} }
out := output.New(logger, "resh-collect ERROR") out := output.New(logger, "resh-collect ERROR")
// version args := opt.HandleVersionOpts(out, os.Args, version, commit)
showVersion := flag.Bool("version", false, "Show version and exit")
showRevision := flag.Bool("revision", false, "Show git revision and exit") flags := pflag.NewFlagSet("", pflag.ExitOnError)
cmdLine := flags.String("cmd-line", "", "Command line")
requireVersion := flag.String("requireVersion", "", "abort if version doesn't match") gitRemote := flags.String("git-remote", "", "> git remote get-url origin")
requireRevision := flag.String("requireRevision", "", "abort if revision doesn't match") home := flags.String("home", "", "$HOME")
pwd := flags.String("pwd", "", "$PWD - present working directory")
// core recordID := flags.String("record-id", "", "Resh generated record ID")
cmdLine := flag.String("cmdLine", "", "command line") sessionID := flags.String("session-id", "", "Resh generated session ID")
sessionPID := flags.Int("session-pid", -1, "$$ - Shell session PID")
home := flag.String("home", "", "$HOME") shell := flags.String("shell", "", "Current shell")
pwd := flag.String("pwd", "", "$PWD - present working directory") shlvl := flags.Int("shlvl", -1, "$SHLVL")
timeStr := flags.String("time", "-1", "$EPOCHREALTIME")
sessionID := flag.String("sessionID", "", "resh generated session ID") flags.Parse(args)
recordID := flag.String("recordID", "", "resh generated record ID")
sessionPID := flag.Int("sessionPID", -1, "PID at the start of the terminal session") time, err := strconv.ParseFloat(*timeStr, 64)
shell := flag.String("shell", "", "current shell")
// non-posix
shlvl := flag.Int("shlvl", -1, "$SHLVL")
gitRemote := flag.String("gitRemote", "", "git remote get-url origin")
time_ := flag.String("time", "-1", "$EPOCHREALTIME")
flag.Parse()
if *showVersion == true {
fmt.Println(version)
os.Exit(0)
}
if *showRevision == true {
fmt.Println(commit)
os.Exit(0)
}
if *requireVersion != "" && *requireVersion != version {
out.FatalTerminalVersionMismatch(version, *requireVersion)
}
if *requireRevision != "" && *requireRevision != commit {
// this is only relevant for dev versions so we can reuse FatalVersionMismatch()
out.FatalTerminalVersionMismatch("revision "+commit, "revision "+*requireVersion)
}
time, err := strconv.ParseFloat(*time_, 64)
if err != nil { if err != nil {
out.Fatal("Error while parsing flag --time", err) out.Fatal("Error while parsing flag --time", err)
} }
realPwd, err := filepath.EvalSymlinks(*pwd) realPwd, err := filepath.EvalSymlinks(*pwd)
if err != nil { if err != nil {
logger.Error("Error while handling pwd realpath", zap.Error(err)) out.Error("Error while evaluating symlinks in PWD", err)
realPwd = "" realPwd = ""
} }

@ -11,18 +11,17 @@ import (
func versionCmdFunc(config cfg.Config) func(*cobra.Command, []string) { func versionCmdFunc(config cfg.Config) func(*cobra.Command, []string) {
return func(cmd *cobra.Command, args []string) { return func(cmd *cobra.Command, args []string) {
printVersion("Installed", version, commit) fmt.Printf("Installed: %s\n", version)
versionEnv := getEnvVarWithDefault("__RESH_VERSION", "<unknown>") versionEnv := getEnvVarWithDefault("__RESH_VERSION", "<unknown>")
commitEnv := getEnvVarWithDefault("__RESH_REVISION", "<unknown>") fmt.Printf("This terminal session: %s\n", version)
printVersion("This terminal session", versionEnv, commitEnv)
resp, err := status.GetDaemonStatus(config.Port) resp, err := status.GetDaemonStatus(config.Port)
if err != nil { if err != nil {
out.ErrorDaemonNotRunning(err) out.ErrorDaemonNotRunning(err)
return return
} }
printVersion("Currently running daemon", resp.Version, resp.Commit) fmt.Printf("Currently running daemon: %s\n", resp.Version)
if version != resp.Version { if version != resp.Version {
out.ErrorDaemonVersionMismatch(version, resp.Version) out.ErrorDaemonVersionMismatch(version, resp.Version)
@ -35,10 +34,6 @@ func versionCmdFunc(config cfg.Config) func(*cobra.Command, []string) {
} }
} }
func printVersion(title, version, commit string) {
fmt.Printf("%s: %s (commit: %s)\n", title, version, commit)
}
func getEnvVarWithDefault(varName, defaultValue string) string { func getEnvVarWithDefault(varName, defaultValue string) string {
val, found := os.LookupEnv(varName) val, found := os.LookupEnv(varName)
if !found { if !found {

@ -1,20 +1,19 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"os" "os"
"github.com/curusarn/resh/internal/cfg" "github.com/curusarn/resh/internal/cfg"
"github.com/curusarn/resh/internal/collect" "github.com/curusarn/resh/internal/collect"
"github.com/curusarn/resh/internal/logger" "github.com/curusarn/resh/internal/logger"
"github.com/curusarn/resh/internal/opt"
"github.com/curusarn/resh/internal/output" "github.com/curusarn/resh/internal/output"
"github.com/curusarn/resh/internal/recordint" "github.com/curusarn/resh/internal/recordint"
"github.com/curusarn/resh/record" "github.com/curusarn/resh/record"
"github.com/spf13/pflag"
"go.uber.org/zap" "go.uber.org/zap"
// "os/exec"
"strconv" "strconv"
) )
@ -35,49 +34,28 @@ func main() {
} }
out := output.New(logger, "resh-postcollect ERROR") out := output.New(logger, "resh-postcollect ERROR")
showVersion := flag.Bool("version", false, "Show version and exit") args := opt.HandleVersionOpts(out, os.Args, version, commit)
showRevision := flag.Bool("revision", false, "Show git revision and exit")
requireVersion := flag.String("requireVersion", "", "abort if version doesn't match")
requireRevision := flag.String("requireRevision", "", "abort if revision doesn't match")
exitCode := flag.Int("exitCode", -1, "exit code")
sessionID := flag.String("sessionID", "", "resh generated session id")
recordID := flag.String("recordID", "", "resh generated record id")
shlvl := flag.Int("shlvl", -1, "$SHLVL")
rtb := flag.String("timeBefore", "-1", "before $EPOCHREALTIME")
rta := flag.String("timeAfter", "-1", "after $EPOCHREALTIME")
flag.Parse()
if *showVersion == true { flags := pflag.NewFlagSet("", pflag.ExitOnError)
fmt.Println(version) exitCode := flags.Int("exit-code", -1, "Exit code")
os.Exit(0) sessionID := flags.String("session-id", "", "Resh generated session ID")
} recordID := flags.String("record-id", "", "Resh generated record ID")
if *showRevision == true { shlvl := flags.Int("shlvl", -1, "$SHLVL")
fmt.Println(commit) rtb := flags.String("time-before", "-1", "Before $EPOCHREALTIME")
os.Exit(0) rta := flags.String("time-after", "-1", "After $EPOCHREALTIME")
} flags.Parse(args)
if *requireVersion != "" && *requireVersion != version {
out.FatalTerminalVersionMismatch(version, *requireVersion)
}
if *requireRevision != "" && *requireRevision != commit {
// this is only relevant for dev versions so we can reuse FatalVersionMismatch()
out.FatalTerminalVersionMismatch("revision "+commit, "revision "+*requireVersion)
}
timeAfter, err := strconv.ParseFloat(*rta, 64) timeAfter, err := strconv.ParseFloat(*rta, 64)
if err != nil { if err != nil {
out.Fatal("Error while parsing flag --timeAfter", err) out.Fatal("Error while parsing flag --time-after", err)
} }
timeBefore, err := strconv.ParseFloat(*rtb, 64) timeBefore, err := strconv.ParseFloat(*rtb, 64)
if err != nil { if err != nil {
out.Fatal("Error while parsing flag --timeBefore", err) out.Fatal("Error while parsing flag --time-before", err)
} }
duration := timeAfter - timeBefore duration := timeAfter - timeBefore
// FIXME: use recordint.Postollect // FIXME: use recordint.Postcollect
rec := recordint.Collect{ rec := recordint.Collect{
SessionID: *sessionID, SessionID: *sessionID,
Shlvl: *shlvl, Shlvl: *shlvl,

@ -1,15 +1,16 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"os" "os"
"github.com/curusarn/resh/internal/cfg" "github.com/curusarn/resh/internal/cfg"
"github.com/curusarn/resh/internal/collect" "github.com/curusarn/resh/internal/collect"
"github.com/curusarn/resh/internal/logger" "github.com/curusarn/resh/internal/logger"
"github.com/curusarn/resh/internal/opt"
"github.com/curusarn/resh/internal/output" "github.com/curusarn/resh/internal/output"
"github.com/curusarn/resh/internal/recordint" "github.com/curusarn/resh/internal/recordint"
"github.com/spf13/pflag"
"go.uber.org/zap" "go.uber.org/zap"
"strconv" "strconv"
@ -32,32 +33,12 @@ func main() {
} }
out := output.New(logger, "resh-collect ERROR") out := output.New(logger, "resh-collect ERROR")
showVersion := flag.Bool("version", false, "Show version and exit") args := opt.HandleVersionOpts(out, os.Args, version, commit)
showRevision := flag.Bool("revision", false, "Show git revision and exit")
requireVersion := flag.String("requireVersion", "", "abort if version doesn't match") flags := pflag.NewFlagSet("", pflag.ExitOnError)
requireRevision := flag.String("requireRevision", "", "abort if revision doesn't match") sessionID := flags.String("session-id", "", "Resh generated session ID")
sessionPID := flags.Int("session-pid", -1, "$$ - Shell session PID")
sessionID := flag.String("sessionId", "", "resh generated session id") flags.Parse(args)
sessionPID := flag.Int("sessionPid", -1, "$$ at session start")
flag.Parse()
if *showVersion == true {
fmt.Println(version)
os.Exit(0)
}
if *showRevision == true {
fmt.Println(commit)
os.Exit(0)
}
if *requireVersion != "" && *requireVersion != version {
out.FatalTerminalVersionMismatch(version, *requireVersion)
}
if *requireRevision != "" && *requireRevision != commit {
// this is only relevant for dev versions so we can reuse FatalVersionMismatch()
out.FatalTerminalVersionMismatch("revision "+commit, "revision "+*requireVersion)
}
rec := recordint.SessionInit{ rec := recordint.SessionInit{
SessionID: *sessionID, SessionID: *sessionID,

@ -9,6 +9,7 @@ require (
github.com/mattn/go-isatty v0.0.3 github.com/mattn/go-isatty v0.0.3
github.com/mitchellh/go-ps v1.0.0 github.com/mitchellh/go-ps v1.0.0
github.com/spf13/cobra v1.2.1 github.com/spf13/cobra v1.2.1
github.com/spf13/pflag v1.0.5
github.com/whilp/git-urls v1.0.0 github.com/whilp/git-urls v1.0.0
go.uber.org/zap v1.21.0 go.uber.org/zap v1.21.0
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6
@ -21,7 +22,6 @@ require (
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.uber.org/atomic v1.7.0 // indirect go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect go.uber.org/multierr v1.6.0 // indirect
golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect

@ -0,0 +1,35 @@
package opt
import (
"os"
"github.com/curusarn/resh/internal/output"
)
// HandleVersionOpts reads the first option and handles it
// This is a helper for resh-{collect,postcollect,session-init} commands
func HandleVersionOpts(out *output.Output, args []string, version, commit string) []string {
if len(os.Args) == 0 {
return os.Args[1:]
}
// We use go-like options because of backwards compatibility.
// Not ideal but we should support them because they have worked once
// and adding "more correct" variants would mean supporting more variants.
switch os.Args[1] {
case "-version":
out.Info(version)
os.Exit(0)
case "-revision":
out.Info(commit)
os.Exit(0)
case "-requireVersion":
if len(os.Args) < 3 {
out.FatalTerminalVersionMismatch(version, "")
}
if os.Args[2] != version {
out.FatalTerminalVersionMismatch(version, os.Args[2])
}
return os.Args[3:]
}
return os.Args[1:]
}

@ -48,7 +48,7 @@ var msgDaemonNotRunning = `Resh-daemon didn't respond - it's probably not runnin
-> You can create an issue at: https://github.com/curusarn/resh/issues -> You can create an issue at: https://github.com/curusarn/resh/issues
` `
var msgVersionMismatch = `This terminal session was started with different resh version than is installed now. 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. It looks like you updated resh and didn't restart this terminal.
-> Restart this terminal window to fix that -> Restart this terminal window to fix that
@ -74,23 +74,23 @@ func (f *Output) FatalDaemonNotRunning(err error) {
} }
func (f *Output) ErrorTerminalVersionMismatch(installedVer, terminalVer string) { func (f *Output) ErrorTerminalVersionMismatch(installedVer, terminalVer string) {
fmt.Fprintf(os.Stderr, "%s: %s\n\n(installed version: %s, this terminal version: %s)", fmt.Fprintf(os.Stderr, "%s: %s(installed version: %s, this terminal version: %s)\n\n",
f.ErrPrefix, msgVersionMismatch, installedVer, terminalVer) f.ErrPrefix, msgTerminalVersionMismatch, installedVer, terminalVer)
f.Logger.Fatal("Version mismatch", f.Logger.Fatal("Version mismatch",
zap.String("installed", installedVer), zap.String("installed", installedVer),
zap.String("terminal", terminalVer)) zap.String("terminal", terminalVer))
} }
func (f *Output) FatalTerminalVersionMismatch(installedVer, terminalVer string) { func (f *Output) FatalTerminalVersionMismatch(installedVer, terminalVer string) {
fmt.Fprintf(os.Stderr, "%s: %s\n(installed version: %s, this terminal version: %s)\n", fmt.Fprintf(os.Stderr, "%s: %s(installed version: %s, this terminal version: %s)\n\n",
f.ErrPrefix, msgVersionMismatch, installedVer, terminalVer) f.ErrPrefix, msgTerminalVersionMismatch, installedVer, terminalVer)
f.Logger.Fatal("Version mismatch", f.Logger.Fatal("Version mismatch",
zap.String("installed", installedVer), zap.String("installed", installedVer),
zap.String("terminal", terminalVer)) zap.String("terminal", terminalVer))
} }
func (f *Output) ErrorDaemonVersionMismatch(installedVer, daemonVer string) { func (f *Output) ErrorDaemonVersionMismatch(installedVer, daemonVer string) {
fmt.Fprintf(os.Stderr, "%s: %s\n(installed version: %s, running daemon version: %s)\n", fmt.Fprintf(os.Stderr, "%s: %s(installed version: %s, running daemon version: %s)\n\n",
f.ErrPrefix, msgDaemonVersionMismatch, installedVer, daemonVer) f.ErrPrefix, msgDaemonVersionMismatch, installedVer, daemonVer)
f.Logger.Error("Version mismatch", f.Logger.Error("Version mismatch",
zap.String("installed", installedVer), zap.String("installed", installedVer),
@ -98,7 +98,7 @@ func (f *Output) ErrorDaemonVersionMismatch(installedVer, daemonVer string) {
} }
func (f *Output) FatalDaemonVersionMismatch(installedVer, daemonVer string) { func (f *Output) FatalDaemonVersionMismatch(installedVer, daemonVer string) {
fmt.Fprintf(os.Stderr, "%s: %s\n(installed version: %s, running daemon version: %s)\n", fmt.Fprintf(os.Stderr, "%s: %s(installed version: %s, running daemon version: %s)\n\n",
f.ErrPrefix, msgDaemonVersionMismatch, installedVer, daemonVer) f.ErrPrefix, msgDaemonVersionMismatch, installedVer, daemonVer)
f.Logger.Fatal("Version mismatch", f.Logger.Fatal("Version mismatch",
zap.String("installed", installedVer), zap.String("installed", installedVer),

@ -34,7 +34,7 @@ func sendSignals(sugar *zap.SugaredLogger, sig os.Signal, subscribers []chan os.
time.Sleep(delay) time.Sleep(delay)
} }
if time.Since(start) > timeout { if time.Since(start) > timeout {
sugar.Errorw("Timouted while waiting for proper shutdown", sugar.Errorw("Timeouted while waiting for proper shutdown",
"componentsStillUp", strconv.Itoa(chanCount), "componentsStillUp", strconv.Itoa(chanCount),
"timeout", timeout.String(), "timeout", timeout.String(),
) )
@ -48,7 +48,7 @@ func Run(sugar *zap.SugaredLogger, subscribers []chan os.Signal, done chan strin
sugar = sugar.With("module", "signalhandler") sugar = sugar.With("module", "signalhandler")
signals := make(chan os.Signal, 1) signals := make(chan os.Signal, 1)
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
var sig os.Signal var sig os.Signal
for { for {

@ -1,87 +1,106 @@
#!/hint/sh #!/hint/sh
__resh_maybe_reload() { __resh_reload_shellrc() {
if [ "$__RESH_VERSION" != "$(resh-collect -version)" ]; then source ~/.resh/shellrc
# shellcheck source=shellrc.sh printf '\n'
source ~/.resh/shellrc printf '+--------------------------------------------------------------+\n'
local version="$(resh-collect -version)" printf '| New version of RESH shell files was loaded in this terminal. |\n'
if [ "$__RESH_VERSION" != "$version" ]; then printf '| This is an informative message - no action is necessary. |\n'
# this should not happen printf '| Please restart this terminal if you encounter any issues. |\n'
echo "RESH WARNING: You probably just updated RESH - PLEASE RESTART OR RELOAD THIS TERMINAL SESSION (resh version: $version); resh version of this terminal session: ${__RESH_VERSION})" printf '+--------------------------------------------------------------+\n'
return 1 printf '\n'
else
echo "RESH INFO: New RESH shellrc script was loaded - if you encounter any issues please restart this terminal session."
fi
fi
return 0
} }
__resh_reset_variables() { # BACKWARDS COMPATIBILITY NOTES:
__RESH_RECORD_ID=$(resh-generate-uuid) #
} # Stable names and options:
# * `resh-collect -version` / `resh-postcollect -version` is used to detect version mismatch.
# => The go-like/short `-version` option needs to exist for new resh-(post)collect commands in all future version.
# => Prefer using go-like/short `-version` option so that we don't have more options to support indefinitely.
# * `__resh_preexec <CMDLINE>` with `__RESH_NO_RELOAD=1` is called on version mismatch.
# => The `__resh_preexec` function needs to exist in all future versions.
# => Make sure that `__RESH_NO_RELOAD` behavior is not broken in any future version.
# => Prefer only testing `__RESH_NO_RELOAD` for emptyness instead of specific value
# Other:
# - Return status code of `resh-collect` and `resh-postcollect` commands from `__resh_preexec` and `__resh_precmd` respectively.
# - Even nested calls of `__resh_preexec` should propagate the status.
# (pre)collect
# Backwards compatibilty: Please see notes above before making any changes here.
__resh_preexec() { __resh_preexec() {
# core # $1 is command line
__RESH_COLLECT=1 # $2 can be --no-reload opt
__RESH_CMDLINE="$1" # not local to preserve it for postcollect (useful as sanity check) # Backwards compatibity: Do not change -version opt.
__resh_collect --cmdLine "$__RESH_CMDLINE" # It is called by new shell files to detect version mismatch.
} if [ "$(resh-collect -version)" != "$__RESH_VERSION" ] && [ -z "${__RESH_NO_RELOAD-}" ]; then
# Reload shell files and restart __resh_preexec - i.e. the full command will be recorded only with a slight delay.
# This should happens in every already open terminal after resh update.
# used for collect and collect --recall # If `$2` is non-empty we play it safe, don't reload, and leave it up to resh-collect to error because of `--required-version` option.
__resh_collect() { # This behavior gives user and error instead of handling things silently and risking infinite recursion.
# posix
local __RESH_PWD="$PWD"
# non-posix
local __RESH_SHLVL="$SHLVL"
local __RESH_GIT_REMOTE; __RESH_GIT_REMOTE="$(git remote get-url origin 2>/dev/null)"
__RESH_RT_BEFORE=$(resh-get-epochtime) __resh_reload_shellrc
# Rerun self but prevent another reload. Extra protection against infinite recursion.
if __resh_maybe_reload; then __RESH_NO_RELOAD=1 __resh_preexec "$@"
resh-collect -requireVersion "$__RESH_VERSION" \
-requireRevision "$__RESH_REVISION" \
-shell "$__RESH_SHELL" \
-sessionID "$__RESH_SESSION_ID" \
-recordID "$__RESH_RECORD_ID" \
-home "$__RESH_HOME" \
-pwd "$__RESH_PWD" \
-sessionPID "$__RESH_SESSION_PID" \
-shlvl "$__RESH_SHLVL" \
-gitRemote "$__RESH_GIT_REMOTE" \
-time "$__RESH_RT_BEFORE" \
"$@"
return $? return $?
fi fi
return 1 __RESH_COLLECT=1
__RESH_RECORD_ID=$(resh-generate-uuid)
# TODO: do this in resh-collect
# shellcheck disable=2155
local git_remote="$(git remote get-url origin 2>/dev/null)"
# TODO: do this in resh-collect
__RESH_RT_BEFORE=$(resh-get-epochtime)
resh-collect -requireVersion "$__RESH_VERSION" \
--git-remote "$git_remote" \
--home "$HOME" \
--pwd "$PWD" \
--record-id "$__RESH_RECORD_ID" \
--session-id "$__RESH_SESSION_ID" \
--session-pid "$$" \
--shell "$__RESH_SHELL" \
--shlvl "$SHLVL" \
--time "$__RESH_RT_BEFORE" \
--cmd-line "$1"
return $?
} }
# postcollect
# Backwards compatibilty: Please see notes above before making any changes here.
__resh_precmd() { __resh_precmd() {
local __RESH_EXIT_CODE=$? # Get status first before it gets overriden by another command.
local __RESH_RT_AFTER local exit_code=$?
local __RESH_SHLVL="$SHLVL" # Don't do anything if __resh_preexec was not called.
__RESH_RT_AFTER=$(resh-get-epochtime) # There are situations (in bash) where no command was submitted but __resh_precmd gets called anyway.
if [ -n "${__RESH_COLLECT}" ]; then [ -n "${__RESH_COLLECT-}" ] || return
if __resh_maybe_reload; then if [ "$(resh-postcollect -version)" != "$__RESH_VERSION" ]; then
resh-postcollect -requireVersion "$__RESH_VERSION" \ # Reload shell files and return - i.e. skip recording part2 for this command.
-requireRevision "$__RESH_REVISION" \ # We don't call __resh_precmd because the new __resh_preexec might not be backwards compatible with variables set by old __resh_preexec.
-timeBefore "$__RESH_RT_BEFORE" \ # This should happen only in the one terminal where resh update was executed.
-exitCode "$__RESH_EXIT_CODE" \ # And the resh-daemon was likely restarted so we likely don't even have the matching part1 of the comand in the resh-daemon memory.
-sessionID "$__RESH_SESSION_ID" \ __resh_reload_shellrc
-recordID "$__RESH_RECORD_ID" \ return
-shlvl "$__RESH_SHLVL" \
-timeAfter "$__RESH_RT_AFTER"
fi
__resh_reset_variables
fi fi
unset __RESH_COLLECT unset __RESH_COLLECT
# do this in resh-postcollect
# shellcheck disable=2155
local rt_after=$(resh-get-epochtime)
resh-postcollect -requireVersion "$__RESH_VERSION" \
--exit-code "$exit_code" \
--record-id "$__RESH_RECORD_ID" \
--session-id "$__RESH_SESSION_ID" \
--shlvl "$SHLVL" \
--time-after "$rt_after" \
--time-before "$__RESH_RT_BEFORE"
return $?
} }
# Backwards compatibilty: No restrictions. This is only used at the start of the session.
__resh_session_init() { __resh_session_init() {
if __resh_maybe_reload; then resh-session-init -requireVersion "$__RESH_VERSION" \
resh-session-init -requireVersion "$__RESH_VERSION" \ --session-id "$__RESH_SESSION_ID" \
-requireRevision "$__RESH_REVISION" \ --session-pid "$$"
-sessionId "$__RESH_SESSION_ID" \ return $?
-sessionPid "$__RESH_SESSION_PID"
fi
} }

@ -180,7 +180,6 @@ info="---- Scroll down using arrow keys ----
##################################### #####################################
" "
# FIMXE: update info - resh history path
info="$info info="$info
RESH SEARCH APPLICATION = Redesigned reverse search that actually works RESH SEARCH APPLICATION = Redesigned reverse search that actually works
@ -206,13 +205,6 @@ ISSUES & FEEDBACK
Please report issues to: https://github.com/curusarn/resh/issues Please report issues to: https://github.com/curusarn/resh/issues
Feedback and suggestions are very welcome! Feedback and suggestions are very welcome!
" "
if [ -z "${__RESH_VERSION:-}" ]; then info="$info
##############################################################
# #
# Finish the installation by RESTARTING this terminal! #
# #
##############################################################"
fi
info="$info info="$info
---- Close this by pressing Q ----" ---- Close this by pressing Q ----"
@ -224,11 +216,3 @@ echo "All done!"
echo "Thank you for using RESH" echo "Thank you for using RESH"
echo "Report issues here: https://github.com/curusarn/resh/issues" echo "Report issues here: https://github.com/curusarn/resh/issues"
echo "Ctrl+R launches the RESH SEARCH app" echo "Ctrl+R launches the RESH SEARCH app"
if [ -z "${__RESH_VERSION:-}" ]; then echo "
##############################################################
# #
# Finish the installation by RESTARTING this terminal! #
# #
##############################################################"
fi

@ -15,7 +15,7 @@ __resh_bind_control_R() {
if [ "${__RESH_control_R_bind_enabled-0}" != 0 ]; then if [ "${__RESH_control_R_bind_enabled-0}" != 0 ]; then
# Re-binding is a valid usecase but it shouldn't happen much # Re-binding is a valid usecase but it shouldn't happen much
# so this is a warning # so this is a warning
echo "Re-binding RESH SEARCH app to Ctrl+R ..." # echo "Re-binding RESH SEARCH app to Ctrl+R ..."
else else
# Only save original binding if resh binding was not enabled # Only save original binding if resh binding was not enabled
__RESH_bindfunc_revert_control_R_bind=$_bindfunc_revert __RESH_bindfunc_revert_control_R_bind=$_bindfunc_revert

@ -16,15 +16,8 @@ else
echo "RESH PANIC: unrecognized shell - please report this to https://github.com/curusarn/resh/issues" echo "RESH PANIC: unrecognized shell - please report this to https://github.com/curusarn/resh/issues"
fi fi
# TODO: read this from resh-specific file
# create that file during install
__RESH_DEVICE="$__RESH_HOST"
__RESH_HOME="$HOME"
# shellcheck disable=2155 # shellcheck disable=2155
export __RESH_VERSION=$(resh-collect -version) export __RESH_VERSION=$(resh-collect -version)
# shellcheck disable=2155
export __RESH_REVISION=$(resh-collect -revision)
resh-daemon-start resh-daemon-start
@ -34,10 +27,9 @@ resh-daemon-start
# NOTE: nested shells are still the same session # NOTE: nested shells are still the same session
# i.e. $__RESH_SESSION_ID will be set in nested shells # i.e. $__RESH_SESSION_ID will be set in nested shells
if [ -z "${__RESH_SESSION_ID+x}" ]; then if [ -z "${__RESH_SESSION_ID+x}" ]; then
export __RESH_SESSION_ID; __RESH_SESSION_ID=$(resh-generate-uuid) # shellcheck disable=2155
export __RESH_SESSION_PID="$$" export __RESH_SESSION_ID=$(resh-generate-uuid)
__resh_reset_variables
__resh_session_init __resh_session_init
fi fi
@ -48,7 +40,5 @@ if [ -z "${__RESH_INIT_DONE+x}" ]; then
preexec_functions+=(__resh_preexec) preexec_functions+=(__resh_preexec)
precmd_functions+=(__resh_precmd) precmd_functions+=(__resh_precmd)
__resh_reset_variables
__RESH_INIT_DONE=1 __RESH_INIT_DONE=1
fi fi
Loading…
Cancel
Save