2021-03-03 23:57:36 +01:00
#!/usr/bin/env sh
set -eu
printf '\n'
2019-12-05 19:15:21 +01:00
2021-03-03 23:57:36 +01:00
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 '' ) "
2019-12-05 19:15:21 +01:00
2021-01-21 23:17:02 +01:00
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 \
2021-01-30 12:50:38 +01:00
i686-pc-windows-msvc aarch64-pc-windows-msvc \
x86_64-unknown-freebsd"
2021-01-13 19:39:39 +01:00
2019-12-05 19:15:21 +01:00
info( ) {
2021-03-03 23:57:36 +01:00
printf '%s\n' " ${ BOLD } ${ GREY } > ${ NO_COLOR } $* "
2019-12-05 19:15:21 +01:00
}
warn( ) {
2021-03-03 23:57:36 +01:00
printf '%s\n' " ${ YELLOW } ! $* ${ NO_COLOR } "
2019-12-05 19:15:21 +01:00
}
error( ) {
2021-03-03 23:57:36 +01:00
printf '%s\n' " ${ RED } x $* ${ NO_COLOR } " >& 2
}
completed( ) {
printf '%s\n' " ${ GREEN } ✓ ${ NO_COLOR } $* "
2019-12-05 19:15:21 +01:00
}
2021-03-03 23:57:36 +01:00
has( ) {
command -v " $1 " 1>/dev/null 2>& 1
2019-12-05 19:15:21 +01:00
}
2022-01-21 17:25:49 +01:00
# Make sure user is not using zsh or non-POSIX-mode bash, which can cause issues
verify_shell_is_posix_or_exit( ) {
if [ -n " ${ ZSH_VERSION +x } " ] ; then
error "Running installation script with \`zsh\` is known to cause errors."
error "Please use \`sh\` instead."
exit 1
elif [ -n " ${ BASH_VERSION +x } " ] && [ -z " ${ POSIXLY_CORRECT +x } " ] ; then
error "Running installation script with non-POSIX \`bash\` may cause errors."
error "Please use \`sh\` instead."
exit 1
else
true # No-op: no issues detected
fi
}
2020-06-10 20:40:05 +02:00
# Gets path to a temporary file, even if
get_tmpfile( ) {
2020-06-10 00:21:35 +02:00
suffix = " $1 "
2021-03-03 23:57:36 +01:00
if has mktemp; then
2020-06-10 20:40:05 +02:00
printf "%s.%s" " $( mktemp) " " ${ suffix } "
2020-06-10 00:21:35 +02:00
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
2020-06-10 20:40:05 +02:00
test_writeable( ) {
2020-06-10 00:21:35 +02:00
path = " ${ 1 :- } /test.txt "
2020-06-10 20:40:05 +02:00
if touch " ${ path } " 2>/dev/null; then
2020-06-10 00:21:35 +02:00
rm " ${ path } "
return 0
else
return 1
fi
}
2021-03-03 23:57:36 +01:00
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 "
2019-12-05 19:15:21 +01:00
else
2021-03-03 23:57:36 +01:00
error "No HTTP download program (curl, wget, fetch) found, exiting…"
return 1
2019-12-05 19:15:21 +01:00
fi
2021-03-03 23:57:36 +01:00
$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
2019-12-05 19:15:21 +01:00
}
2021-03-03 23:57:36 +01:00
unpack( ) {
2021-05-19 20:47:38 +02:00
archive = $1
bin_dir = $2
sudo = ${ 3 - }
2021-03-03 23:57:36 +01:00
case " $archive " in
*.tar.gz)
2022-06-05 18:56:58 +02:00
flags = $( test -n " ${ VERBOSE - } " && echo "-xzvof" || echo "-xzof" )
2021-04-14 18:52:16 +02:00
${ sudo } tar " ${ flags } " " ${ archive } " -C " ${ bin_dir } "
2021-03-03 23:57:36 +01:00
return 0
; ;
*.zip)
2022-03-10 18:40:43 +01:00
flags = $( test -z " ${ VERBOSE - } " && echo "-qqo" || echo "-o" )
2021-03-03 23:57:36 +01:00
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
2020-06-10 00:21:35 +02:00
}
2021-05-18 16:01:02 +02:00
usage( ) {
2021-09-06 19:10:41 +02:00
printf "%s\n" \
"install.sh [option]" \
"" \
"Fetch and install the latest version of starship, if starship is already" \
"installed it will be updated to the latest version."
printf "\n%s\n" "Options"
printf "\t%s\n\t\t%s\n\n" \
"-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 } ] " \
2022-03-11 21:48:19 +01:00
"-h, --help" "Display this help message"
2021-05-18 16:01:02 +02:00
}
2020-06-10 20:40:05 +02:00
elevate_priv( ) {
2021-03-03 23:57:36 +01:00
if ! has sudo; then
2020-06-10 20:40:05 +02:00
error 'Could not find the command "sudo", needed to get permissions for install.'
2020-06-10 00:21:35 +02:00
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
}
2020-02-13 03:13:21 +01:00
install( ) {
2021-05-19 20:47:38 +02:00
ext = " $1 "
2020-06-10 00:21:35 +02:00
2020-06-10 20:40:05 +02:00
if test_writeable " ${ BIN_DIR } " ; then
2020-06-10 00:21:35 +02:00
sudo = ""
msg = "Installing Starship, please wait…"
else
2020-07-08 23:26:51 +02:00
warn " Escalated permissions are required to install to ${ BIN_DIR } "
2020-06-10 00:21:35 +02:00
elevate_priv
sudo = "sudo"
msg = "Installing Starship as root, please wait…"
fi
info " $msg "
2021-03-03 23:57:36 +01:00
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 } "
2020-02-13 03:13:21 +01:00
}
2019-12-05 19:15:21 +01:00
# Currently supporting:
# - win (Git Bash)
# - darwin
# - linux
# - linux_musl (Alpine)
2021-01-30 12:50:38 +01:00
# - freebsd
2019-12-05 19:15:21 +01:00
detect_platform( ) {
2019-12-20 16:54:40 +01:00
platform = " $( uname -s | tr '[:upper:]' '[:lower:]' ) "
2019-12-05 19:15:21 +01:00
2020-10-25 10:16:47 +01:00
case " ${ platform } " in
msys_nt*) platform = "pc-windows-msvc" ; ;
2021-01-09 15:45:42 +01:00
cygwin_nt*) platform = "pc-windows-msvc" ; ;
2020-10-25 10:16:47 +01:00
# mingw is Git-Bash
mingw*) platform = "pc-windows-msvc" ; ;
2020-08-16 17:30:10 +02:00
# use the statically compiled musl bins on linux to avoid linking issues.
2020-10-25 10:16:47 +01:00
linux) platform = "unknown-linux-musl" ; ;
darwin) platform = "apple-darwin" ; ;
2021-01-30 12:50:38 +01:00
freebsd) platform = "unknown-freebsd" ; ;
2020-10-25 10:16:47 +01:00
esac
2019-12-05 19:15:21 +01:00
2021-03-03 23:57:36 +01:00
printf '%s' " ${ platform } "
2019-12-05 19:15:21 +01:00
}
# Currently supporting:
# - x86_64
# - i386
2021-05-18 16:01:02 +02:00
# - arm
# - arm64
2019-12-05 19:15:21 +01:00
detect_arch( ) {
2019-12-20 16:54:40 +01:00
arch = " $( uname -m | tr '[:upper:]' '[:lower:]' ) "
2019-12-05 19:15:21 +01:00
2021-01-21 23:17:02 +01:00
case " ${ arch } " in
2021-01-30 12:50:38 +01:00
amd64) arch = "x86_64" ; ;
2021-01-21 23:17:02 +01:00
armv*) arch = "arm" ; ;
arm64) arch = "aarch64" ; ;
esac
2019-12-05 19:15:21 +01:00
# `uname -m` in some cases mis-reports 32-bit OS as 64-bit, so double check
2021-01-29 22:54:36 +01:00
if [ " ${ arch } " = "x86_64" ] && [ " $( getconf LONG_BIT) " -eq 32 ] ; then
2021-01-13 19:39:39 +01:00
arch = i686
2021-01-21 23:17:02 +01:00
elif [ " ${ arch } " = "aarch64" ] && [ " $( getconf LONG_BIT) " -eq 32 ] ; then
arch = arm
2019-12-05 19:15:21 +01:00
fi
2021-03-03 23:57:36 +01:00
printf '%s' " ${ arch } "
2019-12-05 19:15:21 +01:00
}
2021-01-21 23:17:02 +01:00
detect_target( ) {
2021-05-19 20:47:38 +02:00
arch = " $1 "
platform = " $2 "
target = " $arch - $platform "
2021-01-21 23:17:02 +01:00
if [ " ${ target } " = "arm-unknown-linux-musl" ] ; then
target = " ${ target } eabihf "
fi
2021-03-03 23:57:36 +01:00
printf '%s' " ${ target } "
2021-01-21 23:17:02 +01:00
}
2019-12-05 19:15:21 +01:00
confirm( ) {
if [ -z " ${ FORCE - } " ] ; then
2020-06-10 20:40:05 +02:00
printf "%s " " ${ MAGENTA } ? ${ NO_COLOR } $* ${ BOLD } [y/N] ${ NO_COLOR } "
2019-12-05 19:15:21 +01:00
set +e
2020-06-10 20:40:05 +02:00
read -r yn </dev/tty
2019-12-05 19:15:21 +01:00
rc = $?
set -e
if [ $rc -ne 0 ] ; then
2020-10-03 10:58:06 +02:00
error "Error reading from prompt (please re-run with the '--yes' option)"
2019-12-05 19:15:21 +01:00
exit 1
fi
if [ " $yn " != "y" ] && [ " $yn " != "yes" ] ; then
2020-06-10 20:40:05 +02:00
error 'Aborting (please answer "yes" to continue)'
2019-12-05 19:15:21 +01:00
exit 1
fi
fi
}
check_bin_dir( ) {
2022-03-10 18:40:33 +01:00
bin_dir = " ${ 1 %/ } "
2019-12-05 19:15:21 +01:00
2020-06-10 00:21:35 +02:00
if [ ! -d " $BIN_DIR " ] ; then
2020-06-10 20:40:05 +02:00
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."
2021-05-18 16:01:02 +02:00
usage
2020-06-10 20:40:05 +02:00
exit 1
2020-06-10 00:21:35 +02:00
fi
2019-12-05 19:15:21 +01:00
# https://stackoverflow.com/a/11655875
2020-06-10 20:40:05 +02:00
good = $(
IFS = :
2019-12-05 19:15:21 +01:00
for path in $PATH ; do
2022-03-10 18:40:33 +01:00
if [ " ${ path %/ } " = " ${ bin_dir } " ] ; then
2021-03-03 23:57:36 +01:00
printf 1
2019-12-05 19:15:21 +01:00
break
fi
done
)
if [ " ${ good } " != "1" ] ; then
warn " Bin directory ${ bin_dir } is not in your \$PATH "
fi
}
2021-09-06 19:10:41 +02:00
print_install( ) {
# if the shell does not fit the default case change the config file
# and or the config cmd variable
for s in "bash" "zsh" "ion" "tcsh" "xonsh" "fish"
do
# shellcheck disable=SC2088
# we don't want these '~' expanding
config_file = " ~/. ${ s } rc "
config_cmd = " eval \"\$(starship init ${ s } )\" "
2022-03-24 20:06:24 +01:00
2021-09-06 19:10:41 +02:00
case ${ s } in
ion )
# shellcheck disable=SC2088
config_file = "~/.config/ion/initrc"
config_cmd = " eval \$(starship init ${ s } ) "
; ;
fish )
# shellcheck disable=SC2088
config_file = "~/.config/fish/config.fish"
config_cmd = "starship init fish | source"
; ;
tcsh )
config_cmd = " eval \`starship init ${ s } \` "
; ;
xonsh )
config_cmd = "execx(\$(starship init xonsh))"
; ;
esac
printf " %s\n Add the following to the end of %s:\n\n\t%s\n\n" \
" ${ BOLD } ${ UNDERLINE } ${ s } ${ NO_COLOR } " \
" ${ BOLD } ${ config_file } ${ NO_COLOR } " \
" ${ config_cmd } "
done
for s in "elvish" "nushell"
do
warning = " ${ BOLD } Warning ${ NO_COLOR } "
case ${ s } in
elvish )
# shellcheck disable=SC2088
config_file = "~/.elvish/rc.elv"
config_cmd = "eval (starship init elvish)"
2021-12-30 09:49:55 +01:00
warning = " ${ warning } Only elvish v0.17 or higher is supported. "
2021-09-06 19:10:41 +02:00
; ;
nushell )
# shellcheck disable=SC2088
2022-05-05 01:02:39 +02:00
config_file = " ${ BOLD } your nu config file ${ NO_COLOR } (find it by running ${ BOLD } \$nu.config-path ${ NO_COLOR } in Nushell) "
2022-03-24 20:06:24 +01:00
config_cmd = " mkdir ~/.cache/starship
starship init nu | save ~/.cache/starship/init.nu
source ~/.cache/starship/init.nu"
2021-09-06 19:10:41 +02:00
warning = " ${ warning } This will change in the future.
2022-05-05 01:02:39 +02:00
Only Nushell v0.61 or higher is supported.
Add the following to the end of ${ BOLD } your Nushell env file${ NO_COLOR } ( find it by running ${ BOLD } \$ nu.env-path${ NO_COLOR } in Nushell) : \" mkdir ~/.cache/starship; starship init nu | save ~/.cache/starship/init.nu\" "
2021-09-06 19:10:41 +02:00
; ;
esac
2022-05-05 01:02:39 +02:00
printf " %s\n %s\n And add the following to the end of %s:\n\n\t%s\n\n" \
2021-09-06 19:10:41 +02:00
" ${ BOLD } ${ UNDERLINE } ${ s } ${ NO_COLOR } " \
" ${ warning } " \
2022-05-05 01:02:39 +02:00
" ${ config_file } " \
2021-09-06 19:10:41 +02:00
" ${ config_cmd } "
done
printf " %s\n Add the following to the end of %s:\n %s\n\n\t%s\n\n" \
" ${ BOLD } ${ UNDERLINE } PowerShell ${ NO_COLOR } " \
" ${ BOLD } Microsoft.PowerShell_profile.ps1 ${ NO_COLOR } " \
" You can check the location of this file by querying the \$PROFILE variable in PowerShell.
Typically the path is ~\D ocuments\P owerShell\M icrosoft.PowerShell_profile.ps1 or ~/.config/powershell/Microsoft.PowerShell_profile.ps1 on -Nix." \
"Invoke-Expression (&starship init powershell)"
2022-06-18 23:22:57 +02:00
printf " %s\n You need to use Clink (v1.2.30+) with Cmd. Add the following to a file %s and place this file in Clink scripts directory:\n\n\t%s\n\n" \
2022-01-10 06:47:53 +01:00
" ${ BOLD } ${ UNDERLINE } Cmd ${ NO_COLOR } " \
" ${ BOLD } starship.lua ${ NO_COLOR } " \
"load(io.popen('starship init cmd'):read(\"*a\"))()"
2021-09-06 19:10:41 +02:00
printf "\n"
}
2021-01-13 19:39:39 +01:00
is_build_available( ) {
2021-05-19 20:47:38 +02:00
arch = " $1 "
platform = " $2 "
target = " $3 "
2021-03-03 23:57:36 +01:00
2021-01-13 19:39:39 +01:00
good = $(
IFS = " "
for t in $SUPPORTED_TARGETS ; do
2021-03-03 23:57:36 +01:00
if [ " ${ t } " = " ${ target } " ] ; then
printf 1
2021-01-13 19:39:39 +01:00
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
}
2019-12-05 19:15:21 +01:00
# 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
2022-01-21 17:25:49 +01:00
# Non-POSIX shells can break once executing code due to semantic differences
verify_shell_is_posix_or_exit
2019-12-05 19:15:21 +01:00
# parse argv variables
while [ " $# " -gt 0 ] ; do
case " $1 " in
2020-06-10 20:40:05 +02:00
-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
; ;
2021-05-18 16:01:02 +02:00
-h | --help)
usage
exit
; ;
2020-06-10 20:40:05 +02:00
-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 "
2021-05-18 16:01:02 +02:00
usage
2020-06-10 20:40:05 +02:00
exit 1
; ;
2019-12-05 19:15:21 +01:00
esac
done
2021-01-21 23:17:02 +01:00
TARGET = " $( detect_target " ${ ARCH } " " ${ PLATFORM } " ) "
is_build_available " ${ ARCH } " " ${ PLATFORM } " " ${ TARGET } "
2019-12-05 19:15:21 +01:00
2020-06-10 20:40:05 +02:00
printf " %s\n" " ${ UNDERLINE } Configuration ${ NO_COLOR } "
2019-12-05 19:15:21 +01:00
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
2019-12-20 16:54:40 +01:00
if [ -n " ${ VERBOSE - } " ] ; then
2019-12-05 19:15:21 +01:00
VERBOSE = v
info " ${ BOLD } Verbose ${ NO_COLOR } : yes "
else
VERBOSE =
fi
2021-03-03 23:57:36 +01:00
printf '\n'
2019-12-05 19:15:21 +01:00
EXT = tar.gz
2020-06-10 00:21:35 +02:00
if [ " ${ PLATFORM } " = "pc-windows-msvc" ] ; then
2019-12-05 19:15:21 +01:00
EXT = zip
fi
2021-01-21 23:17:02 +01:00
URL = " ${ BASE_URL } /latest/download/starship- ${ TARGET } . ${ EXT } "
2019-12-05 19:15:21 +01:00
info " Tarball URL: ${ UNDERLINE } ${ BLUE } ${ URL } ${ NO_COLOR } "
confirm " Install Starship ${ GREEN } latest ${ NO_COLOR } to ${ BOLD } ${ GREEN } ${ BIN_DIR } ${ NO_COLOR } ? "
2020-06-10 00:21:35 +02:00
check_bin_dir " ${ BIN_DIR } "
2019-12-05 19:15:21 +01:00
2021-03-03 23:57:36 +01:00
install " ${ EXT } "
completed "Starship installed"
2020-02-13 03:13:21 +01:00
2021-03-03 23:57:36 +01:00
printf '\n'
2021-09-06 19:10:41 +02:00
info "Please follow the steps for your shell to complete the installation:"
2021-07-16 21:25:01 +02:00
2021-09-06 19:10:41 +02:00
print_install