Added zoxide and added more robust arch detection

This commit is contained in:
2023-05-23 23:53:27 +02:00
parent d9449e72c8
commit 5f2db41d3a

630
kfg
View File

@@ -1,10 +1,10 @@
#!/bin/bash #!/bin/bash
NAME="kfg" NAME="kfg"
VERSION="0.3" VERSION="0.4"
HOME_PATH="$HOME" HOME_PATH="$HOME"
TMP_PATH="$HOME_PATH/tmp/kamu_install" TMP_PATH="$HOME_PATH/.tmp/kfg_install"
CONFIG_PATH="$HOME_PATH/.config" CONFIG_PATH="$HOME_PATH/.config"
BINARY_PATH="/usr/bin" BINARY_PATH="/usr/bin"
RC_FILE=".zshrc" RC_FILE=".zshrc"
@@ -24,6 +24,7 @@ TOOLS[unp]="Perl script to make file archive extraction easier"
TOOLS[bat]="cat replacement with syntax highlighting and git integration - https://github.com/sharkdp/bat" TOOLS[bat]="cat replacement with syntax highlighting and git integration - https://github.com/sharkdp/bat"
TOOLS[lsd]="ls replacement with colors, icons, tree-view and more - https://github.com/lsd-rs/lsd" TOOLS[lsd]="ls replacement with colors, icons, tree-view and more - https://github.com/lsd-rs/lsd"
TOOLS[omp]="Customisable shell prompt renderer - https://github.com/jandedobbeleer/oh-my-pos" TOOLS[omp]="Customisable shell prompt renderer - https://github.com/jandedobbeleer/oh-my-pos"
TOOLS[zoxide]="A smarter cd command. - https://github.com/ajeetdsouza/zoxide"
function show_help_name { function show_help_name {
echo "$NAME v$VERSION" echo "$NAME v$VERSION"
@@ -72,7 +73,12 @@ function log_info {
} }
function log_error { function log_error {
log $ERROR "!" "$1" echo "$(log $ERROR "!" "$1")" >&2
}
function err {
log_error "Error: $1"
exit 1
} }
function log_debug { function log_debug {
@@ -118,7 +124,8 @@ function download_config {
FILE="$CONFIG_PATH/$1/$2" FILE="$CONFIG_PATH/$1/$2"
if [ ! -e "$FILE" ] || user_confirm_overwrite "$FILE"; then if [ ! -e "$FILE" ] || user_confirm_overwrite "$FILE"; then
wget -O "$FILE" "$3" > /dev/null 2>&1 download "$3" "$FILE"
#wget -O "$FILE" "$3" > /dev/null 2>&1
log_add "Added $FILE" log_add "Added $FILE"
fi fi
} }
@@ -134,7 +141,8 @@ function install_rc {
# Does the file already exist? or does the user want to overwrite it? # Does the file already exist? or does the user want to overwrite it?
if [ ! -e "$FILE" ] || user_confirm_overwrite "$FILE"; then if [ ! -e "$FILE" ] || user_confirm_overwrite "$FILE"; then
# Download the file and save it # Download the file and save it
wget -O "$FILE" "$2" > /dev/null 2>&1 download "$2" "$FILE"
#wget -O "$FILE" "$2" > /dev/null 2>&1
log_add "Added $FILE" log_add "Added $FILE"
fi fi
@@ -180,11 +188,156 @@ function init_install_rc {
fi fi
} }
function download {
local _url=$1
local _path=$2
local _result
if check_cmd curl; then
_dld=curl
elif check_cmd wget; then
_dld=wget
else
need_cmd 'curl or wget'
fi
if [ ! -z $_path ]; then
mkdir -p "$(dirname "$_path")"
log_info "Downloading $_url to $_path"
case "${_dld}" in
curl) _args="-sLo $_path" ;;
wget) _args="-qO $_path" ;;
esac
else
case "${_dld}" in
curl) _args="-sL" ;;
wget) _args="-qO-" ;;
esac
fi
case "${_dld}" in
curl) _result="$(curl $_args "${_url}")" || err "curl: failed to download ${_url}" ;;
wget) _result="$(wget $_args "${_url}")" || err "wget: failed to download ${_url}" ;;
*) err "unsupported downloader: ${_dld}" ;;
esac
RETVAL="${_result}"
return 0
}
function github_install {
ensure get_architecture
local _program=$1
local _arch="${RETVAL}"
local _url="https://api.github.com/repos/$2/releases/latest"
assert_nz "${_arch}" "arch"
need_cmd grep
download "${_url}"
local _releases=$RETVAL
(echo "${_releases}" | grep -q 'API rate limit exceeded') && (log_error "GitHub API rate limit exceeded. Please try again later." || return 1)
local _package_url _package_urls
_package_urls="$(echo "${_releases}" | grep "browser_download_url" | cut -d '"' -f 4)"
#log_debug "Packages: ${_package_urls}"
# Check for Rust package
local _rust_package_url="$(echo "$_package_urls" | grep $_arch)"
local _other_package_url="$(echo "$_package_urls" | grep $ARCH | grep -vE "$APP_FILTER")"
log_debug "Rust package: $_rust_package_url"
log_debug "Filter: $APP_FILTER"
log_debug "Other package: $_other_package_url"
if [ ! -z "$_other_package_url" ]; then
_package_url="${_other_package_url}"
elif [ ! -z "$_rust_package_url" ]; then
_package_url="${_rust_package_url}"
else
log_error "Can not find installable package for '$_program' for the detected architecture (${_arch})."
return 0
fi
log_debug "Selected package: ${_package_url}"
# Check the extension
local _ext
case "${_package_url}" in
*.tar.gz) _ext="tar.gz" ;;
*.deb) _ext="deb" ;;
*.zip) _ext="zip" ;;
*) _ext="" ;;
esac
local _package
if [ -z $_ext ]; then
_package="$TMP_PATH/$_program"
else
_package="$TMP_PATH/$_program.$_ext"
fi
download "$_package_url" "$_package"
# unpack
cd "${TMP_PATH}"
case "${_package}" in
*.tar.gz)
need_cmd tar
log_info "Unpacking ${_package}"
tar -xf "${_package}"
;;
*.zip)
need_cmd unzip
log_info "Unpacking ${_package}"
unzip -oq "${_package}"
;;
*) ;; # ignore
esac
# install
local _binary
case "${_ext}" in
tar.gz)
_binary="$(tar --list -f "${_package}" | grep -E "^(.*/)?$_program$")"
log_debug $_binary
install_binary "$_program" "$TMP_PATH/$_binary"
return 0
;;
deb)
install_deb "${_program}" "${_package}"
return 0
;;
zip)
_binary="$(unzip -l "${_package}" | sed -E 's/ {1,}/ /g' | cut -d ' ' -f 5 | grep -E "^(.*/)?$_program$")"
log_debug $_binary
install_binary "$_program" "$TMP_PATH/$_binary"
return 0
;;
*)
_binary="${_program}"
log_debug $_binary
log_debug "Installing binary!"
install_binary "$_program" "$TMP_PATH/$_binary"
;;
esac
}
function install_deb_check { function install_deb_check {
CHECK_CURRENT=$(dpkg -s "$1" | grep -E "Status|Version") CHECK_CURRENT=$(dpkg -s "$1" | grep -E "Status|Version")
INSTALLED_CURRENT=$(echo $CHECK_CURRENT | grep -oE "Status: .*" | cut -d ' ' -f 2) INSTALLED_CURRENT=$(echo $CHECK_CURRENT | grep -oE "Status: .*" | cut -d ' ' -f 2)
VERSION_CURRENT=$(echo $CHECK_CURRENT | grep -oE "Version: .*" | cut -d ' ' -f 2) VERSION_CURRENT=$(echo $CHECK_CURRENT | grep -oE "Version: .*" | cut -d ' ' -f 2)
CHECK_NEW=$(sudo dpkg -I $TMP_PATH/$1.deb | grep -E "Status|Version") CHECK_NEW=$(sudo dpkg -I $2 | grep -E "Status|Version")
INSTALLED_NEW=$(echo $CHECK_NEW | grep -oE "Status: .*" | cut -d ' ' -f 2) INSTALLED_NEW=$(echo $CHECK_NEW | grep -oE "Status: .*" | cut -d ' ' -f 2)
VERSION_NEW=$(echo $CHECK_NEW | grep -oE "Version: .*" | cut -d ' ' -f 2) VERSION_NEW=$(echo $CHECK_NEW | grep -oE "Version: .*" | cut -d ' ' -f 2)
@@ -203,15 +356,17 @@ function install_deb_check {
} }
function install_deb { function install_deb {
if [ -z "$P_DEB" ]; then return 0; fi local _file=$2
log_info "Downloading $2 to $TMP_PATH ..." local _program=$1
wget -O $TMP_PATH/$1.deb $2 > /dev/null 2>&1 #if [ -z "$P_DEB" ]; then return 0; fi
#log_info "Downloading $2 to $TMP_PATH ..."
#wget -O $TMP_PATH/$1.deb $2 > /dev/null 2>&1
if ! install_deb_check $1; then if ! install_deb_check "$_program" "$_file"; then
return 1 return 1
fi fi
INSTALL=$(sudo dpkg -i $TMP_PATH/$1.deb) INSTALL=$(sudo dpkg -i $_file)
UNPACK=$(echo -n "$INSTALL" | grep -oE "Unpacking .*") UNPACK=$(echo -n "$INSTALL" | grep -oE "Unpacking .*")
PROG=$(echo -n $UNPACK | cut -d '(' -f 1 | cut -d ' ' -f 2) PROG=$(echo -n $UNPACK | cut -d '(' -f 1 | cut -d ' ' -f 2)
CURR_VERSION=$(echo -n $UNPACK | cut -d '(' -f 2 | cut -d ')' -f 1) CURR_VERSION=$(echo -n $UNPACK | cut -d '(' -f 2 | cut -d ')' -f 1)
@@ -228,13 +383,13 @@ function install_deb {
} }
function init { function init {
if [ ! -z "$P_BINARY" ] || [ ! -z "$P_DEB" ]; then #if [ ! -z "$P_BINARY" ] || [ ! -z "$P_DEB" ]; then
log_info "Found Architecture: $ARCH" # log_info "Found Architecture: $ARCH"
if ! user_confirm "Is '$ARCH' the correct architecture to download programs?"; then # if ! user_confirm "Is '$ARCH' the correct architecture to download programs?"; then
log_info "Exiting ..." # log_info "Exiting ..."
exit 0 # exit 0
fi # fi
fi #fi
if [ ! -z "$P_APT" ]; then if [ ! -z "$P_APT" ]; then
log_info "Running apt update ..." log_info "Running apt update ..."
sudo apt update > /dev/null 2>&1 sudo apt update > /dev/null 2>&1
@@ -257,23 +412,23 @@ function apt_install {
fi fi
} }
function github_latest { #function github_latest {
VERSION=$(curl -I "https://github.com/$1/releases/latest/" 2> /dev/null | grep -iE "^Location:" | tr -s ' ' | cut -d '/' -f 8 2> /dev/null) # VERSION=$(curl -I "https://github.com/$1/releases/latest/" 2> /dev/null | grep -iE "^Location:" | tr -s ' ' | cut -d '/' -f 8 2> /dev/null)
echo -n ${VERSION//[$'\t\r\n']} # echo -n ${VERSION//[$'\t\r\n']}
} #}
function install_deb_github { #function install_deb_github {
if [ -z "$P_DEB" ]; then return 0; fi # if [ -z "$P_DEB" ]; then return 0; fi
local PATTERN=${3/ARCH/$ARCH}; # local PATTERN=${3/ARCH/$ARCH};
log_debug "Loading most recent version for $1" # log_debug "Loading most recent version for $1"
local VERSION=$(github_latest $2 2> /dev/null ) # local VERSION=$(github_latest $2 2> /dev/null )
VERSION=${VERSION/v/} # VERSION=${VERSION/v/}
log_debug "Found version $VERSION" # log_debug "Found version $VERSION"
local FILE=${PATTERN/VERSION/$VERSION} # local FILE=${PATTERN/VERSION/$VERSION}
local LINK="https://github.com/$2/releases/latest/download/$FILE" # local LINK="https://github.com/$2/releases/latest/download/$FILE"
log_debug "Download link: $LINK" # log_debug "Download link: $LINK"
install_deb "$1" ${LINK//[$'\t\r\n']} # install_deb "$1" ${LINK//[$'\t\r\n']}
} #}
function git_clone { function git_clone {
CLONE=$(git clone "$1" "$2" 2>&1) CLONE=$(git clone "$1" "$2" 2>&1)
@@ -285,24 +440,30 @@ function git_clone {
} }
function install_binary { function install_binary {
local _app=$1
local _path=$2
if [ -z "$P_BINARY" ]; then return 0; fi if [ -z "$P_BINARY" ]; then return 0; fi
log_info "Downloading $2 to $BINARY_PATH ..." #log_info "Downloading $2 to $BINARY_PATH ..."
sudo wget -O $BINARY_PATH/$1 $2 > /dev/null 2>&1 #sudo wget -O $BINARY_PATH/$1 $2 > /dev/null 2>&1
sudo chmod +x $BINARY_PATH/$1 log_debug $_path
log_debug $BINARY_PATH/$_app
sudo cp $_path $BINARY_PATH/$_app
sudo chmod +x $BINARY_PATH/$_app
log_add "Installed $_app into $BINARY_PATH/$_app"
} }
function install_binary_github { #function install_binary_github {
if [ -z "$P_BINARY" ]; then return 0; fi # if [ -z "$P_BINARY" ]; then return 0; fi
local PATTERN=${3/ARCH/$ARCH}; # local PATTERN=${3/ARCH/$ARCH};
log_debug "Loading most recent version for $1" # log_debug "Loading most recent version for $1"
VERSION=$(github_latest $2 2> /dev/null) # VERSION=$(github_latest $2 2> /dev/null)
VERSION=${VERSION/v/} # VERSION=${VERSION/v/}
log_debug "Found version $VERSION" # log_debug "Found version $VERSION"
local FILE=${PATTERN/VERSION/$VERSION} # local FILE=${PATTERN/VERSION/$VERSION}
local LINK="https://github.com/$2/releases/latest/download/$FILE" # local LINK="https://github.com/$2/releases/latest/download/$FILE"
log_debug "Download link: $LINK" # log_debug "Download link: $LINK"
install_binary "$1" ${LINK//[$'\t\r\n']} # install_binary "$1" ${LINK//[$'\t\r\n']}
} #}
function set_shell { function set_shell {
if [ -z "$P_ZSH" ]; then return 0; fi if [ -z "$P_ZSH" ]; then return 0; fi
@@ -321,7 +482,7 @@ function set_shell {
function update { function update {
cd "$(dirname "$0")" cd "$(dirname "$0")"
wget -O kfg https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/kfg download "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/kfg" "kfg"
exit 0 exit 0
} }
@@ -329,8 +490,19 @@ function show_help_install {
show_help_name show_help_name
echo -e "Usage: $NAME install <program> [ opt ]\n" echo -e "Usage: $NAME install <program> [ opt ]\n"
echo -e "program := {" echo -e "program := {"
local _length _space
for key in ${!TOOLS[@]}; do for key in ${!TOOLS[@]}; do
echo -e " ${INFO}${key}${ENDCOLOR}\t\t\t ${TOOLS[$key]}" _length="$(echo -n $key | wc -m)"
if [ "$_length" -gt 21 ]; then
_space=""
elif [ "$_length" -gt 13 ]; then
_space="\t"
elif [ "$_length" -gt 5 ]; then
_space="\t\t"
else
_space="\t\t\t"
fi
echo -e " ${INFO}${key}${ENDCOLOR}${_space} ${TOOLS[$key]}"
done done
echo -e "}\n" echo -e "}\n"
show_help_opt show_help_opt
@@ -344,6 +516,7 @@ function p_all {
p_bat p_bat
p_lsd p_lsd
p_omp p_omp
p_zoxide
} }
function p_zsh { function p_zsh {
@@ -385,7 +558,8 @@ function p_bat {
# ----------------- # -----------------
# bat # bat
# ----------------- # -----------------
install_deb_github bat "sharkdp/bat" "bat_VERSION_ARCH.deb" github_install bat "sharkdp/bat"
#install_deb_github bat "sharkdp/bat" "bat_VERSION_ARCH.deb"
install_rc bat https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.bat.rc install_rc bat https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.bat.rc
} }
@@ -393,24 +567,31 @@ function p_lsd {
# ----------------- # -----------------
# Install lsd https://github.com/Peltoche/lsd # Install lsd https://github.com/Peltoche/lsd
# ----------------- # -----------------
install_deb_github "lsd" "lsd-rs/lsd" "lsd_VERSION_ARCH.deb" github_install "lsd" "lsd-rs/lsd"
#install_deb_github "lsd" "lsd-rs/lsd" "lsd_VERSION_ARCH.deb"
install_rc lsd https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.rc install_rc lsd https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.rc
download_config lsd "config.yaml" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.conf" download_config lsd "config.yaml" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.conf"
download_config lsd "themes/kamu.yaml" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.theme" download_config lsd "themes/kamu.yaml" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.lsd.theme"
} }
function p_zoxide {
github_install "zoxide" "ajeetdsouza/zoxide"
}
function p_omp { function p_omp {
# ----------------- # -----------------
# Install OhMyPosh # Install OhMyPosh
# ----------------- # -----------------
github_install "oh-my-posh" "JanDeDobbeleer/oh-my-posh"
download_config "omp" "omp.json" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.omp.json" download_config "omp" "omp.json" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.omp.json"
install_rc "omp" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.omp.rc" install_rc "omp" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.omp.rc"
install_binary_github "oh-my-posh" "JanDeDobbeleer/oh-my-posh" "posh-linux-ARCH" #install_binary_github "oh-my-posh" "JanDeDobbeleer/oh-my-posh" "posh-linux-ARCH"
} }
function install { function install {
if [ -z $1 ]; then if [ -z $1 ]; then
show_help_install show_help_install
exit 0
fi fi
init init
@@ -436,57 +617,330 @@ function install {
unp) p_unp; shift ;; unp) p_unp; shift ;;
lsd) p_lsd; shift ;; lsd) p_lsd; shift ;;
omp) p_omp; shift ;; omp) p_omp; shift ;;
zoxide) p_zoxide; shift ;;
# If invalid options were passed, then getopt should have reported an error, # If invalid options were passed, then getopt should have reported an error,
# which we checked as VALID_ARGUMENTS when getopt was called... # which we checked as VALID_ARGUMENTS when getopt was called...
*) log_error "Unrecognised program: $1"; shift ;; *) log_error "Unrecognised program: $1"; shift ;;
esac esac
done done
cleanup #cleanup
exit 0 exit 0
} }
if [ -z $1 ]; then function main {
show_help if [ -z $1 ]; then
fi show_help
fi
PARSED_ARGUMENTS=$(getopt -a -n install.sh -o hvdya: --long yes,help,debug,arch,verbose: -- "$@") PARSED_ARGUMENTS=$(getopt -a -n install.sh -o hvdya: --long yes,help,debug,arch,verbose: -- "$@")
VALID_ARGUMENTS=$? VALID_ARGUMENTS=$?
if [ "$VALID_ARGUMENTS" != "0" ]; then if [ "$VALID_ARGUMENTS" != "0" ]; then
show_help show_help
fi fi
ARCH=$(/usr/bin/dpkg --print-architecture) ARCH=$(/usr/bin/dpkg --print-architecture)
#echo "PARSED_ARGUMENTS is $PARSED_ARGUMENTS" #echo "PARSED_ARGUMENTS is $PARSED_ARGUMENTS"
eval set -- "$PARSED_ARGUMENTS" eval set -- "$PARSED_ARGUMENTS"
while : while :
do do
case "$1" in
-h | --help) show_help ;;
-v | --verbose) P_Verbose=1 ; shift ;;
-d | --debug) P_Debug=1 ; shift ;;
-y | --yes) P_Yes=1 ; shift ;;
-a | --arch) ARCH="$2" ; shift 2 ;;
# -- means the end of the arguments; drop this, and break out of the while loop
--) shift; break ;;
# If invalid options were passed, then getopt should have reported an error,
# which we checked as VALID_ARGUMENTS when getopt was called...
*) log_error "Unexpected option: $1"
show_help ;;
esac
done
#echo "Parameters remaining are: $@"
case "$1" in case "$1" in
-h | --help) show_help ;; update) update ;;
-v | --verbose) P_Verbose=1 ; shift ;; version) version ;;
-d | --debug) P_Debug=1 ; shift ;; install) shift; install $@;;
-y | --yes) P_Yes=1 ; shift ;;
-a | --arch) ARCH="$2" ; shift 2 ;;
# -- means the end of the arguments; drop this, and break out of the while loop # -- means the end of the arguments; drop this, and break out of the while loop
--) shift; break ;; --) shift; break ;;
# If invalid options were passed, then getopt should have reported an error, # If invalid options were passed, then getopt should have reported an error,
# which we checked as VALID_ARGUMENTS when getopt was called... # which we checked as VALID_ARGUMENTS when getopt was called...
*) log_error "Unexpected option: $1" *) log_error "Unexpected command: $1"; show_help ;;
show_help ;;
esac esac
done }
#echo "Parameters remaining are: $@" # The following is from (with modifications): https://github.com/rust-lang/rustup/blob/4c1289b2c3f3702783900934a38d7c5f912af787/rustup-init.sh
case "$1" in function get_architecture {
update) update ;; _ostype="$(uname -s)"
version) version ;; _cputype="$(uname -m)"
install) shift; install $@;; _clibtype="gnu"
# -- means the end of the arguments; drop this, and break out of the while loop
--) shift; break ;; APP_FILTER="arm64|amd64|aarch64|i686|x86_64|x86-64|x64|musl|gnu|windows|darwin|linux|android|exe|sig|sha256"
# If invalid options were passed, then getopt should have reported an error,
# which we checked as VALID_ARGUMENTS when getopt was called... if [ "${_ostype}" = Linux ]; then
*) log_error "Unexpected command: $1" if [ "$(uname -o || true)" = Android ]; then
show_help ;; _ostype=Android
esac fi
if ldd --version 2>&1 | grep -q 'musl'; then
_clibtype="musl"
APP_FILTER=$(echo $APP_FILTER | sed -e "s/musl|//gi")
else
APP_FILTER=$(echo $APP_FILTER | sed -e "s/gnu|//gi")
fi
fi
if [ "${_ostype}" = Darwin ] && [ "${_cputype}" = i386 ]; then
# Darwin `uname -m` lies
if sysctl hw.optional.x86_64 | grep -q ': 1'; then
_cputype=x86_64
fi
fi
if [ "${_ostype}" = SunOS ]; then
# Both Solaris and illumos presently announce as "SunOS" in "uname -s"
# so use "uname -o" to disambiguate. We use the full path to the
# system uname in case the user has coreutils uname first in PATH,
# which has historically sometimes printed the wrong value here.
if [ "$(/usr/bin/uname -o || true)" = illumos ]; then
_ostype=illumos
fi
# illumos systems have multi-arch userlands, and "uname -m" reports the
# machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
# systems. Check for the native (widest) instruction set on the
# running kernel:
if [ "${_cputype}" = i86pc ]; then
_cputype="$(isainfo -n)"
fi
fi
case "${_ostype}" in
Android)
_ostype=linux-android
APP_FILTER=$(echo $APP_FILTER | sed -e "s/android|//gi")
;;
Linux)
check_proc
_ostype=unknown-linux-${_clibtype}
_bitness=$(get_bitness)
APP_FILTER=$(echo $APP_FILTER | sed -e "s/linux|//gi")
;;
FreeBSD)
_ostype=unknown-freebsd
;;
NetBSD)
_ostype=unknown-netbsd
;;
DragonFly)
_ostype=unknown-dragonfly
;;
Darwin)
_ostype=apple-darwin
APP_FILTER=$(echo $APP_FILTER | sed -e "s/darwin|//gi")
;;
illumos)
_ostype=unknown-illumos
;;
MINGW* | MSYS* | CYGWIN* | Windows_NT)
_ostype=pc-windows-msvc
;;
*)
err "unrecognized OS type: ${_ostype}"
;;
esac
case "${_cputype}" in
i386 | i486 | i686 | i786 | x86)
_cputype=i686
APP_FILTER=$(echo $APP_FILTER | sed -e "s/i686|//gi")
;;
xscale | arm)
_cputype=arm
if [ "${_ostype}" = "linux-android" ]; then
_ostype=linux-androideabi
fi
;;
armv6l)
_cputype=arm
if [ "${_ostype}" = "linux-android" ]; then
_ostype=linux-androideabi
else
_ostype="${_ostype}eabihf"
fi
;;
armv7l | armv8l)
_cputype=armv7
if [ "${_ostype}" = "linux-android" ]; then
_ostype=linux-androideabi
else
_ostype="${_ostype}eabihf"
fi
;;
aarch64 | arm64)
_cputype=aarch64
APP_FILTER=$(echo $APP_FILTER | sed -e "s/aarch64|//gi")
APP_FILTER=$(echo $APP_FILTER | sed -e "s/arm64|//gi")
;;
x86_64 | x86-64 | x64 | amd64)
_cputype=x86_64
APP_FILTER=$(echo $APP_FILTER | sed -e "s/amd64|//gi")
APP_FILTER=$(echo $APP_FILTER | sed -e "s/x86_64|//gi")
APP_FILTER=$(echo $APP_FILTER | sed -e "s/x86-64|//gi")
APP_FILTER=$(echo $APP_FILTER | sed -e "s/x64|//gi")
;;
mips)
_cputype=$(get_endianness mips '' el)
;;
mips64)
if [ "${_bitness}" -eq 64 ]; then
# only n64 ABI is supported for now
_ostype="${_ostype}abi64"
_cputype=$(get_endianness mips64 '' el)
fi
;;
ppc)
_cputype=powerpc
;;
ppc64)
_cputype=powerpc64
;;
ppc64le)
_cputype=powerpc64le
;;
s390x)
_cputype=s390x
;;
riscv64)
_cputype=riscv64gc
;;
*)
err "unknown CPU type: ${_cputype}"
;;
esac
# Detect 64-bit linux with 32-bit userland
if [ "${_ostype}" = unknown-linux-musl ] && [ "${_bitness}" -eq 32 ]; then
case ${_cputype} in
x86_64)
# 32-bit executable for amd64 = x32
if is_host_amd64_elf; then {
echo "x32 userland is unsupported" 1>&2
exit 1
}; else
_cputype=i686
fi
;;
mips64)
_cputype=$(get_endianness mips '' el)
;;
powerpc64)
_cputype=powerpc
;;
aarch64)
_cputype=armv7
if [ "${_ostype}" = "linux-android" ]; then
_ostype=linux-androideabi
else
_ostype="${_ostype}eabihf"
fi
;;
riscv64gc)
err "riscv64 with 32-bit userland unsupported"
;;
*) ;;
esac
fi
# Detect armv7 but without the CPU features Rust needs in that build,
# and fall back to arm.
# See https://github.com/rust-lang/rustup.rs/issues/587.
if [ "${_ostype}" = "unknown-linux-musleabihf" ] && [ "${_cputype}" = armv7 ]; then
if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then
# At least one processor does not have NEON.
_cputype=arm
fi
fi
_arch="${_cputype}-${_ostype}"
log_debug "Detected architecture: ${_arch}"
log_debug "APP_FILTER: $APP_FILTER"
RETVAL="${_arch}"
}
function get_bitness {
need_cmd head
# Architecture detection without dependencies beyond coreutils.
# ELF files start out "\x7fELF", and the following byte is
# 0x01 for 32-bit and
# 0x02 for 64-bit.
# The printf builtin on some shells like dash only supports octal
# escape sequences, so we use those.
local _current_exe_head
_current_exe_head=$(head -c 5 /proc/self/exe)
if [ "${_current_exe_head}" = "$(printf '\177ELF\001')" ]; then
echo 32
elif [ "${_current_exe_head}" = "$(printf '\177ELF\002')" ]; then
echo 64
else
err "unknown platform bitness"
fi
}
function get_endianness {
local cputype=$1
local suffix_eb=$2
local suffix_el=$3
# detect endianness without od/hexdump, like get_bitness() does.
need_cmd head
need_cmd tail
local _current_exe_endianness
_current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
if [ "${_current_exe_endianness}" = "$(printf '\001')" ]; then
echo "${cputype}${suffix_el}"
elif [ "${_current_exe_endianness}" = "$(printf '\002')" ]; then
echo "${cputype}${suffix_eb}"
else
err "unknown platform endianness"
fi
}
function is_host_amd64_elf() {
need_cmd head
need_cmd tail
# ELF e_machine detection without dependencies beyond coreutils.
# Two-byte field at offset 0x12 indicates the CPU,
# but we're interested in it being 0x3E to indicate amd64, or not that.
local _current_exe_machine
_current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
[ "${_current_exe_machine}" = "$(printf '\076')" ]
}
function check_proc() {
# Check for /proc by looking for the /proc/self/exe link.
# This is only run on Linux.
if ! test -L /proc/self/exe; then
err "unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
fi
}
function need_cmd() {
if ! check_cmd "$1"; then
err "need '$1' (command not found)"
fi
}
function check_cmd() {
command -v "$1" >/dev/null 2>&1
}
function ensure() {
if ! "$@"; then err "command failed: $*"; fi
}
function assert_nz() {
if [ -z "$1" ]; then err "found empty string: $2"; fi
}
{
main "$@" || exit 1
}