Skip to content

Instantly share code, notes, and snippets.

@loopyd
Created January 21, 2024 06:11
Show Gist options
  • Save loopyd/24ae1c37eb31ee38b3d437c83f29bd5e to your computer and use it in GitHub Desktop.
Save loopyd/24ae1c37eb31ee38b3d437c83f29bd5e to your computer and use it in GitHub Desktop.
[bash] Ant in jenv
#!/bin/bash
# make.sh: Build script for Apache Ant in jenv environment | DeityDurg (2024-01-17)
#
# This script will download the specified version of Apache Ant,
# build it, and install it into the specified jenv environment.
# This script will also update the PATH environment variable to
# include the ant binary, set the JAVA_HOME environment variable
# to the specified jenv environment, and set the ANT_HOME environment
# variable to the installed ant directory.
#
# Why this script?
#
# This gets those repositories building again. Why do I bother?
# Because I'm a nice guy, and I like to help people out. But you
# should really consider migrating to maven, or gradle, or something
# else that includes ant...
#
BUILD_ANT_VERSION="1.10.14"
BUILD_JENV_USE="openjdk64-21.0.1"
# __check_command: Check that the specified command is available on the system.
# Returns the path to the command if it is available, otherwise
# returns an empty string. The error code is set to 0 if the
# command is not available, and 1 if it is available.
function __check_command() {
local COMMAND
COMMAND="${1}"
if [[ "[${COMMAND}]" == "[]" ]]; then
echo "Missing COMMAND argument at position 1" >&2
return 0
fi
if ! command -v "${COMMAND}" 2>&1 >/dev/null; then
echo "Error: Command not found: ${COMMAND}" >&2
return 0
fi
COMMAND_PATH=$(command -v "${COMMAND}" 2>/dev/null)
if [ "$?" -ne 0 ] || [[ "[${COMMAND_PATH}]" == "[]" ]]; then
echo "Failed to fetch path for command: ${COMMAND}" >&2
return 0
fi
if [ ! -f "${COMMAND_PATH}" ]; then
echo "Command path is not a file: ${COMMAND_PATH}" >&2
return 0
fi
if [ ! -x "${COMMAND_PATH}" ]; then
echo "Command path is not executable: ${COMMAND_PATH}" >&2
return 0
fi
echo "${COMMAND_PATH}"
return 1
}
# __run_command: Run the specified command with the specified arguments.
# Returns 1 if the command was run successfully, otherwise
# returns 0. If the command is not found, or fails to run.
# This function supports sudo commands, and will prompt for
# the sudo password if required.
function __run_command() {
local COMMAND
local IS_SUDO
COMMAND="${1}"
if [[ "[${COMMAND}]" == "[]" ]]; then
echo "Missing COMMAND argument at position 1" >&2
return 0
fi
if [[ "${COMMAND}" == "sudo"* ]]; then
if ! command -v sudo >/dev/null 2>&1; then
echo "Sudo not found, this command requires sudo" >&2
return 0
fi
IS_SUDO="true"
shift
COMMAND="${1}"
shift
else
IS_SUDO="false"
shift
fi
local COMMAND_ARGS
COMMAND_ARGS=("${*}")
if [ "${#COMMAND_ARGS[@]}" -eq 0 ]; then
echo "Missing COMMAND_ARGS argument at position 2" >&2
return 0
fi
local COMMAND_PATH
COMMAND_PATH=$(__check_command "${COMMAND}")
if [ $? -ne 1 ] || [[ "[${COMMAND_PATH}]" == "[]" ]]; then
echo "Command not found: ${COMMAND}" >&2
return 0
fi
if [ "${IS_SUDO}" == "true" ]; then
# check if need to prompt for sudo password
sudo -n true >/dev/null 2>&1
if [ "$?" -ne 0 ]; then
echo "Sudo password required to continue, please enter sudo password for $USER:" >&2
sudo -v
if [ "$?" -ne 0 ]; then
echo "Failed to authenticate sudo" >&2
return 0
fi
fi
eval "sudo ${COMMAND_PATH} ${COMMAND_ARGS[@]}" >&2
else
eval "${COMMAND_PATH} ${COMMAND_ARGS[@]}" >&2
fi
if [ "$?" -ne 0 ]; then
echo "Command failed: ${COMMAND_PATH} ${COMMAND_ARGS[@]}" >&2
return 0
fi
return 1
}
# __mod_path: Modify the PATH variable, and return the modified value.
# If the second parameter is "true" or "1", then the PATH variable
# will be updated in the current environment.
function __mod_path() {
local NEW_PART
local UPDATE_PATH
local MOD_PATH
NEW_PART="${1}"
if [[ "[${NEW_PART}]" == "[]" ]]; then
echo "Missing NEW_PART argument at postiion 1" >&2
return 0
fi
UPDATE_PATH="${2}"
MOD_PATH=$(echo "${PATH}" | sed -e "s|${NEW_PART}:||g" -e "s|:${NEW_PART}||g")
if [ "${UPDATE_PATH}" == "true" ] || [ "${UPDATE_PATH}" == "1" ]; then
export PATH="${MOD_PATH}" >/dev/null 2>&1
fi
echo "${MOD_PATH}"
return 1
}
# __check_jenv: Check that the specified java environment is installed and configured.
# If not, toss an error on stdout. Automatically sets JAVA_HOME if you
# have specified the second parameter as "true" or "1".
function __check_jenv() {
local JENV_VERSION="${1}"
local JENV_UPDATE="${2}"
if ! command -v jenv >/dev/null 2>&1; then
echo "Jenv binary is not available." >&2
return 0
fi
local JENV_CURRENT_VERSION
JENV_CURRENT_VERSION=$(jenv local 2>/dev/null)
if [ "$?" -ne 0 ] || ! echo "${JENV_CURRENT_VERSION}" | grep -qi "${JENV_VERSION}"; then
echo "Local version does not match specified java version: ${JENV_VERSION}" >&2
jenv local "${JENV_VERSION}" 2>/dev/null
if [ "$?" -ne 0 ]; then
echo "Failed to set local java version to: ${JENV_VERSION}" >&2
return 0
fi
JENV_CURRENT_VERSION=$(jenv local 2>/dev/null)
if [ "$?" -ne 0 ] || ! echo "${JENV_CURRENT_VERSION}" | grep -qi "${JENV_VERSION}"; then
echo "Failed to switch local java version to: ${JENV_VERSION}" >&2
return 0
fi
fi
JENV_HOME=$(jenv javahome 2>/dev/null)
if [ "$?" -ne 0 ]; then
echo "Failed to fetch JAVA_HOME for version: ${JENV_VERSION}" >&2
return 0
fi
if [ ! -f "${JENV_HOME}/bin/java" ]; then
echo "Java installation is not valid (could not find the java binary)" >&2
return 0
fi
if [ "${JENV_UPDATE}" == "true" ] || [ "${JENV_UPDATE}" == "1" ]; then
echo "Using java version: ${JENV_VERSION} at ${JENV_HOME}" >&2
export JAVA_HOME="${JENV_HOME}" >/dev/null 2>&1
fi
echo "${JENV_HOME}"
return 1
}
# __check_ant: Check that the ant compiler is installed into the specified java environment.
# and update ANT_HOME if so, otherwise, toss an error on stdout.
function __check_ant() {
local USE_ANT_VERSION
USE_ANT_VERSION="${1}"
if [ "[${USE_ANT_VERSION}]" == "[]" ]; then
echo "Missing USE_ANT_VERSION argument at position 1" >&2
return 0
fi
if [[ "[${ANT_HOME}]" == "[]" ]] || [[ ! -d "${ANT_HOME}" ]]; then
local ANT_HOME="${JAVA_HOME}/plugins/ant"
if [ ! -d "${ANT_HOME}" ]; then
echo "Ant not found at: ${ANT_HOME}" >&2
return 0
fi
fi
if [ ! -d "${ANT_HOME}/bin" ] || [ ! -d "${ANT_HOME}/lib" ] || [ ! -f "${ANT_HOME}/bin/ant" ]; then
echo "Ant not installed at: ${ANT_HOME}" >&2
return 0
fi
if ! command -v ant >/dev/null 2>&1; then
echo "Ant for java version was not found on PATH environment variable" >&2
local MOD_PATH
MOD_PATH=$(__mod_path "${ANT_HOME}/bin" "true")
if [ $? -ne 1 ] || [[ "[${MOD_PATH}]" == "[]" ]]; then
echo "Failed to update PATH to include ant binary" >&2
return 0
fi
if ! command -v ant >/dev/null 2>&1; then
echo "Ant for java version was not found on PATH, failed to fix." >&2
return 0
fi
fi
local ANT_VERSION
ANT_VERSION=$(ant -version 2>/dev/null | grep -ioP "(?<=Apache\ Ant\(TM\)\ version\ )([0-9\.]+)")
if [ $? -ne 0 ] || [[ "[${ANT_VERSION}]" == "[]" ]]; then
echo "Failed to fetch ant version" >&2
return 0
fi
if [[ "${ANT_VERSION}" != "${USE_ANT_VERSION}" ]]; then
echo "Ant version mismatch: expected ${USE_ANT_VERSION} but found ${ANT_VERSION}" >&2
return 0
fi
echo "${ANT_HOME}"
return 1
}
function build() {
local JENV_USE
JENV_USE="${1}"
if [ "[${JENV_USE}]" == "[]" ]; then
echo "Missing JENV_USE argument at position 1" >&2
return 0
fi
local ANT_VERSION
ANT_VERSION="${2}"
if [ "[${ANT_VERSION}]" == "[]" ]; then
echo "Missing ANT_VERSION argument at position 2" >&2
return 0
fi
local CURRENT_DIR
CURRENT_DIR=$(dirname "${0}")
# Check build dependencies.
JAVA_HOME=$(__check_jenv "${JENV_USE}" "true")
if [ "$?" -ne 1 ] || [[ "[${JAVA_HOME}]" == "[]" ]]; then
echo "Java version ${JENV_USE} not found" >&2
return 0
fi
ANT_HOME=$(__check_ant "${ANT_VERSION}" "true")
if [ "$?" -eq 1 ] || [[ "[${ANT_HOME}]" != "[]" ]]; then
echo "Ant version ${ANT_VERSION} already installed at: ${ANT_HOME}" >&2
return 0
fi
# Create temporary directory.
local TEMP_DIR
TEMP_DIR=$(mktemp -d 2>/dev/null)
if [ ! -d "${TEMP_DIR}" ]; then
echo "Creating temporary directory FAILED" >&2
return 0
fi
# Download source.
cd "${TEMP_DIR}" >&2 || exit 1
echo "Downloading apache ant version ${ANT_VERSION} to ${TEMP_DIR}..." >&2
__run_command "curl" "-fSsL \"https://dlcdn.apache.org//ant/source/apache-ant-${ANT_VERSION}-src.tar.xz\" -o - | tar xJ --strip-components=1"
if [ ! -f "${TEMP_DIR}/build.sh" ]; then
echo "Apache ant download FAILED" >&2
return 0
fi
# Build source.
__run_command "chmod" "+x \"${TEMP_DIR}/build.sh\""
if [ $? -ne 1 ]; then
echo "Failed to make build.sh executable" >&2
return 0
fi
__run_command "jenv" "local ${JENV_USE}"
if [ $? -ne 1 ]; then
echo "Failed to set local java version to: ${JENV_USE}" >&2
return 0
fi
echo "Working with JAVA_HOME: $(jenv javahome)" >&2
__run_command "./build.sh"
if [ "$?" -ne 1 ] || [ ! -d "${TEMP_DIR}/dist/bin" ] || [ ! -d "${TEMP_DIR}/dist/lib" ]; then
echo "Build FAILED" >&2
return 0
fi
# Move to final location.
export ANT_HOME="${JAVA_HOME}/plugins/ant"
__run_command "sudo" "mkdir" "-p" "${ANT_HOME}"
if [ "$?" -ne 1 ]; then
echo "Failed to create output directory: ${ANT_HOME}" >&2
return 0
fi
__run_command "sudo" "mv" "-f" "${TEMP_DIR}/dist/*" "${ANT_HOME}"
if [ "$?" -ne 1 ]; then
echo "Failed to move ant to output directory: ${ANT_HOME}" >&2
return 0
fi
__run_command "sudo" "chown" "-R" "root:java" "${ANT_HOME}"
if [ "$?" -ne 1 ]; then
echo "Failed to change ownership of ANT_HOME to root:java" >&2
return 0
fi
__run_command "sudo" "chmod" "-R" "0775" "${ANT_HOME}"
if [ $? -ne 1 ]; then
echo "Failed to change permissions of ANT_HOME to 0775" >&2
return 0
fi
# Update PATH
local MOD_PATH
MOD_PATH=$(__mod_path "${ANT_HOME}/bin" "true")
if [ $? -ne 1 ] || [[ "[${MOD_PATH}]" == "[]" ]]; then
echo "Failed to update PATH to include ant binary" >&2
return 0
fi
# Cleanup
cd "${CURRENT_DIR}" >&2 || exit 1
echo "Cleaning up temporary directory: ${TEMP_DIR}" >&2
__run_command "sudo" "rm" "-rf \"${TEMP_DIR}\""
if [ "$?" -ne 1 ]; then
echo "Clean FAILED" >&2
return 0
fi
echo "${ANT_HOME}"
return 1
}
# Main
BUILD_DIR=$(build "${BUILD_JENV_USE}" "${BUILD_ANT_VERSION}")
if [ $? -ne 1 ] || [[ "[${BUILD_DIR}]" == "[]" ]]; then
echo "❌ Build FAILED" >&2
exit 1
fi
echo "✨ Built successfully: ${BUILD_DIR}" >&2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment