466 lines
10 KiB
Bash
Executable File
466 lines
10 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
|
|
set -eu
|
|
printf '\n'
|
|
|
|
BOLD="$(tput bold 2>/dev/null || printf '')"
|
|
GREY="$(tput setaf 0 2>/dev/null || printf '')"
|
|
UNDERLINE="$(tput smul 2>/dev/null || printf '')"
|
|
RED="$(tput setaf 1 2>/dev/null || printf '')"
|
|
GREEN="$(tput setaf 2 2>/dev/null || printf '')"
|
|
YELLOW="$(tput setaf 3 2>/dev/null || printf '')"
|
|
BLUE="$(tput setaf 4 2>/dev/null || printf '')"
|
|
MAGENTA="$(tput setaf 5 2>/dev/null || printf '')"
|
|
NO_COLOR="$(tput sgr0 2>/dev/null || printf '')"
|
|
|
|
SUPPORTED_TARGETS="x86_64-unknown-linux-gnu x86_64-unknown-linux-musl \
|
|
i686-unknown-linux-musl aarch64-unknown-linux-musl \
|
|
arm-unknown-linux-musleabihf x86_64-apple-darwin \
|
|
aarch64-apple-darwin x86_64-pc-windows-msvc \
|
|
i686-pc-windows-msvc aarch64-pc-windows-msvc \
|
|
x86_64-unknown-freebsd"
|
|
|
|
info() {
|
|
printf '%s\n' "${BOLD}${GREY}>${NO_COLOR} $*"
|
|
}
|
|
|
|
warn() {
|
|
printf '%s\n' "${YELLOW}! $*${NO_COLOR}"
|
|
}
|
|
|
|
error() {
|
|
printf '%s\n' "${RED}x $*${NO_COLOR}" >&2
|
|
}
|
|
|
|
completed() {
|
|
printf '%s\n' "${GREEN}✓${NO_COLOR} $*"
|
|
}
|
|
|
|
has() {
|
|
command -v "$1" 1>/dev/null 2>&1
|
|
}
|
|
|
|
# Gets path to a temporary file, even if
|
|
get_tmpfile() {
|
|
suffix="$1"
|
|
if has mktemp; then
|
|
printf "%s.%s" "$(mktemp)" "${suffix}"
|
|
else
|
|
# No really good options here--let's pick a default + hope
|
|
printf "/tmp/starship.%s" "${suffix}"
|
|
fi
|
|
}
|
|
|
|
# Test if a location is writeable by trying to write to it. Windows does not let
|
|
# you test writeability other than by writing: https://stackoverflow.com/q/1999988
|
|
test_writeable() {
|
|
path="${1:-}/test.txt"
|
|
if touch "${path}" 2>/dev/null; then
|
|
rm "${path}"
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
download() {
|
|
file="$1"
|
|
url="$2"
|
|
|
|
if has curl; then
|
|
cmd="curl --fail --silent --location --output $file $url"
|
|
elif has wget; then
|
|
cmd="wget --quiet --output-document=$file $url"
|
|
elif has fetch; then
|
|
cmd="fetch --quiet --output=$file $url"
|
|
else
|
|
error "No HTTP download program (curl, wget, fetch) found, exiting…"
|
|
return 1
|
|
fi
|
|
|
|
$cmd && return 0 || rc=$?
|
|
|
|
error "Command failed (exit code $rc): ${BLUE}${cmd}${NO_COLOR}"
|
|
printf "\n" >&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,"
|
|
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}"
|
|
return $rc
|
|
}
|
|
|
|
unpack() {
|
|
archive=$1
|
|
bin_dir=$2
|
|
sudo=${3-}
|
|
|
|
case "$archive" in
|
|
*.tar.gz)
|
|
flags=$(test -n "${VERBOSE-}" && echo "-xzvf" || echo "-xzf")
|
|
${sudo} tar "${flags}" "${archive}" -C "${bin_dir}"
|
|
return 0
|
|
;;
|
|
*.zip)
|
|
flags=$(test -z "${VERBOSE-}" && echo "-qq" || echo "")
|
|
UNZIP="${flags}" ${sudo} unzip "${archive}" -d "${bin_dir}"
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
error "Unknown package extension."
|
|
printf "\n"
|
|
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
|
|
}
|
|
|
|
usage() {
|
|
cat <<EOT
|
|
install.sh [option]
|
|
|
|
Fetch and install the latest version of starship, if starship is already
|
|
installed it will be updated to the latest version.
|
|
|
|
Options
|
|
|
|
-V, --verbose
|
|
Enable verbose output for the installer
|
|
|
|
-f, -y, --force, --yes
|
|
Skip the confirmation prompt during installation
|
|
|
|
-p, --platform
|
|
Override the platform identified by the installer [default: ${PLATFORM}]
|
|
|
|
-b, --bin-dir
|
|
Override the bin installation directory [default: ${BIN_DIR}]
|
|
|
|
-a, --arch
|
|
Override the architecture identified by the installer [default: ${ARCH}]
|
|
|
|
-B, --base-url
|
|
Override the base URL used for downloading releases [default: ${BASE_URL}]
|
|
|
|
-h, --help
|
|
Dispays this help message
|
|
|
|
EOT
|
|
}
|
|
|
|
elevate_priv() {
|
|
if ! has sudo; then
|
|
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 "rerun this script. Otherwise, please run this script as root, or install"
|
|
info "sudo."
|
|
exit 1
|
|
fi
|
|
if ! sudo -v; then
|
|
error "Superuser not granted, aborting installation"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
install() {
|
|
ext="$1"
|
|
|
|
if test_writeable "${BIN_DIR}"; then
|
|
sudo=""
|
|
msg="Installing Starship, please wait…"
|
|
else
|
|
warn "Escalated permissions are required to install to ${BIN_DIR}"
|
|
elevate_priv
|
|
sudo="sudo"
|
|
msg="Installing Starship as root, please wait…"
|
|
fi
|
|
info "$msg"
|
|
|
|
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:
|
|
# - win (Git Bash)
|
|
# - darwin
|
|
# - linux
|
|
# - linux_musl (Alpine)
|
|
# - freebsd
|
|
detect_platform() {
|
|
platform="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
|
|
|
case "${platform}" in
|
|
msys_nt*) platform="pc-windows-msvc" ;;
|
|
cygwin_nt*) platform="pc-windows-msvc";;
|
|
# mingw is Git-Bash
|
|
mingw*) platform="pc-windows-msvc" ;;
|
|
# use the statically compiled musl bins on linux to avoid linking issues.
|
|
linux) platform="unknown-linux-musl" ;;
|
|
darwin) platform="apple-darwin" ;;
|
|
freebsd) platform="unknown-freebsd" ;;
|
|
esac
|
|
|
|
printf '%s' "${platform}"
|
|
}
|
|
|
|
# Currently supporting:
|
|
# - x86_64
|
|
# - i386
|
|
# - arm
|
|
# - arm64
|
|
detect_arch() {
|
|
arch="$(uname -m | tr '[:upper:]' '[:lower:]')"
|
|
|
|
case "${arch}" in
|
|
amd64) arch="x86_64" ;;
|
|
armv*) arch="arm" ;;
|
|
arm64) arch="aarch64" ;;
|
|
esac
|
|
|
|
# `uname -m` in some cases mis-reports 32-bit OS as 64-bit, so double check
|
|
if [ "${arch}" = "x86_64" ] && [ "$(getconf LONG_BIT)" -eq 32 ]; then
|
|
arch=i686
|
|
elif [ "${arch}" = "aarch64" ] && [ "$(getconf LONG_BIT)" -eq 32 ]; then
|
|
arch=arm
|
|
fi
|
|
|
|
printf '%s' "${arch}"
|
|
}
|
|
|
|
detect_target() {
|
|
arch="$1"
|
|
platform="$2"
|
|
target="$arch-$platform"
|
|
|
|
if [ "${target}" = "arm-unknown-linux-musl" ]; then
|
|
target="${target}eabihf"
|
|
fi
|
|
|
|
printf '%s' "${target}"
|
|
}
|
|
|
|
|
|
confirm() {
|
|
if [ -z "${FORCE-}" ]; then
|
|
printf "%s " "${MAGENTA}?${NO_COLOR} $* ${BOLD}[y/N]${NO_COLOR}"
|
|
set +e
|
|
read -r yn </dev/tty
|
|
rc=$?
|
|
set -e
|
|
if [ $rc -ne 0 ]; then
|
|
error "Error reading from prompt (please re-run with the '--yes' option)"
|
|
exit 1
|
|
fi
|
|
if [ "$yn" != "y" ] && [ "$yn" != "yes" ]; then
|
|
error 'Aborting (please answer "yes" to continue)'
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
check_bin_dir() {
|
|
bin_dir="$1"
|
|
|
|
if [ ! -d "$BIN_DIR" ]; then
|
|
error "Installation location $BIN_DIR does not appear to be a directory"
|
|
info "Make sure the location exists and is a directory, then try again."
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
# https://stackoverflow.com/a/11655875
|
|
good=$(
|
|
IFS=:
|
|
for path in $PATH; do
|
|
if [ "${path}" = "${bin_dir}" ]; then
|
|
printf 1
|
|
break
|
|
fi
|
|
done
|
|
)
|
|
|
|
if [ "${good}" != "1" ]; then
|
|
warn "Bin directory ${bin_dir} is not in your \$PATH"
|
|
fi
|
|
}
|
|
|
|
is_build_available() {
|
|
arch="$1"
|
|
platform="$2"
|
|
target="$3"
|
|
|
|
good=$(
|
|
IFS=" "
|
|
for t in $SUPPORTED_TARGETS; do
|
|
if [ "${t}" = "${target}" ]; then
|
|
printf 1
|
|
break
|
|
fi
|
|
done
|
|
)
|
|
|
|
if [ "${good}" != "1" ]; then
|
|
error "${arch} builds for ${platform} are not yet available for Starship"
|
|
printf "\n" >&2
|
|
info "If you would like to see a build for your configuration,"
|
|
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}"
|
|
printf "\n"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# defaults
|
|
if [ -z "${PLATFORM-}" ]; then
|
|
PLATFORM="$(detect_platform)"
|
|
fi
|
|
|
|
if [ -z "${BIN_DIR-}" ]; then
|
|
BIN_DIR=/usr/local/bin
|
|
fi
|
|
|
|
if [ -z "${ARCH-}" ]; then
|
|
ARCH="$(detect_arch)"
|
|
fi
|
|
|
|
if [ -z "${BASE_URL-}" ]; then
|
|
BASE_URL="https://github.com/starship/starship/releases"
|
|
fi
|
|
|
|
# parse argv variables
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
-p | --platform)
|
|
PLATFORM="$2"
|
|
shift 2
|
|
;;
|
|
-b | --bin-dir)
|
|
BIN_DIR="$2"
|
|
shift 2
|
|
;;
|
|
-a | --arch)
|
|
ARCH="$2"
|
|
shift 2
|
|
;;
|
|
-B | --base-url)
|
|
BASE_URL="$2"
|
|
shift 2
|
|
;;
|
|
|
|
-V | --verbose)
|
|
VERBOSE=1
|
|
shift 1
|
|
;;
|
|
-f | -y | --force | --yes)
|
|
FORCE=1
|
|
shift 1
|
|
;;
|
|
-h | --help)
|
|
usage
|
|
exit
|
|
;;
|
|
|
|
-p=* | --platform=*)
|
|
PLATFORM="${1#*=}"
|
|
shift 1
|
|
;;
|
|
-b=* | --bin-dir=*)
|
|
BIN_DIR="${1#*=}"
|
|
shift 1
|
|
;;
|
|
-a=* | --arch=*)
|
|
ARCH="${1#*=}"
|
|
shift 1
|
|
;;
|
|
-B=* | --base-url=*)
|
|
BASE_URL="${1#*=}"
|
|
shift 1
|
|
;;
|
|
-V=* | --verbose=*)
|
|
VERBOSE="${1#*=}"
|
|
shift 1
|
|
;;
|
|
-f=* | -y=* | --force=* | --yes=*)
|
|
FORCE="${1#*=}"
|
|
shift 1
|
|
;;
|
|
|
|
*)
|
|
error "Unknown option: $1"
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
TARGET="$(detect_target "${ARCH}" "${PLATFORM}")"
|
|
|
|
is_build_available "${ARCH}" "${PLATFORM}" "${TARGET}"
|
|
|
|
printf " %s\n" "${UNDERLINE}Configuration${NO_COLOR}"
|
|
info "${BOLD}Bin directory${NO_COLOR}: ${GREEN}${BIN_DIR}${NO_COLOR}"
|
|
info "${BOLD}Platform${NO_COLOR}: ${GREEN}${PLATFORM}${NO_COLOR}"
|
|
info "${BOLD}Arch${NO_COLOR}: ${GREEN}${ARCH}${NO_COLOR}"
|
|
|
|
# non-empty VERBOSE enables verbose untarring
|
|
if [ -n "${VERBOSE-}" ]; then
|
|
VERBOSE=v
|
|
info "${BOLD}Verbose${NO_COLOR}: yes"
|
|
else
|
|
VERBOSE=
|
|
fi
|
|
|
|
printf '\n'
|
|
|
|
EXT=tar.gz
|
|
if [ "${PLATFORM}" = "pc-windows-msvc" ]; then
|
|
EXT=zip
|
|
fi
|
|
|
|
URL="${BASE_URL}/latest/download/starship-${TARGET}.${EXT}"
|
|
info "Tarball URL: ${UNDERLINE}${BLUE}${URL}${NO_COLOR}"
|
|
confirm "Install Starship ${GREEN}latest${NO_COLOR} to ${BOLD}${GREEN}${BIN_DIR}${NO_COLOR}?"
|
|
check_bin_dir "${BIN_DIR}"
|
|
|
|
install "${EXT}"
|
|
completed "Starship installed"
|
|
|
|
printf '\n'
|
|
info "Please follow the steps for your shell to complete the installation:
|
|
|
|
${BOLD}${UNDERLINE}Bash${NO_COLOR}
|
|
Add the following to the end of ${BOLD}~/.bashrc${NO_COLOR}:
|
|
|
|
eval \"\$(starship init bash)\"
|
|
|
|
${BOLD}${UNDERLINE}Fish${NO_COLOR}
|
|
Add the following to the end of ${BOLD}~/.config/fish/config.fish${NO_COLOR}:
|
|
|
|
starship init fish | source
|
|
|
|
${BOLD}${UNDERLINE}Zsh${NO_COLOR}
|
|
Add the following to the end of ${BOLD}~/.zshrc${NO_COLOR}:
|
|
|
|
eval \"\$(starship init zsh)\"
|
|
|
|
${BOLD}${UNDERLINE}Ion${NO_COLOR}
|
|
Add the following to the end of ${BOLD}~/.config/ion/initrc${NO_COLOR}:
|
|
|
|
eval \$(starship init ion)
|
|
|
|
${BOLD}${UNDERLINE}Tcsh${NO_COLOR}
|
|
Add the following to the end of ${BOLD}~/.tcshrc${NO_COLOR}:
|
|
|
|
eval \`starship init tcsh\`
|
|
|
|
${BOLD}${UNDERLINE}Xonsh${NO_COLOR}
|
|
Add the following to the end of ${BOLD}~/.xonshrc${NO_COLOR}:
|
|
|
|
execx($(starship init xonsh))
|
|
|
|
"
|