mirror of
https://github.com/Llewellynvdm/starship.git
synced 2024-12-01 09:13:54 +00:00
3ebd2c0ad5
Adds several cross-platform utility functions to the install.sh script and rewrites core functionality so that it might work on Windows. Among these are: - Correct platform extensions to match the output of `detect_platform` - Check to make sure installation directory actually exists - If sudo is not available, print a message asking the user to manually escalate - Unpack zip files (used for Windows builds) without using pipes, since zip files cannot be read through pipes After these changes, install.sh works on a testing copy of Git Bash on Windows, though it still has known issues (e.g. if the `unzip` program is not installed, it will crash).
352 lines
8.7 KiB
Bash
Executable File
352 lines
8.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# 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
|
|
#
|
|
# -b, --bin-dir
|
|
# Override the bin installation directory
|
|
#
|
|
# -a, --arch
|
|
# Override the architecture identified by the installer
|
|
#
|
|
# -B, --base-url
|
|
# Override the base URL used for downloading releases
|
|
|
|
set -euo pipefail
|
|
printf "\n"
|
|
|
|
BOLD="$(tput bold 2>/dev/null || echo '')"
|
|
GREY="$(tput setaf 0 2>/dev/null || echo '')"
|
|
UNDERLINE="$(tput smul 2>/dev/null || echo '')"
|
|
RED="$(tput setaf 1 2>/dev/null || echo '')"
|
|
GREEN="$(tput setaf 2 2>/dev/null || echo '')"
|
|
YELLOW="$(tput setaf 3 2>/dev/null || echo '')"
|
|
BLUE="$(tput setaf 4 2>/dev/null || echo '')"
|
|
MAGENTA="$(tput setaf 5 2>/dev/null || echo '')"
|
|
NO_COLOR="$(tput sgr0 2>/dev/null || echo '')"
|
|
|
|
info() {
|
|
printf "${BOLD}${GREY}>${NO_COLOR} $@\n"
|
|
}
|
|
|
|
warn() {
|
|
printf "${YELLOW}! $@${NO_COLOR}\n"
|
|
}
|
|
|
|
error() {
|
|
printf "${RED}x $@${NO_COLOR}\n" >&2
|
|
}
|
|
|
|
complete() {
|
|
printf "${GREEN}✓${NO_COLOR} $@\n"
|
|
}
|
|
|
|
# Gets path to a temporary file, even if
|
|
get_tmpfile(){
|
|
local suffix
|
|
suffix="$1"
|
|
if hash mktemp; then
|
|
printf "$(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(){
|
|
local path
|
|
path="${1:-}/test.txt"
|
|
if touch "${path}" 2> /dev/null; then
|
|
rm "${path}"
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
fetch() {
|
|
local command
|
|
if hash curl 2>/dev/null; then
|
|
set +e
|
|
command="curl --silent --fail --location $1"
|
|
curl --silent --fail --location "$1"
|
|
rc=$?
|
|
set -e
|
|
else
|
|
if hash wget 2>/dev/null; then
|
|
set +e
|
|
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
|
|
|
|
if [ $rc -ne 0 ]; then
|
|
printf "\n" >&2
|
|
error "Command failed (exit code $rc): ${BLUE}${command}${NO_COLOR}"
|
|
printf "\n" >&2
|
|
info "This is likely due to Starship not yet supporting your configuration." >&2
|
|
info "If you would like to see a build for your configuration," >&2
|
|
info "please create an issue requesting a build for ${MAGENTA}${ARCH}-${PLATFORM}${NO_COLOR}:" >&2
|
|
info "${BOLD}${UNDERLINE}https://github.com/starship/starship/issues/new/${NO_COLOR}\n" >&2
|
|
exit $rc
|
|
fi
|
|
}
|
|
|
|
fetch_and_unpack(){
|
|
local sudo
|
|
local tmpfile
|
|
sudo="$1"
|
|
# 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
|
|
if [ "${EXT}" = "tar.gz" ]; then
|
|
fetch "${URL}" | ${sudo} tar xzf${VERBOSE} - -C "${BIN_DIR}"
|
|
elif [ "${EXT}" = "zip" ]; then
|
|
# According to https://unix.stackexchange.com/q/2690, zip files cannot be read
|
|
# through a pipe. We'll have to do our own file-based setup.
|
|
tmpfile="$(get_tmpfile "${EXT}")"
|
|
fetch "${URL}" > "${tmpfile}"
|
|
${sudo} unzip "${tmpfile}" -d "${BIN_DIR}"
|
|
rm "${tmpfile}"
|
|
else
|
|
error "Unknown package extension."
|
|
info "This almost certainly results from a bug in this script--please file a"
|
|
info "bug report at https://github.com/starship/starship/issues"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
elevate_priv(){
|
|
if ! hash sudo 2>/dev/null; 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() {
|
|
local msg
|
|
local sudo
|
|
|
|
if test_writeable "${BIN_DIR}" ; then
|
|
sudo=""
|
|
msg="Installing Starship, please wait…"
|
|
else
|
|
warn "Escalated permission are required to install to ${BIN_DIR}"
|
|
elevate_priv
|
|
sudo="sudo"
|
|
msg="Installing Starship as root, please wait…"
|
|
fi
|
|
info "$msg"
|
|
fetch_and_unpack "${sudo}"
|
|
}
|
|
|
|
# Currently supporting:
|
|
# - win (Git Bash)
|
|
# - darwin
|
|
# - linux
|
|
# - linux_musl (Alpine)
|
|
detect_platform() {
|
|
local platform
|
|
platform="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
|
|
|
# check for MUSL
|
|
if [ "${platform}" = "linux" ]; then
|
|
if ldd /bin/sh | grep -i musl >/dev/null; then
|
|
platform=unknown-linux-musl
|
|
fi
|
|
fi
|
|
|
|
# mingw is Git-Bash
|
|
if echo "${platform}" | grep -i mingw >/dev/null; then
|
|
platform=pc-windows-msvc
|
|
fi
|
|
|
|
if [ "${platform}" = "linux" ]; then
|
|
platform=unknown-linux-gnu
|
|
fi
|
|
|
|
if [ "${platform}" = "darwin" ]; then
|
|
platform=apple-darwin
|
|
fi
|
|
|
|
echo "${platform}"
|
|
}
|
|
|
|
# Currently supporting:
|
|
# - x86_64
|
|
# - i386
|
|
detect_arch() {
|
|
local arch
|
|
arch="$(uname -m | tr '[:upper:]' '[:lower:]')"
|
|
|
|
# `uname -m` in some cases mis-reports 32-bit OS as 64-bit, so double check
|
|
if [ "${arch}" = "x64" ] && [ "$(getconf LONG_BIT)" -eq 32 ]; then
|
|
arch=i386
|
|
fi
|
|
|
|
echo "${arch}"
|
|
}
|
|
|
|
confirm() {
|
|
if [ -z "${FORCE-}" ]; then
|
|
printf "${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() {
|
|
local 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."
|
|
exit 1
|
|
fi
|
|
|
|
# https://stackoverflow.com/a/11655875
|
|
local good
|
|
good=$( IFS=:
|
|
for path in $PATH; do
|
|
if [ "${path}" = "${bin_dir}" ]; then
|
|
echo 1
|
|
break
|
|
fi
|
|
done
|
|
)
|
|
|
|
if [ "${good}" != "1" ]; then
|
|
warn "Bin directory ${bin_dir} is not in your \$PATH"
|
|
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;;
|
|
|
|
-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"; exit 1;;
|
|
esac
|
|
done
|
|
|
|
if [ "${ARCH}" = "i386" ]; then
|
|
error "i386 builds are not yet available for Starship\n"
|
|
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}:"
|
|
info "${BOLD}${UNDERLINE}https://github.com/starship/starship/issues/new/${NO_COLOR}\n"
|
|
exit 1
|
|
fi
|
|
|
|
printf " ${UNDERLINE}Configuration${NO_COLOR}\n"
|
|
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
|
|
|
|
echo
|
|
|
|
EXT=tar.gz
|
|
if [ "${PLATFORM}" = "pc-windows-msvc" ]; then
|
|
EXT=zip
|
|
fi
|
|
|
|
URL="${BASE_URL}/latest/download/starship-${ARCH}-${PLATFORM}.${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
|
|
complete "Starship installed"
|
|
|
|
echo
|
|
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)
|
|
"
|