adnix-rs/docs/adnix-installer.sh.txt

281 lines
7.5 KiB
Bash

#!/bin/bash
#
# Licensed under the MIT license
# <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# This is just a little script that can be downloaded from the internet to
# install $APP_NAME. It downloads the tarball from ARTIFACT_DOWNLOAD_URL,
# and extracts it to ~/.cargo/bin/
#
# In the future this script will gain extra features, but for now it's
# intentionally very simplistic to avoid shipping broken things.
set -u
# FIXME: patch in the repo's URL for suggesting filling an issue
# REPO="{{REPO_URL}}"
APP_NAME="adnix"
APP_VERSION="0.4.6"
ARTIFACT_DOWNLOAD_URL="https://github.com/msfjarvis/adnix-rs/releases/download/v0.4.6"
download_binary_and_run_installer() {
downloader --check
need_cmd mktemp
need_cmd chmod
need_cmd mkdir
need_cmd rm
need_cmd rmdir
need_cmd tar
need_cmd which
need_cmd dirname
need_cmd awk
need_cmd cut
get_architecture || return 1
local _arch="$RETVAL"
assert_nz "$_arch" "arch"
local _bins=""
local _zip_ext=""
local _artifact_name=""
# This """lookup table""" is generated by cargo-dist
# and populates the above locals with the right values
case "$_arch" in
"aarch64-apple-darwin")
_artifact_name="adnix-aarch64-apple-darwin.tar.xz"
_zip_ext=".tar.xz"
_bins="adnix"
;;
"x86_64-apple-darwin")
_artifact_name="adnix-x86_64-apple-darwin.tar.xz"
_zip_ext=".tar.xz"
_bins="adnix"
;;
"x86_64-unknown-linux-gnu")
_artifact_name="adnix-x86_64-unknown-linux-gnu.tar.xz"
_zip_ext=".tar.xz"
_bins="adnix"
;;
*)
err "there isn't a package for $_arch"
;;
esac
# download the zip
local _url="$ARTIFACT_DOWNLOAD_URL/$_artifact_name"
local _dir="$(mktemp -d 2>/dev/null || ensure mktemp -d -t $APP_NAME)"
local _file="$_dir/input$_zip_ext"
say "downloading $APP_NAME $APP_VERSION ${_arch}" 1>&2
say " from $_url" 1>&2
say " to $_file" 1>&2
ensure mkdir -p "$_dir"
downloader "$_url" "$_file"
if [ $? != 0 ]; then
say "failed to download $_url"
say "this may be a standard network error, but it may also indicate"
say "that $APP_NAME's release process is not working. When in doubt"
say "please feel free to open an issue!"
# say "$REPO/issues/new/choose"
exit 1
fi
# unpack the archive
say "unpacking to $_dir" 1>&2
case "$_zip_ext" in
".zip")
ensure unzip -q "$_file" -d "$_dir"
;;
".tar."*)
ensure tar xf "$_file" --strip-components 1 -C "$_dir"
;;
*)
err "unknown archive format: $_zip_ext"
;;
esac
for _bin_name in $_bins; do
say " unpacked $_bin_name"
done
install "$_dir" "$_bins" "$@"
local _retval=$?
ignore rm -rf "$_dir"
return "$_retval"
}
install() {
# FIXME: prefer $CARGO_HOME over $HOME/.cargo/ if available
# FIXME: let the user choose the dir to install to
local _install_dir="$HOME/.cargo/bin/"
say "installing to $_install_dir"
mkdir -p "$_install_dir"
# copy all the binaries to the install dir
local _src_dir="$1"
local _bins="$2"
for _bin_name in $_bins; do
local _bin="$_src_dir/$_bin_name"
cp "$_bin" "$_install_dir"
# unzip seems to need this chmod
chmod +x "$_install_dir/$_bin_name"
done
say "everything's installed!"
}
get_architecture() {
local _ostype="$(uname -s)"
local _cputype="$(uname -m)"
if [ "$_ostype" = Darwin -a "$_cputype" = i386 ]; then
# Darwin `uname -s` lies
if sysctl hw.optional.x86_64 | grep -q ': 1'; then
local _cputype=x86_64
fi
fi
if [ "$_ostype" = Darwin -a "$_cputype" = arm64 ]; then
# Darwin `uname -s` doesn't seem to lie on Big Sur
# but the cputype we want is called aarch64, not arm64 (they are equivalent)
local _cputype=aarch64
fi
case "$_ostype" in
Linux)
if has_required_glibc; then
local _ostype=unknown-linux-gnu
else
local _ostype=unknown-linux-musl
say "Downloading musl binary."
fi
;;
Darwin)
local _ostype=apple-darwin
;;
MINGW* | MSYS* | CYGWIN*)
local _ostype=pc-windows-msvc
;;
*)
err "no precompiled binaries available for OS: $_ostype"
;;
esac
case "$_cputype" in
# these are the only two acceptable values for cputype
x86_64 | aarch64 )
;;
*)
err "no precompiled binaries available for CPU architecture: $_cputype"
esac
local _arch="$_cputype-$_ostype"
RETVAL="$_arch"
}
say() {
local green=`tput setaf 2 2>/dev/null || echo ''`
local reset=`tput sgr0 2>/dev/null || echo ''`
echo "$1"
}
err() {
local red=`tput setaf 1 2>/dev/null || echo ''`
local reset=`tput sgr0 2>/dev/null || echo ''`
say "${red}ERROR${reset}: $1" >&2
exit 1
}
has_required_glibc() {
local _ldd_version="$(ldd --version 2>&1 | head -n1)"
# glibc version string is inconsistent across distributions
# instead check if the string does not contain musl (case insensitive)
if echo "${_ldd_version}" | grep -iv musl >/dev/null; then
local _glibc_version=$(echo "${_ldd_version}" | awk 'NR==1 { print $NF }')
local _glibc_major_version=$(echo "${_glibc_version}" | cut -d. -f1)
local _glibc_min_version=$(echo "${_glibc_version}" | cut -d. -f2)
local _min_major_version=2
local _min_minor_version=17
if [ "${_glibc_major_version}" -gt "${_min_major_version}" ] \
|| { [ "${_glibc_major_version}" -eq "${_min_major_version}" ] \
&& [ "${_glibc_min_version}" -ge "${_min_minor_version}" ]; }; then
return 0
else
say "This operating system needs glibc >= ${_min_major_version}.${_min_minor_version}, but only has ${_libc_version} installed."
fi
else
say "This operating system does not support dynamic linking to glibc."
fi
return 1
}
need_cmd() {
if ! check_cmd "$1"
then err "need '$1' (command not found)"
fi
}
check_cmd() {
command -v "$1" > /dev/null 2>&1
return $?
}
need_ok() {
if [ $? != 0 ]; then err "$1"; fi
}
assert_nz() {
if [ -z "$1" ]; then err "assert_nz $2"; fi
}
# Run a command that should never fail. If the command fails execution
# will immediately terminate with an error showing the failing
# command.
ensure() {
"$@"
need_ok "command failed: $*"
}
# This is just for indicating that commands' results are being
# intentionally ignored. Usually, because it's being executed
# as part of error handling.
ignore() {
"$@"
}
# This wraps curl or wget. Try curl first, if not installed,
# use wget instead.
downloader() {
if check_cmd curl
then _dld=curl
elif check_cmd wget
then _dld=wget
else _dld='curl or wget' # to be used in error message of need_cmd
fi
if [ "$1" = --check ]
then need_cmd "$_dld"
elif [ "$_dld" = curl ]
then curl -sSfL "$1" -o "$2"
elif [ "$_dld" = wget ]
then wget "$1" -O "$2"
else err "Unknown downloader" # should not reach here
fi
}
download_binary_and_run_installer "$@" || exit 1