Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

570 wiersze
21KB

  1. #!/usr/bin/env bash
  2. #
  3. # A more capable sbt runner, coincidentally also called sbt.
  4. # Author: Paul Phillips <paulp@improving.org>
  5. # https://github.com/paulp/sbt-extras
  6. set -o pipefail
  7. declare -r sbt_release_version="1.2.8"
  8. declare -r sbt_unreleased_version="1.2.8"
  9. declare -r latest_213="2.13.0-RC1"
  10. declare -r latest_212="2.12.8"
  11. declare -r latest_211="2.11.12"
  12. declare -r latest_210="2.10.7"
  13. declare -r latest_29="2.9.3"
  14. declare -r latest_28="2.8.2"
  15. declare -r buildProps="project/build.properties"
  16. declare -r sbt_launch_ivy_release_repo="http://repo.typesafe.com/typesafe/ivy-releases"
  17. declare -r sbt_launch_ivy_snapshot_repo="https://repo.scala-sbt.org/scalasbt/ivy-snapshots"
  18. declare -r sbt_launch_mvn_release_repo="http://repo.scala-sbt.org/scalasbt/maven-releases"
  19. declare -r sbt_launch_mvn_snapshot_repo="http://repo.scala-sbt.org/scalasbt/maven-snapshots"
  20. declare -r default_jvm_opts_common="-Xms512m -Xss2m"
  21. declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy"
  22. declare sbt_jar sbt_dir sbt_create sbt_version sbt_script sbt_new
  23. declare sbt_explicit_version
  24. declare verbose noshare batch trace_level
  25. declare debugUs
  26. declare java_cmd="java"
  27. declare sbt_launch_dir="$HOME/.sbt/launchers"
  28. declare sbt_launch_repo
  29. # pull -J and -D options to give to java.
  30. declare -a java_args scalac_args sbt_commands residual_args
  31. # args to jvm/sbt via files or environment variables
  32. declare -a extra_jvm_opts extra_sbt_opts
  33. echoerr () { echo >&2 "$@"; }
  34. vlog () { [[ -n "$verbose" ]] && echoerr "$@"; }
  35. die () { echo "Aborting: $*" ; exit 1; }
  36. setTrapExit () {
  37. # save stty and trap exit, to ensure echo is re-enabled if we are interrupted.
  38. SBT_STTY="$(stty -g 2>/dev/null)"
  39. export SBT_STTY
  40. # restore stty settings (echo in particular)
  41. onSbtRunnerExit() {
  42. [ -t 0 ] || return
  43. vlog ""
  44. vlog "restoring stty: $SBT_STTY"
  45. stty "$SBT_STTY"
  46. }
  47. vlog "saving stty: $SBT_STTY"
  48. trap onSbtRunnerExit EXIT
  49. }
  50. # this seems to cover the bases on OSX, and someone will
  51. # have to tell me about the others.
  52. get_script_path () {
  53. local path="$1"
  54. [[ -L "$path" ]] || { echo "$path" ; return; }
  55. local -r target="$(readlink "$path")"
  56. if [[ "${target:0:1}" == "/" ]]; then
  57. echo "$target"
  58. else
  59. echo "${path%/*}/$target"
  60. fi
  61. }
  62. script_path="$(get_script_path "${BASH_SOURCE[0]}")"
  63. declare -r script_path
  64. script_name="${script_path##*/}"
  65. declare -r script_name
  66. init_default_option_file () {
  67. local overriding_var="${!1}"
  68. local default_file="$2"
  69. if [[ ! -r "$default_file" && "$overriding_var" =~ ^@(.*)$ ]]; then
  70. local envvar_file="${BASH_REMATCH[1]}"
  71. if [[ -r "$envvar_file" ]]; then
  72. default_file="$envvar_file"
  73. fi
  74. fi
  75. echo "$default_file"
  76. }
  77. sbt_opts_file="$(init_default_option_file SBT_OPTS .sbtopts)"
  78. jvm_opts_file="$(init_default_option_file JVM_OPTS .jvmopts)"
  79. build_props_sbt () {
  80. [[ -r "$buildProps" ]] && \
  81. grep '^sbt\.version' "$buildProps" | tr '=\r' ' ' | awk '{ print $2; }'
  82. }
  83. set_sbt_version () {
  84. sbt_version="${sbt_explicit_version:-$(build_props_sbt)}"
  85. [[ -n "$sbt_version" ]] || sbt_version=$sbt_release_version
  86. export sbt_version
  87. }
  88. url_base () {
  89. local version="$1"
  90. case "$version" in
  91. 0.7.*) echo "http://simple-build-tool.googlecode.com" ;;
  92. 0.10.* ) echo "$sbt_launch_ivy_release_repo" ;;
  93. 0.11.[12]) echo "$sbt_launch_ivy_release_repo" ;;
  94. 0.*-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]) # ie "*-yyyymmdd-hhMMss"
  95. echo "$sbt_launch_ivy_snapshot_repo" ;;
  96. 0.*) echo "$sbt_launch_ivy_release_repo" ;;
  97. *-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]) # ie "*-yyyymmdd-hhMMss"
  98. echo "$sbt_launch_mvn_snapshot_repo" ;;
  99. *) echo "$sbt_launch_mvn_release_repo" ;;
  100. esac
  101. }
  102. make_url () {
  103. local version="$1"
  104. local base="${sbt_launch_repo:-$(url_base "$version")}"
  105. case "$version" in
  106. 0.7.*) echo "$base/files/sbt-launch-0.7.7.jar" ;;
  107. 0.10.* ) echo "$base/org.scala-tools.sbt/sbt-launch/$version/sbt-launch.jar" ;;
  108. 0.11.[12]) echo "$base/org.scala-tools.sbt/sbt-launch/$version/sbt-launch.jar" ;;
  109. 0.*) echo "$base/org.scala-sbt/sbt-launch/$version/sbt-launch.jar" ;;
  110. *) echo "$base/org/scala-sbt/sbt-launch/$version/sbt-launch.jar" ;;
  111. esac
  112. }
  113. addJava () { vlog "[addJava] arg = '$1'" ; java_args+=("$1"); }
  114. addSbt () { vlog "[addSbt] arg = '$1'" ; sbt_commands+=("$1"); }
  115. addScalac () { vlog "[addScalac] arg = '$1'" ; scalac_args+=("$1"); }
  116. addResidual () { vlog "[residual] arg = '$1'" ; residual_args+=("$1"); }
  117. addResolver () { addSbt "set resolvers += $1"; }
  118. addDebugger () { addJava "-Xdebug" ; addJava "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1"; }
  119. setThisBuild () {
  120. vlog "[addBuild] args = '$*'"
  121. local key="$1" && shift
  122. addSbt "set $key in ThisBuild := $*"
  123. }
  124. setScalaVersion () {
  125. [[ "$1" == *"-SNAPSHOT" ]] && addResolver 'Resolver.sonatypeRepo("snapshots")'
  126. addSbt "++ $1"
  127. }
  128. setJavaHome () {
  129. java_cmd="$1/bin/java"
  130. setThisBuild javaHome "_root_.scala.Some(file(\"$1\"))"
  131. export JAVA_HOME="$1"
  132. export JDK_HOME="$1"
  133. export PATH="$JAVA_HOME/bin:$PATH"
  134. }
  135. getJavaVersion() {
  136. local -r str=$("$1" -version 2>&1 | grep -E -e '(java|openjdk) version' | awk '{ print $3 }' | tr -d '"')
  137. # java -version on java8 says 1.8.x
  138. # but on 9 and 10 it's 9.x.y and 10.x.y.
  139. if [[ "$str" =~ ^1\.([0-9]+)\..*$ ]]; then
  140. echo "${BASH_REMATCH[1]}"
  141. elif [[ "$str" =~ ^([0-9]+)\..*$ ]]; then
  142. echo "${BASH_REMATCH[1]}"
  143. elif [[ -n "$str" ]]; then
  144. echoerr "Can't parse java version from: $str"
  145. fi
  146. }
  147. checkJava() {
  148. # Warn if there is a Java version mismatch between PATH and JAVA_HOME/JDK_HOME
  149. [[ -n "$JAVA_HOME" && -e "$JAVA_HOME/bin/java" ]] && java="$JAVA_HOME/bin/java"
  150. [[ -n "$JDK_HOME" && -e "$JDK_HOME/lib/tools.jar" ]] && java="$JDK_HOME/bin/java"
  151. if [[ -n "$java" ]]; then
  152. pathJavaVersion=$(getJavaVersion java)
  153. homeJavaVersion=$(getJavaVersion "$java")
  154. if [[ "$pathJavaVersion" != "$homeJavaVersion" ]]; then
  155. echoerr "Warning: Java version mismatch between PATH and JAVA_HOME/JDK_HOME, sbt will use the one in PATH"
  156. echoerr " Either: fix your PATH, remove JAVA_HOME/JDK_HOME or use -java-home"
  157. echoerr " java version from PATH: $pathJavaVersion"
  158. echoerr " java version from JAVA_HOME/JDK_HOME: $homeJavaVersion"
  159. fi
  160. fi
  161. }
  162. java_version () {
  163. local -r version=$(getJavaVersion "$java_cmd")
  164. vlog "Detected Java version: $version"
  165. echo "$version"
  166. }
  167. # MaxPermSize critical on pre-8 JVMs but incurs noisy warning on 8+
  168. default_jvm_opts () {
  169. local -r v="$(java_version)"
  170. if [[ $v -ge 8 ]]; then
  171. echo "$default_jvm_opts_common"
  172. else
  173. echo "-XX:MaxPermSize=384m $default_jvm_opts_common"
  174. fi
  175. }
  176. build_props_scala () {
  177. if [[ -r "$buildProps" ]]; then
  178. versionLine="$(grep '^build.scala.versions' "$buildProps")"
  179. versionString="${versionLine##build.scala.versions=}"
  180. echo "${versionString%% .*}"
  181. fi
  182. }
  183. execRunner () {
  184. # print the arguments one to a line, quoting any containing spaces
  185. vlog "# Executing command line:" && {
  186. for arg; do
  187. if [[ -n "$arg" ]]; then
  188. if printf "%s\n" "$arg" | grep -q ' '; then
  189. printf >&2 "\"%s\"\n" "$arg"
  190. else
  191. printf >&2 "%s\n" "$arg"
  192. fi
  193. fi
  194. done
  195. vlog ""
  196. }
  197. setTrapExit
  198. if [[ -n "$batch" ]]; then
  199. "$@" < /dev/null
  200. else
  201. "$@"
  202. fi
  203. }
  204. jar_url () { make_url "$1"; }
  205. is_cygwin () { [[ "$(uname -a)" == "CYGWIN"* ]]; }
  206. jar_file () {
  207. is_cygwin \
  208. && cygpath -w "$sbt_launch_dir/$1/sbt-launch.jar" \
  209. || echo "$sbt_launch_dir/$1/sbt-launch.jar"
  210. }
  211. download_url () {
  212. local url="$1"
  213. local jar="$2"
  214. echoerr "Downloading sbt launcher for $sbt_version:"
  215. echoerr " From $url"
  216. echoerr " To $jar"
  217. mkdir -p "${jar%/*}" && {
  218. if command -v curl > /dev/null 2>&1; then
  219. curl --fail --silent --location "$url" --output "$jar"
  220. elif command -v wget > /dev/null 2>&1; then
  221. wget -q -O "$jar" "$url"
  222. fi
  223. } && [[ -r "$jar" ]]
  224. }
  225. acquire_sbt_jar () {
  226. {
  227. sbt_jar="$(jar_file "$sbt_version")"
  228. [[ -r "$sbt_jar" ]]
  229. } || {
  230. sbt_jar="$HOME/.ivy2/local/org.scala-sbt/sbt-launch/$sbt_version/jars/sbt-launch.jar"
  231. [[ -r "$sbt_jar" ]]
  232. } || {
  233. sbt_jar="$(jar_file "$sbt_version")"
  234. download_url "$(make_url "$sbt_version")" "$sbt_jar"
  235. }
  236. }
  237. usage () {
  238. set_sbt_version
  239. cat <<EOM
  240. Usage: $script_name [options]
  241. Note that options which are passed along to sbt begin with -- whereas
  242. options to this runner use a single dash. Any sbt command can be scheduled
  243. to run first by prefixing the command with --, so --warn, --error and so on
  244. are not special.
  245. Output filtering: if there is a file in the home directory called .sbtignore
  246. and this is not an interactive sbt session, the file is treated as a list of
  247. bash regular expressions. Output lines which match any regex are not echoed.
  248. One can see exactly which lines would have been suppressed by starting this
  249. runner with the -x option.
  250. -h | -help print this message
  251. -v verbose operation (this runner is chattier)
  252. -d, -w, -q aliases for --debug, --warn, --error (q means quiet)
  253. -x debug this script
  254. -trace <level> display stack traces with a max of <level> frames (default: -1, traces suppressed)
  255. -debug-inc enable debugging log for the incremental compiler
  256. -no-colors disable ANSI color codes
  257. -sbt-create start sbt even if current directory contains no sbt project
  258. -sbt-dir <path> path to global settings/plugins directory (default: ~/.sbt/<version>)
  259. -sbt-boot <path> path to shared boot directory (default: ~/.sbt/boot in 0.11+)
  260. -ivy <path> path to local Ivy repository (default: ~/.ivy2)
  261. -no-share use all local caches; no sharing
  262. -offline put sbt in offline mode
  263. -jvm-debug <port> Turn on JVM debugging, open at the given port.
  264. -batch Disable interactive mode
  265. -prompt <expr> Set the sbt prompt; in expr, 's' is the State and 'e' is Extracted
  266. -script <file> Run the specified file as a scala script
  267. # sbt version (default: sbt.version from $buildProps if present, otherwise $sbt_release_version)
  268. -sbt-force-latest force the use of the latest release of sbt: $sbt_release_version
  269. -sbt-version <version> use the specified version of sbt (default: $sbt_release_version)
  270. -sbt-dev use the latest pre-release version of sbt: $sbt_unreleased_version
  271. -sbt-jar <path> use the specified jar as the sbt launcher
  272. -sbt-launch-dir <path> directory to hold sbt launchers (default: $sbt_launch_dir)
  273. -sbt-launch-repo <url> repo url for downloading sbt launcher jar (default: $(url_base "$sbt_version"))
  274. # scala version (default: as chosen by sbt)
  275. -28 use $latest_28
  276. -29 use $latest_29
  277. -210 use $latest_210
  278. -211 use $latest_211
  279. -212 use $latest_212
  280. -213 use $latest_213
  281. -scala-home <path> use the scala build at the specified directory
  282. -scala-version <version> use the specified version of scala
  283. -binary-version <version> use the specified scala version when searching for dependencies
  284. # java version (default: java from PATH, currently $(java -version 2>&1 | grep version))
  285. -java-home <path> alternate JAVA_HOME
  286. # passing options to the jvm - note it does NOT use JAVA_OPTS due to pollution
  287. # The default set is used if JVM_OPTS is unset and no -jvm-opts file is found
  288. <default> $(default_jvm_opts)
  289. JVM_OPTS environment variable holding either the jvm args directly, or
  290. the reference to a file containing jvm args if given path is prepended by '@' (e.g. '@/etc/jvmopts')
  291. Note: "@"-file is overridden by local '.jvmopts' or '-jvm-opts' argument.
  292. -jvm-opts <path> file containing jvm args (if not given, .jvmopts in project root is used if present)
  293. -Dkey=val pass -Dkey=val directly to the jvm
  294. -J-X pass option -X directly to the jvm (-J is stripped)
  295. # passing options to sbt, OR to this runner
  296. SBT_OPTS environment variable holding either the sbt args directly, or
  297. the reference to a file containing sbt args if given path is prepended by '@' (e.g. '@/etc/sbtopts')
  298. Note: "@"-file is overridden by local '.sbtopts' or '-sbt-opts' argument.
  299. -sbt-opts <path> file containing sbt args (if not given, .sbtopts in project root is used if present)
  300. -S-X add -X to sbt's scalacOptions (-S is stripped)
  301. EOM
  302. }
  303. process_args () {
  304. require_arg () {
  305. local type="$1"
  306. local opt="$2"
  307. local arg="$3"
  308. if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then
  309. die "$opt requires <$type> argument"
  310. fi
  311. }
  312. while [[ $# -gt 0 ]]; do
  313. case "$1" in
  314. -h|-help) usage; exit 0 ;;
  315. -v) verbose=true && shift ;;
  316. -d) addSbt "--debug" && shift ;;
  317. -w) addSbt "--warn" && shift ;;
  318. -q) addSbt "--error" && shift ;;
  319. -x) debugUs=true && shift ;;
  320. -trace) require_arg integer "$1" "$2" && trace_level="$2" && shift 2 ;;
  321. -ivy) require_arg path "$1" "$2" && addJava "-Dsbt.ivy.home=$2" && shift 2 ;;
  322. -no-colors) addJava "-Dsbt.log.noformat=true" && shift ;;
  323. -no-share) noshare=true && shift ;;
  324. -sbt-boot) require_arg path "$1" "$2" && addJava "-Dsbt.boot.directory=$2" && shift 2 ;;
  325. -sbt-dir) require_arg path "$1" "$2" && sbt_dir="$2" && shift 2 ;;
  326. -debug-inc) addJava "-Dxsbt.inc.debug=true" && shift ;;
  327. -offline) addSbt "set offline in Global := true" && shift ;;
  328. -jvm-debug) require_arg port "$1" "$2" && addDebugger "$2" && shift 2 ;;
  329. -batch) batch=true && shift ;;
  330. -prompt) require_arg "expr" "$1" "$2" && setThisBuild shellPrompt "(s => { val e = Project.extract(s) ; $2 })" && shift 2 ;;
  331. -script) require_arg file "$1" "$2" && sbt_script="$2" && addJava "-Dsbt.main.class=sbt.ScriptMain" && shift 2 ;;
  332. -sbt-create) sbt_create=true && shift ;;
  333. -sbt-jar) require_arg path "$1" "$2" && sbt_jar="$2" && shift 2 ;;
  334. -sbt-version) require_arg version "$1" "$2" && sbt_explicit_version="$2" && shift 2 ;;
  335. -sbt-force-latest) sbt_explicit_version="$sbt_release_version" && shift ;;
  336. -sbt-dev) sbt_explicit_version="$sbt_unreleased_version" && shift ;;
  337. -sbt-launch-dir) require_arg path "$1" "$2" && sbt_launch_dir="$2" && shift 2 ;;
  338. -sbt-launch-repo) require_arg path "$1" "$2" && sbt_launch_repo="$2" && shift 2 ;;
  339. -scala-version) require_arg version "$1" "$2" && setScalaVersion "$2" && shift 2 ;;
  340. -binary-version) require_arg version "$1" "$2" && setThisBuild scalaBinaryVersion "\"$2\"" && shift 2 ;;
  341. -scala-home) require_arg path "$1" "$2" && setThisBuild scalaHome "_root_.scala.Some(file(\"$2\"))" && shift 2 ;;
  342. -java-home) require_arg path "$1" "$2" && setJavaHome "$2" && shift 2 ;;
  343. -sbt-opts) require_arg path "$1" "$2" && sbt_opts_file="$2" && shift 2 ;;
  344. -jvm-opts) require_arg path "$1" "$2" && jvm_opts_file="$2" && shift 2 ;;
  345. -D*) addJava "$1" && shift ;;
  346. -J*) addJava "${1:2}" && shift ;;
  347. -S*) addScalac "${1:2}" && shift ;;
  348. -28) setScalaVersion "$latest_28" && shift ;;
  349. -29) setScalaVersion "$latest_29" && shift ;;
  350. -210) setScalaVersion "$latest_210" && shift ;;
  351. -211) setScalaVersion "$latest_211" && shift ;;
  352. -212) setScalaVersion "$latest_212" && shift ;;
  353. -213) setScalaVersion "$latest_213" && shift ;;
  354. new) sbt_new=true && : ${sbt_explicit_version:=$sbt_release_version} && addResidual "$1" && shift ;;
  355. *) addResidual "$1" && shift ;;
  356. esac
  357. done
  358. }
  359. # process the direct command line arguments
  360. process_args "$@"
  361. # skip #-styled comments and blank lines
  362. readConfigFile() {
  363. local end=false
  364. until $end; do
  365. read -r || end=true
  366. [[ $REPLY =~ ^# ]] || [[ -z $REPLY ]] || echo "$REPLY"
  367. done < "$1"
  368. }
  369. # if there are file/environment sbt_opts, process again so we
  370. # can supply args to this runner
  371. if [[ -r "$sbt_opts_file" ]]; then
  372. vlog "Using sbt options defined in file $sbt_opts_file"
  373. while read -r opt; do extra_sbt_opts+=("$opt"); done < <(readConfigFile "$sbt_opts_file")
  374. elif [[ -n "$SBT_OPTS" && ! ("$SBT_OPTS" =~ ^@.*) ]]; then
  375. vlog "Using sbt options defined in variable \$SBT_OPTS"
  376. IFS=" " read -r -a extra_sbt_opts <<< "$SBT_OPTS"
  377. else
  378. vlog "No extra sbt options have been defined"
  379. fi
  380. [[ -n "${extra_sbt_opts[*]}" ]] && process_args "${extra_sbt_opts[@]}"
  381. # reset "$@" to the residual args
  382. set -- "${residual_args[@]}"
  383. argumentCount=$#
  384. # set sbt version
  385. set_sbt_version
  386. checkJava
  387. # only exists in 0.12+
  388. setTraceLevel() {
  389. case "$sbt_version" in
  390. "0.7."* | "0.10."* | "0.11."* ) echoerr "Cannot set trace level in sbt version $sbt_version" ;;
  391. *) setThisBuild traceLevel "$trace_level" ;;
  392. esac
  393. }
  394. # set scalacOptions if we were given any -S opts
  395. [[ ${#scalac_args[@]} -eq 0 ]] || addSbt "set scalacOptions in ThisBuild += \"${scalac_args[*]}\""
  396. [[ -n "$sbt_explicit_version" && -z "$sbt_new" ]] && addJava "-Dsbt.version=$sbt_explicit_version"
  397. vlog "Detected sbt version $sbt_version"
  398. if [[ -n "$sbt_script" ]]; then
  399. residual_args=( "$sbt_script" "${residual_args[@]}" )
  400. else
  401. # no args - alert them there's stuff in here
  402. (( argumentCount > 0 )) || {
  403. vlog "Starting $script_name: invoke with -help for other options"
  404. residual_args=( shell )
  405. }
  406. fi
  407. # verify this is an sbt dir, -create was given or user attempts to run a scala script
  408. [[ -r ./build.sbt || -d ./project || -n "$sbt_create" || -n "$sbt_script" || -n "$sbt_new" ]] || {
  409. cat <<EOM
  410. $(pwd) doesn't appear to be an sbt project.
  411. If you want to start sbt anyway, run:
  412. $0 -sbt-create
  413. EOM
  414. exit 1
  415. }
  416. # pick up completion if present; todo
  417. # shellcheck disable=SC1091
  418. [[ -r .sbt_completion.sh ]] && source .sbt_completion.sh
  419. # directory to store sbt launchers
  420. [[ -d "$sbt_launch_dir" ]] || mkdir -p "$sbt_launch_dir"
  421. [[ -w "$sbt_launch_dir" ]] || sbt_launch_dir="$(mktemp -d -t sbt_extras_launchers.XXXXXX)"
  422. # no jar? download it.
  423. [[ -r "$sbt_jar" ]] || acquire_sbt_jar || {
  424. # still no jar? uh-oh.
  425. echo "Download failed. Obtain the jar manually and place it at $sbt_jar"
  426. exit 1
  427. }
  428. if [[ -n "$noshare" ]]; then
  429. for opt in ${noshare_opts}; do
  430. addJava "$opt"
  431. done
  432. else
  433. case "$sbt_version" in
  434. "0.7."* | "0.10."* | "0.11."* | "0.12."* )
  435. [[ -n "$sbt_dir" ]] || {
  436. sbt_dir="$HOME/.sbt/$sbt_version"
  437. vlog "Using $sbt_dir as sbt dir, -sbt-dir to override."
  438. }
  439. ;;
  440. esac
  441. if [[ -n "$sbt_dir" ]]; then
  442. addJava "-Dsbt.global.base=$sbt_dir"
  443. fi
  444. fi
  445. if [[ -r "$jvm_opts_file" ]]; then
  446. vlog "Using jvm options defined in file $jvm_opts_file"
  447. while read -r opt; do extra_jvm_opts+=("$opt"); done < <(readConfigFile "$jvm_opts_file")
  448. elif [[ -n "$JVM_OPTS" && ! ("$JVM_OPTS" =~ ^@.*) ]]; then
  449. vlog "Using jvm options defined in \$JVM_OPTS variable"
  450. IFS=" " read -r -a extra_jvm_opts <<< "$JVM_OPTS"
  451. else
  452. vlog "Using default jvm options"
  453. IFS=" " read -r -a extra_jvm_opts <<< "$(default_jvm_opts)"
  454. fi
  455. # traceLevel is 0.12+
  456. [[ -n "$trace_level" ]] && setTraceLevel
  457. main () {
  458. execRunner "$java_cmd" \
  459. "${extra_jvm_opts[@]}" \
  460. "${java_args[@]}" \
  461. -jar "$sbt_jar" \
  462. "${sbt_commands[@]}" \
  463. "${residual_args[@]}"
  464. }
  465. # sbt inserts this string on certain lines when formatting is enabled:
  466. # val OverwriteLine = "\r\u001BM\u001B[2K"
  467. # ...in order not to spam the console with a million "Resolving" lines.
  468. # Unfortunately that makes it that much harder to work with when
  469. # we're not going to print those lines anyway. We strip that bit of
  470. # line noise, but leave the other codes to preserve color.
  471. mainFiltered () {
  472. local -r excludeRegex=$(grep -E -v '^#|^$' ~/.sbtignore | paste -sd'|' -)
  473. echoLine () {
  474. local -r line="$1"
  475. local -r line1="${line//\r\x1BM\x1B\[2K//g}" # This strips the OverwriteLine code.
  476. local -r line2="${line1//\x1B\[[0-9;]*[JKmsu]//g}" # This strips all codes - we test regexes against this.
  477. if [[ $line2 =~ $excludeRegex ]]; then
  478. [[ -n $debugUs ]] && echo "[X] $line1"
  479. else
  480. [[ -n $debugUs ]] && echo " $line1" || echo "$line1"
  481. fi
  482. }
  483. echoLine "Starting sbt with output filtering enabled."
  484. main | while read -r line; do echoLine "$line"; done
  485. }
  486. # Only filter if there's a filter file and we don't see a known interactive command.
  487. # Obviously this is super ad hoc but I don't know how to improve on it. Testing whether
  488. # stdin is a terminal is useless because most of my use cases for this filtering are
  489. # exactly when I'm at a terminal, running sbt non-interactively.
  490. shouldFilter () { [[ -f ~/.sbtignore ]] && ! grep -E -q '\b(shell|console|consoleProject)\b' <<<"${residual_args[@]}"; }
  491. # run sbt
  492. if shouldFilter; then mainFiltered; else main; fi