termscp/install.sh

455 lines
13 KiB
Bash
Executable File

#!/usr/bin/env sh
# Options
#
# -V, --verbose
# Enable verbose output for the installer
#
# -f, -y, --force, --yes
# Skip the confirmation prompt during installation
TERMSCP_VERSION="0.7.0"
GITHUB_URL="https://github.com/veeso/termscp/releases/download/v${TERMSCP_VERSION}"
DEB_URL="${GITHUB_URL}/termscp_${TERMSCP_VERSION}_amd64.deb"
RPM_URL="${GITHUB_URL}/termscp-${TERMSCP_VERSION}-1.x86_64.rpm"
set -eu
printf "\n"
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 '')"
# Functions
info() {
printf '%s\n' "${BOLD}${GREY}>${NO_COLOR} $*"
}
warn() {
printf '%s\n' "${YELLOW}! $*${NO_COLOR}"
}
error() {
printf '%s\n' "${RED}x $*${NO_COLOR}" >&2
}
completed() {
printf '%s\n' "${GREEN}${NO_COLOR} $*"
}
has() {
command -v "$1" 1>/dev/null 2>&1
}
get_tmpfile() {
local suffix
suffix="$1"
if has mktemp; then
printf "%s.%s" "$(mktemp)" "${suffix}"
else
# No really good options here--let's pick a default + hope
printf "/tmp/termscp.%s" "${suffix}"
fi
}
download() {
output="$1"
url="$2"
if has curl; then
cmd="curl --fail --silent --location --output $output $url"
elif has wget; then
cmd="wget --quiet --output-document=$output $url"
elif has fetch; then
cmd="fetch --quiet --output=$output $url"
else
error "No HTTP download program (curl, wget, fetch) found, exiting…"
return 1
fi
$cmd && return 0 || rc=$?
error "Command failed (exit code $rc): ${BLUE}${cmd}${NO_COLOR}"
warn "If you believe this is a bug, please report immediately an issue to <https://github.com/veeso/termscp/issues/new>"
return $rc
}
test_writeable() {
local path
path="${1:-}/test.txt"
if touch "${path}" 2>/dev/null; then
rm "${path}"
return 0
else
return 1
fi
}
elevate_priv() {
if ! has sudo; then
error 'Could not find the command "sudo", needed to install termscp on your system.'
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
}
elevate_priv_ex() {
check_dir="$1"
if test_writeable "$check_dir"; then
sudo=""
else
warn "Root permissions are required to install dependecies"
elevate_priv
sudo="sudo"
fi
echo $sudo
}
# Currently supporting:
# - macos
# - linux
# - freebsd
detect_platform() {
local platform
platform="$(uname -s | tr '[:upper:]' '[:lower:]')"
case "${platform}" in
linux) platform="linux" ;;
darwin) platform="macos" ;;
freebsd) platform="freebsd" ;;
esac
printf '%s' "${platform}"
}
# Currently supporting:
# - x86_64
detect_arch() {
local arch
arch="$(uname -m | tr '[:upper:]' '[:lower:]')"
case "${arch}" in
amd64) arch="x86_64" ;;
armv*) arch="arm" ;;
arm64) arch="aarch64" ;;
esac
# `uname -m` in some cases mis-reports 32-bit OS as 64-bit, so double check
if [ "${arch}" = "x86_64" ] && [ "$(getconf LONG_BIT)" -eq 32 ]; then
arch="i686"
elif [ "${arch}" = "aarch64" ] && [ "$(getconf LONG_BIT)" -eq 32 ]; then
arch="arm"
fi
if [ "${arch}" != "x86_64" ]; then
error "Unsupported arch ${arch}"
return 1
fi
printf '%s' "${arch}"
}
confirm() {
if [ -z "${FORCE-}" ]; then
printf "%s " "${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
}
# Installers
install_on_bsd() {
try_with_cargo "packages for freeBSD are distribuited no more. Only cargo installations are supported."
}
install_on_arch_linux() {
pkg="$1"
info "Detected ${YELLOW}${pkg}${NO_COLOR} on your system"
confirm "${YELLOW}rust${NO_COLOR} is required to install ${GREEN}termscp${NO_COLOR}; would you like to proceed?"
$pkg -S rust
info "Installing ${GREEN}termscp${NO_COLOR} AUR package…"
$pkg -S termscp
}
install_on_linux() {
local msg
local sudo
local archive
if has yay; then
install_on_arch_linux yay
elif has pakku; then
install_on_arch_linux pakku
elif has paru; then
install_on_arch_linux paru
elif has aurutils; then
install_on_arch_linux aurutils
elif has pamac; then
install_on_arch_linux pamac
elif has pikaur; then
install_on_arch_linux pikaur
elif has dpkg; then
if [ "${ARCH}" != "x86_64" ]; then # It's okay on AUR; not on other distros
try_with_cargo "we don't distribute packages for ${ARCH} at the moment"
else
info "Detected dpkg on your system"
info "Installing ${GREEN}termscp${NO_COLOR} via Debian package"
archive=$(get_tmpfile "deb")
download "${archive}" "${DEB_URL}"
info "Downloaded debian package to ${archive}"
if test_writeable "/usr/bin"; then
sudo=""
msg="Installing ${GREEN}termscp${NO_COLOR}, please wait…"
else
warn "Root permissions are required to install ${GREEN}termscp${NO_COLOR}"
elevate_priv
sudo="sudo"
msg="Installing ${GREEN}termscp${NO_COLOR} as root, please wait…"
fi
info "$msg"
$sudo dpkg -i "${archive}"
fi
elif has rpm; then
if [ "${ARCH}" != "x86_64" ]; then # It's okay on AUR; not on other distros
try_with_cargo "we don't distribute packages for ${ARCH} at the moment"
else
info "Detected rpm on your system"
info "Installing ${GREEN}termscp${NO_COLOR} via RPM package"
archive=$(get_tmpfile "rpm")
download "${archive}" "${RPM_URL}"
info "Downloaded rpm package to ${archive}"
if test_writeable "/usr/bin"; then
sudo=""
msg="Installing ${GREEN}termscp${NO_COLOR}, please wait…"
else
warn "Root permissions are required to install ${GREEN}termscp${NO_COLOR}"
elevate_priv
sudo="sudo"
msg="Installing ${GREEN}termscp${NO_COLOR} as root, please wait…"
fi
info "$msg"
$sudo rpm -U "${archive}"
fi
else
try_with_cargo "No suitable installation method found for your Linux distribution; if you're running on Arch linux, please install an AUR package manager (such as yay). Currently only Arch, Debian based and Red Hat based distros are supported"
fi
}
install_on_macos() {
if has brew; then
if has termscp; then
info "Upgrading ${GREEN}termscp${NO_COLOR}"
# The OR is used since someone could have installed via cargo previously
brew update && brew upgrade termscp || brew install veeso/termscp/termscp
else
info "Installing ${GREEN}termscp${NO_COLOR}"
brew install veeso/termscp/termscp
fi
else
try_with_cargo "brew is missing on your system; please install it from <https://brew.sh/>"
fi
}
# -- cargo installation
install_bsd_cargo_deps() {
set -e
confirm "${YELLOW}libssh, gcc${NO_COLOR} are required to install ${GREEN}termscp${NO_COLOR}; would you like to proceed?"
sudo="$(elevate_priv_ex /usr/local/bin)"
$sudo pkg install -y curl wget libssh gcc dbus pkgconf
info "Dependencies installed successfully"
}
install_linux_cargo_deps() {
local debian_deps="gcc pkg-config libssl-dev libssh2-1-dev libdbus-1-dev"
local rpm_deps="gcc openssl pkgconfig libdbus-devel openssl-devel"
local arch_deps="gcc openssl pkg-config dbus"
local deps_cmd=""
# Get pkg manager
if has apt; then
deps_cmd="apt install -y $debian_deps"
elif has apt-get; then
deps_cmd="apt-get install -y $debian_deps"
elif has yum; then
deps_cmd="yum -y install $rpm_deps"
elif has dnf; then
deps_cmd="dnf -y install $rpm_deps"
elif has pacman; then
deps_cmd="pacman -S --noconfirm $arch_deps"
else
error "Could not find any suitable package manager for your linux distro 🙄"
error "Supported package manager are: 'apt', 'apt-get', 'yum', 'dnf', 'pacman'"
exit 1
fi
set -e
confirm "${YELLOW}libssh, gcc, openssl, pkg-config, libdbus${NO_COLOR} are required to install ${GREEN}termscp${NO_COLOR}. The following command will be used to install the dependencies: '${BOLD}${YELLOW}${deps_cmd}${NO_COLOR}'. Would you like to proceed?"
sudo="$(elevate_priv_ex /usr/local/bin)"
$sudo $deps_cmd
info "Dependencies installed successfully"
}
install_cargo() {
if has cargo; then
return 0
fi
cargo_env="$HOME/.cargo/env"
# Check if cargo is already installed (actually), but not loaded
if [ -f $cargo_env ]; then
. $cargo_env
fi
# Check again cargo
if has cargo; then
return 0
else
confirm "${YELLOW}rust${NO_COLOR} is required to build termscp with cargo; would you like to install it now?"
set -e
rustup=$(get_tmpfile "sh")
info "Downloading rustup.sh…"
download "${rustup}" "https://sh.rustup.rs"
chmod +x $rustup
$rustup -y
info "Rust installed with success"
. $cargo_env
fi
}
try_with_cargo() {
err="$1"
# Install cargo
install_cargo
if has cargo; then
info "Installing ${GREEN}termscp${NO_COLOR} via Cargo…"
case $PLATFORM in
"freebsd")
install_bsd_cargo_deps
cargo install --locked --no-default-features termscp
;;
"linux")
install_linux_cargo_deps
cargo install --locked termscp
;;
*)
cargo install --locked termscp
;;
esac
else
error "$err"
error "Alternatively you can opt for installing Cargo <https://www.rust-lang.org/tools/install>"
return 1
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
-V | --verbose)
VERBOSE=1
shift 1
;;
-f | -y | --force | --yes)
FORCE=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
printf " %s\n" "${UNDERLINE}Termscp configuration${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
printf "\n"
confirm "Install ${GREEN}termscp ${TERMSCP_VERSION}${NO_COLOR}?"
# Installation based on arch
case $PLATFORM in
"freebsd")
install_on_bsd
;;
"linux")
install_on_linux
;;
"macos")
install_on_macos
;;
*)
error "${PLATFORM} is not supported by this installer"
exit 1
;;
esac
completed "Congratulations! Termscp has successfully been installed on your system!"
info "If you're a new user, you might be interested in reading the user manual <https://veeso.github.io/termscp/#user-manual>"
info "While if you've just updated your termscp version, you can find the changelog at this link <https://veeso.github.io/termscp/#changelog>"
info "Remember that if you encounter any issue, you can report them on Github <https://github.com/veeso/termscp/issues/new>"
info "Feel free to open an issue also if you have an idea which could improve the project"
info "If you want to support the project, please, consider a little donation <https://www.buymeacoffee.com/veeso>"
info "I hope you'll enjoy using termscp :D"
exit 0