|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +# |
| 4 | +# To run this script remotely type this in your shell |
| 5 | +# (where <args>... are the arguments you want to pass to JBang): |
| 6 | +# curl -Ls https://sh.jbang.dev | bash -s - <args>... |
| 7 | +# |
| 8 | + |
| 9 | +# The Java version to install when it's not installed on the system yet |
| 10 | +javaVersion=${JBANG_DEFAULT_JAVA_VERSION:-17} |
| 11 | + |
| 12 | +script_dir() { |
| 13 | + script=${BASH_SOURCE[0]} |
| 14 | + while [ -L "$script" ]; do |
| 15 | + dir=$( cd -P "$( dirname "$script" )" >/dev/null 2>&1 && pwd ) |
| 16 | + script=$(readlink "$script") |
| 17 | + [[ $script != /* ]] && script=$dir/$script |
| 18 | + done |
| 19 | + dir=$( cd -P "$( dirname "$script" )" >/dev/null 2>&1 && pwd ) |
| 20 | + echo $dir |
| 21 | +} |
| 22 | + |
| 23 | +download() { |
| 24 | + if [ -x "$(command -v curl)" ]; then |
| 25 | + curl -sLf -o "$2" "$1" |
| 26 | + retval=$? |
| 27 | + elif [ -x "$(command -v wget)" ]; then |
| 28 | + wget -q -O "$2" "$1" |
| 29 | + retval=$? |
| 30 | + else |
| 31 | + echo "Error: curl or wget not found, please make sure one of them is installed" 1>&2 |
| 32 | + exit 1 |
| 33 | + fi |
| 34 | +} |
| 35 | + |
| 36 | +unpack() { |
| 37 | + if [[ "$1" == *.tar.gz ]]; then |
| 38 | + gzip -cd "$1" | tar xf - -C "$2" |
| 39 | + retval=$? |
| 40 | + if [[ $os == mac && $retval -eq 0 ]]; then |
| 41 | + mv "$TDIR/jdks/$javaVersion.tmp/"*/Contents/Home/* "$TDIR/jdks/$javaVersion.tmp/" |
| 42 | + retval=$? |
| 43 | + else |
| 44 | + mv "$TDIR/jdks/$javaVersion.tmp/"*/* "$TDIR/jdks/$javaVersion.tmp/" |
| 45 | + fi |
| 46 | + else |
| 47 | + unzip -qq -o "$1" -d "$2" |
| 48 | + retval=$? |
| 49 | + mv "$TDIR/jdks/$javaVersion.tmp/"*/* "$TDIR/jdks/$javaVersion.tmp/" |
| 50 | + fi |
| 51 | +} |
| 52 | + |
| 53 | +javacInPath() { |
| 54 | + [[ -x "$(command -v javac)" ]] && ( [[ $os != "mac" ]] || /usr/libexec/java_home &> /dev/null ) |
| 55 | +} |
| 56 | + |
| 57 | +abs_jbang_dir=$(script_dir) |
| 58 | + |
| 59 | +# todo might vary by os so can be overwritten below |
| 60 | +libc_type=glibc |
| 61 | +file_type=tar.gz |
| 62 | + |
| 63 | +case "$(uname -s)" in |
| 64 | + Linux*) |
| 65 | + os=linux |
| 66 | + if [ -f /etc/alpine-release ]; then |
| 67 | + os=alpine-linux |
| 68 | + javaVersion=16 |
| 69 | + fi |
| 70 | + ;; |
| 71 | + Darwin*) |
| 72 | + os=mac |
| 73 | + libc_type=libc;; |
| 74 | + CYGWIN*|MINGW*|MSYS*) |
| 75 | + os=windows |
| 76 | + libc_type=c_std_lib |
| 77 | + file_type=zip;; |
| 78 | + AIX) |
| 79 | + os=aix;; |
| 80 | + *) |
| 81 | + os= |
| 82 | +esac |
| 83 | + |
| 84 | +case "$(uname -m)" in |
| 85 | + i?86) |
| 86 | + arch=x32;; |
| 87 | + x86_64|amd64) |
| 88 | + arch=x64;; |
| 89 | + aarch64) |
| 90 | + arch=aarch64;; |
| 91 | + armv7l) |
| 92 | + arch=arm;; |
| 93 | + ppc64le) |
| 94 | + arch=ppc64le;; |
| 95 | + s390x) |
| 96 | + arch=s390x;; |
| 97 | + arm64) |
| 98 | + arch=arm64 |
| 99 | + ;; |
| 100 | + *) |
| 101 | + ## AIX gives a machine ID for `uname -m` but it only supports ppc64 |
| 102 | + if [ "$os" = "aix" ]; then |
| 103 | + arch=ppc64 |
| 104 | + else |
| 105 | + arch= |
| 106 | + fi |
| 107 | + ;; |
| 108 | +esac |
| 109 | + |
| 110 | +## when using cygwin fall out to just running the bat file. |
| 111 | +if [[ $os == windows && -f "$abs_jbang_dir/jbang.cmd" && "$(uname -s)" == CYGWIN* ]]; then |
| 112 | + cmd /c "$(cygpath -m "$abs_jbang_dir"/jbang.cmd)" "$@" |
| 113 | + exit $? |
| 114 | +fi |
| 115 | + |
| 116 | +if [[ -z "$JBANG_JDK_VENDOR" ]]; then |
| 117 | + if [[ "$javaVersion" -eq 8 || "$javaVersion" -eq 11 || "$javaVersion" -ge 17 ]]; then |
| 118 | + distro="temurin"; |
| 119 | + else |
| 120 | + distro="aoj"; fi |
| 121 | +else |
| 122 | + distro=$JBANG_JDK_VENDOR |
| 123 | +fi |
| 124 | + |
| 125 | +if [[ -z "$JBANG_DIR" ]]; then JBDIR="$HOME/.jbang"; else JBDIR="$JBANG_DIR"; fi |
| 126 | +if [[ -z "$JBANG_CACHE_DIR" ]]; then TDIR="$JBDIR/cache"; else TDIR="$JBANG_CACHE_DIR"; fi |
| 127 | + |
| 128 | +## resolve application jar path from script location |
| 129 | +if [ -f "$abs_jbang_dir/jbang.jar" ]; then |
| 130 | + jarPath=$abs_jbang_dir/jbang.jar |
| 131 | +elif [ -f "$abs_jbang_dir/.jbang/jbang.jar" ]; then |
| 132 | + jarPath=$abs_jbang_dir/.jbang/jbang.jar |
| 133 | +else |
| 134 | + if [[ ! -f "$JBDIR/bin/jbang.jar" || ! -f "$JBDIR/bin/jbang" ]]; then |
| 135 | + echo "Downloading JBang $JBANG_DOWNLOAD_VERSION..." 1>&2 |
| 136 | + mkdir -p "$TDIR/urls" |
| 137 | + if [ -z "$JBANG_DOWNLOAD_VERSION" ]; then |
| 138 | + jburl="https://github.com/jbangdev/jbang/releases/latest/download/jbang.tar"; |
| 139 | + else |
| 140 | + jburl="https://github.com/jbangdev/jbang/releases/download/v$JBANG_DOWNLOAD_VERSION/jbang.tar"; |
| 141 | + fi |
| 142 | + download $jburl "$TDIR/urls/jbang.tar" |
| 143 | + if [ $retval -ne 0 ]; then echo "Error downloading JBang from $jburl" 1>&2; exit $retval; fi |
| 144 | + echo "Installing JBang..." 1>&2 |
| 145 | + rm -rf "$TDIR/urls/jbang" |
| 146 | + tar xf "$TDIR/urls/jbang.tar" -C "$TDIR/urls" |
| 147 | + if [ $retval -ne 0 ]; then echo "Error installing JBang" 1>&2; exit $retval; fi |
| 148 | + mkdir -p "$JBDIR/bin" |
| 149 | + rm -f "$JBDIR/bin/jbang" "$JBDIR/bin"/jbang.* |
| 150 | + cp -f "$TDIR/urls/jbang/bin"/* "$JBDIR/bin" |
| 151 | + fi |
| 152 | + "$JBDIR"/bin/jbang "$@" |
| 153 | + exit $? |
| 154 | +fi |
| 155 | +if [ -f "$jarPath.new" ]; then |
| 156 | + # a new jbang version was found, we replace the old one with it |
| 157 | + mv "$jarPath.new" "$jarPath" |
| 158 | +fi |
| 159 | + |
| 160 | +# Find/get a JDK |
| 161 | +unset JAVA_EXEC |
| 162 | +if [[ -n "$JAVA_HOME" ]]; then |
| 163 | + # Determine if a (working) JDK is available in JAVA_HOME |
| 164 | + if [ -x "$(command -v "$JAVA_HOME"/bin/javac)" ]; then |
| 165 | + JAVA_EXEC="$JAVA_HOME/bin/java" |
| 166 | + else |
| 167 | + echo "JAVA_HOME is set but does not seem to point to a valid Java JDK" 1>&2 |
| 168 | + fi |
| 169 | +fi |
| 170 | +if [[ -z "$JAVA_EXEC" ]]; then |
| 171 | + # Determine if a (working) JDK is available on the PATH |
| 172 | + if javacInPath; then |
| 173 | + unset JAVA_HOME |
| 174 | + JAVA_EXEC="java" |
| 175 | + elif [ -x "$JBDIR/currentjdk/bin/javac" ]; then |
| 176 | + export JAVA_HOME="$JBDIR/currentjdk" |
| 177 | + JAVA_EXEC="$JBDIR/currentjdk/bin/java" |
| 178 | + else |
| 179 | + export JAVA_HOME="$TDIR/jdks/$javaVersion" |
| 180 | + JAVA_EXEC="$JAVA_HOME/bin/java" |
| 181 | + # Check if we installed a JDK before |
| 182 | + if [ ! -d "$TDIR/jdks/$javaVersion" ]; then |
| 183 | + # If not, download and install it |
| 184 | + if [[ $os == "" ]]; then |
| 185 | + echo "Unable to download JDK, unsupported Operating System: $(uname -s)" 1>&2 |
| 186 | + exit 1 |
| 187 | + fi |
| 188 | + if [[ $arch == "" ]]; then |
| 189 | + echo "Unable to download JDK, unsupported Architecture: $(uname -m)" 1>&2 |
| 190 | + exit 1 |
| 191 | + fi |
| 192 | + mkdir -p "$TDIR/jdks" |
| 193 | + echo "Downloading JDK $javaVersion. Be patient, this can take several minutes..." 1>&2 |
| 194 | + jdkurl="https://api.foojay.io/disco/v3.0/directuris?distro=$distro&javafx_bundled=false&libc_type=$libc_type&archive_type=$file_type&operating_system=$os&package_type=jdk&version=$javaVersion&architecture=$arch&latest=available" |
| 195 | + download "$jdkurl" "$TDIR/bootstrap-jdk.$file_type" |
| 196 | + if [ $retval -ne 0 ]; then echo "Error downloading JDK" 1>&2; exit $retval; fi |
| 197 | + echo "Installing JDK $javaVersion..." 1>&2 |
| 198 | + rm -rf "$TDIR/jdks/$javaVersion.tmp/" |
| 199 | + mkdir -p "$TDIR/jdks/$javaVersion.tmp" |
| 200 | + unpack "$TDIR/bootstrap-jdk.$file_type" "$TDIR/jdks/$javaVersion.tmp" |
| 201 | + if [ $retval -ne 0 ]; then |
| 202 | + # Check if the JDK was installed properly |
| 203 | + javac -version > /dev/null 2>&1 |
| 204 | + retval=$? |
| 205 | + fi |
| 206 | + if [ $retval -ne 0 ]; then echo "Error installing JDK" 1>&2; exit $retval; fi |
| 207 | + # Activate the downloaded JDK giving it its proper name |
| 208 | + mv "$TDIR/jdks/$javaVersion.tmp" "$TDIR/jdks/$javaVersion" |
| 209 | + # Set the current JDK |
| 210 | + "${JAVA_EXEC}" -classpath "${jarPath}" dev.jbang.Main jdk default $javaVersion |
| 211 | + fi |
| 212 | + fi |
| 213 | +fi |
| 214 | + |
| 215 | +## https://stackoverflow.com/questions/1668649/how-to-keep-quotes-in-bash-arguments |
| 216 | +## attempt to ensure each argument keeps its original quoting |
| 217 | + |
| 218 | +## run it using command substitution to have just the user process once jbang is done |
| 219 | +export JBANG_RUNTIME_SHELL=bash |
| 220 | +export JBANG_STDIN_NOTTY=$([ -t 0 ] && echo "false" || echo "true") |
| 221 | +output=$(CLICOLOR_FORCE=1 "${JAVA_EXEC}" ${JBANG_JAVA_OPTIONS} -classpath "${jarPath}" dev.jbang.Main "$@") |
| 222 | +err=$? |
| 223 | +if [ $err -eq 255 ]; then |
| 224 | + eval "exec $output" |
| 225 | +elif [ -n "$output" ]; then |
| 226 | + echo "$output" |
| 227 | + exit $err |
| 228 | +else |
| 229 | + exit $err |
| 230 | +fi |
0 commit comments