Skip to content

Instantly share code, notes, and snippets.

@AltGr
Last active October 24, 2017 09:32
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 AltGr/f11944ffb55d3833d3cf08d1ccfb50df to your computer and use it in GitHub Desktop.
Save AltGr/f11944ffb55d3833d3cf08d1ccfb50df to your computer and use it in GitHub Desktop.
A script to safely download and try the newest opam release
#!/bin/bash -ue
VERSION=2.0.0~beta4
MINORV=${VERSION##*[^0-9]}
BASEV=${VERSION%$MINORV}
CURRENT_VERSION=$(opam --version --safe)
if [ $? -ne 0 ]; then CURRENT_VERSION=none; fi
if [ -z "${OPAMROOT:-}" ]; then OPAMROOT=~/.opam; fi
NOBACKUP=0
FRESH=0
while [ $# -gt 0 ]; do
case "$1" in
--revert)
if [ -e "$OPAMROOT.bak" ]; then
rm -rf "$OPAMROOT"
mv "$OPAMROOT.bak" "$OPAMROOT"
echo "Opam reverted to the backup at $OPAMROOT.bak"
exit 0
else
echo "No opam 1.2 backup found" >&2
exit 1
fi
;;
--no-backup)
NOBACKUP=1
;;
--fresh)
FRESH=1
;;
--root)
if [ $# -lt 2 ]; then
echo "Option $1 requires an argument";
exit 2
fi
shift
OPAMROOT=$1
;;
--help|-help|-h)
echo "Usage: $0 [--revert] [--no-backup] [--help] [VERSION]"
echo " --revert restore the backup and revert to the previous opam version"
echo " --no-backup don't backup the opam root (it will be upgraded or destroyed)"
echo " --fresh start with a fresh opam root instead of an existing one"
echo " VERSION the new opam version to install. Defaults to $VERSION."
echo " It must be newer than the current version"
exit 0
;;
-*)
echo "Invalid option $1. Try '--help'." >&2
exit 2
;;
*)
VERSION=$1
esac
shift
done
recursive_backup() {
if [ -e "$1" ]; then
recursive_backup "$1.bak"
mv "$1" "$1.bak"
fi
}
case "$CURRENT_VERSION" in
1.2.*)
echo "# opam 1.2 detected. Your opam root will be backed up as '$OPAMROOT.bak'"
USE_UPGRADE=1
BINDIR=$OPAMROOT
;;
$BASEV*)
if ! [ "${CURRENT_VERSION#$BASEV}" -lt "$MINORV" ]; then
echo "Newer or conflicting installed opam version found ($CURRENT_VERSION)"
exit 1
else
USE_UPGRADE=1
BINDIR=$OPAMROOT
fi
;;
2.0.0~*)
USE_UPGRADE=1
BINDIR=$OPAMROOT
;;
1.0.*|1.1.*|none)
if [ -d "$OPAMROOT" ]; then
if [ "NOBACKUP" = "1" ]; then
rm -rf "$OPAMROOT"
echo "removed old opam root at '$OPAMROOT'"
else
recursive_backup "$OPAMROOT"
echo "old opam root detected, backed up as '$OPAMROOT.bak'"
fi
fi
echo "Please choose a directory where the binary should be installed (it should be in"
echo "your PATH)"
printf "Binary directory (default /usr/local/bin): "
read BINDIR
if [ "x" = "x$BINDIR" ]; then BINDIR=/usr/local/bin; fi
;;
*)
echo "Newer or conflicting installed opam version found ($CURRENT_VERSION)"
exit 1
esac
ARCH=$(uname -m)
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=$(awk '{print tolower($0)}' <<<"$ARCH")
esac
OS=$(uname -s)
case "$OS" in
darwin|macos) OS=darwin;;
*) OS=$(awk '{print tolower($0)}' <<<"$OS")
esac
OPAM_BIN="opam-${VERSION/\~/-}-${ARCH}-${OS}"
OPAM_BIN_URL="https://github.com/ocaml/opam/releases/download/${VERSION/\~/-}/${OPAM_BIN}"
TEMP_OPAM=$(mktemp /tmp/$OPAM_BIN.XXXXX)
trap "rm -f \"$TEMP_OPAM\"" EXIT
chmod a+x "$TEMP_OPAM"
download() {
if command -v wget >/dev/null; then wget -q -O "$@"
else curl -s -L -o "$@"
fi
}
echo "# Downloading opam for your system ($OS/$ARCH)"
if ! download "$TEMP_OPAM" "$OPAM_BIN_URL"; then
echo "Sorry, could not download a binary for your platform. Check"
echo "https://github.com/ocaml/opam/releases/tag/${VERSION/\~/-}, or please use the"
echo "source"
exit 1
fi
if [ "$USE_UPGRADE" = "1" ]; then
if [ "$FRESH" = "1" ]; then
if [ "$NOBACKUP" = "0" ]; then
recursive_backup "$OPAMROOT"
else
rm -rf "$OPAMROOT"
fi
mkdir -p "$OPAMROOT"
elif ! [ "$NOBACKUP" = "1" ]; then
echo "# Backing up $OPAMROOT (this may take a while)"
FREE=$(df -k "$OPAMROOT" | awk 'NR>1 {print $4}')
NEEDED=$(du -s "$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
recursive_backup "$OPAMROOT.bak"
cp -a "$OPAMROOT" "$OPAMROOT.bak"
fi
echo "$VERSION" > "$OPAMROOT/opam.version"
mv "$TEMP_OPAM" "$OPAMROOT/opam"
rm -f "$OPAMROOT/repo/state.cache"
if [ "$FRESH" = "0" ]; then
echo "# Converting the opam root format"
opam update --yes >/dev/null
echo "# Updating the repositories"
opam update
echo
echo "# opam $VERSION installed"
else
echo "# Initialising opam"
opam init
echo
echo "# opam $VERSION installed"
fi
echo
echo "Note: system opam is still $CURRENT_VERSION, as reported by 'opam --version',"
echo " but $OPAMROOT is set to switch automatically"
echo " to the newer $VERSION"
else
if [ -w "$BINDIR" ]; then
mv "$TEMP_OPAM" "$BINDIR/opam"
else
echo "Root access is needed to write to $BINDIR:"
echo " sudo mv \"$TEMP_OPAM\" \"$BINDIR/opam\""
sudo mv "$TEMP_OPAM" "$BINDIR/opam"
fi
if [ "$(opam --version)" != "$VERSION" ]; then
FOUND_OPAM=$(command -v opam || echo $BINDIR/opam)
if [ $FOUND_OPAM != $BINDIR/opam ]; then
echo "WARNING: a different opam is present at $FOUND_OPAM. Remove it, rename it or"
echo "fix your PATH to use the newer one"
else
echo "Newer opam reports an incorrect version, aborting. Please file a bug report to"
echo "https://github.com/ocaml/opam/issues with the following information:"
opam config report
fi
fi
echo "Opam $VERSION installed. Run 'opam init' to get started"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment