From 98ed726ec412f3624e3daa5efe54e805c747046f Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sat, 18 Nov 2023 23:39:50 +0000 Subject: [PATCH] ref(install): bring into parity with curl-pipe-bootstrap --- _webi/install-package.tpl.sh | 611 +++++++++++++++++++++++------------ 1 file changed, 403 insertions(+), 208 deletions(-) diff --git a/_webi/install-package.tpl.sh b/_webi/install-package.tpl.sh index 8aac40d..3b33be9 100644 --- a/_webi/install-package.tpl.sh +++ b/_webi/install-package.tpl.sh @@ -1,27 +1,10 @@ #!/bin/sh __bootstrap_webi() { - - set -e - set -u - #set -x - - my_libc='' - if ldd /bin/ls 2> /dev/null | grep -q 'musl' 2> /dev/null; then - my_libc='musl' - elif uname -o | grep -q 'GNU' || uname -s | grep -q 'Linux'; then - my_libc='gnu' - else - my_libc='libc' - fi - WEBI_UA="$(uname -s)/$(uname -r) $(uname -m)/unknown ${my_libc}" - - #WEBI_PKG= #PKG_NAME= #WEBI_OS= #WEBI_ARCH= #WEBI_LIBC= - #WEBI_HOST= #WEBI_RELEASES= #WEBI_CSV= #WEBI_TAG= @@ -43,7 +26,6 @@ __bootstrap_webi() { #PKG_ARCHES= #PKG_LIBCS= #PKG_FORMATS= - WEBI_UA="$(uname -s)/$(uname -r) $(uname -m)/unknown ${my_libc}" WEBI_PKG_DOWNLOAD="" WEBI_DOWNLOAD_DIR="${HOME}/Downloads" if command -v xdg-user-dir > /dev/null; then @@ -55,43 +37,6 @@ __bootstrap_webi() { WEBI_PKG_PATH="${WEBI_DOWNLOAD_DIR}/webi/${PKG_NAME:-error}/${WEBI_VERSION:-latest}" - export WEBI_HOST - - ## - ## Set up tmp, download, and install directories - ## - - WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-"${WEBI_PKG-}".XXXXXXXX)"} - export _webi_tmp="${_webi_tmp:-"$HOME/.local/opt/webi-tmp.d"}" - - mkdir -p "${WEBI_PKG_PATH}" - mkdir -p "$HOME/.local/bin" - mkdir -p "$HOME/.local/opt" - - if test -e ~/.local/bin; then - echo "Found ~/.local/bin" - else - echo "Creating ~/.local/bin" - mkdir -p "$HOME/.local/bin" - fi - - if test -e ~/.local/bin/webi; then - echo "Found ~/.local/bin/webi" - else - echo "Creating ~/.local/bin" - mkdir -p "$HOME/.local/bin" - fi - - ## - ## Detect http client - ## - set +e - WEBI_CURL="$(command -v curl)" - export WEBI_CURL - WEBI_WGET="$(command -v wget)" - export WEBI_WGET - set -e - # get the special formatted version # (i.e. "go is go1.14" while node is "node v12.10.8") my_versioned_name="" @@ -142,38 +87,30 @@ __bootstrap_webi() { if [ -n "$my_current_cmd" ]; then my_canonical_name="$(_webi_canonical_name)" if [ "$my_current_cmd" != "$pkg_dst_cmd" ]; then - echo >&2 "WARN: possible PATH conflict between $my_canonical_name and currently installed version" - echo >&2 " ${pkg_dst_cmd} (new)" - echo >&2 " ${my_current_cmd} (existing)" + echo >&2 " $(t_err "WARN: possible PATH conflict between $my_canonical_name and currently installed version")" + echo >&2 " $(t_path "${pkg_dst_cmd}") (new)" + echo >&2 " $(t_path "${my_current_cmd}") (existing)" #my_current_version=false fi # 'readlink' can't read links in paths on macOS 🤦 # but that's okay, 'cmp -s' is good enough for us if cmp -s "${pkg_src_cmd}" "${my_current_cmd}"; then - echo "${my_canonical_name} already installed:" - my_dst_rel="$( - webi_sub_home "${pkg_dst}" - )" - printf " %s" "${my_dst_rel}" + echo " $(t_pkg "${my_canonical_name}") already installed:" + my_dst_rel="$(fn_sub_home "${pkg_dst}")" + printf " %s" "$(t_link "${my_dst_rel}")" if [ "${pkg_src_cmd}" != "${my_current_cmd}" ]; then - my_src_rel="$( - webi_sub_home "${pkg_src}" - )" - printf " => %s" "${my_src_rel}" + my_src_rel="$(fn_sub_home "${pkg_src}")" + printf " => %s" "$(t_path "${my_src_rel}")" fi echo "" exit 0 fi if [ -x "$pkg_src_cmd" ]; then webi_link - echo "switched to $my_canonical_name:" - my_src_rel="$( - webi_sub_home "${pkg_src}" - )" - my_dst_rel="$( - webi_sub_home "${pkg_dst}" - )" - echo " ${my_dst_rel} => ${my_src_rel}" + echo " Switched to ${my_canonical_name}:" + my_src_rel="$(fn_sub_home "${pkg_src}")" + my_dst_rel="$(fn_sub_home "${pkg_dst}")" + echo " $(t_link "${my_dst_rel}") => $(t_path "${my_src_rel}")" exit 0 fi fi @@ -185,110 +122,61 @@ __bootstrap_webi() { return 0 fi - echo >&2 "Error: no '${PKG_NAME:-"Unknown Package"}@${WEBI_TAG:-"Unknown Tag"}' release for '${WEBI_OS:-"Unknown OS"}' (${WEBI_LIBC:-"Unknown Libc"}) on '${WEBI_ARCH:-"Unknown CPU"}' as one of '${WEBI_FORMATS:-"Unknown File Type"}'" - echo >&2 " '$PKG_NAME' is available for '$PKG_OSES' ($PKG_LIBCS) on '$PKG_ARCHES' as one of '$PKG_FORMATS'" - echo >&2 " (check that the package name and version are correct)" - echo >&2 "" - my_release_url="$( - echo "$WEBI_RELEASES" | - sed 's:?.*::' - )" - my_release_params="$( - echo "$WEBI_RELEASES" | - sed 's:.*?:?:' - )" - echo >&2 " Double check at ${my_release_url}" - echo >&2 " ${my_release_params}" - echo >&2 "" + { + echo "" + echo " $(t_err "Error: no '${PKG_NAME:-"Unknown Package"}@${WEBI_TAG:-"Unknown Tag"}' release for '${WEBI_OS:-"Unknown OS"}' (${WEBI_LIBC:-"Unknown Libc"}) on '${WEBI_ARCH:-"Unknown CPU"}' as one of '${WEBI_FORMATS:-"Unknown File Type"}'")" + echo " '$PKG_NAME' is available for '$PKG_OSES' ($PKG_LIBCS) on '$PKG_ARCHES' as one of '$PKG_FORMATS'" + echo " (check that the package name and version are correct)" + + echo "" + my_release_url="$(echo "$WEBI_RELEASES" | sed 's:?.*::')" + my_release_params="$(echo "$WEBI_RELEASES" | sed 's:.*?:?:')" + echo " Double check at ${my_release_url}" + echo " ${my_release_params}" + echo "" + } >&2 exit 1 } - is_interactive_shell() { - # $- shows shell flags (error,unset,interactive,etc) - case $- in - *i*) return 0 ;; - *) return 1 ;; - esac - } - - webi_sub_home() { ( - my_rel=${HOME} - my_abs=${1} - echo "${my_abs}" | sed "s:^${my_rel}:~:" - ); } - # detect if file is downloaded, and how to download it webi_download() { my_url="${1}" my_dl="${2}" my_dl_name="${3:-${PKG_NAME}}" - my_dl_rel="$( - webi_sub_home "${my_dl}" - )" + my_dl_rel="$(fn_sub_home "${my_dl}")" WEBI_PKG_DOWNLOAD="${my_dl}" export WEBI_PKG_DOWNLOAD if [ -e "${my_dl}" ]; then - echo "Found ${my_dl_rel}" + echo " $(t_dim 'Found') $(t_path "${my_dl_rel}")" return 0 fi - - echo "Downloading ${my_dl_name} from" - echo "$my_url" - - # It's only 2020, we can't expect to have reliable CLI tools - # to tell us the size of a file as part of a base system... - if [ -n "$WEBI_WGET" ]; then - # wget has resumable downloads - # TODO wget -c --content-disposition "$my_url" - set +e - my_show_progress="" - if is_interactive_shell; then - my_show_progress="--show-progress" - fi - if ! wget -q $my_show_progress --user-agent="wget $WEBI_UA" -c "$my_url" -O "$my_dl.part"; then - echo >&2 "failed to download from $WEBI_PKG_URL" - exit 1 - fi - set -e - else - # Neither GNU nor BSD curl have sane resume download options, hence we don't bother - my_show_progress="-#" - if is_interactive_shell; then - my_show_progress="" - fi - # shellcheck disable=SC2086 - # we want the flags to be split - curl -fSL $my_show_progress -H "User-Agent: curl $WEBI_UA" "$my_url" -o "$my_dl.part" - fi - mv "$my_dl.part" "$my_dl" - - echo "" - echo "Saved as ${my_dl_rel}" + echo " Downloading $(t_pkg "${my_dl_name}") from" + echo " $(t_url "${my_url}")" + fn_download_to_path "${my_url}" "${my_dl}" + echo " $(t_dim 'Saved as') $(t_path "${my_dl_rel}")" } webi_git_clone() { ( my_url="${1}" my_dl="${2}" - my_dl_rel="$( - webi_sub_home "${my_dl}" - )" + my_dl_rel="$(fn_sub_home "${my_dl}")" if [ -e "${my_dl}" ]; then - echo "Found ${my_dl_rel}" + echo " $(t_dim 'Found') $(t_path "${my_dl_rel}")" cp -RPp "${my_dl}" "${WEBI_TMP}/${WEBI_PKG_FILE}/" return 0 fi - echo "Cloning ${my_url}" + echo " Cloning $(t_url "${my_url}")" cmd_git="git clone --config advice.detachedHead=false --quiet --depth=1 --single-branch" rm -rf "${my_dl}.part" if ! $cmd_git "${my_url}" --branch "${WEBI_GIT_TAG}" "${my_dl}.part"; then - echo >&2 "failed to git clone ${WEBI_PKG_URL}" + echo >&2 " $(t_err "failed to git clone ${WEBI_PKG_URL}")" exit 1 fi mv "${my_dl}.part" "${my_dl}" @@ -297,34 +185,33 @@ __bootstrap_webi() { ); } # detect which archives can be used - webi_extract() { - ( - cd "$WEBI_TMP" + webi_extract() { ( + cd "$WEBI_TMP" - my_dl_rel="$( - webi_sub_home "${WEBI_PKG_PATH}/${WEBI_PKG_FILE}" - )" - if [ "tar" = "$WEBI_EXT" ]; then - echo "Extracting ${my_dl_rel}" - tar xf "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" - elif [ "zip" = "$WEBI_EXT" ]; then - echo "Extracting ${my_dl_rel}" - unzip "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > __unzip__.log - elif [ "exe" = "$WEBI_EXT" ]; then - echo "Moving ${my_dl_rel}" - mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" . - elif [ "git" = "$WEBI_EXT" ]; then - echo "Moving ${my_dl_rel}" - mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" . - elif [ "xz" = "$WEBI_EXT" ]; then - echo "Inflating ${my_dl_rel}" - unxz -c "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > "$(basename "$WEBI_PKG_FILE")" - else - echo "Failed to extract ${WEBI_PKG_PATH}/$WEBI_PKG_FILE" - exit 1 - fi - ) - } + my_dl_rel="$( + fn_sub_home "${WEBI_PKG_PATH}/${WEBI_PKG_FILE}" + )" + if [ "tar" = "$WEBI_EXT" ]; then + echo " Extracting $(t_path "${my_dl_rel}")" + tar xf "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" + elif [ "zip" = "$WEBI_EXT" ]; then + echo " Extracting $(t_path "${my_dl_rel}")" + unzip "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > __unzip__.log + elif [ "exe" = "$WEBI_EXT" ]; then + echo " Moving $(t_path "${my_dl_rel}")" + echo " to $(t_path "$(fn_sub_home "$(pwd)")")" + mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" . + elif [ "git" = "$WEBI_EXT" ]; then + echo " Moving $(t_path "${my_dl_rel}")" + mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" . + elif [ "xz" = "$WEBI_EXT" ]; then + echo " Inflating $(t_path "${my_dl_rel}")" + unxz -c "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > "$(basename "$WEBI_PKG_FILE")" + else + echo " $(t_err 'Failed to extract') $(t_path "${WEBI_PKG_PATH}/$WEBI_PKG_FILE")" + exit 1 + fi + ); } # use 'pathman' to update $HOME/.config/envman/PATH.env webi_path_add() { @@ -522,13 +409,19 @@ __bootstrap_webi() { # move commands from the extracted archive directory # to $HOME/.local/opt or $HOME/.local/bin webi_install() { + b_src='' if test -n "${WEBI_SINGLE}"; then + b_src="${pkg_src_cmd}" mkdir -p "$(dirname "$pkg_src_cmd")" - mv ./"$pkg_cmd_name"* "$pkg_src_cmd" else + echo " Removing $(t_path "${pkg_src}")" rm -rf "$pkg_src" - mv ./"$pkg_cmd_name"* "$pkg_src" + b_src="${pkg_src}" fi + + echo " Moving $(t_path "${pkg_cmd_name}")" + echo " to $(t_path "$(fn_sub_home "${b_src}")")" + mv ./"${pkg_cmd_name}"* "${b_src}" } # run post-install functions - just updating PATH by default @@ -549,15 +442,30 @@ __bootstrap_webi() { } _webi_done_message() { - my_dst_rel="$( - webi_sub_home "${pkg_dst_cmd}" - )" - my_canonical_name="$( - _webi_canonical_name - )" - echo "Installed ${my_canonical_name} as ${my_dst_rel}" + my_dst_rel="$(fn_sub_home "${pkg_dst_cmd}")" + my_canonical_name="$(_webi_canonical_name)" + echo "" + echo " Installed $(t_pkg "${my_canonical_name}") as $(t_link "${my_dst_rel}")" } + ## + ## Set up tmp, download, and install directories + ## + + WEBI_TMP=${WEBI_TMP:-"$(mktemp -d -t webinstall-"${WEBI_PKG-}".XXXXXXXX)"} + export _webi_tmp="${_webi_tmp:-"$HOME/.local/opt/webi-tmp.d"}" + + mkdir -p "${WEBI_PKG_PATH}" + mkdir -p "$HOME/.local/bin" + mkdir -p "$HOME/.local/opt" + + if test -e ~/.local/bin; then + echo " $(t_dim 'Found') $(t_path ' ~/.local/bin')" + else + echo " Creating$(t_path ' ~/.local/bin')" + mkdir -p "$HOME/.local/bin" + fi + ## ## ## BEGIN custom override functions from /install.sh @@ -566,20 +474,6 @@ __bootstrap_webi() { WEBI_SINGLE= - if [ -z "${WEBI_WELCOME-}" ]; then - echo "" - printf "Thanks for using webi to install '\e[32m%s\e[0m' on '\e[33m%s (%s) %s\e[0m'.\n" "${WEBI_PKG:-"Unknown Package"}" "$(uname -s)" "${WEBI_LIBC:-"Unknown Libc"}" "$(uname -m)" - echo "Have a problem? Experience a bug? Please let us know:" - printf " \e[2m\e[36mhttps://github.com/webinstall/webi-installers/issues\e[0m\n" - echo "" - printf "\e[35mLovin'\e[0m it? Say thanks with a \e[1m\e[33mStar on GitHub\e[0m:\n" - printf " \e[36mhttps://github.com/webinstall/webi-installers\e[0m\n" - echo "" - fi - - WEBI_WELCOME=true - export WEBI_WELCOME - __init_installer() { # the installer will be injected here # {{ installer }} @@ -642,12 +536,12 @@ __bootstrap_webi() { ( cd "$WEBI_TMP" my_src_rel="$( - webi_sub_home "${pkg_src_cmd}" + fn_sub_home "${pkg_src_cmd}" )" if test -e "${pkg_src_cmd}"; then - echo "Found ${my_src_rel} (remove to force reinstall)" + echo " $(t_dim 'Found') $(t_path "${my_src_rel}") $(t_dim '(remove to force reinstall)')" else - echo "Installing to ${my_src_rel}" + echo " Installing to $(t_path "${my_src_rel}")" if command -v pkg_install > /dev/null; then pkg_install; else webi_install; fi chmod a+x "$pkg_src" chmod a+x "$pkg_src_cmd" @@ -674,22 +568,323 @@ __bootstrap_webi() { webi_path_add "$HOME/.local/bin" if [ -z "${_WEBI_CHILD-}" ] && [ -f "$_webi_tmp/.PATH.env" ]; then if test -s "$_webi_tmp/.PATH.env"; then - printf 'PATH.env updated with:\n' + # shellcheck disable=SC2088 # ~ should not expand here + echo " Updated $(t_path '~/.config/envman/PATH.env') updated with:" sort -u "$_webi_tmp/.PATH.env" | while read -r my_new_path; do - echo " ${my_new_path}" + echo " $(t_path "${my_new_path}")" done - printf "\n" + echo "" rm -f "$_webi_tmp/.PATH.env" - printf "\e[1m\e[35mTO FINISH\e[0m: copy, paste & run the following command:\n" - printf "\n" - printf " \e[1m\e[32msource ~/.config/envman/PATH.env\e[0m\n" - printf " (newly opened terminal windows will update automatically)\n" + echo ">>> $(t_attn 'ACTION REQUIRED') <<<" + echo "" + echo " Copy, paste & run the following command:" + echo " $(t_attn 'source ~/.config/envman/PATH.env')" + echo " (newly opened terminal windows will update automatically)" + echo "" + echo "^^^ $(t_attn 'ACTION REQUIRED') ^^^" fi fi rm -rf "$WEBI_TMP" } -__bootstrap_webi +######################################### +# # +# Display Debug Info in Case of Failure # +# # +######################################### + +fn_show_welcome() { ( + echo "" + echo "" + # invert t_task and t_pkg for top-level welcome message + printf -- ">>> %s %s <<<\n" \ + "$(t_pkg 'Welcome to') $(t_task 'Webi')$(t_pkg '!')" \ + "$(t_dim "- modern tools, instant installs.")" + echo " We expect your experience to be $(t_em 'absolutely perfect')!" + echo "" + echo " $(t_attn 'Success')? Star it! $(t_url 'https://github.com/webinstall/webi-installers')" + echo " $(t_attn 'Problem')? Report it: $(t_url 'https://github.com/webinstall/webi-installers/issues')" + echo " $(t_dim "(your system is") $(t_host "$(uname -s)")/$(t_host "$(uname -m)") $(t_dim "with") $(t_host "$(fn_get_libc)") $(t_dim "&") $(t_host "$(fn_get_http_client_name)")$(t_dim ")")" + + sleep 0.2 +); } + +fn_get_libc() { ( + # Ex: + # musl + # libc + if ldd /bin/ls 2> /dev/null | grep -q 'musl' 2> /dev/null; then + echo 'musl' + elif uname -o | grep -q 'GNU' || uname -s | grep -q 'Linux'; then + echo 'gnu' + else + echo 'libc' + fi +); } + +fn_get_http_client_name() { ( + # Ex: + # curl + # curl+wget + b_client="" + if command -v curl > /dev/null; then + b_client="curl" + fi + if command -v wget > /dev/null; then + if test -z "${b_client}"; then + b_client="wget" + else + b_client="curl+wget" + fi + fi + + echo "${b_client}" +); } + +######################################### +# # +# For Making the Display Nice # +# # +######################################### + +# Term Types +t_cmd() { (fn_printf '\e[2m\e[35m%s\e[39m\e[22m' "${1}"); } +t_host() { (fn_printf '\e[2m\e[33m%s\e[39m\e[22m' "${1}"); } +t_link() { (fn_printf '\e[1m\e[36m%s\e[39m\e[22m' "${1}"); } +t_path() { (fn_printf '\e[2m\e[32m%s\e[39m\e[22m' "${1}"); } +t_pkg() { (fn_printf '\e[1m\e[32m%s\e[39m\e[22m' "${1}"); } +t_task() { (fn_printf '\e[36m%s\e[39m' "${1}"); } +t_url() { (fn_printf '\e[2m%s\e[22m' "${1}"); } + +# Levels +t_info() { (fn_printf '\e[1m\e[36m%s\e[39m\e[22m' "${1}"); } +t_attn() { (fn_printf '\e[1m\e[33m%s\e[39m\e[22m' "${1}"); } +t_warn() { (fn_printf '\e[1m\e[33m%s\e[39m\e[22m' "${1}"); } +t_err() { (fn_printf '\e[31m%s\e[39m' "${1}"); } + +# Styles +t_bold() { (fn_printf '\e[1m%s\e[22m' "${1}"); } +t_dim() { (fn_printf '\e[2m%s\e[22m' "${1}"); } +t_em() { (fn_printf '\e[3m%s\e[23m' "${1}"); } +t_under() { (fn_printf '\e[4m%s\e[24m' "${1}"); } + +# FG Colors +t_cyan() { (fn_printf '\e[36m%s\e[39m' "${1}"); } +t_green() { (fn_printf '\e[32m%s\e[39m' "${1}"); } +t_magenta() { (fn_printf '\e[35m%s\e[39m' "${1}"); } +t_yellow() { (fn_printf '\e[33m%s\e[39m' "${1}"); } + +fn_printf() { ( + a_style="${1}" + a_text="${2}" + if fn_is_tty; then + #shellcheck disable=SC2059 + printf -- "${a_style}" "${a_text}" + else + printf -- '%s' "${a_text}" + fi +); } + +fn_sub_home() { ( + my_rel=${HOME} + my_abs=${1} + echo "${my_abs}" | sed "s:^${my_rel}:~:" +); } + +################################### +# # +# Detect HTTP Client # +# # +################################### + +fn_wget() { ( + # Doc: + # Downloads the file at the given url to the given path + a_url="${1}" + a_path="${2}" + + cmd_wget="wget -q --user-agent" + if fn_is_tty; then + cmd_wget="wget -q --show-progress --user-agent" + fi + + b_triple_ua="$(fn_get_target_triple_user_agent)" + b_agent="webi/wget ${b_triple_ua}" + if command -v curl > /dev/null; then + b_agent="webi/wget+curl ${b_triple_ua}" + fi + + if ! $cmd_wget "${b_agent}" -c "${a_url}" -O "${a_path}"; then + echo >&2 " $(t_err "failed to download (wget)") '$(t_url "${a_url}")'" + echo >&2 " $cmd_wget '${b_agent}' -c '${a_url}' -O '${a_path}'" + echo >&2 " $(wget -V)" + return 1 + fi +); } + +fn_curl() { ( + # Doc: + # Downloads the file at the given url to the given path + a_url="${1}" + a_path="${2}" + + cmd_curl="curl -f -sSL -#" + if fn_is_tty; then + cmd_curl="curl -f -sSL" + fi + + b_triple_ua="$(fn_get_target_triple_user_agent)" + b_agent="webi/curl ${b_triple_ua}" + if command -v wget > /dev/null; then + b_agent="webi/curl+wget ${b_triple_ua}" + fi + + if ! $cmd_curl -A "${b_agent}" "${a_url}" -o "${a_path}"; then + echo >&2 " $(t_err "failed to download (curl)") '$(t_url "${a_url}")'" + echo >&2 " $cmd_curl -A '${b_agent}' '${a_url}' -o '${a_path}'" + echo >&2 " $(curl -V)" + return 1 + fi +); } + +fn_get_target_triple_user_agent() { ( + # Ex: + # x86_64/unknown Linux/5.15.107-2-pve gnu + # arm64/unknown Darwin/22.6.0 libc + echo "$(uname -m)/unknown $(uname -s)/$(uname -r) $(fn_get_libc)" +); } + +fn_download_to_path() { ( + a_url="${1}" + a_path="${2}" + + mkdir -p "$(dirname "${a_path}")" + if command -v wget > /dev/null; then + fn_wget "${a_url}" "${a_path}.part" + elif command -v curl > /dev/null; then + fn_curl "${a_url}" "${a_path}.part" + else + echo >&2 " $(t_err "failed to detect HTTP client (curl, wget)")" + return 1 + fi + mv "${a_path}.part" "${a_path}" +); } + +############################################## +# # +# Install or Update Webi and Install Package # +# # +############################################## + +webi_bootstrap() { ( + a_path="${1}" + + echo "" + echo "$(t_task 'Bootstrapping') $(t_pkg 'Webi')" + + b_path_rel="$(fn_sub_home "${a_path}")" + b_checksum="" + if test -r "${a_path}"; then + b_checksum="$(fn_checksum "${a_path}")" + fi + if test "$b_checksum" = "${WEBI_CHECKSUM}"; then + echo " $(t_dim 'Found') $(t_path "${b_path_rel}")" + sleep 0.1 + return 0 + fi + + b_webi_file_url="${WEBI_HOST}/packages/webi/webi.sh" + b_tmp='' + if test -r "${a_path}"; then + b_ts="$(date -u '+%s')" + b_tmp="${a_path}.${b_ts}.bak" + mv "${a_path}" "${b_tmp}" + echo " Updating $(t_path "${b_path_rel}")" + fi + + echo " Downloading $(t_url "${b_webi_file_url}")" + echo " to $(t_path "${b_path_rel}")" + fn_download_to_path "${b_webi_file_url}" "${a_path}" + chmod u+x "${a_path}" + + if test -r "${b_tmp}"; then + rm -f "${b_tmp}" + fi +); } + +fn_checksum() { + a_filepath="${1}" + + cmd_shasum='sha1sum' + if command -v shasum > /dev/null; then + cmd_shasum='shasum' + fi + + $cmd_shasum "${a_filepath}" | cut -d' ' -f1 | cut -c 1-8 +} + +############################################## +# # +# Detect TTY and run main # +# # +############################################## + +fn_is_tty() { + if test "${WEBI_TTY}" = 'tty'; then + return 0 + fi + return 1 +} + +fn_detect_tty() { ( + # stdin will NOT be a tty if it's being piped + # stdout & stderr WILL be a tty even when piped + # they are not a tty if being captured or redirected + # 'set -i' is NOT available in sh + if test -t 1 && test -t 2; then + return 0 + fi + + return 1 +); } + +main() { ( + set -e + set -u + #set -x + + export WEBI_HOST= + export WEBI_CHECKSUM= + export WEBI_PKG= + + WEBI_TTY="${WEBI_TTY:-}" + if test -z "${WEBI_TTY}"; then + if fn_detect_tty; then + WEBI_TTY="tty" + fi + export WEBI_TTY + fi + + if test -z "${WEBI_WELCOME:-}"; then + fn_show_welcome + fi + export WEBI_WELCOME='shown' + + # note: we may support custom locations in the future + export WEBI_HOME="${HOME}/.local" + b_webi_path="${WEBI_HOME}/bin/webi" + + WEBI_CURRENT="${WEBI_CURRENT:-}" + if test "${WEBI_CURRENT}" != "${WEBI_CHECKSUM}"; then + webi_bootstrap "${b_webi_path}" + export WEBI_CURRENT="${WEBI_CHECKSUM}" + fi + + echo "$(t_task 'Installing') $(t_pkg "${WEBI_PKG}") $(t_task '...')" + __bootstrap_webi +); } + +main