feat(updater): add background-alpha update mode (preview) (#11928)

NOTE: this feature is in alpha / preview mode, it is not guaranteed to work 100% of the
time in all cases. If you experience any issues, open an issue or search for an open
one describing your same situation.

To use this, use the zstyle update mode settings [1] with the value `background-alpha`:

  zstyle ':omz:update' mode background-alpha

[1] https://github.com/ohmyzsh/ohmyzsh#getting-updates
This commit is contained in:
Marc Cornellà 2023-10-09 18:00:17 +02:00 committed by GitHub
parent 30a8a5d3e2
commit 29b99c2c7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -9,6 +9,7 @@ fi
# - prompt (default): the user is asked before updating when it's time to update
# - auto: the update is performed automatically when it's time
# - reminder: a reminder is shown to the user when it's time to update
# - background-alpha: an experimental update-on-the-background option
# - disabled: automatic update is turned off
zstyle -s ':omz:update' mode update_mode || {
update_mode=prompt
@ -91,13 +92,37 @@ function is_update_available() {
}
function update_last_updated_file() {
local exit_status="$1" error="$2"
if [[ -z "${1}${2}" ]]; then
echo "LAST_EPOCH=$(current_epoch)" >! "${ZSH_CACHE_DIR}/.zsh-update"
return
fi
cat >! "${ZSH_CACHE_DIR}/.zsh-update" <<EOD
LAST_EPOCH=$(current_epoch)
EXIT_STATUS=${exit_status}
ERROR='${error//\'/}'
EOD
}
function update_ohmyzsh() {
local verbose_mode
zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default
if ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode; then
if [[ "$update_mode" != background-alpha ]] \
&& LANG= ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode; then
update_last_updated_file
return $?
fi
local exit_status error
if error=$(LANG= ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" -i -v silent 2>&1); then
update_last_updated_file 0 "Update successful"
else
exit_status=$?
update_last_updated_file $exit_status "$error"
return $exit_status
fi
}
@ -126,7 +151,8 @@ function has_typed_input() {
}
}
() {
function handle_update() {
() {
emulate -L zsh
local epoch_target mtime option LAST_EPOCH
@ -154,7 +180,7 @@ function has_typed_input() {
trap "
ret=\$?
unset update_mode
unset -f current_epoch is_update_available update_last_updated_file update_ohmyzsh 2>/dev/null
unset -f current_epoch is_update_available update_last_updated_file update_ohmyzsh handle_update 2>/dev/null
command rm -rf '$ZSH/log/update.lock'
return \$ret
" EXIT INT QUIT
@ -185,14 +211,14 @@ function has_typed_input() {
fi
# If in reminder mode or user has typed input, show reminder and exit
if [[ "$update_mode" = reminder ]] || has_typed_input; then
if [[ "$update_mode" = reminder ]] || { [[ "$update_mode" != background-alpha ]] && has_typed_input }; then
printf '\r\e[0K' # move cursor to first column and clear whole line
echo "[oh-my-zsh] It's time to update! You can do that by running \`omz update\`"
return 0
fi
# Don't ask for confirmation before updating if in auto mode
if [[ "$update_mode" = auto ]]; then
if [[ "$update_mode" = (auto|background-alpha) ]]; then
update_ohmyzsh
return $?
fi
@ -207,7 +233,63 @@ function has_typed_input() {
[nN]) update_last_updated_file ;&
*) echo "[oh-my-zsh] You can update manually by running \`omz update\`" ;;
esac
}
unset update_mode
unset -f current_epoch is_update_available update_last_updated_file update_ohmyzsh handle_update
}
unset update_mode
unset -f current_epoch is_update_available update_last_updated_file update_ohmyzsh
case "$update_mode" in
background-alpha)
autoload -Uz add-zsh-hook
_omz_bg_update() {
# do the update in a subshell
(handle_update) &|
# register update results function
add-zsh-hook precmd _omz_bg_update_status
# deregister background function
add-zsh-hook -d precmd _omz_bg_update
unset -f _omz_bg_update
}
_omz_bg_update_status() {
{
local LAST_EPOCH EXIT_STATUS ERROR
if [[ ! -f "$ZSH_CACHE_DIR"/.zsh-update ]]; then
return 1
fi
# check update results until timeout is reached
. "$ZSH_CACHE_DIR/.zsh-update"
if [[ -z "$EXIT_STATUS" || -z "$ERROR" ]]; then
return 1
fi
if [[ "$EXIT_STATUS" -eq 0 ]]; then
print -P "\n%F{green}[oh-my-zsh] Update successful.%f"
return 0
elif [[ "$EXIT_STATUS" -ne 0 ]]; then
print -P "\n%F{red}[oh-my-zsh] There was an error updating:%f"
printf "\n${fg[yellow]}%s${reset_color}" "$ERROR"
return 0
fi
} always {
if (( TRY_BLOCK_ERROR == 0 )); then
# if last update results have been handled, remove them from the status file
update_last_updated_file
# deregister background function
add-zsh-hook -d precmd _omz_bg_update_status
unset -f _omz_bg_update_status
fi
}
}
add-zsh-hook precmd _omz_bg_update
;;
*)
handle_update ;;
esac