#!/bin/sh # Installs amp, Amp's command-line interface: # # curl -fsSL https://dl.amp.motor.dev | sh # # It installs the latest release into $AMP_INSTALL_DIR (default: ~/.local/bin). Set AMP_VERSION to # install a specific release. If the directory isn't on the PATH, the script adds it in the profile of # your shell (zsh, bash, fish, or ~/.profile for other shells). Set AMP_NO_MODIFY_PATH=1 to get # instructions instead. set -e -u BASE="${AMP_DIST_URL:-https://dl.amp.motor.dev}" DIR="${AMP_INSTALL_DIR:-$HOME/.local/bin}" fail() { echo "install.sh: $1" >&2 exit 1 } case "$(uname -s)" in Darwin) OS=darwin ;; Linux) OS=linux ;; *) fail "amp isn't available for $(uname -s)" ;; esac case "$(uname -m)" in arm64 | aarch64) ARCH=arm64 ;; x86_64 | amd64) ARCH=amd64 ;; *) fail "amp isn't available for $(uname -m)" ;; esac # A shell under Rosetta reports x86_64 on an Apple silicon Mac: prefer the native binary. if [ "$OS" = darwin ] && [ "$ARCH" = amd64 ] && [ "$(sysctl -n hw.optional.arm64 2>/dev/null)" = 1 ]; then ARCH=arm64 fi TARGET="$OS-$ARCH" download() { if command -v curl >/dev/null 2>&1; then curl -fsSL -o "$2" "$1" || fail "can't download $1" elif command -v wget >/dev/null 2>&1; then wget -q -O "$2" "$1" || fail "can't download $1" else fail "install curl or wget, then try again" fi } checksum() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d' ' -f1 else shasum -a 256 "$1" | cut -d' ' -f1 fi } WORK="$(mktemp -d)" trap 'rm -rf "$WORK"' EXIT VERSION="${AMP_VERSION:-}" if [ -z "$VERSION" ]; then download "$BASE/index.json" "$WORK/index.json" VERSION="$(tr -d ' \n' < "$WORK/index.json" | sed -n 's/.*"latest":"\([0-9_]*\)".*/\1/p')" [ -n "$VERSION" ] || fail "the published index doesn't name a latest version" fi download "$BASE/releases/$VERSION/manifest.json" "$WORK/manifest.json" EXPECTED="$(tr -d ' \n' < "$WORK/manifest.json" | sed -n "s/.*\"$TARGET\":{\"sha256\":\"\([0-9a-f]*\)\".*/\1/p")" [ -n "$EXPECTED" ] || fail "amp $VERSION isn't published for $TARGET" echo "Downloading amp $VERSION for $TARGET" download "$BASE/releases/$VERSION/amp-$TARGET.gz" "$WORK/amp.gz" [ "$(checksum "$WORK/amp.gz")" = "$EXPECTED" ] || fail "the download doesn't match its checksum; try again" gunzip "$WORK/amp.gz" chmod +x "$WORK/amp" mkdir -p "$DIR" mv -f "$WORK/amp" "$DIR/amp" echo "Installed amp $VERSION to $DIR/amp" # Write the directory with $HOME, so that the profile line is easy to read. case "$DIR" in "$HOME"/*) SHOWN="\$HOME/${DIR#"$HOME"/}" ;; *) SHOWN="$DIR" ;; esac LINE="export PATH=\"$SHOWN:\$PATH\"" case "$(basename "${SHELL:-sh}")" in zsh) PROFILE="${ZDOTDIR:-$HOME}/.zshrc" ;; bash) # macOS opens login shells, which read ~/.bash_profile; Linux opens shells that read ~/.bashrc. if [ "$OS" = darwin ]; then PROFILE="$HOME/.bash_profile"; else PROFILE="$HOME/.bashrc"; fi ;; fish) PROFILE="${XDG_CONFIG_HOME:-$HOME/.config}/fish/conf.d/amp.fish" LINE="fish_add_path \"$SHOWN\"" ;; *) PROFILE="$HOME/.profile" ;; esac case ":${PATH}:" in *:"$DIR":*) # Another amp earlier on the PATH would hide this one. FOUND="$(command -v amp 2>/dev/null || true)" if [ -n "$FOUND" ] && [ "$FOUND" != "$DIR/amp" ]; then echo echo "warning: $FOUND comes before $DIR/amp on your PATH; remove it, or put $DIR first" fi ;; *) if [ -n "${AMP_NO_MODIFY_PATH:-}" ]; then echo echo "$DIR isn't on your PATH. Add this line to $PROFILE:" echo " $LINE" elif grep -qsF "$LINE" "$PROFILE"; then echo echo "$PROFILE adds $DIR to your PATH. Open a new shell to use amp." elif mkdir -p "$(dirname "$PROFILE")" && printf '\n# Added by the amp installer\n%s\n' "$LINE" >> "$PROFILE"; then echo echo "Added $DIR to your PATH in $PROFILE. Open a new shell, or run this line to use amp now:" echo " $LINE" else echo echo "Can't write $PROFILE. Add this line to the profile of your shell:" echo " $LINE" fi ;; esac echo echo "Run \`amp learn\` to learn how to use amp. Run \`amp update\` to get new releases."