#!/usr/bin/env bash set -euo pipefail repository="gakonst/nanocodex" install_root="${NANOCODEX_DIR:-$HOME/.nanocodex}" bin_dir="$install_root/bin" versions_dir="$install_root/versions" updater_dir="$install_root/updater" case "$(uname -s)" in Linux) platform="unknown-linux-gnu" ;; Darwin) platform="apple-darwin" ;; *) echo "nanocodex: unsupported operating system $(uname -s)" >&2 echo "Download a binary from https://github.com/$repository/releases/latest" >&2 exit 1 ;; esac case "$(uname -m)" in x86_64|amd64) architecture="x86_64" ;; arm64|aarch64) architecture="aarch64" ;; *) echo "nanocodex: unsupported architecture $(uname -m)" >&2 exit 1 ;; esac case "${architecture}-${platform}" in x86_64-unknown-linux-gnu|aarch64-apple-darwin) ;; *) echo "nanocodex: no release binary is published for ${architecture}-${platform}" >&2 exit 1 ;; esac binary="nanocodex-${architecture}-${platform}" asset="$binary.gz" temporary_dir="$(mktemp -d 2>/dev/null)" || { echo "nanocodex: failed to create a temporary directory" >&2 exit 1 } trap 'rm -rf -- "$temporary_dir"' EXIT echo "Installing the latest Nanocodex release..." release_redirect="$( curl --fail --silent --show-error --head \ --output /dev/null --write-out '%{redirect_url}' \ "https://github.com/$repository/releases/latest" )" release_tag="${release_redirect##*/}" version="${release_tag#v}" if [[ -z "$release_tag" || -z "$version" || "$version" == "$release_tag" ]]; then echo "nanocodex: could not resolve the latest release version" >&2 exit 1 fi release_url="https://github.com/$repository/releases/download/$release_tag" echo "Downloading $asset..." curl --fail --show-error --location --progress-bar "$release_url/$asset" --output "$temporary_dir/$asset" curl --fail --silent --show-error --location "$release_url/SHA256SUMS" --output "$temporary_dir/SHA256SUMS" expected="$(awk -v asset="$asset" '$2 == asset || $2 == "*" asset { print $1; exit }' "$temporary_dir/SHA256SUMS")" if [[ -z "$expected" ]]; then echo "nanocodex: SHA256SUMS does not contain $asset" >&2 exit 1 fi if ! command -v gzip >/dev/null 2>&1; then echo "nanocodex: gzip is required to unpack the download" >&2 exit 1 fi if ! command -v sha256sum >/dev/null 2>&1 && ! command -v shasum >/dev/null 2>&1; then echo "nanocodex: sha256sum or shasum is required to verify the download" >&2 exit 1 fi sha256_file() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{ print $1 }' else shasum -a 256 "$1" | awk '{ print $1 }' fi } actual="$(sha256_file "$temporary_dir/$asset")" if [[ "$actual" != "$expected" ]]; then echo "nanocodex: checksum mismatch for $asset" >&2 exit 1 fi if ! gzip -dc "$temporary_dir/$asset" > "$temporary_dir/$binary"; then echo "nanocodex: failed to unpack $asset" >&2 exit 1 fi binary_checksum="$(sha256_file "$temporary_dir/$binary")" version_dir="$versions_dir/$version" mkdir -p "$bin_dir" "$version_dir" "$updater_dir" install -m 755 "$temporary_dir/$binary" "$version_dir/nanocodex" printf '%s\n' "$binary_checksum" > "$version_dir/nanocodex.sha256" install -m 755 "$temporary_dir/$binary" "$updater_dir/nanocodex" printf '%s\n' "$binary_checksum" > "$updater_dir/nanocodex.sha256" ln -sfn "versions/$version" "$install_root/current" cat > "$temporary_dir/nanocodex-launcher" <<'EOF' #!/bin/sh set -eu case "$0" in */*) launcher=$0 ;; *) launcher=$(command -v "$0") ;; esac bin_dir=$(CDPATH= cd -- "$(dirname -- "$launcher")" && pwd -P) install_root=$(dirname -- "$bin_dir") export NANOCODEX_DIR="$install_root" if [ "${1-}" = "update" ] && [ -f "$install_root/updater/nanocodex.sha256" ]; then exec "$install_root/updater/nanocodex" "$@" fi exec "$install_root/current/nanocodex" "$@" EOF install -m 755 "$temporary_dir/nanocodex-launcher" "$bin_dir/nanocodex" path_line="export PATH=\"\$PATH:$bin_dir\"" profile="" case "${SHELL:-}" in */zsh) profile="${ZDOTDIR:-$HOME}/.zshenv" ;; */bash) profile="$HOME/.bashrc" ;; */fish) profile="${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish" path_line="fish_add_path -a \"$bin_dir\"" ;; */ash|*/dash|*/ksh|*/sh) profile="$HOME/.profile" ;; esac if [[ ":$PATH:" != *":$bin_dir:"* && -n "$profile" ]]; then if [[ ( -e "$profile" || -L "$profile" ) && ! -w "$profile" ]]; then echo "nanocodex: cannot update $profile; add this line yourself:" >&2 echo " $path_line" >&2 elif ! mkdir -p "$(dirname "$profile")" || ! touch "$profile"; then echo "nanocodex: cannot create $profile; add this line yourself:" >&2 echo " $path_line" >&2 elif ! grep -Fq "$bin_dir" "$profile"; then if ! printf '\n# Nanocodex\n%s\n' "$path_line" >> "$profile"; then echo "nanocodex: cannot update $profile; add this line yourself:" >&2 echo " $path_line" >&2 fi fi fi echo "Installed nanocodex $version to $version_dir/nanocodex" echo "Activated it through $bin_dir/nanocodex" if [[ ":$PATH:" != *":$bin_dir:"* ]]; then echo "Restart your shell or add $bin_dir to PATH." fi echo "Run 'nanocodex update' whenever you want the latest release."