104 lines
3.8 KiB
Bash
Executable File
104 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
repository_root=$(cd "$(dirname "$0")/.." && pwd)
|
|
install_directory="${THT_INSTALL_DIRECTORY:-/usr/local/bin}"
|
|
staging_root=$(mktemp -d)
|
|
trap 'rm -rf "$staging_root"' EXIT HUP INT TERM
|
|
|
|
fail() {
|
|
echo "install-tht.sh: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
sha256() {
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
sha256sum "$1" | awk '{print $1}'
|
|
elif command -v shasum >/dev/null 2>&1; then
|
|
shasum -a 256 "$1" | awk '{print $1}'
|
|
else
|
|
fail "SHA-256 verification requires sha256sum or shasum"
|
|
fi
|
|
}
|
|
|
|
platform_artifact_name() {
|
|
local system architecture
|
|
system=$(uname -s)
|
|
architecture=$(uname -m)
|
|
case "$system" in
|
|
Darwin) system=darwin ;;
|
|
Linux) system=linux ;;
|
|
*) fail "unsupported operating system: $system (supported: macOS and Linux)" ;;
|
|
esac
|
|
case "$architecture" in
|
|
x86_64|amd64) architecture=amd64 ;;
|
|
arm64|aarch64) architecture=arm64 ;;
|
|
*) fail "unsupported processor architecture: $architecture (supported: amd64 and arm64)" ;;
|
|
esac
|
|
printf 'tht-%s-%s\n' "$system" "$architecture"
|
|
}
|
|
|
|
validate_packaged_artifact() {
|
|
local artifact=$1 expected actual
|
|
expected=${THT_BUILD_ARTIFACT_SHA256:-}
|
|
[[ "$expected" =~ ^[[:xdigit:]]{64}$ ]] || fail "THT_BUILD_ARTIFACT_SHA256 must be a 64-character SHA-256 digest"
|
|
actual=$(sha256 "$artifact")
|
|
actual=$(printf '%s' "$actual" | tr '[:upper:]' '[:lower:]')
|
|
expected=$(printf '%s' "$expected" | tr '[:upper:]' '[:lower:]')
|
|
[[ "$actual" == "$expected" ]] || fail "packaged tht artifact checksum does not match"
|
|
}
|
|
|
|
build_artifact() {
|
|
local build_output="$staging_root/build"
|
|
mkdir -p "$build_output"
|
|
THT_THT_OUTPUT_DIRECTORY="$build_output" bash "$repository_root/scripts/build-tht.sh" --all >&2
|
|
printf '%s/%s\n' "$build_output" "$(platform_artifact_name)"
|
|
}
|
|
|
|
install_atomically() {
|
|
local destination_directory=$1 source_file=$2
|
|
local temporary_destination
|
|
if mkdir -p "$destination_directory" 2>/dev/null && [[ -w "$destination_directory" ]]; then
|
|
temporary_destination=$(mktemp "$destination_directory/.tht.XXXXXX")
|
|
cp "$source_file" "$temporary_destination"
|
|
chmod 0755 "$temporary_destination"
|
|
mv -f "$temporary_destination" "$destination_directory/tht"
|
|
return
|
|
fi
|
|
|
|
command -v sudo >/dev/null 2>&1 || fail "cannot write to $destination_directory and sudo is unavailable"
|
|
sudo sh -c '
|
|
set -eu
|
|
destination_directory=$1
|
|
source_file=$2
|
|
mkdir -p "$destination_directory"
|
|
temporary_destination=$(mktemp "$destination_directory/.tht.XXXXXX")
|
|
trap "rm -f \"$temporary_destination\"" EXIT HUP INT TERM
|
|
cp "$source_file" "$temporary_destination"
|
|
chmod 0755 "$temporary_destination"
|
|
mv -f "$temporary_destination" "$destination_directory/tht"
|
|
' sh "$destination_directory" "$source_file"
|
|
}
|
|
|
|
[[ "$install_directory" == /* ]] || fail "THT_INSTALL_DIRECTORY must be an absolute path"
|
|
artifact_name=$(platform_artifact_name)
|
|
if [[ -n "${THT_BUILD_ARTIFACT:-}" ]]; then
|
|
source_artifact=$THT_BUILD_ARTIFACT
|
|
[[ -f "$source_artifact" ]] || fail "THT_BUILD_ARTIFACT is not a regular file"
|
|
validate_packaged_artifact "$source_artifact"
|
|
else
|
|
source_artifact=$(build_artifact)
|
|
fi
|
|
|
|
[[ -s "$source_artifact" ]] || fail "native artifact is missing: $artifact_name"
|
|
staged_binary="$staging_root/tht"
|
|
cp "$source_artifact" "$staged_binary"
|
|
chmod 0755 "$staged_binary"
|
|
"$staged_binary" --help >/dev/null || fail "native artifact did not pass its help check"
|
|
|
|
install_atomically "$install_directory" "$staged_binary"
|
|
resolved_command=$(command -v tht || true)
|
|
[[ "$resolved_command" == "$install_directory/tht" ]] || fail "installed tht is not resolvable at $install_directory/tht; add $install_directory to PATH and open a new terminal"
|
|
"$install_directory/tht" --help >/dev/null || fail "installed tht did not pass its help check"
|
|
printf 'Installed tht at %s/tht\n' "$install_directory"
|