#!/bin/sh set -eu fail() { printf 'nixcache: %s\n' "$*" >&2 exit 1 } main() { version=latest install_dir=${HOME:?HOME must be set}/.local/bin while [ "$#" -gt 0 ]; do case "$1" in --version|--install-dir) [ "$#" -ge 2 ] && [ -n "$2" ] || fail "$1 requires a value" case "$1" in --version) version=$2 ;; --install-dir) install_dir=$2 ;; esac shift 2 ;; --help|-h) printf 'Usage: sh install.sh [--version latest|vX.Y.Z] [--install-dir DIR]\nDefaults: latest release, $HOME/.local/bin. Does not configure or start Nix.\n' return ;; *) fail "unknown argument: $1" ;; esac done case "$(uname -s)" in Linux) os=linux ;; Darwin) os=darwin ;; *) fail 'only Linux and macOS are supported' ;; esac case "$(uname -m)" in x86_64|amd64) arch=amd64 ;; arm64|aarch64) arch=arm64 ;; *) fail 'only amd64 and arm64 are supported' ;; esac for tool in curl tar sed awk; do command -v "$tool" >/dev/null 2>&1 || fail "$tool is required" done if command -v sha256sum >/dev/null 2>&1; then hash_tool=sha256sum elif command -v shasum >/dev/null 2>&1; then hash_tool=shasum else fail 'sha256sum or shasum is required' fi tmp=$(mktemp -d) stage= trap 'rm -rf "$tmp"; if [ -n "$stage" ]; then rm -f "$stage"; fi' 0 trap 'exit 1' HUP INT TERM base=https://public.namespaceblobs.com/nixcache/releases if [ "$version" = latest ]; then curl --proto '=https' --proto-redir '=https' -fsSL "$base/latest/nixcache.json" -o "$tmp/manifest.json" version=$(sed -n 's/^[[:space:]]*"version":[[:space:]]*"\([^"]*\)"[,]\{0,1\}[[:space:]]*$/\1/p' "$tmp/manifest.json") fi version=${version#v} printf '%s\n' "$version" | awk '/^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/ { valid++ } END { exit !(NR == 1 && valid == 1) }' || fail 'version must be latest or a stable version such as v0.2.0' archive="nixcache_${version}_${os}_${arch}.tar.gz" curl --proto '=https' --proto-redir '=https' -fsSL "$base/v$version/checksums.txt" -o "$tmp/checksums.txt" expected=$(awk -v name="$archive" '$2 == name { print $1 }' "$tmp/checksums.txt") [ "${#expected}" -eq 64 ] || fail 'missing or ambiguous archive checksum' case "$expected" in *[!0-9a-f]*) fail 'invalid archive checksum' ;; esac curl --proto '=https' --proto-redir '=https' -fsSL "$base/v$version/$archive" -o "$tmp/archive.tar.gz" if [ "$hash_tool" = sha256sum ]; then actual=$(sha256sum "$tmp/archive.tar.gz") else actual=$(shasum -a 256 "$tmp/archive.tar.gz") fi [ "${actual%% *}" = "$expected" ] || fail 'archive checksum mismatch' tar -xzf "$tmp/archive.tar.gz" -C "$tmp" nixcache [ -f "$tmp/nixcache" ] && [ ! -L "$tmp/nixcache" ] || fail 'archive does not contain a regular nixcache binary' mkdir -p "$install_dir" install_dir=$(cd "$install_dir" && pwd) [ ! -d "$install_dir/nixcache" ] || fail 'destination nixcache is a directory' # Rename within the destination filesystem so updates never expose a partial binary. stage=$(mktemp "$install_dir/.nixcache.XXXXXX") cp "$tmp/nixcache" "$stage" chmod 755 "$stage" mv -f "$stage" "$install_dir/nixcache" stage= printf 'Installed nixcache v%s to %s/nixcache\n' "$version" "$install_dir" case ":${PATH:-}:" in *":$install_dir:"*) ;; *) printf 'Add %s to PATH to run nixcache.\n' "$install_dir" ;; esac } main "$@"