From 16712a41c53833ba1d70ee2c83a7cebdc1f8e6b1 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Wed, 12 Jan 2022 18:27:18 +0900 Subject: [PATCH] tools/upgrade: Enable upgrading/(un)installing in the interactive shell process --- lib/functions.sh | 2 +- lib/utils.sh | 14 ++++++- oh-my-bash.sh | 4 +- tools/check_for_upgrade.sh | 84 ++++++++++++++++++-------------------- tools/install.sh | 8 ++-- tools/uninstall.sh | 21 ++++++---- tools/upgrade.sh | 60 +++++++++++++++------------ 7 files changed, 107 insertions(+), 86 deletions(-) diff --git a/lib/functions.sh b/lib/functions.sh index a0c134b..33fade2 100644 --- a/lib/functions.sh +++ b/lib/functions.sh @@ -8,7 +8,7 @@ function uninstall_oh_my_bash() { } function upgrade_oh_my_bash() { - env OSH=$OSH sh $OSH/tools/upgrade.sh + source "$OSH"/tools/upgrade.sh } function take() { diff --git a/lib/utils.sh b/lib/utils.sh index d0f0798..30764e9 100644 --- a/lib/utils.sh +++ b/lib/utils.sh @@ -250,6 +250,17 @@ else } fi +_omb_util_unload_hook=() +_omb_util_unload() { + local hook + for hook in "${_omb_util_unload_hook[@]}"; do + eval -- "$hook" + done +} + +_omb_util_original_PS1=$PS1 +_omb_util_unload_hook+=('PS1=$_omb_util_original_PS1') + _omb_util_prompt_command=() _omb_util_prompt_command_hook() { local status=$? lastarg=$_ hook @@ -259,8 +270,9 @@ _omb_util_prompt_command_hook() { done } -: "${_omb_util_prompt_command_setup=}" +_omb_util_unload_hook+=('_omb_util_prompt_command=()') +: "${_omb_util_prompt_command_setup=}" _omb_util_add_prompt_command() { local other for other in "${_omb_util_prompt_command[@]}"; do diff --git a/oh-my-bash.sh b/oh-my-bash.sh index 2f2d072..49c5c91 100644 --- a/oh-my-bash.sh +++ b/oh-my-bash.sh @@ -11,8 +11,8 @@ case $- in esac # Check for updates on initial load... -if [ "$DISABLE_AUTO_UPDATE" != "true" ]; then - env OSH="$OSH" DISABLE_UPDATE_PROMPT="$DISABLE_UPDATE_PROMPT" bash -f "$OSH"/tools/check_for_upgrade.sh +if [[ $DISABLE_AUTO_UPDATE != true ]]; then + source "$OSH"/tools/check_for_upgrade.sh fi # Initializes Oh My Bash diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh index 31a0033..539277e 100644 --- a/tools/check_for_upgrade.sh +++ b/tools/check_for_upgrade.sh @@ -1,60 +1,54 @@ #!/usr/bin/env bash -EPOCHSECONDS="$(date +%s)" - -function _current_epoch() { - echo $(( $EPOCHSECONDS / 60 / 60 / 24 )) +function _omb_upgrade_current_epoch { + local sec=${EPOCHSECONDS-} + [[ $sec ]] || printf -v sec '%(%s)T' -1 2>/dev/null || sec=$(command date +%s) + echo $((sec / 60 / 60 / 24)) } -function _update_osh_update() { - echo "LAST_EPOCH=$(_current_epoch)" >| ~/.osh-update +function _omb_upgrade_update_timestamp { + echo "LAST_EPOCH=$(_omb_upgrade_current_epoch)" >| ~/.osh-update } -function _upgrade_osh() { - env BASH=$OSH sh $OSH/tools/upgrade.sh - # update the osh file - _update_osh_update -} +function _omb_upgrade_check { + if [[ ! -f ~/.osh-update ]]; then + # create ~/.osh-update + _omb_upgrade_update_timestamp + return 0 + fi -epoch_target=$UPDATE_OSH_DAYS -if [[ -z "$epoch_target" ]]; then - # Default to old behavior - epoch_target=13 -fi + local LAST_EPOCH + . ~/.osh-update + if [[ ! $LAST_EPOCH ]]; then + _omb_upgrade_update_timestamp + return 0 + fi + + # Default to the old behavior + local epoch_expires=${UPDATE_OSH_DAYS:-13} + local epoch_elapsed=$(($(_omb_upgrade_current_epoch) - LAST_EPOCH)) + if ((epoch_elapsed <= epoch_expires)); then + return 0 + fi + + # update ~/.osh-update + _omb_upgrade_update_timestamp + if [[ $DISABLE_UPDATE_PROMPT == true ]] || + { read -p '[Oh My Bash] Would you like to check for updates? [Y/n]: ' line && + [[ $line == Y* || $line == y* || ! $line ]]; } + then + source "$OSH"/tools/upgrade.sh + fi +} # Cancel upgrade if the current user doesn't have write permissions for the # oh-my-bash directory. [[ -w "$OSH" ]] || return 0 # Cancel upgrade if git is unavailable on the system -which git >/dev/null || return 0 +type -P git &>/dev/null || return 0 -if mkdir "$OSH/log/update.lock" 2>/dev/null; then - if [ -f ~/.osh-update ]; then - . ~/.osh-update - - if [[ -z "$LAST_EPOCH" ]]; then - _update_osh_update && return 0; - fi - - epoch_diff=$(($(_current_epoch) - $LAST_EPOCH)) - if [ $epoch_diff -gt $epoch_target ]; then - if [ "$DISABLE_UPDATE_PROMPT" = "true" ]; then - _upgrade_osh - else - echo "[Oh My Bash] Would you like to check for updates? [Y/n]: \c" - read line - if [[ "$line" == Y* ]] || [[ "$line" == y* ]] || [ -z "$line" ]; then - _upgrade_osh - else - _update_osh_update - fi - fi - fi - else - # create the osh file - _update_osh_update - fi - - rmdir $OSH/log/update.lock +if command mkdir "$OSH/log/update.lock" 2>/dev/null; then + _omb_upgrade_check + command rmdir "$OSH"/log/update.lock fi diff --git a/tools/install.sh b/tools/install.sh index 03e3a79..048568e 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -63,7 +63,7 @@ _omb_install_run() { printf '%s\n' "$BOLD$GREEN[dryrun]$NORMAL $BOLD$*$NORMAL" >&5 else printf '%s\n' "$BOLD\$ $*$NORMAL" >&5 - "$@" + command "$@" fi } @@ -124,19 +124,19 @@ _omb_install_main() { umask g-w,o-w printf "${BLUE}Cloning Oh My Bash...${NORMAL}\n" - hash git >/dev/null 2>&1 || { + type -P git &>/dev/null || { echo "Error: git is not installed" return 1 } # The Windows (MSYS) Git is not compatible with normal use on cygwin if [[ $OSTYPE = cygwin ]]; then - if git --version | grep msysgit > /dev/null; then + if command git --version | command grep msysgit > /dev/null; then echo "Error: Windows/MSYS Git is not supported on Cygwin" echo "Error: Make sure the Cygwin git package is installed and is first on the path" return 1 fi fi - _omb_install_run env git clone --depth=1 https://github.com/ohmybash/oh-my-bash.git "$OSH" || { + _omb_install_run git clone --depth=1 https://github.com/ohmybash/oh-my-bash.git "$OSH" || { printf "Error: git clone of oh-my-bash repo failed\n" return 1 } diff --git a/tools/uninstall.sh b/tools/uninstall.sh index 3032acb..e4678e8 100755 --- a/tools/uninstall.sh +++ b/tools/uninstall.sh @@ -1,7 +1,10 @@ #!/usr/bin/env bash +# Note: this file is intentionally written in POSIX sh so that oh-my-bash can +# be uninstalled without bash. + _omb_uninstall_contains_omb() { - grep -qE '(source|\.)[[:space:]]+.*[/[:space:]]oh-my-bash\.sh' "$1" 2>/dev/null + command grep -qE '(source|\.)[[:space:]]+.*[/[:space:]]oh-my-bash\.sh' "$1" 2>/dev/null } # Find the latest bashrc that do not source oh-my-bash.sh @@ -36,7 +39,7 @@ unset _omb_uninstall_confirmation if [ -d ~/.oh-my-bash ]; then printf '%s\n' "Removing ~/.oh-my-bash" - rm -rf ~/.oh-my-bash + command rm -rf ~/.oh-my-bash fi _omb_uninstall_bashrc_original= @@ -56,16 +59,16 @@ _omb_uninstall_bashrc_uninstalled= if [ -e ~/.bashrc ] || [ -h ~/.bashrc ]; then _omb_uninstall_bashrc_uninstalled=".bashrc.omb-uninstalled-$(date +%Y%m%d%H%M%S)"; printf '%s\n' "Found ~/.bashrc -- Renaming to ~/${_omb_uninstall_bashrc_uninstalled}"; - mv ~/.bashrc ~/"${_omb_uninstall_bashrc_uninstalled}"; + command mv ~/.bashrc ~/"${_omb_uninstall_bashrc_uninstalled}"; fi if [ -n "$_omb_uninstall_bashrc_original" ]; then printf '%s\n' "Found $_omb_uninstall_bashrc_original -- Restoring to ~/.bashrc"; - mv "$_omb_uninstall_bashrc_original" ~/.bashrc; + command mv "$_omb_uninstall_bashrc_original" ~/.bashrc; printf '%s\n' "Your original bash config was restored. Please restart your session." else - sed '/oh-my-bash\.sh/s/^/: #/' ~/"${_omb_uninstall_bashrc_uninstalled:-.bashrc}" >| ~/.bashrc.omb-temp && \ - mv ~/.bashrc.omb-temp ~/.bashrc + command sed '/oh-my-bash\.sh/s/^/: #/' ~/"${_omb_uninstall_bashrc_uninstalled:-.bashrc}" >| ~/.bashrc.omb-temp && \ + command mv ~/.bashrc.omb-temp ~/.bashrc fi unset _omb_uninstall_bashrc_original @@ -73,5 +76,9 @@ unset _omb_uninstall_bashrc_uninstalled echo "Thanks for trying out Oh My Bash. It has been uninstalled." case $- in -*i*) exec bash; source ~/.bashrc ;; +*i*) + if [ -n "${BASH_VERSION-}" ]; then + declare -f _omb_util_unload >/dev/null 2>&1 && _omb_util_unload + source ~/.bashrc + fi ;; esac diff --git a/tools/upgrade.sh b/tools/upgrade.sh index 53e88a8..37d66b6 100644 --- a/tools/upgrade.sh +++ b/tools/upgrade.sh @@ -1,29 +1,35 @@ #!/usr/bin/env bash -# Use colors, but only if connected to a terminal, and that terminal -# supports them. -if which tput >/dev/null 2>&1; then - ncolors=$(tput colors) -fi -if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then - RED=$(tput setaf 1) - GREEN=$(tput setaf 2) - YELLOW=$(tput setaf 3) - BLUE=$(tput setaf 4) - BOLD=$(tput bold) - NORMAL=$(tput sgr0) -else - RED="" - GREEN="" - YELLOW="" - BLUE="" - BOLD="" - NORMAL="" -fi +function _omb_upgrade { + # Use colors, but only if connected to a terminal, and that terminal + # supports them. + if type -P tput &>/dev/null; then + local ncolors=$(tput colors) + fi -printf "${BLUE}%s${NORMAL}\n" "Updating Oh My Bash" + if [[ -t 1 && $ncolors && $ncolors -ge 8 ]]; then + local RED=$(tput setaf 1) + local GREEN=$(tput setaf 2) + local YELLOW=$(tput setaf 3) + local BLUE=$(tput setaf 4) + local BOLD=$(tput bold) + local NORMAL=$(tput sgr0) + else + local RED="" + local GREEN="" + local YELLOW="" + local BLUE="" + local BOLD="" + local NORMAL="" + fi + + printf "${BLUE}%s${NORMAL}\n" "Updating Oh My Bash" + + if ! command git -C "$OSH" pull --rebase --stat origin master; then + printf "${RED}%s${NORMAL}\n" 'There was an error updating. Try again later?' + return 1 + fi -if git -C "$OSH" pull --rebase --stat origin master; then printf '%s' "$GREEN" printf '%s\n' ' __ __ __ ' printf '%s\n' ' ____ / /_ ____ ___ __ __ / /_ ____ ______/ /_ ' @@ -33,7 +39,9 @@ if git -C "$OSH" pull --rebase --stat origin master; then printf '%s\n' ' /____/ ' printf "${BLUE}%s\n" "Hooray! Oh My Bash has been updated and/or is at the current version." printf "${BLUE}${BOLD}%s${NORMAL}\n" "To keep up on the latest news and updates, follow us on GitHub: https://github.com/ohmybash/oh-my-bash" - exec bash; source ~/.bashrc -else - printf "${RED}%s${NORMAL}\n" 'There was an error updating. Try again later?' -fi + if [[ $- == *i* ]]; then + declare -f _omb_util_unload &>/dev/null && _omb_util_unload + source ~/.bashrc + fi +} +_omb_upgrade