feat(install): make install script posix compliant (#2228)

- update shebang to support posix-compliant shells (like dash)
- replace all usages of echo with printf (to normalise)
- command variable to fetch_cmd as it overloads a posix 
- rename complete function to completed as it overloads 
  the bash builtin for completion

Co-authored-by: David Knaack <davidkna@users.noreply.github.com>
This commit is contained in:
Deavon M. McCaffery 2021-03-03 22:57:36 +00:00 committed by GitHub
parent 6ef15b6d80
commit d1b2723033
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 90 additions and 80 deletions

View File

@ -1,4 +1,6 @@
#!/bin/bash #!/usr/bin/env sh
# shellcheck disable=SC2039
# Options # Options
# #
@ -20,18 +22,18 @@
# -B, --base-url # -B, --base-url
# Override the base URL used for downloading releases # Override the base URL used for downloading releases
set -euo pipefail set -eu
printf "\n" printf '\n'
BOLD="$(tput bold 2>/dev/null || echo '')" BOLD="$(tput bold 2>/dev/null || printf '')"
GREY="$(tput setaf 0 2>/dev/null || echo '')" GREY="$(tput setaf 0 2>/dev/null || printf '')"
UNDERLINE="$(tput smul 2>/dev/null || echo '')" UNDERLINE="$(tput smul 2>/dev/null || printf '')"
RED="$(tput setaf 1 2>/dev/null || echo '')" RED="$(tput setaf 1 2>/dev/null || printf '')"
GREEN="$(tput setaf 2 2>/dev/null || echo '')" GREEN="$(tput setaf 2 2>/dev/null || printf '')"
YELLOW="$(tput setaf 3 2>/dev/null || echo '')" YELLOW="$(tput setaf 3 2>/dev/null || printf '')"
BLUE="$(tput setaf 4 2>/dev/null || echo '')" BLUE="$(tput setaf 4 2>/dev/null || printf '')"
MAGENTA="$(tput setaf 5 2>/dev/null || echo '')" MAGENTA="$(tput setaf 5 2>/dev/null || printf '')"
NO_COLOR="$(tput sgr0 2>/dev/null || echo '')" NO_COLOR="$(tput sgr0 2>/dev/null || printf '')"
SUPPORTED_TARGETS="x86_64-unknown-linux-gnu x86_64-unknown-linux-musl \ SUPPORTED_TARGETS="x86_64-unknown-linux-gnu x86_64-unknown-linux-musl \
i686-unknown-linux-musl aarch64-unknown-linux-musl \ i686-unknown-linux-musl aarch64-unknown-linux-musl \
@ -41,26 +43,30 @@ SUPPORTED_TARGETS="x86_64-unknown-linux-gnu x86_64-unknown-linux-musl \
x86_64-unknown-freebsd" x86_64-unknown-freebsd"
info() { info() {
printf "%s\n" "${BOLD}${GREY}>${NO_COLOR} $*" printf '%s\n' "${BOLD}${GREY}>${NO_COLOR} $*"
} }
warn() { warn() {
printf "%s\n" "${YELLOW}! $*${NO_COLOR}" printf '%s\n' "${YELLOW}! $*${NO_COLOR}"
} }
error() { error() {
printf "%s\n" "${RED}x $*${NO_COLOR}" >&2 printf '%s\n' "${RED}x $*${NO_COLOR}" >&2
} }
complete() { completed() {
printf "%s\n" "${GREEN}${NO_COLOR} $*" printf '%s\n' "${GREEN}${NO_COLOR} $*"
}
has() {
command -v "$1" 1>/dev/null 2>&1
} }
# Gets path to a temporary file, even if # Gets path to a temporary file, even if
get_tmpfile() { get_tmpfile() {
local suffix local suffix
suffix="$1" suffix="$1"
if hash mktemp; then if has mktemp; then
printf "%s.%s" "$(mktemp)" "${suffix}" printf "%s.%s" "$(mktemp)" "${suffix}"
else else
# No really good options here--let's pick a default + hope # No really good options here--let's pick a default + hope
@ -81,64 +87,59 @@ test_writeable() {
fi fi
} }
fetch() { download() {
local command file="$1"
if hash curl 2>/dev/null; then url="$2"
set +e
command="curl --silent --fail --location $1" if has curl; then
curl --silent --fail --location "$1" cmd="curl --fail --silent --location --output $file $url"
rc=$? elif has wget; then
set -e cmd="wget --quiet --output-document=$file $url"
elif has fetch; then
cmd="fetch --quiet --output=$file $url"
else else
if hash wget 2>/dev/null; then error "No HTTP download program (curl, wget, fetch) found, exiting…"
set +e return 1
command="wget -O- -q $1"
wget -O- -q "$1"
rc=$?
set -e
else
error "No HTTP download program (curl, wget) found…"
exit 1
fi
fi fi
if [ $rc -ne 0 ]; then $cmd && return 0 || rc=$?
printf "\n" >&2
error "Command failed (exit code $rc): ${BLUE}${command}${NO_COLOR}" error "Command failed (exit code $rc): ${BLUE}${cmd}${NO_COLOR}"
printf "\n" >&2 printf "\n" >&2
info "This is likely due to Starship not yet supporting your configuration." >&2 info "This is likely due to Starship not yet supporting your configuration."
info "If you would like to see a build for your configuration," >&2 info "If you would like to see a build for your configuration,"
info "please create an issue requesting a build for ${MAGENTA}${ARCH}-${PLATFORM}${NO_COLOR}:" >&2 info "please create an issue requesting a build for ${MAGENTA}${TARGET}${NO_COLOR}:"
info "${BOLD}${UNDERLINE}https://github.com/starship/starship/issues/new/${NO_COLOR}\n" >&2 info "${BOLD}${UNDERLINE}https://github.com/starship/starship/issues/new/${NO_COLOR}"
exit $rc return $rc
fi
} }
fetch_and_unpack() { unpack() {
local sudo local archive=$1
local tmpfile local bin_dir=$2
sudo="$1" local sudo=${3-}
# I'd like to separate this into a fetch() and unpack() function, but I can't
# figure out how to get bash functions to read STDIN/STDOUT from pipes case "$archive" in
if [ "${EXT}" = "tar.gz" ]; then *.tar.gz)
fetch "${URL}" | ${sudo} tar xz"${VERBOSE}"f - -C "${BIN_DIR}" flags=$(test -n "${VERBOSE-}" && echo "-v" || echo "")
elif [ "${EXT}" = "zip" ]; then ${sudo} tar "${flags}" -xzf "${archive}" -C "${bin_dir}"
# According to https://unix.stackexchange.com/q/2690, zip files cannot be read return 0
# through a pipe. We'll have to do our own file-based setup. ;;
tmpfile="$(get_tmpfile "${EXT}")" *.zip)
fetch "${URL}" >"${tmpfile}" flags=$(test -z "${VERBOSE-}" && echo "-qq" || echo "")
${sudo} unzip "${tmpfile}" -d "${BIN_DIR}" UNZIP="${flags}" ${sudo} unzip "${archive}" -d "${bin_dir}"
rm "${tmpfile}" return 0
else ;;
error "Unknown package extension." esac
info "This almost certainly results from a bug in this script--please file a"
info "bug report at https://github.com/starship/starship/issues" error "Unknown package extension."
exit 1 printf "\n"
fi info "This almost certainly results from a bug in this script--please file a"
info "bug report at https://github.com/starship/starship/issues"
return 1
} }
elevate_priv() { elevate_priv() {
if ! hash sudo 2>/dev/null; then if ! has sudo; then
error 'Could not find the command "sudo", needed to get permissions for install.' error 'Could not find the command "sudo", needed to get permissions for install.'
info "If you are on Windows, please run your shell as an administrator, then" info "If you are on Windows, please run your shell as an administrator, then"
info "rerun this script. Otherwise, please run this script as root, or install" info "rerun this script. Otherwise, please run this script as root, or install"
@ -154,6 +155,8 @@ elevate_priv() {
install() { install() {
local msg local msg
local sudo local sudo
local archive
local ext="$1"
if test_writeable "${BIN_DIR}"; then if test_writeable "${BIN_DIR}"; then
sudo="" sudo=""
@ -165,7 +168,14 @@ install() {
msg="Installing Starship as root, please wait…" msg="Installing Starship as root, please wait…"
fi fi
info "$msg" info "$msg"
fetch_and_unpack "${sudo}"
archive=$(get_tmpfile "$ext")
# download to the temp file
download "${archive}" "${URL}"
# unpack the temp file to the bin dir, using sudo if required
unpack "${archive}" "${BIN_DIR}" "${sudo}"
} }
# Currently supporting: # Currently supporting:
@ -189,7 +199,7 @@ detect_platform() {
freebsd) platform="unknown-freebsd" ;; freebsd) platform="unknown-freebsd" ;;
esac esac
echo "${platform}" printf '%s' "${platform}"
} }
# Currently supporting: # Currently supporting:
@ -212,7 +222,7 @@ detect_arch() {
arch=arm arch=arm
fi fi
echo "${arch}" printf '%s' "${arch}"
} }
detect_target() { detect_target() {
@ -224,7 +234,7 @@ detect_target() {
target="${target}eabihf" target="${target}eabihf"
fi fi
echo "${target}" printf '%s' "${target}"
} }
@ -261,7 +271,7 @@ check_bin_dir() {
IFS=: IFS=:
for path in $PATH; do for path in $PATH; do
if [ "${path}" = "${bin_dir}" ]; then if [ "${path}" = "${bin_dir}" ]; then
echo 1 printf 1
break break
fi fi
done done
@ -278,12 +288,12 @@ is_build_available() {
local target="$3" local target="$3"
local good local good
good=$( good=$(
IFS=" " IFS=" "
for t in $SUPPORTED_TARGETS; do for t in $SUPPORTED_TARGETS; do
if [ "${t}" == "${target}" ]; then if [ "${t}" = "${target}" ]; then
echo 1 printf 1
break break
fi fi
done done
@ -395,7 +405,7 @@ else
VERBOSE= VERBOSE=
fi fi
echo printf '\n'
EXT=tar.gz EXT=tar.gz
if [ "${PLATFORM}" = "pc-windows-msvc" ]; then if [ "${PLATFORM}" = "pc-windows-msvc" ]; then
@ -407,10 +417,10 @@ info "Tarball URL: ${UNDERLINE}${BLUE}${URL}${NO_COLOR}"
confirm "Install Starship ${GREEN}latest${NO_COLOR} to ${BOLD}${GREEN}${BIN_DIR}${NO_COLOR}?" confirm "Install Starship ${GREEN}latest${NO_COLOR} to ${BOLD}${GREEN}${BIN_DIR}${NO_COLOR}?"
check_bin_dir "${BIN_DIR}" check_bin_dir "${BIN_DIR}"
install install "${EXT}"
complete "Starship installed" completed "Starship installed"
echo printf '\n'
info "Please follow the steps for your shell to complete the installation: info "Please follow the steps for your shell to complete the installation:
${BOLD}${UNDERLINE}Bash${NO_COLOR} ${BOLD}${UNDERLINE}Bash${NO_COLOR}