@ -2,6 +2,45 @@
#
#
# This script does not have a stable API.
# This script does not have a stable API.
_gitstatus_install_daemon_found() {
local installed="$1"
shift
case "$daemon" in
*-darwin-x86_64);;
*)
[ $# = 0 ] || "$@" "$daemon" "$version" "$installed"
return
;;
esac
local cpu
if [ "$uname_sm" != 'darwin arm64' ] ||
[ -e /Library/Apple/System/Library/LaunchDaemons/com.apple.oahd.plist ] ||
[ ! -x /usr/sbin/softwareupdate ] ||
! cpu="$(/usr/sbin/sysctl -n machdep.cpu.brand_string)"; then
[ $# = 0 ] || "$@" "$daemon" "$version" "$installed"
return
fi
case "$cpu" in
*Intel*);;
*)
[ $# = 0 ] || "$@" "$daemon" "$version" "$installed"
return
;;
esac
>&"$e" printf 'Please run the following command to install Rosetta:\n'
>&"$e" printf '\n'
>&"$e" printf ' \033[32m/usr/sbin/softwareupdate\033[0m --install-rosetta\n'
>&"$e" printf '\n'
>&"$e" printf 'See for details: \033[4mhttps://support.apple.com/en-us/HT211861\033[0m\n'
>&"$e" printf '\n'
>&"$e" printf 'Once Rosetta is installed, restart your shell.\n'
return 1
}
_gitstatus_install_main() {
_gitstatus_install_main() {
if [ -n "${ZSH_VERSION:-}" ]; then
if [ -n "${ZSH_VERSION:-}" ]; then
emulate -L sh -o no_unset
emulate -L sh -o no_unset
@ -12,14 +51,14 @@ _gitstatus_install_main() {
local argv1="$1"
local argv1="$1"
shift
shift
local no_check= no_install= uname_s= uname_m= gitstatus_dir= dl_status=
local no_check= no_install= uname_s= uname_m= gitstatus_dir= dl_status= e=
local opt= OPTARG= OPTIND=1
local opt= OPTARG= OPTIND=1
while getopts ':s:m:d:p:fnh' opt "$@"; do
while getopts ':s:m:d:p:e: fnh' opt "$@"; do
case "$opt" in
case "$opt" in
h)
h)
command cat <<\END
command cat <<\END
Usage: install [-s KERNEL] [-m ARCH] [-d DIR] [-p CMD] [-f|-n] [-- CMD [ARG]...]
Usage: install [-s KERNEL] [-m ARCH] [-d DIR] [-p CMD] [-e ERRFD] [- f|-n] [-- CMD [ARG]...]
If positional arguments are specified, call this on success:
If positional arguments are specified, call this on success:
@ -36,6 +75,7 @@ Options:
-m ARCH use this instead of lowercase `uname -m`
-m ARCH use this instead of lowercase `uname -m`
-d DIR use this instead of `dirname "$0"`
-d DIR use this instead of `dirname "$0"`
-p CMD eval this every second while downloading gitstatusd
-p CMD eval this every second while downloading gitstatusd
-e ERRFD write error messages to this file descriptor
-f download gitstatusd even if there is one locally
-f download gitstatusd even if there is one locally
-n do not download gitstatusd (fail instead)
-n do not download gitstatusd (fail instead)
END
END
@ -77,6 +117,17 @@ END
fi
fi
dl_status="$OPTARG"
dl_status="$OPTARG"
;;
;;
e)
if [ -n "$e" ]; 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
e="$OPTARG"
;;
m)
m)
if [ -n "$uname_m" ]; then
if [ -n "$uname_m" ]; then
>&2 echo "[gitstatus] error: duplicate option: -$opt"
>&2 echo "[gitstatus] error: duplicate option: -$opt"
@ -107,6 +158,7 @@ END
shift "$((OPTIND - 1))"
shift "$((OPTIND - 1))"
: "${e:=2}"
: "${gitstatus_dir:=$argv1}"
: "${gitstatus_dir:=$argv1}"
if [ -n "$no_check" -a -n "$no_install" ]; then
if [ -n "$no_check" -a -n "$no_install" ]; then
@ -144,7 +196,8 @@ END
>&2 echo "[gitstatus] internal error: empty gitstatus_version in build.info"
>&2 echo "[gitstatus] internal error: empty gitstatus_version in build.info"
return 1
return 1
fi
fi
[ $# = 0 ] || "$@" "$daemon" "$gitstatus_version" 0
local version="$gitstatus_version"
_gitstatus_install_daemon_found 0 "$@"
return
return
fi
fi
fi
fi
@ -184,7 +237,7 @@ END
[ -e "$daemon" ] || daemon=
[ -e "$daemon" ] || daemon=
fi
fi
if [ -n "$daemon" ]; then
if [ -n "$daemon" ]; then
[ $# = 0 ] || "$@" "$daemon" "$version" 0
_gitstatus_install_daemon_found 0 "$@"
return
return
fi
fi
fi
fi
@ -202,17 +255,59 @@ END
>&2 echo "[gitstatus] error: GITSTATUS_CACHE_DIR is not absolute: $cache_dir"
>&2 echo "[gitstatus] error: GITSTATUS_CACHE_DIR is not absolute: $cache_dir"
return 1
return 1
fi
fi
[ -d "$cache_dir" ] || mkdir -p -- "$cache_dir" || return
if [ ! -d "$cache_dir" ] && ! mkdir -p -- "$cache_dir" || [ ! -w "$cache_dir" ]; then
local dir="$cache_dir"
while true; do
if [ -e "$dir" ]; then
if [ ! -d "$dir" ]; then
>&"$e" printf 'Not a directory: \033[4;31m%s\033[0m\n' "$dir"
>&"$e" printf '\n'
>&"$e" printf 'Delete it, then restart your shell.\n'
elif [ ! -w "$dir" ]; then
>&"$e" printf 'Directory is not writable: \033[4;31m%s\033[0m\n' "$dir"
>&"$e" printf '\n'
>&"$e" printf 'Make it writable, then restart your shell.\n'
fi
break
fi
if [ "$dir" = / ] || [ "$dir" = . ]; then
break
fi
dir="$(dirname -- "$dir")"
done
return 1
fi
local tmpdir
local tmpdir
if ! command -v mktemp >/dev/null 2>&1 ||
if ! command -v mktemp >/dev/null 2>&1 ||
! tmpdir="$(command mktemp -d "${TMPDIR:-/tmp}"/gitstatus-install.XXXXXXXXXX)"; then
! tmpdir="$(command mktemp -d "${TMPDIR:-/tmp}"/gitstatus-install.XXXXXXXXXX)"; then
tmpdir="${TMPDIR:-/tmp}/gitstatus-install.tmp.$$"
tmpdir="${TMPDIR:-/tmp}/gitstatus-install.tmp.$$"
mkdir -p -- "$tmpdir" || return
if ! mkdir -p -- "$tmpdir"; then
local dir="${TMPDIR:-/tmp}"
if [ -z "${TMPDIR:-}" ]; then
local label='directory'
else
local label='directory (\033[1mTMPDIR\033[m)'
fi
if [ ! -e "$dir" ]; then
>&"$e" printf 'Temporary '"$label"' does not exist: \033[4;31m%s\033[0m\n' "$dir"
>&"$e" printf '\n'
>&"$e" printf 'Create it, then restart your shell.\n'
elif [ ! -d "$dir" ]; then
>&"$e" printf 'Not a '"$label"': \033[4;31m%s\033[0m\n' "$dir"
>&"$e" printf '\n'
>&"$e" printf 'Make it a directory, then restart your shell.\n'
elif [ ! -w "$dir" ]; then
>&"$e" printf 'Temporary '"$label"' is not writable: \033[4;31m%s\033[0m\n' "$dir"
>&"$e" printf '\n'
>&"$e" printf 'Make it writable, then restart your shell.\n'
fi
return 1
fi
fi
fi
if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then
if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then
>&2 echo "[gitstatus] error: please install curl or wget"
>&"$e" printf 'Please install \033[32mcurl\033[0m or \033[32mwget\033[0m, then restart your shell.\n'
return 1
return 1
fi
fi
@ -363,10 +458,12 @@ END
trap - $sig
trap - $sig
if [ -z "$n" ]; then
if [ -z "$n" ]; then
>&2 echo "[gitstatus] error: failed to download gitstatusd from any mirror"
>&"$e" printf 'Failed to download \033[32m%s\033[0m from any mirror:\n' "$file"
>&2 echo ""
>&"$e" printf '\n'
>&2 echo " 1. $url1"
>&"$e" printf ' 1. \033[4m%s\033[0m\n' "$url1"
>&2 echo " 2. $url2"
>&"$e" printf ' 2. \033[4m%s\033[0m\n' "$url2"
>&"$e" printf '\n'
>&"$e" printf 'Check your internet connection, then restart your shell.\n'
exit 1
exit 1
fi
fi
@ -378,7 +475,7 @@ END
tmpfile="$cache_dir"/gitstatusd.tmp.$$
tmpfile="$cache_dir"/gitstatusd.tmp.$$
fi
fi
command mv -f -- "$tmpdir"/gitstatusd-* "$tmpfile" || exit
command mv -f -- "$tmpdir"/"$file" "$tmpfile" || exit
command mv -f -- "$tmpfile" "$cache_dir"/"$file" && exit
command mv -f -- "$tmpfile" "$cache_dir"/"$file" && exit
command rm -f -- "$cache_dir"/"$file"
command rm -f -- "$cache_dir"/"$file"
command mv -f -- "$tmpfile" "$cache_dir"/"$file" && exit
command mv -f -- "$tmpfile" "$cache_dir"/"$file" && exit
@ -390,13 +487,13 @@ END
command rm -rf -- "$tmpdir"
command rm -rf -- "$tmpdir"
[ "$ret" = 0 ] || return
[ "$ret" = 0 ] || return
[ $# = 0 ] || "$@" "$daemon" "$version" 1
_gitstatus_install_daemon_found 1 "$@"
return
return
done <"$gitstatus_dir"/install.info
done <"$gitstatus_dir"/install.info
>&2 echo "[gitstatus] error: no gitstatusd found for $uname_s $uname_m"
>&"$e" printf 'There is no prebuilt \033[32mgitstatusd\033[0m for \033[1m%s\033[0m.\n' " $uname_s $uname_m"
>&2 echo ""
>&"$e" printf '\n'
>&2 echo "See: https://github.com/romkatv/gitstatus/blob/master/README.md#compiling"
>&"$e" printf 'See: \033[4mhttps://github.com/romkatv/gitstatus#compiling\033[0m\n'
return 1
return 1
}
}