#ft=bash bail () ( >&2 echo "ERROR: $1" exit 1 ) must_be_root () ( if [ "$(id --user)" != 0 ]; then bail "must run as root" fi ) set_link () ( TARGET=${1} APP_DIR=${2} APP_PATH=${3:-} pushd "$(dirname "${TARGET}")" >/dev/null || exit 1 unlink_if_set "${TARGET}" REL_PATH=$(relative_path "$(dirname "${TARGET}")" "${APP_DIR}/current/${APP_PATH}") ln -s "${REL_PATH}" "$(basename "${TARGET}")" popd >/dev/null || exit 1 ) get_os () ( case $(uname -s) in Linux*) echo linux;; Darwin*) echo darwin;; Dragonfly*) echo dragonfly;; FreeBSD*) echo freebsd;; NetBSD*) echo netbsd;; OpenBSD*) echo openbsd;; SunOS*) echo solaris;; Windows_NT*) echo windows;; CYGWIN_NT*) echo windows;; *) >&2 echo "unsupported os"; return; esac ) get_arch () ( case $(uname -m) in x86_64*) echo amd64;; amd64*) echo amd64;; i386*) echo 386;; i686*) echo 386;; arm) echo arm;; armv7*) echo arm;; armv6*) echo arm;; armv8*) echo arm;; aarch64*) echo arm64;; *) >&2 echo "unsupported architecture: $(uname -m)"; exit 1;; esac ) set_current_link () ( prefix=${1} version=${2} sudo=${3:-} current="${prefix}/current" if [ -L "${current}" ] ; then $sudo unlink "${current}" fi rel="$(relative_path "${prefix}" "${prefix}/${version}")" $sudo ln -s "$rel" "${current}" ) unlink_if_set () ( dir=$1 sudo=${2:-} if [ -L "${dir}" ]; then # shellcheck disable=SC2086 ${sudo} unlink "${dir}" fi ) mkdir_if_missing () ( dir=${1} sudo=${2:-} if [ ! -d "${dir}" ]; then # shellcheck disable=SC2086 $sudo mkdir -p "${dir}" fi ) extract_zip () ( url=${1} dest=${2} args=${3} sudo=${4:-} if [ -d "${dest}" ]; then return fi mkdir_if_missing "${dest}" "${sudo}" tmp_dir="$(mktemp -d)" zipfile=${tmp_dir}/release.zip curl --silent --location --output "${zipfile}" "${url}" # shellcheck disable=SC2086 $sudo unzip -o "${zipfile}" -d "${dest}" ${args} rm -rf "${tmp_dir}" ) extract_tarball () ( url=${1} dest=${2} args=${3} sudo=${4:-} if [ -d "${dest}" ]; then return fi mkdir_if_missing "${dest}" "${sudo}" tmp_dir="$(mktemp -d)" tarball=${tmp_dir}/release.tar.gz curl --silent --location --output "${tarball}" "${url}" # shellcheck disable=SC2086 $sudo tar xf "${tarball}" --directory "${dest}" ${args} rm -rf "${tmp_dir}" ) relative_path() ( # both $1 and $2 are absolute paths beginning with / # $1 must be a canonical path; that is none of its directory # components may be ".", ".." or a symbolic link # # returns relative path to $2/$target from $1/$src src=$1 target=$2 common_part=$src result= while [ "${target#"$common_part"}" = "$target" ]; do # no match, means that candidate common part is not correct # go up one level (reduce common part) common_part=$(dirname "$common_part") # and record that we went back, with correct / handling if [ -z "$result" ]; then result=.. else result=../$result fi done if [ "$common_part" = / ]; then # special case for root (no common path) result=$result/ fi # since we now have identified the common part, # compute the non-common part forward_part=${target#"$common_part"} # and now stick all parts together if [ -n "$result" ] && [ -n "$forward_part" ]; then result=$result$forward_part elif [ -n "$forward_part" ]; then # extra slash removal result=${forward_part#?} fi printf '%s' "$result" )