| #!/bin/bash |
| |
| ### ------------------------------- ### |
| ### Helper methods for BASH scripts ### |
| ### ------------------------------- ### |
| |
| realpath () { |
| ( |
| TARGET_FILE="$1" |
| |
| cd $(dirname "$TARGET_FILE") |
| TARGET_FILE=$(basename "$TARGET_FILE") |
| |
| COUNT=0 |
| while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ] |
| do |
| TARGET_FILE=$(readlink "$TARGET_FILE") |
| cd $(dirname "$TARGET_FILE") |
| TARGET_FILE=$(basename "$TARGET_FILE") |
| COUNT=$(($COUNT + 1)) |
| done |
| |
| if [ "$TARGET_FILE" == "." -o "$TARGET_FILE" == ".." ]; then |
| cd "$TARGET_FILE" |
| TARGET_FILEPATH= |
| else |
| TARGET_FILEPATH=/$TARGET_FILE |
| fi |
| |
| # make sure we grab the actual windows path, instead of cygwin's path. |
| if ! is_cygwin; then |
| echo "$(pwd -P)/$TARGET_FILE" |
| else |
| echo $(cygwinpath "$(pwd -P)/$TARGET_FILE") |
| fi |
| ) |
| } |
| |
| # TODO - Do we need to detect msys? |
| |
| # Uses uname to detect if we're in the odd cygwin environment. |
| is_cygwin() { |
| local os=$(uname -s) |
| case "$os" in |
| CYGWIN*) return 0 ;; |
| *) return 1 ;; |
| esac |
| } |
| |
| # This can fix cygwin style /cygdrive paths so we get the |
| # windows style paths. |
| cygwinpath() { |
| local file="$1" |
| if is_cygwin; then |
| echo $(cygpath -w $file) |
| else |
| echo $file |
| fi |
| } |
| |
| # Make something URI friendly |
| make_url() { |
| url="$1" |
| local nospaces=${url// /%20} |
| if is_cygwin; then |
| echo "/${nospaces//\\//}" |
| else |
| echo "$nospaces" |
| fi |
| } |
| |
| # Detect if we should use JAVA_HOME or just try PATH. |
| get_java_cmd() { |
| if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then |
| echo "$JAVA_HOME/bin/java" |
| else |
| echo "java" |
| fi |
| } |
| |
| echoerr () { |
| echo 1>&2 "$@" |
| } |
| vlog () { |
| [[ $verbose || $debug ]] && echoerr "$@" |
| } |
| dlog () { |
| [[ $debug ]] && echoerr "$@" |
| } |
| execRunner () { |
| # print the arguments one to a line, quoting any containing spaces |
| [[ $verbose || $debug ]] && echo "# Executing command line:" && { |
| for arg; do |
| if printf "%s\n" "$arg" | grep -q ' '; then |
| printf "\"%s\"\n" "$arg" |
| else |
| printf "%s\n" "$arg" |
| fi |
| done |
| echo "" |
| } |
| |
| exec "$@" |
| } |
| addJava () { |
| dlog "[addJava] arg = '$1'" |
| java_args=( "${java_args[@]}" "$1" ) |
| } |
| addApp () { |
| dlog "[addApp] arg = '$1'" |
| sbt_commands=( "${app_commands[@]}" "$1" ) |
| } |
| addResidual () { |
| dlog "[residual] arg = '$1'" |
| residual_args=( "${residual_args[@]}" "$1" ) |
| } |
| addDebugger () { |
| addJava "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" |
| } |
| addConfigOpts () { |
| dlog "[addConfigOpts] arg = '$*'" |
| for item in $* |
| do |
| addJava "$item" |
| done |
| } |
| # a ham-fisted attempt to move some memory settings in concert |
| # so they need not be messed around with individually. |
| get_mem_opts () { |
| local mem=${1:-1024} |
| local meta=$(( $mem / 4 )) |
| (( $meta > 256 )) || meta=256 |
| (( $meta < 1024 )) || meta=1024 |
| |
| # default is to set memory options but this can be overridden by code section below |
| memopts="-Xms${mem}m -Xmx${mem}m" |
| if [[ "${java_version}" > "1.8" ]]; then |
| extmemopts="-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=${meta}m" |
| else |
| extmemopts="-XX:PermSize=64m -XX:MaxPermSize=${meta}m" |
| fi |
| |
| if [[ "${java_opts}" == *-Xmx* ]] || [[ "${java_opts}" == *-Xms* ]] || [[ "${java_opts}" == *-XX:MaxPermSize* ]] || [[ "${java_opts}" == *-XX:ReservedCodeCacheSize* ]] || [[ "${java_opts}" == *-XX:MaxMetaspaceSize* ]]; then |
| # if we detect any of these settings in ${java_opts} we need to NOT output our settings. |
| # The reason is the Xms/Xmx, if they don't line up, cause errors. |
| memopts="" |
| extmemopts="" |
| fi |
| |
| echo "${memopts} ${extmemopts}" |
| } |
| require_arg () { |
| local type="$1" |
| local opt="$2" |
| local arg="$3" |
| if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then |
| die "$opt requires <$type> argument" |
| fi |
| } |
| is_function_defined() { |
| declare -f "$1" > /dev/null |
| } |
| |
| # If we're *not* running in a terminal, and we don't have any arguments, then we need to add the 'ui' parameter |
| detect_terminal_for_ui() { |
| [[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && { |
| addResidual "ui" |
| } |
| # SPECIAL TEST FOR MAC |
| [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && { |
| echo "Detected MAC OSX launched script...." |
| echo "Swapping to UI" |
| addResidual "ui" |
| } |
| } |
| |
| # Processes incoming arguments and places them in appropriate global variables. called by the run method. |
| process_args () { |
| while [[ $# -gt 0 ]]; do |
| case "$1" in |
| -h|-help) usage; exit 1 ;; |
| -v|-verbose) verbose=1 && shift ;; |
| -d|-debug) debug=1 && shift ;; |
| -mem) require_arg integer "$1" "$2" && app_mem="$2" && shift 2 ;; |
| -jvm-debug) |
| if echo "$2" | grep -E ^[0-9]+$ > /dev/null; then |
| addDebugger "$2" && shift |
| else |
| addDebugger 9999 |
| fi |
| shift ;; |
| -java-home) require_arg path "$1" "$2" && java_cmd="$2/bin/java" && shift 2 ;; |
| -D*) addJava "$1" && shift ;; |
| -J*) addJava "${1:2}" && shift ;; |
| *) addResidual "$1" && shift ;; |
| esac |
| done |
| |
| is_function_defined process_my_args && { |
| myargs=("${residual_args[@]}") |
| residual_args=() |
| process_my_args "${myargs[@]}" |
| } |
| } |
| |
| # Actually runs the script. |
| run() { |
| # TODO - check for sane environment |
| |
| # process the combined args, then reset "$@" to the residuals |
| process_args "$@" |
| detect_terminal_for_ui |
| set -- "${residual_args[@]}" |
| argumentCount=$# |
| |
| #check for jline terminal fixes on cygwin |
| if is_cygwin; then |
| stty -icanon min 1 -echo > /dev/null 2>&1 |
| addJava "-Djline.terminal=jline.UnixTerminal" |
| addJava "-Dsbt.cygwin=true" |
| fi |
| |
| # run sbt |
| execRunner "$java_cmd" \ |
| "-Dactivator.home=$(make_url "$activator_home")" \ |
| $(get_mem_opts $app_mem) \ |
| ${java_opts[@]} \ |
| ${java_args[@]} \ |
| -jar "$app_launcher" \ |
| "${app_commands[@]}" \ |
| "${residual_args[@]}" |
| |
| local exit_code=$? |
| if is_cygwin; then |
| stty icanon echo > /dev/null 2>&1 |
| fi |
| exit $exit_code |
| } |
| |
| # Loads a configuration file full of default command line options for this script. |
| loadConfigFile() { |
| cat "$1" | sed '/^\#/d' |
| } |
| |
| ### ------------------------------- ### |
| ### Start of customized settings ### |
| ### ------------------------------- ### |
| usage() { |
| cat <<EOM |
| Usage: $script_name <command> [options] |
| |
| Command: |
| ui Start the Activator UI |
| new [name] [template-id] Create a new project with [name] using template [template-id] |
| list-templates Print all available template names |
| -h | -help Print this message |
| |
| Options: |
| -v | -verbose Make this runner chattier |
| -d | -debug Set sbt log level to debug |
| -mem <integer> Set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem)) |
| -jvm-debug <port> Turn on JVM debugging, open at the given port. |
| |
| # java version (default: java from PATH, currently $(java -version 2>&1 | grep version)) |
| -java-home <path> Alternate JAVA_HOME |
| |
| # jvm options and output control |
| -Dkey=val Pass -Dkey=val directly to the java runtime |
| -J-X Pass option -X directly to the java runtime |
| (-J is stripped) |
| |
| # environment variables (read from context) |
| JAVA_OPTS Environment variable, if unset uses "" |
| SBT_OPTS Environment variable, if unset uses "" |
| ACTIVATOR_OPTS Environment variable, if unset uses "" |
| |
| In the case of duplicated or conflicting options, the order above |
| shows precedence: environment variables lowest, command line options highest. |
| EOM |
| } |
| |
| ### ------------------------------- ### |
| ### Main script ### |
| ### ------------------------------- ### |
| |
| declare -a residual_args |
| declare -a java_args |
| declare -a app_commands |
| declare -r real_script_path="$(realpath "$0")" |
| declare -r activator_home="$(realpath "$(dirname "$real_script_path")")" |
| declare -r app_version="1.2.12" |
| |
| declare -r app_launcher="${activator_home}/activator-launch-${app_version}.jar" |
| declare -r script_name=activator |
| declare -r java_cmd=$(get_java_cmd) |
| declare -r java_opts=( "${ACTIVATOR_OPTS[@]}" "${SBT_OPTS[@]}" "${JAVA_OPTS[@]}" "${java_opts[@]}" ) |
| userhome="$HOME" |
| if is_cygwin; then |
| # cygwin sets home to something f-d up, set to real windows homedir |
| userhome="$USERPROFILE" |
| fi |
| declare -r activator_user_home_dir="${userhome}/.activator" |
| declare -r java_opts_config_home="${activator_user_home_dir}/activatorconfig.txt" |
| declare -r java_opts_config_version="${activator_user_home_dir}/${app_version}/activatorconfig.txt" |
| |
| # Now check to see if it's a good enough version |
| declare -r java_version=$("$java_cmd" -version 2>&1 | awk -F '"' '/version/ {print $2}') |
| if [[ "$java_version" == "" ]]; then |
| echo |
| echo No java installations was detected. |
| echo Please go to http://www.java.com/getjava/ and download |
| echo |
| exit 1 |
| elif [[ ! "$java_version" > "1.6" ]]; then |
| echo |
| echo The java installation you have is not up to date |
| echo Activator requires at least version 1.6+, you have |
| echo version $java_version |
| echo |
| echo Please go to http://www.java.com/getjava/ and download |
| echo a valid Java Runtime and install before running Activator. |
| echo |
| exit 1 |
| fi |
| |
| # if configuration files exist, prepend their contents to the java args so it can be processed by this runner |
| # a "versioned" config trumps one on the top level |
| if [[ -f "$java_opts_config_version" ]]; then |
| addConfigOpts $(loadConfigFile "$java_opts_config_version") |
| elif [[ -f "$java_opts_config_home" ]]; then |
| addConfigOpts $(loadConfigFile "$java_opts_config_home") |
| fi |
| |
| run "$@" |