mirror of https://github.com/curusarn/resh
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 makefilepull/184/head
parent
682b9599e8
commit
9b0c8b3149
@ -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:] |
||||||
|
} |
||||||
@ -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() { |
|
||||||
__RESH_RECORD_ID=$(resh-generate-uuid) |
|
||||||
} |
} |
||||||
|
|
||||||
__resh_preexec() { |
# BACKWARDS COMPATIBILITY NOTES: |
||||||
# core |
# |
||||||
__RESH_COLLECT=1 |
# Stable names and options: |
||||||
__RESH_CMDLINE="$1" # not local to preserve it for postcollect (useful as sanity check) |
# * `resh-collect -version` / `resh-postcollect -version` is used to detect version mismatch. |
||||||
__resh_collect --cmdLine "$__RESH_CMDLINE" |
# => 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. |
||||||
|
|
||||||
# used for collect and collect --recall |
|
||||||
__resh_collect() { |
|
||||||
# posix |
|
||||||
local __RESH_PWD="$PWD" |
|
||||||
|
|
||||||
# non-posix |
# (pre)collect |
||||||
local __RESH_SHLVL="$SHLVL" |
# Backwards compatibilty: Please see notes above before making any changes here. |
||||||
local __RESH_GIT_REMOTE; __RESH_GIT_REMOTE="$(git remote get-url origin 2>/dev/null)" |
__resh_preexec() { |
||||||
|
# $1 is command line |
||||||
|
# $2 can be --no-reload opt |
||||||
|
# Backwards compatibity: Do not change -version opt. |
||||||
|
# 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. |
||||||
|
|
||||||
__RESH_RT_BEFORE=$(resh-get-epochtime) |
# 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. |
||||||
|
# This behavior gives user and error instead of handling things silently and risking infinite recursion. |
||||||
|
|
||||||
if __resh_maybe_reload; then |
__resh_reload_shellrc |
||||||
resh-collect -requireVersion "$__RESH_VERSION" \ |
# Rerun self but prevent another reload. Extra protection against infinite recursion. |
||||||
-requireRevision "$__RESH_REVISION" \ |
__RESH_NO_RELOAD=1 __resh_preexec "$@" |
||||||
-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 |
|
||||||
} |
} |
||||||
Loading…
Reference in new issue