diff --git a/.gitignore b/.gitignore index c4ebb0f..c3d3ab0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ +.dotfiles-update .DS_store -*antigen-compat *.zwc history.sqlite -dhist ipython/profile_default/{log,db} ipython/profile_default/history.sqlite diff --git a/brethil_dotfile.sh b/brethil_dotfile.sh index 12c3bf5..7bde156 100755 --- a/brethil_dotfile.sh +++ b/brethil_dotfile.sh @@ -1,5 +1,5 @@ # Check for update, set DISABLE_UPDATE_PROMPT=yes to disable the prompt and automatically update -env DISABLE_UPDATE_PROMPT=$DISABLE_UPDATE_PROMPT DOTFILES="$DOTFILES" zsh -f "$DOTFILES/check_for_update.sh" +env DISABLE_UPDATE_PROMPT=$DISABLE_UPDATE_PROMPT zsh -f "$DOTFILES/check_for_update.sh" # theme-related variables export ZSH_CUSTOM="$DOTFILES" diff --git a/check_for_update.sh b/check_for_update.sh index 020bbaf..b88e0ff 100755 --- a/check_for_update.sh +++ b/check_for_update.sh @@ -1,78 +1,98 @@ #!/usr/bin/env zsh -# # brethil, brutally copied from https://github.com/robbyrussell/oh-my-zsh/blob/master/tools/check_for_upgrade.sh -# This also tries to update amix's vimrc and runs "antigen update" -# 14 July 2017 +# This also runs antibody update" +# First version: 14 July 2017 +# Rebased on upstream: 08 December 2020 -zmodload zsh/datetime +# Migrate .dotfiles-update file to $DOTFILES +if [[ -f ~/.dotfiles-update && ! -f "${DOTFILES}/.dotfiles-update" ]]; then + mv ~/.dotfiles-update "${DOTFILES}/.dotfiles-update" +fi -function _current_epoch() { - echo $(( $EPOCHSECONDS / 60 / 60 / 24 )) +# Cancel update if: +# - the automatic update is disabled. +# - the current user doesn't have write permissions nor owns the $ZSH directory. +# - git is unavailable on the system. +if [[ "$DISABLE_AUTO_UPDATE" = true ]] \ + || [[ ! -w "$ZSH" || ! -O "$ZSH" ]] \ + || ! command -v git &>/dev/null; then + return +fi + + +function current_epoch() { + zmodload zsh/datetime + echo $(( EPOCHSECONDS / 60 / 60 / 24 )) } function _update_dotfiles_update() { - echo "LAST_EPOCH=$(_current_epoch)" >! ~/.dotfiles-update + echo "LAST_EPOCH=$(current_epoch)" >! "${DOTFILES}/.dotfiles-update" } -function _upgrade_dotfiles() { +function update_dotfiles() { (cd $DOTFILES; git pull -q --rebase && echo "Succesfully upgraded dotfiles" || echo "Could not upgrade dotfiles.") - # amix's vimrc update - amix_vimrc=$HOME/.vim_runtime - if [[ -d $amix_vimrc ]]; then - # the update_plugins.py script makes the vim_runtime dir dirty, so we have to reset --hard - (cd $amix_vimrc && git reset --hard HEAD >/dev/null && git pull -q --rebase && echo "Upgraded amix's vimrc" || echo "Could not upgrade amix's vimrc" >&2) - (python $amix_vimrc/update_plugins.py >/dev/null || echo "upgraded amix's vimrc's plugins || "echo "Could not upgrade amix's vimrc's plugins" >&2) - else - echo "Could not upgrade amix's vimrc and plugins (missing .vim_runtime folder)" >&2 - fi - antibody update # update the zsh file _update_dotfiles_update } -epoch_target=$UPDATE_ZSH_DAYS -if [[ -z "$epoch_target" ]]; then - # Default to old behavior - epoch_target=13 -fi +() { + emulate -L zsh -# Cancel upgrade if the current user doesn't have write permissions for the -# dotfiles directory. -[[ -w "$DOTFILES" ]] || return 0 + local epoch_target mtime option LAST_EPOCH -# Cancel upgrade if git is unavailable on the system -whence git >/dev/null || return 0 - -# Clean up old lock files -find $DOTFILES/update.lock -mmin 60 -exec rm {} \; &>/dev/null - -if mkdir "$DOTFILES/update.lock" 2>/dev/null; then - if [ -f ~/.dotfiles-update ]; then - . ~/.dotfiles-update - - if [[ -z "$LAST_EPOCH" ]]; then - _update_dotfiles_update && return 0; + # Remove lock directory if older than a day + zmodload zsh/datetime + zmodload -F zsh/stat b:zstat + if mtime=$(zstat +mtime "$DOTFILES/update.lock" 2>/dev/null); then + if (( (mtime + 3600 * 24) < EPOCHSECONDS )); then + command rm -rf "$DOTFILES/update.lock" fi - - epoch_diff=$(($(_current_epoch) - $LAST_EPOCH)) - if [ $epoch_diff -gt $epoch_target ]; then - if [ "$DISABLE_UPDATE_PROMPT" = "true" ]; then - _upgrade_dotfiles - else - echo "[brethil dotfiles] Would you like to check for updates? [Y/n]: \c" - read line - if [[ "$line" == Y* ]] || [[ "$line" == y* ]] || [ -z "$line" ]; then - _upgrade_dotfiles - else - _update_dotfiles_update - fi - fi - fi - else - # create the dotfiles file - _update_dotfiles_update fi - rmdir $DOTFILES/update.lock -fi + # Check for lock directory + if ! command mkdir "$DOTFILES/update.lock" 2>/dev/null; then + return + fi + + # Remove lock directory on exit. `return 1` 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. + trap " + unset -f current_epoch _update_dotfiles_update update_dotfiles + command rm -rf '$DOTFILES/update.lock' + return 1 + " EXIT INT QUIT + + # Create or update .zsh-update file if missing or malformed + if ! source "~/.dotfiles-update" 2>/dev/null || [[ -z "$LAST_EPOCH" ]]; then + _update_dotfiles_update + return + fi + + # Number of days before trying to update again + epoch_target=${UPDATE_DOTFILES_DAYS:-5} + # Test if enough time has passed until the next update + if (( ( $(current_epoch) - $LAST_EPOCH ) < $epoch_target )); then + return + fi + + # Ask for confirmation before updating unless disabled + if [[ "$DISABLE_UPDATE_PROMPT" = true ]]; then + update_dotfiles + else + # input sink to swallow all characters typed before the prompt + # and add a newline if there wasn't one after characters typed + while read -t -k 1 option; do true; done + [[ "$option" != ($'\n'|"") ]] && echo + + echo -n "[brethil-dotfiles] Would you like to update? [Y/n] " + read -r -k 1 option + [[ "$option" != $'\n' ]] && echo + case "$option" in + [yY$'\n']) update_dotfiles ;; + [nN]) _update_dotfiles_update ;; + esac + fi +}