mirror of
https://github.com/denisidoro/navi
synced 2024-11-30 23:39:11 +00:00
300 lines
6.4 KiB
Bash
Executable file
300 lines
6.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
if ${X_MODE:-false}; then
|
|
set -x
|
|
fi
|
|
|
|
# =====================
|
|
# paths
|
|
# =====================
|
|
|
|
export CARGO_DEFAULT_BIN="${HOME}/.cargo/bin"
|
|
export BIN_DIR="${BIN_DIR:-"$CARGO_DEFAULT_BIN"}"
|
|
|
|
|
|
# =====================
|
|
# logging
|
|
# =====================
|
|
|
|
echoerr() {
|
|
echo "$@" 1>&2
|
|
}
|
|
|
|
tap() {
|
|
local -r x="$(cat)"
|
|
echoerr "$x"
|
|
echo "$x"
|
|
}
|
|
|
|
log::ansi() {
|
|
local bg=false
|
|
case "$@" in
|
|
*reset*) echo "\e[0m"; return 0 ;;
|
|
*black*) color=30 ;;
|
|
*red*) color=31 ;;
|
|
*green*) color=32 ;;
|
|
*yellow*) color=33 ;;
|
|
*blue*) color=34 ;;
|
|
*purple*) color=35 ;;
|
|
*cyan*) color=36 ;;
|
|
*white*) color=37 ;;
|
|
esac
|
|
case "$@" in
|
|
*regular*) mod=0 ;;
|
|
*bold*) mod=1 ;;
|
|
*underline*) mod=4 ;;
|
|
esac
|
|
case "$@" in
|
|
*background*) bg=true ;;
|
|
*bg*) bg=true ;;
|
|
esac
|
|
|
|
if $bg; then
|
|
echo "\e[${color}m"
|
|
else
|
|
echo "\e[${mod:-0};${color}m"
|
|
fi
|
|
}
|
|
|
|
_log() {
|
|
local template="$1"
|
|
shift
|
|
echoerr "$(printf "$template" "$@")"
|
|
}
|
|
|
|
_header() {
|
|
local TOTAL_CHARS=60
|
|
local total=$TOTAL_CHARS-2
|
|
local size=${#1}
|
|
local left=$((($total - $size) / 2))
|
|
local right=$(($total - $size - $left))
|
|
printf "%${left}s" '' | tr ' ' =
|
|
printf " $1 "
|
|
printf "%${right}s" '' | tr ' ' =
|
|
}
|
|
|
|
log::header() { _log "\n$(log::ansi bold)$(log::ansi purple)$(_header "$1")$(log::ansi reset)\n"; }
|
|
log::success() { _log "$(log::ansi green)✔ %s$(log::ansi reset)\n" "$@"; }
|
|
log::error() { _log "$(log::ansi red)✖ %s$(log::ansi reset)\n" "$@"; }
|
|
log::warning() { _log "$(log::ansi yellow)➜ %s$(log::ansi reset)\n" "$@"; }
|
|
log::note() { _log "$(log::ansi blue)%s$(log::ansi reset)\n" "$@"; }
|
|
|
|
# TODO: remove
|
|
header() {
|
|
echoerr "$*"
|
|
echoerr
|
|
}
|
|
|
|
die() {
|
|
log::error "$@"
|
|
exit 42
|
|
}
|
|
|
|
no_binary_warning() {
|
|
log::note "There's no precompiled binary for your platform: $(uname -a)"
|
|
}
|
|
|
|
installation_finish_instructions() {
|
|
local -r shell="$(get_shell)"
|
|
log::note -e "Finished. To call navi, restart your shell or reload the config file:\n source ~/.${shell}rc"
|
|
local code
|
|
if [[ "$shell" == "zsh" ]]; then
|
|
code="navi widget ${shell} | source"
|
|
else
|
|
code='source <(navi widget '"$shell"')'
|
|
fi
|
|
log::note -e "\nTo add the Ctrl-G keybinding, add the following to ~/.${shell}rc:\n ${code}"
|
|
}
|
|
|
|
|
|
# =====================
|
|
# security
|
|
# =====================
|
|
|
|
sha256() {
|
|
if command_exists sha256sum; then
|
|
sha256sum
|
|
elif command_exists shasum; then
|
|
shasum -a 256
|
|
elif command_exists openssl; then
|
|
openssl dgst -sha256
|
|
else
|
|
log::note "Unable to calculate sha256!"
|
|
exit 43
|
|
fi
|
|
}
|
|
|
|
|
|
# =====================
|
|
# github
|
|
# =====================
|
|
|
|
latest_version_released() {
|
|
curl -s 'https://api.github.com/repos/denisidoro/navi/releases/latest' \
|
|
| grep -Eo 'releases/tag/v([0-9\.]+)' \
|
|
| sed 's|releases/tag/v||'
|
|
}
|
|
|
|
asset_url() {
|
|
local -r version="$1"
|
|
local -r variant="${2:-}"
|
|
|
|
if [[ -n "$variant" ]]; then
|
|
echo "https://github.com/denisidoro/navi/releases/download/v${version}/navi-v${version}-${variant}.tar.gz"
|
|
else
|
|
echo "https://github.com/denisidoro/navi/archive/v${version}.tar.gz"
|
|
fi
|
|
}
|
|
|
|
download_asset() {
|
|
local -r tmp_dir="$(mktemp -d -t navi-install-XXXX)"
|
|
local -r url="$(asset_url "$@")"
|
|
log::note "Downloading ${url}..."
|
|
cd "$tmp_dir"
|
|
curl -L "$url" -o navi.tar.gz
|
|
tar xvzf navi.tar.gz
|
|
mkdir -p "${BIN_DIR}" &>/dev/null || true
|
|
mv "./navi" "${BIN_DIR}/navi"
|
|
}
|
|
|
|
sha_for_asset_on_github() {
|
|
local -r url="$(asset_url "$@")"
|
|
curl -sL "$url" | sha256 | awk '{print $1}'
|
|
}
|
|
|
|
error_installing() {
|
|
log::error "Unable to install navi. Please check https://github.com/denisidoro/navi for alternative installation instructions"
|
|
exit 33
|
|
}
|
|
|
|
|
|
# =====================
|
|
# code
|
|
# =====================
|
|
|
|
version_from_toml() {
|
|
cat "${NAVI_HOME}/Cargo.toml" \
|
|
| grep version \
|
|
| head -n1 \
|
|
| awk '{print $NF}' \
|
|
| tr -d '"' \
|
|
| tr -d "'"
|
|
}
|
|
|
|
|
|
# =====================
|
|
# platform
|
|
# =====================
|
|
|
|
command_exists() {
|
|
type "$1" &>/dev/null
|
|
}
|
|
|
|
get_target() {
|
|
local -r unamea="$(uname -a)"
|
|
local -r archi="$(uname -sm)"
|
|
|
|
local target
|
|
case "$unamea $archi" in
|
|
*arwin*) target="x86_64-apple-darwin" ;;
|
|
*inux*x86*) target="x86_64-unknown-linux-musl" ;;
|
|
*ndroid*aarch*|*ndroid*arm*) target="aarch64-linux-android" ;;
|
|
*inux*aarch*|*inux*arm*) target="armv7-unknown-linux-musleabihf" ;;
|
|
*) target="" ;;
|
|
esac
|
|
|
|
echo "$target"
|
|
}
|
|
|
|
get_shell() {
|
|
echo $SHELL | xargs basename
|
|
}
|
|
|
|
|
|
# =====================
|
|
# main
|
|
# =====================
|
|
|
|
export_path_cmd() {
|
|
echo
|
|
echo ' export PATH="${PATH}:'"$1"'"'
|
|
}
|
|
|
|
append_to_file() {
|
|
local -r path="$1"
|
|
local -r text="$2"
|
|
if [ -f "$path" ]; then
|
|
echo "$text" >> "$path"
|
|
fi
|
|
}
|
|
|
|
get_navi_bin_path() {
|
|
local file="${BIN_DIR}/navi"
|
|
if [ -f "$file" ]; then
|
|
echo "$file"
|
|
return 0
|
|
fi
|
|
file="${CARGO_DEFAULT_BIN}/navi"
|
|
if [ -f "$file" ]; then
|
|
echo "$file"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
install_navi() {
|
|
local -r target="$(get_target)"
|
|
|
|
if command_exists navi; then
|
|
log::success "navi is already installed"
|
|
exit 0
|
|
|
|
elif command_exists brew; then
|
|
brew install navi
|
|
|
|
elif command_exists cargo; then
|
|
cargo install navi
|
|
|
|
elif [[ -n "$target" ]]; then
|
|
local -r version="$(latest_version_released)"
|
|
download_asset "$version" "$target" || error_installing
|
|
|
|
else
|
|
error_installing
|
|
|
|
fi
|
|
|
|
hash -r 2>/dev/null || true
|
|
|
|
local navi_bin_path="$(which navi || get_navi_bin_path)"
|
|
ln -s "$navi_bin_path" "${BIN_DIR}/navi" &>/dev/null || true
|
|
if [ -f "${BIN_DIR}/navi" ]; then
|
|
navi_bin_path="${BIN_DIR}/navi"
|
|
fi
|
|
|
|
local -r navi_bin_dir="$(dirname "$navi_bin_path")"
|
|
|
|
echoerr
|
|
log::success "Finished"
|
|
log::success "navi is now available at ${navi_bin_path}"
|
|
echoerr
|
|
|
|
if echo "$PATH" | grep -q "$navi_bin_path"; then
|
|
:
|
|
else
|
|
local -r cmd="$(export_path_cmd "$navi_bin_path")"
|
|
append_to_file "${HOME}/.bashrc" "$cmd"
|
|
append_to_file "${ZDOTDIR:-"$HOME"}/.zshrc" "$cmd"
|
|
append_to_file "${HOME}/.fishrc" "$cmd"
|
|
fi
|
|
|
|
log::note "To call navi, restart your shell or reload your .bashrc-like config file"
|
|
echo
|
|
log::note "Check https://github.com/denisidoro/navi for more info"
|
|
|
|
export PATH="${PATH}:${navi_bin_path}"
|
|
|
|
return 0
|
|
}
|
|
|
|
(return 0 2>/dev/null) || install_navi "$@"
|