Created
May 22, 2015 15:24
-
-
Save brianwawok/22714eef3860ddce2477 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
### ------------------------------- ### | |
### Helper methods for BASH scripts ### | |
### ------------------------------- ### | |
die() { | |
echo "$@" 1>&2 | |
exit 1 | |
} | |
realpath () { | |
( | |
TARGET_FILE="$1" | |
CHECK_CYGWIN="$2" | |
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 [[ "x$CHECK_CYGWIN" == "x" ]]; 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 | |
} | |
# This crazy function reads in a vanilla "linux" classpath string (only : are separators, and all /), | |
# and returns a classpath with windows style paths, and ; separators. | |
fixCygwinClasspath() { | |
OLDIFS=$IFS | |
IFS=":" | |
read -a classpath_members <<< "$1" | |
declare -a fixed_members | |
IFS=$OLDIFS | |
for i in "${!classpath_members[@]}" | |
do | |
fixed_members[i]=$(realpath "${classpath_members[i]}" "fix") | |
done | |
IFS=";" | |
echo "${fixed_members[*]}" | |
IFS=$OLDIFS | |
} | |
# Fix the classpath we use for cygwin. | |
fix_classpath() { | |
cp="$1" | |
if is_cygwin; then | |
echo "$(fixCygwinClasspath "$cp")" | |
else | |
echo "$cp" | |
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 "" | |
} | |
# we use "exec" here for our pids to be accurate. | |
exec "$@" | |
} | |
addJava () { | |
dlog "[addJava] arg = '$1'" | |
java_args+=( "$1" ) | |
} | |
addApp () { | |
dlog "[addApp] arg = '$1'" | |
app_commands+=( "$1" ) | |
} | |
addResidual () { | |
dlog "[residual] arg = '$1'" | |
residual_args+=( "$1" ) | |
} | |
addDebugger () { | |
addJava "-Xdebug" | |
addJava "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" | |
} | |
# 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 perm=$(( $mem / 4 )) | |
(( $perm > 256 )) || perm=256 | |
(( $perm < 1024 )) || perm=1024 | |
local codecache=$(( $perm / 2 )) | |
# 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. | |
if [[ "${java_opts}" == *-Xmx* ]] || | |
[[ "${java_opts}" == *-Xms* ]] || | |
[[ "${java_opts}" == *-XX:MaxPermSize* ]] || | |
[[ "${java_opts}" == *-XX:ReservedCodeCacheSize* ]] || | |
# check java arguments for settings, too | |
[[ "${java_args[@]}" == *-Xmx* ]] || | |
[[ "${java_args[@]}" == *-Xms* ]] || | |
[[ "${java_args[@]}" == *-XX:MaxPermSize* ]] || | |
[[ "${java_args[@]}" == *-XX:ReservedCodeCacheSize* ]]; | |
then | |
echo "" | |
elif [[ !$no_version_check ]] && [[ "$java_version" > "1.8" ]]; then | |
echo "-Xms${mem}m -Xmx${mem}m -XX:ReservedCodeCacheSize=${codecache}m" | |
else | |
echo "-Xms${mem}m -Xmx${mem}m -XX:MaxPermSize=${perm}m -XX:ReservedCodeCacheSize=${codecache}m" | |
fi | |
} | |
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 | |
} | |
# Attempt to detect if the script is running via a GUI or not | |
# TODO - Determine where/how we use this generically | |
detect_terminal_for_ui() { | |
[[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && { | |
echo "true" | |
} | |
# SPECIAL TEST FOR MAC | |
[[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && { | |
echo "true" | |
} | |
} | |
# Processes incoming arguments and places them in appropriate global variables. called by the run method. | |
process_args () { | |
local no_more_snp_opts=0 | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
--) shift && no_more_snp_opts=1 && break ;; | |
-h|-help) usage; exit 1 ;; | |
-v|-verbose) verbose=1 && shift ;; | |
-d|-debug) debug=1 && shift ;; | |
-no-version-check) no_version_check=1 && shift ;; | |
-mem) require_arg integer "$1" "$2" && app_mem="$2" && shift 2 ;; | |
-jvm-debug) require_arg port "$1" "$2" && addDebugger $2 && shift 2 ;; | |
-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 | |
if [[ no_more_snp_opts ]]; then | |
while [[ $# -gt 0 ]]; do | |
addResidual "$1" && shift | |
done | |
fi | |
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 "$@" | |
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 | |
# check java version | |
if [[ ! $no_version_check ]]; then | |
java_version_check | |
fi | |
# Now we check to see if there are any java opts on the environemnt. These get listed first, with the script able to override them. | |
if [[ "$JAVA_OPTS" != "" ]]; then | |
java_opts="${JAVA_OPTS}" | |
fi | |
# run sbt | |
execRunner "$java_cmd" \ | |
$(get_mem_opts $app_mem) \ | |
${java_opts[@]} \ | |
"${java_args[@]}" \ | |
-cp "$(fix_classpath "$app_classpath")" \ | |
$app_mainclass \ | |
"${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' | |
} | |
# Now check to see if it's a good enough version | |
# TODO - Check to see if we have a configured default java version, otherwise use 1.6 | |
java_version_check() { | |
readonly 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 $app_name 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 $app_name. | |
echo | |
exit 1 | |
fi | |
} | |
### ------------------------------- ### | |
### Start of customized settings ### | |
### ------------------------------- ### | |
usage() { | |
cat <<EOM | |
Usage: $script_name [options] | |
-h | -help print this message | |
-v | -verbose this runner is chattier | |
-d | -debug set sbt log level to debug | |
-no-version-check Don't run the java version check. | |
-mem <integer> set memory options in MB (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 | |
JAVA_OPTS environment variable, if unset uses "$java_opts" | |
-Dkey=val pass -Dkey=val directly to the java runtime | |
-J-X pass option -X directly to the java runtime | |
(-J is stripped) | |
# special option | |
-- To stop parsing built-in commands from the rest of the command-line. | |
e.g.) enabling debug and sending -d as app argument | |
\$ ./start-script -d -- -d | |
In the case of duplicated or conflicting options, basically the order above | |
shows precedence: JAVA_OPTS lowest, command line options highest except "--". | |
EOM | |
} | |
### ------------------------------- ### | |
### Main script ### | |
### ------------------------------- ### | |
declare -a residual_args | |
declare -a java_args | |
declare -a app_commands | |
declare -r real_script_path="$(realpath "$0")" | |
declare -r app_home="$(realpath "$(dirname "$real_script_path")")" | |
# TODO - Check whether this is ok in cygwin... | |
declare -r lib_dir="$(realpath "${app_home}/../lib")" | |
declare -r app_mainclass="play.core.server.NettyServer" | |
declare -r script_conf_file="/etc/default/megacorp" | |
declare -r app_classpath="$lib_dir/megacorp.megacorp-1.0-SNAPSHOT.jar:$lib_dir/attributes-src.jar:$lib_dir/attributes.jar:$lib_dir/ebaycalls-src.jar:$lib_dir/ebaycalls.jar:$lib_dir/ebaysdkcore-src.jar:$lib_dir/ebaysdkcore.jar:$lib_dir/helper-src.jar:$lib_dir/helper.jar:$lib_dir/MaWSJavaClientLibrary-1.1-src.zip:$lib_dir/MaWSJavaClientLibrary-1.1.jar:$lib_dir/MWSClientJavaRuntime-1.0.jar:$lib_dir/MWSOrders_2013-09-01_v2015-03-05-src.zip:$lib_dir/MWSOrders_2013-09-01_v2015-03-05.jar:$lib_dir/MWSProducts_2011-10-01_v2015-02-13-src.zip:$lib_dir/MWSProducts_2011-10-01_v2015-02-13.jar:$lib_dir/org.scala-lang.scala-library-2.11.6.jar:$lib_dir/com.typesafe.play.twirl-api_2.11-1.0.2.jar:$lib_dir/org.apache.commons.commons-lang3-3.1.jar:$lib_dir/org.scala-lang.modules.scala-xml_2.11-1.0.1.jar:$lib_dir/com.typesafe.play.play_2.11-2.3.9.jar:$lib_dir/com.typesafe.play.build-link-2.3.9.jar:$lib_dir/com.typesafe.play.play-exceptions-2.3.9.jar:$lib_dir/org.javassist.javassist-3.18.2-GA.jar:$lib_dir/org.scala-stm.scala-stm_2.11-0.7.jar:$lib_dir/com.typesafe.config-1.2.1.jar:$lib_dir/com.typesafe.play.play-json_2.11-2.3.9.jar:$lib_dir/com.typesafe.play.play-functional_2.11-2.3.9.jar:$lib_dir/com.typesafe.play.play-datacommons_2.11-2.3.9.jar:$lib_dir/joda-time.joda-time-2.3.jar:$lib_dir/org.joda.joda-convert-1.6.jar:$lib_dir/com.fasterxml.jackson.core.jackson-annotations-2.3.2.jar:$lib_dir/com.fasterxml.jackson.core.jackson-core-2.3.2.jar:$lib_dir/com.fasterxml.jackson.core.jackson-databind-2.3.2.jar:$lib_dir/org.scala-lang.scala-reflect-2.11.6.jar:$lib_dir/io.netty.netty-3.9.8.Final.jar:$lib_dir/com.typesafe.netty.netty-http-pipelining-1.1.2.jar:$lib_dir/org.slf4j.slf4j-api-1.7.6.jar:$lib_dir/org.slf4j.jul-to-slf4j-1.7.12.jar:$lib_dir/org.slf4j.jcl-over-slf4j-1.7.6.jar:$lib_dir/com.typesafe.akka.akka-actor_2.11-2.3.11.jar:$lib_dir/com.typesafe.akka.akka-slf4j_2.11-2.3.4.jar:$lib_dir/commons-codec.commons-codec-1.10.jar:$lib_dir/xerces.xercesImpl-2.11.0.jar:$lib_dir/xml-apis.xml-apis-1.4.01.jar:$lib_dir/javax.transaction.jta-1.1.jar:$lib_dir/com.typesafe.play.filters-helpers_2.11-2.3.9.jar:$lib_dir/com.typesafe.play.play-ws_2.11-2.3.9.jar:$lib_dir/com.google.guava.guava-16.0.1.jar:$lib_dir/com.ning.async-http-client-1.8.15.jar:$lib_dir/oauth.signpost.signpost-core-1.2.1.2.jar:$lib_dir/oauth.signpost.signpost-commonshttp4-1.2.1.2.jar:$lib_dir/org.apache.httpcomponents.httpcore-4.4.1.jar:$lib_dir/org.apache.httpcomponents.httpclient-4.4.1.jar:$lib_dir/commons-logging.commons-logging-1.2.jar:$lib_dir/com.websudos.phantom-dsl_2.11-1.8.12.jar:$lib_dir/com.websudos.phantom-connectors_2.11-1.8.12.jar:$lib_dir/com.datastax.cassandra.cassandra-driver-core-2.1.5.jar:$lib_dir/com.codahale.metrics.metrics-core-3.0.2.jar:$lib_dir/com.chuusai.shapeless_2.11-2.2.0-RC4.jar:$lib_dir/com.twitter.util-core_2.11-6.24.0.jar:$lib_dir/com.twitter.util-function_2.11-6.24.0.jar:$lib_dir/org.scala-lang.modules.scala-parser-combinators_2.11-1.0.2.jar:$lib_dir/com.typesafe.play.play-iteratees_2.11-2.4.0-M1.jar:$lib_dir/net.jpountz.lz4.lz4-1.3.0.jar:$lib_dir/com.typesafe.akka.akka-cluster_2.11-2.3.11.jar:$lib_dir/com.typesafe.akka.akka-remote_2.11-2.3.11.jar:$lib_dir/com.google.protobuf.protobuf-java-2.5.0.jar:$lib_dir/org.uncommons.maths.uncommons-maths-1.2.2a.jar:$lib_dir/com.typesafe.akka.akka-contrib_2.11-2.3.11.jar:$lib_dir/com.typesafe.akka.akka-persistence-experimental_2.11-2.3.11.jar:$lib_dir/org.iq80.leveldb.leveldb-0.5.jar:$lib_dir/org.iq80.leveldb.leveldb-api-0.5.jar:$lib_dir/org.fusesource.leveldbjni.leveldbjni-all-1.7.jar:$lib_dir/org.fusesource.leveldbjni.leveldbjni-1.7.jar:$lib_dir/org.fusesource.hawtjni.hawtjni-runtime-1.8.jar:$lib_dir/org.fusesource.leveldbjni.leveldbjni-osx-1.5.jar:$lib_dir/org.fusesource.leveldbjni.leveldbjni-linux32-1.5.jar:$lib_dir/org.fusesource.leveldbjni.leveldbjni-linux64-1.5.jar:$lib_dir/org.fusesource.leveldbjni.leveldbjni-win32-1.5.jar:$lib_dir/org.fusesource.leveldbjni.leveldbjni-win64-1.5.jar:$lib_dir/de.svenkubiak.jBCrypt-0.4.jar:$lib_dir/jp.t2v.play2-auth_2.11-0.13.0.jar:$lib_dir/com.typesafe.play.play-cache_2.11-2.3.0.jar:$lib_dir/net.sf.ehcache.ehcache-core-2.6.8.jar:$lib_dir/jp.t2v.stackable-controller_2.11-0.4.1.jar:$lib_dir/org.apache.commons.commons-email-1.3.3.jar:$lib_dir/javax.mail.mail-1.4.5.jar:$lib_dir/javax.activation.activation-1.1.1.jar:$lib_dir/org.apache.poi.poi-3.11.jar:$lib_dir/com.sksamuel.scrimage.scrimage-core_2.11-1.4.2.jar:$lib_dir/org.apache.sanselan.sanselan-0.97-incubator.jar:$lib_dir/com.twelvemonkeys.imageio.imageio-core-3.0-rc5.jar:$lib_dir/com.twelvemonkeys.common.common-io-3.0-rc5.jar:$lib_dir/com.twelvemonkeys.common.common-image-3.0-rc5.jar:$lib_dir/com.twelvemonkeys.imageio.imageio-metadata-3.0-rc5.jar:$lib_dir/com.twelvemonkeys.imageio.imageio-jpeg-3.0-rc5.jar:$lib_dir/com.twelvemonkeys.common.common-lang-3.0-rc5.jar:$lib_dir/commons-io.commons-io-2.4.jar:$lib_dir/com.drewnoakes.metadata-extractor-2.6.2.jar:$lib_dir/com.adobe.xmp.xmpcore-5.1.2.jar:$lib_dir/ar.com.hjg.pngj-2.0.1.jar:$lib_dir/com.sun.xml.ws.jaxws-rt-2.2.10.jar:$lib_dir/javax.xml.bind.jaxb-api-2.2.12-b140109.1041.jar:$lib_dir/javax.xml.ws.jaxws-api-2.2.11.jar:$lib_dir/javax.xml.soap.javax.xml.soap-api-1.3.7.jar:$lib_dir/javax.annotation.javax.annotation-api-1.2.jar:$lib_dir/javax.jws.jsr181-api-1.0-MR1.jar:$lib_dir/com.sun.xml.bind.jaxb-core-2.2.10-b140802.1033.jar:$lib_dir/com.sun.xml.bind.jaxb-impl-2.2.10-b140802.1033.jar:$lib_dir/com.sun.xml.ws.policy-2.4.jar:$lib_dir/org.glassfish.gmbal.gmbal-api-only-3.1.0-b001.jar:$lib_dir/org.glassfish.external.management-api-3.0.0-b012.jar:$lib_dir/org.jvnet.staxex.stax-ex-1.7.7.jar:$lib_dir/com.sun.xml.stream.buffer.streambuffer-1.5.3.jar:$lib_dir/org.jvnet.mimepull.mimepull-1.9.4.jar:$lib_dir/com.sun.xml.fastinfoset.FastInfoset-1.2.13.jar:$lib_dir/org.glassfish.ha.ha-api-3.1.9.jar:$lib_dir/com.sun.xml.messaging.saaj.saaj-impl-1.3.25.jar:$lib_dir/com.sun.org.apache.xml.internal.resolver-20050927.jar:$lib_dir/org.codehaus.woodstox.woodstox-core-asl-4.2.0.jar:$lib_dir/org.codehaus.woodstox.stax2-api-3.1.1.jar:$lib_dir/xalan.xalan-2.7.2.jar:$lib_dir/xalan.serializer-2.7.2.jar:$lib_dir/org.apache.servicemix.bundles.org.apache.servicemix.bundles.oro-2.0.8_6.jar:$lib_dir/com.papertrailapp.logback-syslog4j-1.0.0.jar:$lib_dir/ch.qos.logback.logback-core-1.1.2.jar:$lib_dir/ch.qos.logback.logback-classic-1.1.2.jar:$lib_dir/org.syslog4j.syslog4j-0.9.30.jar:$lib_dir/megacorp.megacorp-1.0-SNAPSHOT-assets.jar" | |
addJava "-Duser.dir=$(cd "${app_home}/.."; pwd -P)" | |
# java_cmd is overrode in process_args when -java-home is used | |
declare java_cmd=$(get_java_cmd) | |
# if configuration files exist, prepend their contents to $@ so it can be processed by this runner | |
[[ -f "$script_conf_file" ]] && set -- $(loadConfigFile "$script_conf_file") "$@" | |
run "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment