diff options
Diffstat (limited to 'gitstatus/install')
-rwxr-xr-x | gitstatus/install | 135 |
1 files changed, 114 insertions, 21 deletions
diff --git a/gitstatus/install b/gitstatus/install index 1ef27cbb..cc408354 100755 --- a/gitstatus/install +++ b/gitstatus/install @@ -12,14 +12,14 @@ _gitstatus_install_main() { local argv1=$1 shift - local no_check= no_install= uname_s= uname_m= gitstatus_dir= + local no_check= no_install= uname_s= uname_m= gitstatus_dir= dl_status= local opt= OPTARG= OPTIND=1 - while getopts ':s:m:d:fnh' opt "$@"; do + while getopts ':s:m:d:p:fnh' opt "$@"; do case "$opt" in h) command cat <<\END -Usage: install [-s KERNEL] [-m ARCH] [-d DIR] [-f|-n] [-- CMD [ARG]...] +Usage: install [-s KERNEL] [-m ARCH] [-d DIR] [-p CMD] [-f|-n] [-- CMD [ARG]...] If positional arguments are specified, call this on success: @@ -35,6 +35,7 @@ Options: -s KERNEL use this instead of lowercase `uname -s` -m ARCH use this instead of lowercase `uname -m` -d DIR use this instead of `dirname "$0"` + -p CMD eval this every second while downloading gitstatusd -f download gitstatusd even if there is one locally -n do not download gitstatusd (fail instead) END @@ -65,6 +66,17 @@ END fi gitstatus_dir="$OPTARG" ;; + p) + if [ -n "$dl_status" ]; then + >&2 echo "[gitstatus] error: duplicate option: -$opt" + return 1 + fi + if [ -z "$OPTARG" ]; then + >&2 echo "[error] incorrect value of -$opt: $OPTARG" + return 1 + fi + dl_status="$OPTARG" + ;; m) if [ -n "$uname_m" ]; then >&2 echo "[gitstatus] error: duplicate option: -$opt" @@ -204,30 +216,108 @@ END fi [ -d "$cache_dir" ] || mkdir -p -- "$cache_dir" || return - local url="https://github.com/romkatv/gitstatus/releases/download/$version/$file.tar.gz" - ( + local fetch + if command -v curl >/dev/null 2>&1; then + fetch="command curl -fsSLo" + elif command -v wget >/dev/null 2>&1; then + fetch="command wget -O" + else + >&2 echo "[gitstatus] error: please install curl or wget" + exit 1 + fi + + local url1="https://github.com/romkatv/gitstatus/releases/download/$version/$file.tar.gz" + local url2="https://gitee.com/romkatv/gitstatus/raw/release-$version/release/$file.tar.gz" + local tmp="$file".tmp.$$ + if [ -n "${ZSH_VERSION:-}" ]; then builtin cd -q -- "$cache_dir" || exit else cd -- "$cache_dir" || exit fi - local archive="$file".tmp.$$.tar.gz - local err + cleanup() { + local n + for n in "$@"; do + command rm -rf -- "$tmp"."$n".tar.gz "$tmp"."$n".status || return + done + } - if command -v curl >/dev/null 2>&1; then - err="$(command curl -fsSLo "$archive" -- "$url" 2>&1)" - elif command -v wget >/dev/null 2>&1; then - err="$(command wget -O "$archive" -- "$url" 2>&1)" - else - >&2 echo "[gitstatus] error: please install curl or wget" - exit 1 - fi + local sig='INT QUIT TERM ILL PIPE' - if [ $? != 0 ]; then - >&2 printf "%s\n" "$err" - >&2 echo "[gitstatus] error: failed to download gitstatusd: $url" + fetch() { + local trapped= + trap 'trapped=1' $sig + # TODO: enable this after adding sha256 verification. + [ "$1" = 1 ] || return + if [ "$1" != 1 ] && command -v sleep >/dev/null 2>/dev/null; then + sleep "$1" + fi + $fetch "$tmp"."$1".tar.gz -- "$2" 2>/dev/null & + local pid=$! + local die="trap - $sig; kill -- $pid 2>/dev/null; cleanup $1; exit 1" + trap "$die" $sig + [ -z "$trapped" ] || eval "$die" + wait -- "$pid" 2>/dev/null + local ret="$?" + echo -n >"$tmp"."$1".status + trap - $sig + return "$ret" + } + + local trapped= + trap 'trapped=1' $sig + fetch 1 "$url1" & + local pid1=$! + fetch 2 "$url2" & + local pid2=$! + + local die="trap - $sig; kill -- $pid1 $pid2 2>/dev/null; cleanup 1 2; exit 1" + trap "$die" $sig + [ -z "$trapped" ] || eval "$die" + + local n= + while true; do + [ -z "$dl_status" ] || eval "$dl_status" || eval "$die" + if command -v sleep >/dev/null 2>/dev/null; then + command sleep 1 + elif command -v true >/dev/null 2>/dev/null; then + command true + fi + if [ -n "$pid1" -a -e "$tmp".1.status ]; then + wait -- "$pid1" 2>/dev/null + local ret="$?" + pid1= + if [ "$ret" = 0 ]; then + [ -z "$pid2" ] || kill -- "$pid2" 2>/dev/null + n=1 + break + elif [ -z "$pid2" ]; then + break + fi + elif [ -n "$pid2" -a -e "$tmp".2.status ]; then + wait -- "$pid2" 2>/dev/null + local ret="$?" + pid2= + if [ "$ret" = 0 ]; then + [ -z "$pid1" ] || kill -- "$pid1" 2>/dev/null + n=2 + break + elif [ -z "$pid1" ]; then + break + fi + fi + done + + trap - $sig + + if [ -z "$n" ]; then + >&2 echo "[gitstatus] error: failed to download gitstatusd from any mirror" + >&2 echo "" + >&2 echo " 1. $url1" + >&2 echo " 2. $url2" + cleanup 1 2 exit 1 fi @@ -239,12 +329,15 @@ END [ -e "$old" ] || break i="$((i+1))" done - command mv -f -- "$daemon" "$old" || exit + if ! command mv -f -- "$daemon" "$old"; then + cleanup 1 2 + exit 1 + fi fi - command tar -xzf "$archive" + command tar -xzf "$tmp"."$n".tar.gz local ret=$? - command rm -f -- "$archive" + cleanup 1 2 if [ -n "$old" ]; then if [ "$ret" = 0 ]; then command rm -f -- "$old" 2>/dev/null |