Skip to content

Instantly share code, notes, and snippets.

@mathieujobin
Last active February 24, 2020 04:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mathieujobin/bc527752f9dc49d8e6a537b58f151554 to your computer and use it in GitHub Desktop.
Save mathieujobin/bc527752f9dc49d8e6a537b58f151554 to your computer and use it in GitHub Desktop.
#!/bin/sh
set -ue
# (c) Copyright Fabrice Le Fessant INRIA/OCamlPro 2013
# (c) Copyright Louis Gesbert OCamlPro 2014-2017
# modified to not ask where to download it - Mathieu Jobin 2020
VERSION='2.0.6'
TAG=$(echo "$VERSION" | tr '~' '-')
DEFAULT_BINDIR=/usr/local/bin
bin_sha512() {
case "$OPAM_BIN" in
opam-$TAG-arm64-linux) echo "d2b3d92fd5fae7f053702b53ddbc7c224fcfbfc9b232247ba4e40cbf1cda28f160d8c14fde87aebeebfd2545e13265c0ee4a47e292f035767fb944b1b8ff5c90";;
opam-$TAG-armhf-linux) echo "a42a7ad8c1afdb20ac5746934306576e6364f5453b176ccd42a3e5a116a5db05c2758cec31800ffab11411290cf671f9eee3f299df48c7ceca8e4d7e33dfedc8";;
opam-$TAG-i686-linux) echo "6c0d965f89a2026ead3120e217d12b2df7426740d54bc94e2c46faaeff5893081e68aac162621bfa694ab597a18be28165f10cdda1217a4d73653789a9928b64";;
opam-$TAG-x86_64-linux) echo "2b9d4a99aa28a193c88c7c6f6265203bd3cfeef98929d6f5cfce4b52cd9ddbd7be7eddc1d3d9c440f81d65074dd7851b8d29cd397fb06d2cfccffb54d3cdcc6a";;
opam-$TAG-x86_64-macos) echo "cf02546b22ca91b1d97a3657b970b34d4acf4dc745696b7200ff185d25ebb5914ea8b6a94b503eb8c999634de6fdb944998a970105cd6a4c6df538c262b48b7f";;
opam-$TAG-x86_64-openbsd) echo "2f58b3d4902d4c3fb823d251a50e034f9101b0c5a3827725876bb3bcb6c013c4f54138054d82abba0a9e917675275e26f05b98630cf7116c465d2110756f1309";;
*) echo "no sha";;
esac
}
usage() {
echo "opam binary installer v.$VERSION"
echo "Downloads and installs a pre-compiled binary of opam $VERSION to the system."
echo "This can also be used to switch between opam versions"
echo
echo "Options:"
echo " --no-backup Don't attempt to backup the current opam root"
echo " --backup Force the backup the current opam root (even if it"
echo " is from the 2.0 branch already)"
echo " --fresh Create the opam $VERSION root from scratch"
echo " --restore VERSION Restore a backed up opam binary and root"
echo
echo "The default is to backup if the current version of opam is 1.*, or when"
echo "using '--fresh'"
}
RESTORE=
NOBACKUP=
FRESH=
while [ $# -gt 0 ]; do
case "$1" in
--restore)
if [ $# -lt 2 ]; then echo "Option $1 requires an argument"; exit 2; fi
shift;
RESTORE=$1;;
--no-backup)
NOBACKUP=1;;
--backup)
NOBACKUP=0;;
--fresh)
FRESH=1;;
--help|-h)
usage; exit 0;;
*)
usage; exit 2;;
esac
shift
done
EXISTING_OPAM=$(command -v opam || echo)
EXISTING_OPAMV=
if [ -n "$EXISTING_OPAM" ]; then
EXISTING_OPAMV=$("$EXISTING_OPAM" --version || echo "unknown")
fi
FRESH=${FRESH:-0}
OPAMROOT=${OPAMROOT:-$HOME/.opam}
if [ ! -d "$OPAMROOT" ]; then FRESH=1; fi
if [ -z "$NOBACKUP" ] && [ ! "$FRESH" = 1 ] && [ -z "$RESTORE" ]; then
case "$EXISTING_OPAMV" in
2.*) NOBACKUP=1;;
*) NOBACKUP=0;;
esac
fi
xsudo() {
local CMD=$1; shift
local DST
for DST in "$@"; do : ; done
local DSTDIR=$(dirname "$DST")
if [ ! -w "$DSTDIR" ]; then
echo "Write access to $DSTDIR required, using 'sudo'."
echo "Command: $CMD $@"
if [ "$CMD" = "install" ]; then
sudo "$CMD" -g 0 -o root "$@"
else
sudo "$CMD" "$@"
fi
else
"$CMD" "$@"
fi
}
if [ -n "$RESTORE" ]; then
OPAM=$(command -v opam)
OPAMV=$("$OPAM" --version)
OPAM_BAK="$OPAM.$RESTORE"
OPAMROOT_BAK="$OPAMROOT.$RESTORE"
if [ ! -e "$OPAM_BAK" ] || [ ! -d "$OPAMROOT_BAK" ]; then
echo "No backup of opam $RESTORE was found"
exit 1
fi
if [ "$NOBACKUP" = 1 ]; then
printf "## This will clear $OPAM and $OPAMROOT. Continue ? [Y/n] "
read R
case "$R" in
""|"y"|"Y"|"yes")
xsudo rm -f "$OPAM"
rm -rf "$OPAMROOT";;
*) exit 1
esac
else
xsudo mv "$OPAM" "$OPAM.$OPAMV"
mv "$OPAMROOT" "$OPAMROOT.$OPAMV"
fi
xsudo mv "$OPAM_BAK" "$OPAM"
mv "$OPAMROOT_BAK" "$OPAMROOT"
printf "## Opam $RESTORE and its root were restored."
if [ "$NOBACKUP" = 1 ]; then echo
else echo " Opam $OPAMV was backed up."
fi
exit 0
fi
TMP=${TMPDIR:-/tmp}
ARCH=$(uname -m || echo unknown)
case "$ARCH" in
x86|i?86) ARCH="i686";;
x86_64|amd64) ARCH="x86_64";;
ppc|powerpc|ppcle) ARCH="ppc";;
aarch64_be|aarch64|armv8b|armv8l) ARCH="arm64";;
armv5*|armv6*|earmv6*|armv7*|earmv7*) ARCH="armhf";;
*) ARCH=$(echo "$ARCH" | awk '{print tolower($0)}')
esac
OS=$( (uname -s || echo unknown) | awk '{print tolower($0)}')
if [ "$OS" = "darwin" ] ; then
OS=macos
fi
OPAM_BIN_URL_BASE='https://github.com/ocaml/opam/releases/download/'
OPAM_BIN="opam-${TAG}-${ARCH}-${OS}"
OPAM_BIN_URL="${OPAM_BIN_URL_BASE}${TAG}/${OPAM_BIN}"
download() {
if command -v wget >/dev/null; then wget -q -O "$@"
else curl -s -L -o "$@"
fi
}
check_sha512() {
if command -v openssl > /dev/null; then
sha512_devnull="cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
sha512_check=`openssl sha512 2>&1 < /dev/null | cut -f 2 -d ' '`
if [ "x$sha512_devnull" = "x$sha512_check" ]; then
sha512=`openssl sha512 "$TMP/$OPAM_BIN" 2> /dev/null | cut -f 2 -d ' '`
check=`bin_sha512`
test "x$sha512" = "x$check"
else
echo "openssl 512 option not handled, binary integrity check can't be performed."
return 0
fi
else
echo "openssl not found, binary integrity check can't be performed."
return 0
fi
}
if [ -e "$TMP/$OPAM_BIN" ] && ! check_sha512 || [ ! -e "$TMP/$OPAM_BIN" ]; then
echo "## Downloading opam $VERSION for $OS on $ARCH..."
if ! download "$TMP/$OPAM_BIN" "$OPAM_BIN_URL"; then
echo "There may not yet be a binary release for your architecture or OS, sorry."
echo "See https://github.com/ocaml/opam/releases/tag/$TAG for pre-compiled binaries,"
echo "or run 'make cold' from https://github.com/ocaml/opam/archive/$TAG.tar.gz"
echo "to build from scratch"
exit 10
else
if check_sha512; then
echo "## Downloaded."
else
echo "Checksum mismatch, a problem occurred during download."
exit 10
fi
fi
else
echo "## Using already downloaded \"$TMP/$OPAM_BIN\""
fi
if [ -n "$EXISTING_OPAM" ]; then
DEFAULT_BINDIR=$(dirname "$EXISTING_OPAM")
fi
BINDIR="$DEFAULT_BINDIR"
xsudo mkdir -p $BINDIR
if [ -e "$EXISTING_OPAM" ]; then
if [ "$NOBACKUP" = 1 ]; then
xsudo rm -f "$EXISTING_OPAM"
else
xsudo mv "$EXISTING_OPAM" "$EXISTING_OPAM.$EXISTING_OPAMV"
echo "## $EXISTING_OPAM backed up as $(basename $EXISTING_OPAM).$EXISTING_OPAMV"
fi
fi
if [ -d "$OPAMROOT" ]; then
if [ "$FRESH" = 1 ]; then
if [ "$NOBACKUP" = 1 ]; then
printf "## This will clear $OPAMROOT. Continue ? [Y/n] "
read R
case "$R" in
""|"y"|"Y"|"yes")
rm -rf "$OPAMROOT";;
*) exit 1
esac
else
mv "$OPAMROOT" "$OPAMROOT.$EXISTING_OPAMV"
echo "## $OPAMROOT backed up as $(basename $OPAMROOT).$EXISTING_OPAMV"
fi
echo "## opam $VERSION installed. Please run 'opam init' to get started"
elif [ ! "$NOBACKUP" = 1 ]; then
echo "## Backing up $OPAMROOT to $(basename $OPAMROOT).$EXISTING_OPAMV (this may take a while)"
if [ -e "$OPAMROOT.$EXISTING_OPAMV" ]; then
echo "ERROR: there is already a backup at $OPAMROOT.$EXISTING_OPAMV"
echo "Please move it away or run with --no-backup"
fi
FREE=$(df -k "$OPAMROOT" | awk 'NR>1 {print $4}')
NEEDED=$(du -sk "$OPAMROOT" | awk '{print $1}')
if ! [ $NEEDED -lt $FREE ]; then
echo "Error: not enough free space to backup. You can retry with --no-backup,"
echo "--fresh, or remove '$OPAMROOT'"
exit 1
fi
cp -a "$OPAMROOT" "$OPAMROOT.$EXISTING_OPAMV"
echo "## $OPAMROOT backed up as $(basename $OPAMROOT).$EXISTING_OPAMV"
fi
rm -f "$OPAMROOT"/repo/*/*.tar.gz*
fi
xsudo install -m 755 "$TMP/$OPAM_BIN" "$BINDIR/opam"
echo "## opam $VERSION installed to $BINDIR"
if [ ! "$FRESH" = 1 ]; then
echo "## Converting the opam root format & updating"
"$BINDIR/opam" init --reinit -ni
fi
WHICH=$(command -v opam || echo notfound)
case "$WHICH" in
"$BINDIR/opam") ;;
notfound) echo "## Remember to add $BINDIR to your PATH";;
*)
echo "## WARNING: 'opam' command found in PATH does not match the installed one:"
echo " - Installed: '$BINDIR/opam'"
echo " - Found: '$WHICH'"
echo "Make sure to remove the second or fix your PATH to use the new opam"
echo
esac
if [ ! "$NOBACKUP" = 1 ]; then
echo "## Run this script again with '--restore $EXISTING_OPAMV' to revert."
fi
rm -f $TMP/$OPAM_BIN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment