Files
sdkman-cli/src/main/resources/scripts/gvm
2012-12-18 14:39:39 +00:00

473 lines
13 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright 2012 Marco Vermeulen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# function definitions
#
function __gvmtool_help {
echo ""
echo "Usage: gvm <command> <candidate> [version]"
echo ""
echo " command : install, uninstall, list, use, current, version, default, selfupdate, broadcast or help"
echo " candidate : groovy, grails, griffon, gradle, vert.x"
echo " version : optional, defaults to latest stable if not provided"
echo ""
echo "eg: gvm install groovy"
}
function __gvmtool_check_candidate_present {
if [ -z "$1" ]; then
echo -e "\nNo candidate provided."
__gvmtool_help
return 1
fi
}
function __gvmtool_check_version_present {
if [ -z "$1" ]; then
echo -e "\nNo candidate version provided."
__gvmtool_help
return 1
fi
}
function __gvmtool_determine_version {
if [[ "${GVM_OFFLINE}" == "true" && -n "$1" && -d "${GVM_DIR}/${CANDIDATE}/$1" ]]; then
VERSION="$1"
elif [[ "${GVM_OFFLINE}" == "true" && -z "$1" && -L "${GVM_DIR}/${CANDIDATE}/current" ]]; then
VERSION=$(readlink "${GVM_DIR}/${CANDIDATE}/current" | sed -e "s!${GVM_DIR}/${CANDIDATE}/!!g")
elif [[ "${GVM_OFFLINE}" == "true" && -n "$1" ]]; then
echo "Stop! ${CANDIDATE} ${1} is not available in aeroplane mode."
return 1
elif [[ "${GVM_OFFLINE}" == "true" && -z "$1" ]]; then
echo "${OFFLINE_MESSAGE}"
return 1
elif [[ "${GVM_OFFLINE}" == "false" && -z "$1" ]]; then
VERSION=$(curl -s "${GVM_SERVICE}/candidates/${CANDIDATE}/default")
else
VERSION_VALID=$(curl -s "${GVM_SERVICE}/candidates/${CANDIDATE}/$1")
if [[ ${VERSION_VALID} == 'valid' ]]; then
VERSION="$1"
else
echo ""
echo "Stop! $1 is not a valid ${CANDIDATE} version."
return 1
fi
fi
}
function __gvmtool_build_version_csv {
CANDIDATE="$1"
CSV=""
for version in $(ls -1 "${GVM_DIR}/${CANDIDATE}"); do
if [ ${version} != 'current' ]; then
CSV="${version},${CSV}"
fi
done
CSV=${CSV%?}
}
function __gvmtool_determine_current_version {
unset CURRENT
CANDIDATE="$1"
if [[ -n ${isolated_mode} && ${isolated_mode} == 1 ]]; then
CURRENT=$(echo $PATH | sed -E "s|.gvm/${CANDIDATE}/([^/]+)/bin|!!\1!!|1" | sed -E "s|^.*!!(.+)!!.*$|\1|g")
if [[ "${CURRENT}" == "current" ]]; then
unset CURRENT
fi
fi
if [[ -z ${CURRENT} ]]; then
CURRENT=$(readlink "${GVM_DIR}/${CANDIDATE}/current" | sed -e "s!${GVM_DIR}/${CANDIDATE}/!!g")
fi
}
function __gvmtool_download {
CANDIDATE="$1"
VERSION="$2"
mkdir -p "${GVM_DIR}/archives"
if [ ! -f "${GVM_DIR}/archives/${CANDIDATE}-${VERSION}.zip" ]; then
echo ""
echo "Downloading: ${CANDIDATE} ${VERSION}"
echo ""
DOWNLOAD_URL="${GVM_SERVICE}/download/${CANDIDATE}/${VERSION}?platform=${GVM_PLATFORM}"
ZIP_ARCHIVE="${GVM_DIR}/archives/${CANDIDATE}-${VERSION}.zip"
curl -L "${DOWNLOAD_URL}" > "${ZIP_ARCHIVE}"
__gvmtool_validate_zip "${ZIP_ARCHIVE}" || return 1
else
echo ""
echo "Found a previously downloaded ${CANDIDATE} ${VERSION} archive. Not downloading it again..."
__gvmtool_validate_zip "${GVM_DIR}/archives/${CANDIDATE}-${VERSION}.zip" || return 1
fi
echo ""
}
function __gvmtool_validate_zip {
ZIP_ARCHIVE="$1"
ZIP_OK=$(unzip -t "${ZIP_ARCHIVE}" | grep 'No errors detected in compressed data')
if [ -z "${ZIP_OK}" ]; then
rm "${ZIP_ARCHIVE}"
echo ""
echo "Stop! The archive was corrupt and has been removed! Please try installing again."
return 1
fi
}
function __gvmtool_default_environment_variables {
if [ ! "${GVM_SERVICE}" ]; then
GVM_SERVICE="http://localhost:8080"
fi
if [ ! "${GVM_DIR}" ]; then
GVM_DIR="$HOME/.gvm"
fi
}
function __gvmtool_check_upgrade_available {
UPGRADE_AVAILABLE=""
UPGRADE_NOTICE=$(echo "${BROADCAST_LIVE}" | grep 'Your version of GVM is out of date!')
if [[ -n "${UPGRADE_NOTICE}" && ( "${COMMAND}" != 'selfupdate' ) ]]; then
UPGRADE_AVAILABLE="true"
fi
}
function __gvmtool_display_broadcast {
COMMAND="$1"
BROADCAST_FILE="${GVM_DIR}/var/broadcast"
if [ -f "${BROADCAST_FILE}" ]; then
BROADCAST_HIST=$(cat "${BROADCAST_FILE}")
fi
if [[ "${BROADCAST_LIVE}" != "${BROADCAST_HIST}" && "${COMMAND}" != 'broadcast' ]]; then
mkdir -p "${GVM_DIR}/var"
echo "${BROADCAST_LIVE}" > "${BROADCAST_FILE}"
echo "${BROADCAST_LIVE}"
fi
}
function __gvmtool_link_candidate_version {
CANDIDATE="$1"
VERSION="$2"
# Change the 'current' symlink for the candidate, hence affecting all shells.
if [ -L "${GVM_DIR}/${CANDIDATE}/current" ]; then
unlink "${GVM_DIR}/${CANDIDATE}/current"
fi
ln -s "${GVM_DIR}/${CANDIDATE}/${VERSION}" "${GVM_DIR}/${CANDIDATE}/current"
}
function __gvmtool_install_candidate_version {
CANDIDATE="$1"
VERSION="$2"
__gvmtool_download "${CANDIDATE}" "${VERSION}" || return 1
echo "Installing: ${CANDIDATE} ${VERSION}"
mkdir -p "${GVM_DIR}/${CANDIDATE}"
unzip -oq "${GVM_DIR}/archives/${CANDIDATE}-${VERSION}.zip" -d "/tmp/"
mv "/tmp/${CANDIDATE}-${VERSION}" "${GVM_DIR}/${CANDIDATE}/${VERSION}"
echo "Done installing!"
echo ""
}
function __gvmtool_offline_list {
echo "============================================================"
echo "Aeroplane Mode: only showing installed ${CANDIDATE} versions"
echo "------------------------------------------------------------"
echo " "
gvm_versions=($(echo ${CSV//,/ }))
for (( i=0 ; i <= ${#gvm_versions} ; i++ )); do
if [[ -n "${gvm_versions[$i]}" ]]; then
if [[ "${gvm_versions[$i]}" == "${CURRENT}" ]]; then
echo -e " > ${gvm_versions[$i]}"
else
echo -e " * ${gvm_versions[$i]}"
fi
fi
done
if [[ -z "${gvm_versions[@]}" ]]; then
echo " None installed!"
fi
echo "------------------------------------------------------------"
echo "* - installed "
echo "> - currently in use "
echo "------------------------------------------------------------"
unset CSV gvm_versions
}
#
# Command functions
#
function __gvmtool_install {
CANDIDATE="$1"
__gvmtool_check_candidate_present "${CANDIDATE}" || return 1
__gvmtool_determine_version "$2" || return 1
if [ -d "${GVM_DIR}/${CANDIDATE}/${VERSION}" ]; then
echo ""
echo "Stop! ${CANDIDATE} ${VERSION} is already installed."
return 1
fi
__gvmtool_install_candidate_version "${CANDIDATE}" "${VERSION}" || return 1
echo -n "Do you want to use ${CANDIDATE} ${VERSION} now? (Y/n): "
read USE
if [[ -z "${USE}" || "${USE}" == "y" || "${USE}" == "Y" ]]; then
__gvmtool_link_candidate_version "${CANDIDATE}" "${VERSION}"
echo ""
echo Using "${CANDIDATE}" version "${VERSION}"
fi
}
function __gvmtool_use {
CANDIDATE="$1"
__gvmtool_check_candidate_present "${CANDIDATE}" || return 1
__gvmtool_determine_version "$2" || return 1
if [[ "${GVM_OFFLINE}" == "false" && ! -d "${GVM_DIR}/${CANDIDATE}/${VERSION}" ]]; then
echo ""
echo "Stop! ${CANDIDATE} ${VERSION} is not installed."
echo -n "Do you want to install it now? (Y/n): "
read INSTALL
if [[ -z "${INSTALL}" || "${INSTALL}" == "y" || "${INSTALL}" == "Y" ]]; then
__gvmtool_install_candidate_version "${CANDIDATE}" "${VERSION}"
else
return 1
fi
fi
if [[ -n ${isolated_mode} && ${isolated_mode} == 1 ]]; then
# Just update the *_HOME and PATH for this shell.
case "${CANDIDATE}" in
vert.x )
export VERTX_HOME="${GVM_DIR}/vert.x/${VERSION}"
;;
* )
UPPER_CANDIDATE=`echo "${CANDIDATE}" | tr '[:lower:]' '[:upper:]'`
export "${UPPER_CANDIDATE}_HOME"="${GVM_DIR}/${CANDIDATE}/${VERSION}"
;;
esac
# Replace the current path for the candidate with the selected version.
export PATH=`echo $PATH | sed -E "s!${GVM_DIR}/${CANDIDATE}/([0-9][^/]+|current)!${GVM_DIR}/${CANDIDATE}/${VERSION}!g"`
else
__gvmtool_link_candidate_version "${CANDIDATE}" "${VERSION}"
fi
echo ""
echo Using "${CANDIDATE}" version "${VERSION} in this shell."
}
function __gvmtool_default {
CANDIDATE="$1"
__gvmtool_check_candidate_present "${CANDIDATE}" || return 1
__gvmtool_determine_version "$2" || return 1
if [ ! -d "${GVM_DIR}/${CANDIDATE}/${VERSION}" ]; then
echo ""
echo "Stop! ${CANDIDATE} ${VERSION} is not installed."
return 1
fi
__gvmtool_link_candidate_version "${CANDIDATE}" "${VERSION}"
echo ""
echo "Default ${CANDIDATE} version set to ${VERSION}"
}
function __gvmtool_current {
if [ -n "$1" ]; then
CANDIDATE="$1"
__gvmtool_determine_current_version "${CANDIDATE}"
if [ -n "${CURRENT}" ]; then
echo "Using ${CANDIDATE} version ${CURRENT}"
else
echo "Not using any version of ${CANDIDATE}"
fi
elif [[ -z "$1" && "${GVM_OFFLINE}" == "true" ]]; then
echo "${OFFLINE_MESSAGE}"
else
# The candidates are assigned to an array for zsh compliance, a list of words is not iterable
# Arrays are the only way, but unfortunately zsh arrays are not backward compatible with bash
# In bash arrays are zero index based, in zsh they are 1 based(!)
CANDIDATES=($(curl -s "${GVM_SERVICE}/candidates" | tr -d ","))
INSTALLED_COUNT=0
# The starts at 0 for bash, ends at the candidates array size for zsh
for (( i=0; i <= ${#CANDIDATES}; i++ )); do
# Eliminate empty entries due to incompatibility
if [[ -n ${CANDIDATES[$i]} ]]; then
__gvmtool_determine_current_version "${CANDIDATES[$i]}"
if [ -n "${CURRENT}" ]; then
if [ ${INSTALLED_COUNT} -eq 0 ]; then
echo 'Using:'
fi
echo "${CANDIDATES[$i]}: ${CURRENT}"
(( INSTALLED_COUNT += 1 ))
fi
fi
done
if [ ${INSTALLED_COUNT} -eq 0 ]; then
echo 'No candidates are in use'
fi
fi
}
function __gvmtool_list {
CANDIDATE="$1"
__gvmtool_check_candidate_present "${CANDIDATE}" || return 1
__gvmtool_build_version_csv "${CANDIDATE}"
__gvmtool_determine_current_version "${CANDIDATE}"
FRAGMENT=$(curl -s "${GVM_SERVICE}/candidates/${CANDIDATE}/list?platform=${GVM_PLATFORM}&current=${CURRENT}&installed=${CSV}")
if [[ "${GVM_OFFLINE}" == "true" ]]; then
__gvmtool_offline_list
else
echo "${FRAGMENT}"
fi
}
function __gvmtool_uninstall {
CANDIDATE="$1"
VERSION="$2"
__gvmtool_check_candidate_present "${CANDIDATE}" || return 1
__gvmtool_check_version_present "${VERSION}" || return 1
CURRENT=$(readlink "${GVM_DIR}/${CANDIDATE}/current" | sed -e "s_${GVM_DIR}/${CANDIDATE}/__g")
if [[ -h "${GVM_DIR}/${CANDIDATE}/current" && ( "${VERSION}" == "${CURRENT}" ) ]]; then
echo ""
echo "Unselecting ${CANDIDATE} ${VERSION}..."
unlink "${GVM_DIR}/${CANDIDATE}/current"
fi
echo ""
if [ -d "${GVM_DIR}/${CANDIDATE}/${VERSION}" ]; then
echo "Uninstalling ${CANDIDATE} ${VERSION}..."
rm -rf "${GVM_DIR}/${CANDIDATE}/${VERSION}"
else
echo "${CANDIDATE} ${VERSION} is not installed."
fi
}
function __gvmtool_version {
echo "Groovy enVironment Manager ${GVM_VERSION}"
}
function __gvmtool_broadcast {
if [ "${BROADCAST_HIST}" ]; then
echo "${BROADCAST_HIST}"
else
echo "${BROADCAST_LIVE}"
fi
}
function __gvmtool_selfupdate {
if [[ "${GVM_OFFLINE}" == "true" ]]; then
echo "${OFFLINE_MESSAGE}"
else
curl -s "${GVM_SERVICE}/selfupdate" | bash
fi
}
# INSERT NEW COMMANDS BEFORE HERE
# Main command
function gvm {
#
# Various sanity checks and default settings
#
__gvmtool_default_environment_variables
mkdir -p "${GVM_DIR}"
BROADCAST_LIVE=$(curl -s "${GVM_SERVICE}/broadcast/${GVM_VERSION}")
if [[ -z "${BROADCAST_LIVE}" ]]; then
GVM_OFFLINE="true"
BROADCAST_LIVE="${OFFLINE_BROADCAST}"
else
GVM_OFFLINE="false"
fi
__gvmtool_check_upgrade_available
if [[ -n "${UPGRADE_AVAILABLE}" && ( "$1" != "broadcast" ) ]]; then
echo "${BROADCAST_LIVE}"
echo ""
else
__gvmtool_display_broadcast "$1"
fi
# Load the gvm config if it exists.
if [ -f "${GVM_DIR}/etc/config" ]; then
source "${GVM_DIR}/etc/config"
fi
# Check whether the command exists as an internal function...
#
# NOTE Internal commands use underscores rather than hyphens,
# hence the name conversion as the first step here.
CONVERTED_CMD_NAME=`echo "$1" | tr '-' '_'`
CMD_FOUND=""
if [[ -f "${GVM_DIR}/bin/gvm" ]]; then
CMD_FOUND=$(grep __gvmtool_"${CONVERTED_CMD_NAME}" "${GVM_DIR}/bin/gvm")
fi
# ...no command provided
if [[ -z "$1" ]]; then
__gvmtool_help
return 1
fi
# ...or as a script on the path.
SCRIPT_PATH="${GVM_DIR}/ext/gvm-$1.sh"
if [[ -z "${CMD_FOUND}" && ! -f "${SCRIPT_PATH}" ]]; then
echo -e "\nInvalid command: $1"
__gvmtool_help
return 1
fi
# Check whether the candidate exists
CANDIDATE_VALID=$(curl -s "${GVM_SERVICE}/candidates/$2")
if [[ "${CANDIDATE_VALID}" == 'invalid' ]]; then
echo -e "\nStop! $2 is not a valid candidate."
return 1
fi
# Execute the requested command
if [ -n "${CMD_FOUND}" ]; then
# It's available as a shell function
__gvmtool_"${CONVERTED_CMD_NAME}" "$2" "$3"
else
# It's a shell script in the extensions directory
${SCRIPT_PATH} "$1" "$2" "$3"
fi
}