Skip to content

Instantly share code, notes, and snippets.

@tsibley
Last active July 26, 2022 18:48
Show Gist options
  • Select an option

  • Save tsibley/4d4263128da4f156e2af5f099937bda6 to your computer and use it in GitHub Desktop.

Select an option

Save tsibley/4d4263128da4f156e2af5f099937bda6 to your computer and use it in GitHub Desktop.
# Example of a compact, OS-specific installer for Linux.
#
# XXX FIXME: Replace hardcoded URL below with something like https://nextstrain.org/download/cli/linux
dest="${XDG_DATA_HOME:-$HOME/.local/share}/nextstrain/cli/standalone" &&
mkdir -p "${dest}-new" &&
curl -fsSL --proto "=https" https://github.com/nextstrain/cli/releases/download/4.1.1/nextstrain-cli-4.1.1-standalone-x86_64-unknown-linux-gnu.tar.gz \
| tar xzf - -C "${dest}-new" &&
if [[ -d "$dest" ]]; then mv "$dest" "${dest}-old"; fi &&
mv "${dest}-new" "$dest" &&
printf 'Please add PATH="%s:$PATH" to your shell initialization files.\n' "$dest"
#!/bin/bash
set -euo pipefail
shopt -s failglob
: "${NEXTSTRAIN_DOT_ORG:=https://nextstrain.org}"
# Globals declared here to make them more obvious, but set by main() to avoid
# source ordering requirements and delay execution until the full file is
# parsed.
declare KERNEL TARGET DESTINATION
main() {
[[ -z "${KERNEL:-}" ]] && KERNEL="$(uname -s)"
[[ -z "${TARGET:-}" ]] && TARGET="$(target-triple)"
[[ -z "${DESTINATION:-}" ]] && DESTINATION="$(destination)"
local tmp archive archive_url
archive="standalone-${TARGET}.tar.gz"
archive_url="${NEXTSTRAIN_DOT_ORG}/cli/download/latest/${archive}"
# Move into a temporary working dir
tmp="$(mktemp -d)"
if ! debug; then
trap "rm -rf $tmp" EXIT
fi
pushd "$tmp" >/dev/null
log "Temporary working directory: $tmp"
log "Downloading $archive_url"
curl "$archive_url" \
--fail --show-error --location --proto "=https" \
> "$archive"
log "Extracting $archive"
mkdir standalone
tar xz$(if-debug v)f "$archive" -C standalone
if [[ -d "$DESTINATION" ]]; then
log "Removing existing $DESTINATION"
rm -rf "$DESTINATION"
fi
mkdir -p "$(dirname "$DESTINATION")"
mv standalone "$DESTINATION"
popd >/dev/null
if ! debug; then
log "Cleaning up"
rm -rf "$tmp"
fi
echo ______________________________________________________________________________
echo
echo Nextstrain CLI "($("$DESTINATION"/nextstrain --version))" installed to "$DESTINATION".
echo
echo To make the \"nextstrain\" command available on your PATH, please add
echo the following to your shell initialization files:
echo
echo PATH=\""$DESTINATION":\$PATH\"
echo
}
target-triple() {
local machine vendor os
machine="$(uname -m)"
case "$KERNEL" in
Linux)
vendor=unknown
os=linux-gnu
;;
Darwin)
vendor=apple
os=darwin
;;
*)
die "unknown kernel: $KERNEL"
esac
echo "$machine-$vendor-$os"
}
destination() {
local user_data dest
# Paths from appdirs <https://github.com/ActiveState/appdirs/blob/master/appdirs.py>
case "$KERNEL" in
Linux)
user_data="${XDG_DATA_HOME:-$HOME/.local/share}";;
Darwin)
user_data="$HOME/Library/Application Support";;
*)
die "unknown kernel: $KERNEL"
esac
if [[ ! -d "$user_data" ]]; then
# XXX FIXME: should we create it…?
die "user data dir doesn't exist: $user_data"
fi
echo "$user_data/nextstrain/cli/standalone"
}
debug() {
[[ -n "${DEBUG:-}" ]]
}
if-debug() {
if debug; then
echo "$@"
fi
}
if-not-debug() {
if ! debug; then
echo "$@"
fi
}
log() {
echo "--> $@"
}
die() {
echo "ERROR:" "$@" >&2
exit 1
}
main "$@"
# Example of an OS-specific installer for Windows.
$ErrorActionPreference = "Stop"
if (!$IsWindows -and !$env:TESTING) {
echo "This is not Windows. Aborting!"
exit 1
}
if (!(Test-Path $env:LOCALAPPDATA)) {
echo "LOCALAPPDATA does not exist. Aborting!"
exit 1
}
$DESTINATION = "${env:LOCALAPPDATA}/nextstrain/cli/standalone"
function Main {
$tmp = New-Item -Type Directory "$([System.IO.Path]::GetTempPath())/$([System.IO.Path]::GetRandomFileName())"
cd $tmp
log "Temporary working directory: $tmp"
log "Downloading installation archive"
# curl is supposedly built into PowerShell since version 6. \o/
curl -fsSL --proto "=https" https://nextstrain.org/cli/download/latest/standalone-x86_64-pc-windows-msvc.zip -o archive.zip
log "Extracting archive"
New-Item -Type Directory standalone | Out-Null
Expand-Archive -Path archive.zip -DestinationPath standalone
if (Test-Path $DESTINATION) {
log "Removing existing installation"
Remove-Item -Force -Recurse $DESTINATION
}
log "Installing to $DESTINATION"
New-Item -Type Directory -Force $(Split-Path $DESTINATION) | Out-Null
Move-Item standalone $DESTINATION
# Naively splitting is wrong in the general case, but fine for this check as
# long as $DESTINATION itself doesn't contain a semi-colon.
if ($DESTINATION -notin ($env:PATH -split ";")) {
log "Prepending $DESTINATION to PATH for current user"
[Environment]::SetEnvironmentVariable("PATH", "$DESTINATION;${env:PATH}", "User")
}
}
function log {
echo "--> $Args"
}
Main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment