From c08b925d282e35ea7bd9a8f4c29de2ece0debb49 Mon Sep 17 00:00:00 2001 From: Michele Bologna Date: Thu, 23 Mar 2023 14:34:43 +0100 Subject: fix(uninstall): abort uninstall if unable to change shell (#10357) --- tools/uninstall.sh | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/uninstall.sh b/tools/uninstall.sh index 6a0e7b4c7..6e3df7aca 100644 --- a/tools/uninstall.sh +++ b/tools/uninstall.sh @@ -1,3 +1,15 @@ +if hash chsh >/dev/null 2>&1 && [ -f ~/.shell.pre-oh-my-zsh ]; then + old_shell=$(cat ~/.shell.pre-oh-my-zsh) + echo "Switching your shell back to '$old_shell':" + if chsh -s "$old_shell"; then + rm -f ~/.shell.pre-oh-my-zsh + else + echo "Could not change default shell. Change it manually by running chsh" + echo "or editing the /etc/passwd file." + exit + fi +fi + read -r -p "Are you sure you want to remove Oh My Zsh? [y/N] " confirmation if [ "$confirmation" != y ] && [ "$confirmation" != Y ]; then echo "Uninstall cancelled" @@ -25,16 +37,5 @@ else echo "No original zsh config found" fi -if hash chsh >/dev/null 2>&1 && [ -f ~/.shell.pre-oh-my-zsh ]; then - old_shell=$(cat ~/.shell.pre-oh-my-zsh) - echo "Switching your shell back to '$old_shell':" - if chsh -s "$old_shell"; then - rm -f ~/.shell.pre-oh-my-zsh - else - echo "Could not change default shell. Change it manually by running chsh" - echo "or editing the /etc/passwd file." - fi -fi - echo "Thanks for trying out Oh My Zsh. It's been uninstalled." echo "Don't forget to restart your terminal!" -- cgit v1.2.3-70-g09d2 From 8f6fbe238969ecb22fbdae75450a9f8705c9f979 Mon Sep 17 00:00:00 2001 From: Håvard Bartnes Date: Tue, 28 Mar 2023 12:50:05 +0200 Subject: feat(upgrade): add verbosity settings Co-authored-by: Carlo Sala Closes #11574 Closes #11579 --- README.md | 12 +++++++++++ lib/cli.zsh | 5 +++-- tools/check_for_upgrade.sh | 3 ++- tools/upgrade.sh | 53 ++++++++++++++++++++++++++++++++++------------ 4 files changed, 56 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/README.md b/README.md index 4042c8c26..4f0aeb7b4 100644 --- a/README.md +++ b/README.md @@ -317,6 +317,18 @@ zstyle ':omz:update' frequency 7 zstyle ':omz:update' frequency 0 ``` +### Updates verbosity + +You can also limit the update verbosity with the following settings: + +```sh +zstyle ':omz:update' verbose default # default update prompt + +zstyle ':omz:update' verbose minimal # only few lines + +zstyle ':omz:update' verbose silent # only errors +``` + ### Manual Updates If you'd like to update at any point in time (maybe someone just released a new plugin and you don't want to wait a week?) you just need to run: diff --git a/lib/cli.zsh b/lib/cli.zsh index fed00d21d..ba3e39eb5 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -776,10 +776,11 @@ function _omz::update { local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD) # Run update script + zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default if [[ "$1" != --unattended ]]; then - ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" --interactive || return $? + ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $? else - ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" || return $? + ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -v $verbose_mode || return $? fi # Update last updated file diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh index 734714c94..81c371b3f 100644 --- a/tools/check_for_upgrade.sh +++ b/tools/check_for_upgrade.sh @@ -95,7 +95,8 @@ function update_last_updated_file() { } function update_ohmyzsh() { - if ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" --interactive; then + zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default + if ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode; then update_last_updated_file fi } diff --git a/tools/upgrade.sh b/tools/upgrade.sh index 596a59302..684ad894a 100755 --- a/tools/upgrade.sh +++ b/tools/upgrade.sh @@ -12,6 +12,23 @@ esac cd "$ZSH" +verbose_mode="default" +interactive=false + +while getopts "v:i" opt; do + case $opt in + v) + if [[ $OPTARG == default || $OPTARG == minimal || $OPTARG == silent ]]; then + verbose_mode=$OPTARG + else + echo "[oh-my-zsh] update verbosity '$OPTARG' is not valid" + echo "[oh-my-zsh] valid options are 'default', 'minimal' and 'silent'" + fi + ;; + i) interactive=true ;; + esac +done + # Use colors, but only if connected to a terminal # and that terminal supports them. @@ -203,7 +220,9 @@ git checkout -q "$branch" -- || exit 1 last_commit=$(git rev-parse "$branch") # Update Oh My Zsh -printf "${BLUE}%s${RESET}\n" "Updating Oh My Zsh" +if [[ $verbose_mode != silent ]]; then + printf "${BLUE}%s${RESET}\n" "Updating Oh My Zsh" +fi if LANG= git pull --quiet --rebase $remote $branch; then # Check if it was really updated or not if [[ "$(git rev-parse HEAD)" = "$last_commit" ]]; then @@ -215,24 +234,30 @@ if LANG= git pull --quiet --rebase $remote $branch; then git config oh-my-zsh.lastVersion "$last_commit" # Print changelog to the terminal - if [[ "$1" = --interactive ]]; then + if [[ interactive == true && $verbose_mode == default ]] ; then "$ZSH/tools/changelog.sh" HEAD "$last_commit" fi - printf "${BLUE}%s \`${BOLD}%s${RESET}${BLUE}\`${RESET}\n" "You can see the changelog with" "omz changelog" + if [[ $verbose_mode != silent ]]; then + printf "${BLUE}%s \`${BOLD}%s${RESET}${BLUE}\`${RESET}\n" "You can see the changelog with" "omz changelog" + fi fi - printf '%s %s__ %s %s %s %s %s__ %s\n' $RAINBOW $RESET - printf '%s ____ %s/ /_ %s ____ ___ %s__ __ %s ____ %s_____%s/ /_ %s\n' $RAINBOW $RESET - printf '%s / __ \\%s/ __ \\ %s / __ `__ \\%s/ / / / %s /_ / %s/ ___/%s __ \\ %s\n' $RAINBOW $RESET - printf '%s/ /_/ /%s / / / %s / / / / / /%s /_/ / %s / /_%s(__ )%s / / / %s\n' $RAINBOW $RESET - printf '%s\\____/%s_/ /_/ %s /_/ /_/ /_/%s\\__, / %s /___/%s____/%s_/ /_/ %s\n' $RAINBOW $RESET - printf '%s %s %s %s /____/ %s %s %s %s\n' $RAINBOW $RESET - printf '\n' - printf "${BLUE}%s${RESET}\n\n" "$message" - printf "${BLUE}${BOLD}%s %s${RESET}\n" "To keep up with the latest news and updates, follow us on Twitter:" "$(fmt_link @ohmyzsh https://twitter.com/ohmyzsh)" - printf "${BLUE}${BOLD}%s %s${RESET}\n" "Want to get involved in the community? Join our Discord:" "$(fmt_link "Discord server" https://discord.gg/ohmyzsh)" - printf "${BLUE}${BOLD}%s %s${RESET}\n" "Get your Oh My Zsh swag at:" "$(fmt_link "Planet Argon Shop" https://shop.planetargon.com/collections/oh-my-zsh)" + if [[ $verbose_mode == default ]]; then + printf '%s %s__ %s %s %s %s %s__ %s\n' $RAINBOW $RESET + printf '%s ____ %s/ /_ %s ____ ___ %s__ __ %s ____ %s_____%s/ /_ %s\n' $RAINBOW $RESET + printf '%s / __ \\%s/ __ \\ %s / __ `__ \\%s/ / / / %s /_ / %s/ ___/%s __ \\ %s\n' $RAINBOW $RESET + printf '%s/ /_/ /%s / / / %s / / / / / /%s /_/ / %s / /_%s(__ )%s / / / %s\n' $RAINBOW $RESET + printf '%s\\____/%s_/ /_/ %s /_/ /_/ /_/%s\\__, / %s /___/%s____/%s_/ /_/ %s\n' $RAINBOW $RESET + printf '%s %s %s %s /____/ %s %s %s %s\n' $RAINBOW $RESET + printf '\n' + printf "${BLUE}%s${RESET}\n\n" "$message" + printf "${BLUE}${BOLD}%s %s${RESET}\n" "To keep up with the latest news and updates, follow us on Twitter:" "$(fmt_link @ohmyzsh https://twitter.com/ohmyzsh)" + printf "${BLUE}${BOLD}%s %s${RESET}\n" "Want to get involved in the community? Join our Discord:" "$(fmt_link "Discord server" https://discord.gg/ohmyzsh)" + printf "${BLUE}${BOLD}%s %s${RESET}\n" "Get your Oh My Zsh swag at:" "$(fmt_link "Planet Argon Shop" https://shop.planetargon.com/collections/oh-my-zsh)" + elif [[ $verbose_mode == minimal ]]; then + printf "${BLUE}%s${RESET}\n" "$message" + fi else ret=$? printf "${RED}%s${RESET}\n" 'There was an error updating. Try again later?' -- cgit v1.2.3-70-g09d2 From 7837ba6a993fb2243b3e69fdbd63b437a8674b4c Mon Sep 17 00:00:00 2001 From: Webpage-gh <70434775+Webpage-gh@users.noreply.github.com> Date: Fri, 31 Mar 2023 13:37:01 +0800 Subject: fix(installer): don't use `sudo` when user is in Termux (#11591) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marc Cornellà --- tools/install.sh | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/install.sh b/tools/install.sh index f4ef16a0c..efdb7d482 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -84,6 +84,11 @@ command_exists() { user_can_sudo() { # Check if sudo is installed command_exists sudo || return 1 + # Termux can't run sudo unless the device is rooted. Either way, `chsh` works + # without sudo, so we can detect it and exit the function early. + case "$PREFIX" in + *com.termux*) return 1 ;; + esac # The following command has 3 parts: # # 1. Run `sudo` with `-v`. Does the following: -- cgit v1.2.3-70-g09d2 From b9c4e2e82337594c2899db1f9ca005bb02fe20cd Mon Sep 17 00:00:00 2001 From: Guy Sartorelli <36352093+GuySartorelli@users.noreply.github.com> Date: Fri, 31 Mar 2023 18:49:59 +1300 Subject: feat(changelog): provide links in changelog (#11578) --- tools/changelog.sh | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/changelog.sh b/tools/changelog.sh index a5cc468f2..5f7a14d03 100755 --- a/tools/changelog.sh +++ b/tools/changelog.sh @@ -157,6 +157,89 @@ function parse-commit { fi } +################################ +# SUPPORTS HYPERLINKS FUNCTION # +################################ + +# The code for checking if a terminal supports hyperlinks is copied from install.sh + +# The [ -t 1 ] check only works when the function is not called from +# a subshell (like in `$(...)` or `(...)`, so this hack redefines the +# function at the top level to always return false when stdout is not +# a tty. +if [ -t 1 ]; then + is_tty() { + true + } +else + is_tty() { + false + } +fi + +# This function uses the logic from supports-hyperlinks[1][2], which is +# made by Kat Marchán (@zkat) and licensed under the Apache License 2.0. +# [1] https://github.com/zkat/supports-hyperlinks +# [2] https://crates.io/crates/supports-hyperlinks +# +# Copyright (c) 2021 Kat Marchán +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +supports_hyperlinks() { + # $FORCE_HYPERLINK must be set and be non-zero (this acts as a logic bypass) + if [ -n "$FORCE_HYPERLINK" ]; then + [ "$FORCE_HYPERLINK" != 0 ] + return $? + fi + + # If stdout is not a tty, it doesn't support hyperlinks + is_tty || return 1 + + # DomTerm terminal emulator (domterm.org) + if [ -n "$DOMTERM" ]; then + return 0 + fi + + # VTE-based terminals above v0.50 (Gnome Terminal, Guake, ROXTerm, etc) + if [ -n "$VTE_VERSION" ]; then + [ $VTE_VERSION -ge 5000 ] + return $? + fi + + # If $TERM_PROGRAM is set, these terminals support hyperlinks + case "$TERM_PROGRAM" in + Hyper|iTerm.app|terminology|WezTerm) return 0 ;; + esac + + # kitty supports hyperlinks + if [ "$TERM" = xterm-kitty ]; then + return 0 + fi + + # Windows Terminal also supports hyperlinks + if [ -n "$WT_SESSION" ]; then + return 0 + fi + + # Konsole supports hyperlinks, but it's an opt-in setting that can't be detected + # https://github.com/ohmyzsh/ohmyzsh/issues/10964 + # if [ -n "$KONSOLE_VERSION" ]; then + # return 0 + # fi + + return 1 +} + ############################# # RELEASE CHANGELOG DISPLAY # ############################# @@ -208,7 +291,13 @@ function display-release { local hash="${1:-$hash}" case "$output" in raw) printf '%s' "$hash" ;; - text) printf '\e[33m%s\e[0m' "$hash" ;; # red + text) + local text="\e[33m$hash\e[0m"; # red + if supports_hyperlinks; then + printf "\e]8;;%s\a%s\e]8;;\a" "https://github.com/ohmyzsh/ohmyzsh/commit/$hash" $text; + else + echo $text; + fi ;; md) printf '[`%s`](https://github.com/ohmyzsh/ohmyzsh/commit/%s)' "$hash" "$hash" ;; esac } @@ -272,7 +361,12 @@ function display-release { case "$output" in raw) printf '%s' "$subject" ;; # In text mode, highlight (#) and dim text between `backticks` - text) sed -E $'s|#([0-9]+)|\e[32m#\\1\e[0m|g;s|`([^`]+)`|`\e[2m\\1\e[0m`|g' <<< "$subject" ;; + text) + if supports_hyperlinks; then + sed -E $'s|#([0-9]+)|\e]8;;https://github.com/ohmyzsh/ohmyzsh/issues/\\1\a\e[32m#\\1\e[0m\e]8;;\a|g' <<< "$subject" + else + sed -E $'s|#([0-9]+)|\e[32m#\\1\e[0m|g;s|`([^`]+)`|`\e[2m\\1\e[0m`|g' <<< "$subject" + fi ;; # In markdown mode, link to (#) issues md) sed -E 's|#([0-9]+)|[#\1](https://github.com/ohmyzsh/ohmyzsh/issues/\1)|g' <<< "$subject" ;; esac -- cgit v1.2.3-70-g09d2 From 029a6d2de8681d52142129eb8b6ff0f20be9f0a6 Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Fri, 31 Mar 2023 15:30:19 +0200 Subject: fix(upgrade): typo in variable check --- tools/upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/upgrade.sh b/tools/upgrade.sh index 684ad894a..d9a372d13 100755 --- a/tools/upgrade.sh +++ b/tools/upgrade.sh @@ -234,7 +234,7 @@ if LANG= git pull --quiet --rebase $remote $branch; then git config oh-my-zsh.lastVersion "$last_commit" # Print changelog to the terminal - if [[ interactive == true && $verbose_mode == default ]] ; then + if [[ $interactive == true && $verbose_mode == default ]]; then "$ZSH/tools/changelog.sh" HEAD "$last_commit" fi -- cgit v1.2.3-70-g09d2 From 6ef236dd99f2090b54911f9135d00ac37d6757ff Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Sat, 1 Apr 2023 10:14:18 +0200 Subject: fix(updater): search for upstream remote if using non-conventional name (#11135) Fixes #11135 --- tools/upgrade.sh | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/upgrade.sh b/tools/upgrade.sh index d9a372d13..34ff3f027 100755 --- a/tools/upgrade.sh +++ b/tools/upgrade.sh @@ -1,5 +1,7 @@ #!/usr/bin/env zsh +local ret=0 # exit code + # Protect against running with shells other than zsh if [ -z "$ZSH_VERSION" ]; then exec zsh "$0" "$@" @@ -181,17 +183,23 @@ fi # Update upstream remote to ohmyzsh org git remote -v | while read remote url extra; do case "$url" in + git://github.com/robbyrussell/oh-my-zsh(|.git)) + # Update out-of-date "unauthenticated git protocol on port 9418" to https + git remote set-url "$remote" "https://github.com/ohmyzsh/ohmyzsh.git" ;; https://github.com/robbyrussell/oh-my-zsh(|.git)) - git remote set-url "$remote" "https://github.com/ohmyzsh/ohmyzsh.git" - break ;; + git remote set-url "$remote" "https://github.com/ohmyzsh/ohmyzsh.git" ;; git@github.com:robbyrussell/oh-my-zsh(|.git)) - git remote set-url "$remote" "git@github.com:ohmyzsh/ohmyzsh.git" - break ;; - # Update out-of-date "unauthenticated git protocol on port 9418" to https - git://github.com/robbyrussell/oh-my-zsh(|.git)) - git remote set-url "$remote" "https://github.com/ohmyzsh/ohmyzsh.git" - break ;; + git remote set-url "$remote" "git@github.com:ohmyzsh/ohmyzsh.git" ;; + https://github.com/ohmyzsh/ohmyzsh(|.git)) ;; + git@github.com:ohmyzsh/ohmyzsh(|.git)) ;; + *) continue ;; esac + + # If we reach this point we have found the proper ohmyzsh upstream remote. If we don't, + # we'll only update from the set remote if `oh-my-zsh.remote` has been set to a remote, + # as when installing from a fork. + git config --local oh-my-zsh.remote "$remote" + break done # Set git-config values known to fix git errors -- cgit v1.2.3-70-g09d2 From f8bf88edca7a3246e065f13cefac2c5f1ab396e0 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Mon, 3 Apr 2023 22:21:49 +0200 Subject: chore(installer): remove words triggering false positives in antiviruses --- tools/install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/install.sh b/tools/install.sh index efdb7d482..fcfbcf778 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -84,8 +84,7 @@ command_exists() { user_can_sudo() { # Check if sudo is installed command_exists sudo || return 1 - # Termux can't run sudo unless the device is rooted. Either way, `chsh` works - # without sudo, so we can detect it and exit the function early. + # Termux can't run sudo, so we can detect it and exit the function early. case "$PREFIX" in *com.termux*) return 1 ;; esac -- cgit v1.2.3-70-g09d2 From c7bb88f9ad3eb742aecca2e36b615819cead10f4 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Mon, 3 Apr 2023 23:27:14 +0200 Subject: fix(changelog): ignore lines containing whitespace in breaking change commits --- tools/changelog.sh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/changelog.sh b/tools/changelog.sh index 5f7a14d03..1af74e42d 100755 --- a/tools/changelog.sh +++ b/tools/changelog.sh @@ -106,6 +106,9 @@ function parse-commit { message="${match[1]}" # remove CR characters (might be inserted in GitHub UI commit description form) message="${message//$'\r'/}" + # remove lines containing only whitespace + local nlnl=$'\n\n' + message="${message//$'\n'[[:space:]]##$'\n'/$nlnl}" # skip next paragraphs (separated by two newlines or more) message="${message%%$'\n\n'*}" # ... and replace newlines with spaces -- cgit v1.2.3-70-g09d2 From d889eca72633b7a66d6c832736a5460c5f1a1833 Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Mon, 17 Apr 2023 20:09:30 +0200 Subject: fix(check_for_upgrade): update properly `LAST_EPOCH` Fixes #11617 --- tools/check_for_upgrade.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh index 81c371b3f..3210e4375 100644 --- a/tools/check_for_upgrade.sh +++ b/tools/check_for_upgrade.sh @@ -180,6 +180,7 @@ function has_typed_input() { # Check if there are updates available before proceeding if ! is_update_available; then + update_last_updated_file return fi -- cgit v1.2.3-70-g09d2 From 000be72dd0c2f668cd94b36c69e45dec7b06a23e Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Tue, 29 Aug 2023 10:27:36 +0200 Subject: fix(updater): disable `nounset` to avoid warnings (#11856) --- tools/upgrade.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/upgrade.sh b/tools/upgrade.sh index 34ff3f027..f7a263d66 100755 --- a/tools/upgrade.sh +++ b/tools/upgrade.sh @@ -1,4 +1,5 @@ #!/usr/bin/env zsh +set +u # disable nounset local ret=0 # exit code -- cgit v1.2.3-70-g09d2 From bbda81fe4b338f00bbf7c7f33e6d1b12d067dc05 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Wed, 13 Sep 2023 19:23:41 +0200 Subject: fix(changelog): fix regression for unstyled code in commit subjects --- tools/changelog.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/changelog.sh b/tools/changelog.sh index 1af74e42d..6d768963e 100755 --- a/tools/changelog.sh +++ b/tools/changelog.sh @@ -366,7 +366,7 @@ function display-release { # In text mode, highlight (#) and dim text between `backticks` text) if supports_hyperlinks; then - sed -E $'s|#([0-9]+)|\e]8;;https://github.com/ohmyzsh/ohmyzsh/issues/\\1\a\e[32m#\\1\e[0m\e]8;;\a|g' <<< "$subject" + sed -E $'s|#([0-9]+)|\e]8;;https://github.com/ohmyzsh/ohmyzsh/issues/\\1\a\e[32m#\\1\e[0m\e]8;;\a|g;s|`([^`]+)`|`\e[2m\\1\e[0m`|g' <<< "$subject" else sed -E $'s|#([0-9]+)|\e[32m#\\1\e[0m|g;s|`([^`]+)`|`\e[2m\\1\e[0m`|g' <<< "$subject" fi ;; -- cgit v1.2.3-70-g09d2 From 29b99c2c7b16f22f3ca2bdf9478ba700ac6c48b5 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Mon, 9 Oct 2023 18:00:17 +0200 Subject: 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 --- tools/check_for_upgrade.sh | 230 ++++++++++++++++++++++++++++++--------------- 1 file changed, 156 insertions(+), 74 deletions(-) (limited to 'tools') diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh index 3210e4375..1cc193bde 100644 --- a/tools/check_for_upgrade.sh +++ b/tools/check_for_upgrade.sh @@ -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() { - echo "LAST_EPOCH=$(current_epoch)" >! "${ZSH_CACHE_DIR}/.zsh-update" + 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" <&1); then + update_last_updated_file 0 "Update successful" + else + exit_status=$? + update_last_updated_file $exit_status "$error" + return $exit_status fi } @@ -126,88 +151,145 @@ function has_typed_input() { } } -() { - emulate -L zsh +function handle_update() { + () { + emulate -L zsh - local epoch_target mtime option LAST_EPOCH + local epoch_target mtime option LAST_EPOCH - # Remove lock directory if older than a day - zmodload zsh/datetime - zmodload -F zsh/stat b:zstat - if mtime=$(zstat +mtime "$ZSH/log/update.lock" 2>/dev/null); then - if (( (mtime + 3600 * 24) < EPOCHSECONDS )); then - command rm -rf "$ZSH/log/update.lock" + # Remove lock directory if older than a day + zmodload zsh/datetime + zmodload -F zsh/stat b:zstat + if mtime=$(zstat +mtime "$ZSH/log/update.lock" 2>/dev/null); then + if (( (mtime + 3600 * 24) < EPOCHSECONDS )); then + command rm -rf "$ZSH/log/update.lock" + fi fi - fi - # Check for lock directory - if ! command mkdir "$ZSH/log/update.lock" 2>/dev/null; then - return - fi + # Check for lock directory + if ! command mkdir "$ZSH/log/update.lock" 2>/dev/null; then + return + fi - # Remove lock directory on exit. `return $ret` is important for when trapping a SIGINT: - # The return status from the function is handled specially. If it is zero, the signal is - # assumed to have been handled, and execution continues normally. Otherwise, the shell - # will behave as interrupted except that the return status of the trap is retained. - # This means that for a CTRL+C, the trap needs to return the same exit status so that - # the shell actually exits what it's running. - trap " - ret=\$? - unset update_mode - unset -f current_epoch is_update_available update_last_updated_file update_ohmyzsh 2>/dev/null - command rm -rf '$ZSH/log/update.lock' - return \$ret - " EXIT INT QUIT - - # Create or update .zsh-update file if missing or malformed - if ! source "${ZSH_CACHE_DIR}/.zsh-update" 2>/dev/null || [[ -z "$LAST_EPOCH" ]]; then - update_last_updated_file - return - fi + # Remove lock directory on exit. `return $ret` is important for when trapping a SIGINT: + # The return status from the function is handled specially. If it is zero, the signal is + # assumed to have been handled, and execution continues normally. Otherwise, the shell + # will behave as interrupted except that the return status of the trap is retained. + # This means that for a CTRL+C, the trap needs to return the same exit status so that + # the shell actually exits what it's running. + trap " + ret=\$? + unset update_mode + 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 - # Number of days before trying to update again - zstyle -s ':omz:update' frequency epoch_target || epoch_target=${UPDATE_ZSH_DAYS:-13} - # Test if enough time has passed until the next update - if (( ( $(current_epoch) - $LAST_EPOCH ) < $epoch_target )); then - return - fi + # Create or update .zsh-update file if missing or malformed + if ! source "${ZSH_CACHE_DIR}/.zsh-update" 2>/dev/null || [[ -z "$LAST_EPOCH" ]]; then + update_last_updated_file + return + fi - # Test if Oh My Zsh directory is a git repository - if ! (builtin cd -q "$ZSH" && LANG= git rev-parse &>/dev/null); then - echo >&2 "[oh-my-zsh] Can't update: not a git repository." - return - fi + # Number of days before trying to update again + zstyle -s ':omz:update' frequency epoch_target || epoch_target=${UPDATE_ZSH_DAYS:-13} + # Test if enough time has passed until the next update + if (( ( $(current_epoch) - $LAST_EPOCH ) < $epoch_target )); then + return + fi - # Check if there are updates available before proceeding - if ! is_update_available; then - update_last_updated_file - return - fi + # Test if Oh My Zsh directory is a git repository + if ! (builtin cd -q "$ZSH" && LANG= git rev-parse &>/dev/null); then + echo >&2 "[oh-my-zsh] Can't update: not a git repository." + return + fi - # If in reminder mode or user has typed input, show reminder and exit - if [[ "$update_mode" = reminder ]] || 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 + # Check if there are updates available before proceeding + if ! is_update_available; then + update_last_updated_file + return + fi - # Don't ask for confirmation before updating if in auto mode - if [[ "$update_mode" = auto ]]; then - update_ohmyzsh - return $? - fi + # If in reminder mode or user has typed input, show reminder and exit + 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 - # Ask for confirmation and only update on 'y', 'Y' or Enter - # Otherwise just show a reminder for how to update - echo -n "[oh-my-zsh] Would you like to update? [Y/n] " - read -r -k 1 option - [[ "$option" = $'\n' ]] || echo - case "$option" in - [yY$'\n']) update_ohmyzsh ;; - [nN]) update_last_updated_file ;& - *) echo "[oh-my-zsh] You can update manually by running \`omz update\`" ;; - esac + # Don't ask for confirmation before updating if in auto mode + if [[ "$update_mode" = (auto|background-alpha) ]]; then + update_ohmyzsh + return $? + fi + + # Ask for confirmation and only update on 'y', 'Y' or Enter + # Otherwise just show a reminder for how to update + echo -n "[oh-my-zsh] Would you like to update? [Y/n] " + read -r -k 1 option + [[ "$option" = $'\n' ]] || echo + case "$option" in + [yY$'\n']) update_ohmyzsh ;; + [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 -- cgit v1.2.3-70-g09d2