diff --git a/.gitignore b/.gitignore index dbc46e5..58630d8 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ target/* # TODO there are some useful things here .idea + +# Build tools +sbt/ diff --git a/build.sbt b/build.sbt index d451d90..f255169 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,11 @@ lazy val root = (project in file(".")) "com.zaxxer" % "HikariCP" % "6.2.1", // why only hte single percent? idk "com.h2database" % "h2" % "2.2.224", - "ch.qos.logback" % "logback-classic" % "1.5.6" + "ch.qos.logback" % "logback-classic" % "1.5.6", + // OpenTelemetry dependencies + "io.opentelemetry" % "opentelemetry-sdk" % "1.34.1", + "io.opentelemetry" % "opentelemetry-exporter-otlp" % "1.34.1", + "io.opentelemetry.instrumentation" % "opentelemetry-logback-appender-1.0" % "1.32.0-alpha" ), mainClass := Some("dev.whalenet.leaf_lab.Main"), // needed to avoid merge conflicts when assembling diff --git a/sbt/LICENSE b/sbt/LICENSE new file mode 100644 index 0000000..5c4a3cf --- /dev/null +++ b/sbt/LICENSE @@ -0,0 +1,204 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2023, Scala Center + Copyright (c) 2011 - 2022, Lightbend, Inc. + Copyright (c) 2008 - 2010, Mark Harrah + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/sbt/NOTICE b/sbt/NOTICE new file mode 100644 index 0000000..98799ed --- /dev/null +++ b/sbt/NOTICE @@ -0,0 +1,46 @@ +sbt +https://www.scala-sbt.org/ +Copyright 2023, Scala center +Copyright 2011 - 2022, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under Apache v2 license (see LICENSE) + +Portions based on code from the Scala compiler. Portions of the Scala +library are distributed with the launcher. +Copyright 2002-2008 EPFL, Lausanne + +JLine is distributed with the launcher. +It is licensed under a BSD-style license + +Portions based on code from sbt launcher script +Copyright 2011 - 2012, Paul Phillips, and other contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Apache Ivy, licensed under the Apache License, Version 2.0 + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + +Portions of Ivy were originally developed by +Jayasoft SARL (http://www.jayasoft.fr/) +and are licensed to the Apache Software Foundation under the +"Software Grant License Agreement" + +THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sbt/bin/sbt b/sbt/bin/sbt new file mode 100755 index 0000000..52c699c --- /dev/null +++ b/sbt/bin/sbt @@ -0,0 +1,818 @@ +#!/usr/bin/env bash + +set +e +declare builtin_sbt_version="1.9.7" +declare -a residual_args +declare -a java_args +declare -a scalac_args +declare -a sbt_commands +declare -a sbt_options +declare -a print_version +declare -a print_sbt_version +declare -a print_sbt_script_version +declare -a shutdownall +declare -a original_args +declare java_cmd=java +declare java_version +declare init_sbt_version=1.9.7 +declare sbt_default_mem=1024 +declare -r default_sbt_opts="" +declare -r default_java_opts="-Dfile.encoding=UTF-8" +declare sbt_verbose= +declare sbt_debug= +declare build_props_sbt_version= +declare use_sbtn= +declare no_server= +declare sbtn_command="$SBTN_CMD" +declare sbtn_version="1.9.0" + +### ------------------------------- ### +### Helper methods for BASH scripts ### +### ------------------------------- ### + +# Bash reimplementation of realpath to return the absolute path +realpathish () { +( + TARGET_FILE="$1" + FIX_CYGPATH="$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 + + TARGET_DIR="$(pwd -P)" + if [ "$TARGET_DIR" == "/" ]; then + TARGET_FILE="/$TARGET_FILE" + else + TARGET_FILE="$TARGET_DIR/$TARGET_FILE" + fi + + # make sure we grab the actual windows path, instead of cygwin's path. + if [[ "x$FIX_CYGPATH" != "x" ]]; then + echo "$(cygwinpath "$TARGET_FILE")" + else + echo "$TARGET_FILE" + fi +) +} + +# Uses uname to detect if we're in the odd cygwin environment. +is_cygwin() { + local os=$(uname -s) + case "$os" in + CYGWIN*) return 0 ;; + MINGW*) return 0 ;; + MSYS*) return 0 ;; + *) return 1 ;; + esac +} + +# TODO - Use nicer bash-isms here. +CYGWIN_FLAG=$(if is_cygwin; then echo true; else echo false; fi) + +# This can fix cygwin style /cygdrive paths so we get the +# windows style paths. +cygwinpath() { + local file="$1" + if [[ "$CYGWIN_FLAG" == "true" ]]; then #" + echo $(cygpath -w $file) + else + echo $file + fi +} + + +declare -r sbt_bin_dir="$(dirname "$(realpathish "$0")")" +declare -r sbt_home="$(dirname "$sbt_bin_dir")" + +echoerr () { + echo 1>&2 "$@" +} +vlog () { + [[ $sbt_verbose || $sbt_debug ]] && echoerr "$@" +} +dlog () { + [[ $sbt_debug ]] && echoerr "$@" +} + +jar_file () { + echo "$(cygwinpath "${sbt_home}/bin/sbt-launch.jar")" +} + +jar_url () { + local repo_base="$SBT_LAUNCH_REPO" + if [[ $repo_base == "" ]]; then + repo_base="https://repo1.maven.org/maven2" + fi + echo "$repo_base/org/scala-sbt/sbt-launch/$1/sbt-launch-$1.jar" +} + +download_url () { + local url="$1" + local jar="$2" + mkdir -p $(dirname "$jar") && { + if command -v curl > /dev/null; then + curl --silent -L "$url" --output "$jar" + elif command -v wget > /dev/null; then + wget --quiet -O "$jar" "$url" + fi + } && [[ -f "$jar" ]] +} + +acquire_sbt_jar () { + local launcher_sv="$1" + if [[ "$launcher_sv" == "" ]]; then + if [[ "$init_sbt_version" != "_to_be_replaced" ]]; then + launcher_sv="$init_sbt_version" + else + launcher_sv="$builtin_sbt_version" + fi + fi + local user_home && user_home=$(findProperty user.home) + download_jar="${user_home:-$HOME}/.cache/sbt/boot/sbt-launch/$launcher_sv/sbt-launch-$launcher_sv.jar" + if [[ -f "$download_jar" ]]; then + sbt_jar="$download_jar" + else + sbt_url=$(jar_url "$launcher_sv") + echoerr "downloading sbt launcher $launcher_sv" + download_url "$sbt_url" "${download_jar}.temp" + download_url "${sbt_url}.sha1" "${download_jar}.sha1" + if command -v shasum > /dev/null; then + if echo "$(cat "${download_jar}.sha1") ${download_jar}.temp" | shasum -c - > /dev/null; then + mv "${download_jar}.temp" "${download_jar}" + else + echoerr "failed to download launcher jar: $sbt_url (shasum mismatch)" + exit 2 + fi + else + mv "${download_jar}.temp" "${download_jar}" + fi + if [[ -f "$download_jar" ]]; then + sbt_jar="$download_jar" + else + echoerr "failed to download launcher jar: $sbt_url" + exit 2 + fi + fi +} + +acquire_sbtn () { + local sbtn_v="$1" + local user_home && user_home=$(findProperty user.home) + local p="${user_home:-$HOME}/.cache/sbt/boot/sbtn/$sbtn_v" + local target="$p/sbtn" + local archive_target= + local url= + local arch="x86_64" + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + arch=$(uname -m) + if [[ "$arch" == "aarch64" ]] || [[ "$arch" == "x86_64" ]]; then + archive_target="$p/sbtn-${arch}-pc-linux-${sbtn_v}.tar.gz" + url="https://github.com/sbt/sbtn-dist/releases/download/v${sbtn_v}/sbtn-${arch}-pc-linux-${sbtn_v}.tar.gz" + else + echoerr "sbtn is not supported on $arch" + exit 2 + fi + elif [[ "$OSTYPE" == "darwin"* ]]; then + archive_target="$p/sbtn-x86_64-apple-darwin-${sbtn_v}.tar.gz" + url="https://github.com/sbt/sbtn-dist/releases/download/v${sbtn_v}/sbtn-x86_64-apple-darwin-${sbtn_v}.tar.gz" + elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then + target="$p/sbtn.exe" + archive_target="$p/sbtn-x86_64-pc-win32-${sbtn_v}.zip" + url="https://github.com/sbt/sbtn-dist/releases/download/v${sbtn_v}/sbtn-x86_64-pc-win32-${sbtn_v}.zip" + else + echoerr "sbtn is not supported on $OSTYPE" + exit 2 + fi + + if [[ -f "$target" ]]; then + sbtn_command="$target" + else + echoerr "downloading sbtn ${sbtn_v} for ${arch}" + download_url "$url" "$archive_target" + if [[ "$OSTYPE" == "linux-gnu"* ]] || [[ "$OSTYPE" == "darwin"* ]]; then + tar zxf "$archive_target" --directory "$p" + else + unzip "$archive_target" -d "$p" + fi + sbtn_command="$target" + fi +} + +# execRunner should be called only once to give up control to java +execRunner () { + # print the arguments one to a line, quoting any containing spaces + [[ $sbt_verbose || $sbt_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 "" + } + + if [[ "$CYGWIN_FLAG" == "true" ]]; then + # In cygwin we loose the ability to re-hook stty if exec is used + # https://github.com/sbt/sbt-launcher-package/issues/53 + "$@" + else + exec "$@" + fi +} + +addJava () { + dlog "[addJava] arg = '$1'" + java_args=( "${java_args[@]}" "$1" ) +} +addSbt () { + dlog "[addSbt] arg = '$1'" + sbt_commands=( "${sbt_commands[@]}" "$1" ) +} +addResidual () { + dlog "[residual] arg = '$1'" + residual_args=( "${residual_args[@]}" "$1" ) +} +addDebugger () { + addJava "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$1" +} + +addMemory () { + dlog "[addMemory] arg = '$1'" + # evict memory related options + local xs=("${java_args[@]}") + java_args=() + for i in "${xs[@]}"; do + if ! [[ "${i}" == *-Xmx* ]] && ! [[ "${i}" == *-Xms* ]] && ! [[ "${i}" == *-Xss* ]] && ! [[ "${i}" == *-XX:MaxPermSize* ]] && ! [[ "${i}" == *-XX:MaxMetaspaceSize* ]] && ! [[ "${i}" == *-XX:ReservedCodeCacheSize* ]]; then + java_args+=("${i}") + fi + done + local ys=("${sbt_options[@]}") + sbt_options=() + for i in "${ys[@]}"; do + if ! [[ "${i}" == *-Xmx* ]] && ! [[ "${i}" == *-Xms* ]] && ! [[ "${i}" == *-Xss* ]] && ! [[ "${i}" == *-XX:MaxPermSize* ]] && ! [[ "${i}" == *-XX:MaxMetaspaceSize* ]] && ! [[ "${i}" == *-XX:ReservedCodeCacheSize* ]]; then + sbt_options+=("${i}") + fi + done + # a ham-fisted attempt to move some memory settings in concert + local mem=$1 + local codecache=$(( $mem / 8 )) + (( $codecache > 128 )) || codecache=128 + (( $codecache < 512 )) || codecache=512 + local class_metadata_size=$(( $codecache * 2 )) + if [[ -z $java_version ]]; then + java_version=$(jdk_version) + fi + + addJava "-Xms${mem}m" + addJava "-Xmx${mem}m" + addJava "-Xss4M" + addJava "-XX:ReservedCodeCacheSize=${codecache}m" + (( $java_version >= 8 )) || addJava "-XX:MaxPermSize=${class_metadata_size}m" +} + +addDefaultMemory() { + # if we detect any of these settings in ${JAVA_OPTS} or ${JAVA_TOOL_OPTIONS} we need to NOT output our settings. + # The reason is the Xms/Xmx, if they don't line up, cause errors. + if [[ "${java_args[@]}" == *-Xmx* ]] || \ + [[ "${java_args[@]}" == *-Xms* ]] || \ + [[ "${java_args[@]}" == *-Xss* ]] || \ + [[ "${java_args[@]}" == *-XX:+UseCGroupMemoryLimitForHeap* ]] || \ + [[ "${java_args[@]}" == *-XX:MaxRAM* ]] || \ + [[ "${java_args[@]}" == *-XX:InitialRAMPercentage* ]] || \ + [[ "${java_args[@]}" == *-XX:MaxRAMPercentage* ]] || \ + [[ "${java_args[@]}" == *-XX:MinRAMPercentage* ]]; then + : + elif [[ "${JAVA_TOOL_OPTIONS}" == *-Xmx* ]] || \ + [[ "${JAVA_TOOL_OPTIONS}" == *-Xms* ]] || \ + [[ "${JAVA_TOOL_OPTIONS}" == *-Xss* ]] || \ + [[ "${JAVA_TOOL_OPTIONS}" == *-XX:+UseCGroupMemoryLimitForHeap* ]] || \ + [[ "${JAVA_TOOL_OPTIONS}" == *-XX:MaxRAM* ]] || \ + [[ "${JAVA_TOOL_OPTIONS}" == *-XX:InitialRAMPercentage* ]] || \ + [[ "${JAVA_TOOL_OPTIONS}" == *-XX:MaxRAMPercentage* ]] || \ + [[ "${JAVA_TOOL_OPTIONS}" == *-XX:MinRAMPercentage* ]] ; then + : + elif [[ "${sbt_options[@]}" == *-Xmx* ]] || \ + [[ "${sbt_options[@]}" == *-Xms* ]] || \ + [[ "${sbt_options[@]}" == *-Xss* ]] || \ + [[ "${sbt_options[@]}" == *-XX:+UseCGroupMemoryLimitForHeap* ]] || \ + [[ "${sbt_options[@]}" == *-XX:MaxRAM* ]] || \ + [[ "${sbt_options[@]}" == *-XX:InitialRAMPercentage* ]] || \ + [[ "${sbt_options[@]}" == *-XX:MaxRAMPercentage* ]] || \ + [[ "${sbt_options[@]}" == *-XX:MinRAMPercentage* ]] ; then + : + else + addMemory $sbt_default_mem + fi +} + +addSbtScriptProperty () { + if [[ "${java_args[@]}" == *-Dsbt.script=* ]]; then + : + else + sbt_script=$0 + # Use // to replace all spaces with %20. + sbt_script=${sbt_script// /%20} + addJava "-Dsbt.script=$sbt_script" + fi +} + +require_arg () { + local type="$1" + local opt="$2" + local arg="$3" + if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then + echo "$opt requires <$type> argument" + exit 1 + fi +} + +is_function_defined() { + declare -f "$1" > /dev/null +} + +# parses JDK version from the -version output line. +# 8 for 1.8.0_nn, 9 for 9-ea etc, and "no_java" for undetected +jdk_version() { + local result + local lines=$("$java_cmd" -Xms32M -Xmx32M -version 2>&1 | tr '\r' '\n') + local IFS=$'\n' + for line in $lines; do + if [[ (-z $result) && ($line = *"version \""*) ]] + then + local ver=$(echo $line | sed -e 's/.*version "\(.*\)"\(.*\)/\1/; 1q') + # on macOS sed doesn't support '?' + if [[ $ver = "1."* ]] + then + result=$(echo $ver | sed -e 's/1\.\([0-9]*\)\(.*\)/\1/; 1q') + else + result=$(echo $ver | sed -e 's/\([0-9]*\)\(.*\)/\1/; 1q') + fi + fi + done + if [[ -z $result ]] + then + result=no_java + fi + echo "$result" +} + +# Find the first occurrence of the given property name and returns its value by looking at: +# - properties set by command-line options, +# - JAVA_OPTS environment variable, +# - SBT_OPTS environment variable, +# - _JAVA_OPTIONS environment variable and +# - JAVA_TOOL_OPTIONS environment variable +# in that order. +findProperty() { + local -a java_opts_array + local -a sbt_opts_array + local -a _java_options_array + local -a java_tool_options_array + read -a java_opts_array <<< "$JAVA_OPTS" + read -a sbt_opts_array <<< "$SBT_OPTS" + read -a _java_options_array <<< "$_JAVA_OPTIONS" + read -a java_tool_options_array <<< "$JAVA_TOOL_OPTIONS" + + local args_to_check=( + "${java_args[@]}" + "${java_opts_array[@]}" + "${sbt_opts_array[@]}" + "${_java_options_array[@]}" + "${java_tool_options_array[@]}") + + for opt in "${args_to_check[@]}"; do + if [[ "$opt" == -D$1=* ]]; then + echo "${opt#-D$1=}" + return + fi + done +} + +# Extracts the preloaded directory from either -Dsbt.preloaded, -Dsbt.global.base or -Duser.home +# in that order. +getPreloaded() { + local preloaded && preloaded=$(findProperty sbt.preloaded) + [ "$preloaded" ] && echo "$preloaded" && return + + local global_base && global_base=$(findProperty sbt.global.base) + [ "$global_base" ] && echo "$global_base/preloaded" && return + + local user_home && user_home=$(findProperty user.home) + echo "${user_home:-$HOME}/.sbt/preloaded" +} + +syncPreloaded() { + local source_preloaded="$sbt_home/lib/local-preloaded/" + local target_preloaded="$(getPreloaded)" + if [[ "$init_sbt_version" == "" ]]; then + # FIXME: better $init_sbt_version detection + init_sbt_version="$(ls -1 "$source_preloaded/org/scala-sbt/sbt/")" + fi + [[ -f "$target_preloaded/org/scala-sbt/sbt/$init_sbt_version/" ]] || { + # lib/local-preloaded exists (This is optional) + [[ -d "$source_preloaded" ]] && { + command -v rsync >/dev/null 2>&1 && { + mkdir -p "$target_preloaded" + rsync --recursive --links --perms --times --ignore-existing "$source_preloaded" "$target_preloaded" || true + } + } + } +} + +# Detect that we have java installed. +checkJava() { + local required_version="$1" + # Now check to see if it's a good enough version + local good_enough="$(expr $java_version ">=" $required_version)" + if [[ "$java_version" == "" ]]; then + echo + echo "No Java Development Kit (JDK) installation was detected." + echo Please go to http://www.oracle.com/technetwork/java/javase/downloads/ and download. + echo + exit 1 + elif [[ "$good_enough" != "1" ]]; then + echo + echo "The Java Development Kit (JDK) installation you have is not up to date." + echo $script_name requires at least version $required_version+, you have + echo version $java_version + echo + echo Please go to http://www.oracle.com/technetwork/java/javase/downloads/ and download + echo a valid JDK and install before running $script_name. + echo + exit 1 + fi +} + +copyRt() { + local at_least_9="$(expr $java_version ">=" 9)" + if [[ "$at_least_9" == "1" ]]; then + # The grep for java9-rt-ext- matches the filename prefix printed in Export.java + java9_ext=$("$java_cmd" "${sbt_options[@]}" "${java_args[@]}" \ + -jar "$sbt_jar" --rt-ext-dir | grep java9-rt-ext- | tr -d '\r') + java9_rt=$(echo "$java9_ext/rt.jar") + vlog "[copyRt] java9_rt = '$java9_rt'" + if [[ ! -f "$java9_rt" ]]; then + echo copying runtime jar... + mkdir -p "$java9_ext" + "$java_cmd" \ + "${sbt_options[@]}" \ + "${java_args[@]}" \ + -jar "$sbt_jar" \ + --export-rt \ + "${java9_rt}" + fi + addJava "-Dscala.ext.dirs=${java9_ext}" + fi +} + +run() { + # Copy preloaded repo to user's preloaded directory + syncPreloaded + + # no jar? download it. + [[ -f "$sbt_jar" ]] || acquire_sbt_jar "$sbt_version" || { + exit 1 + } + + # TODO - java check should be configurable... + checkJava "6" + + # Java 9 support + copyRt + + # If we're in cygwin, we should use the windows config, and terminal hacks + if [[ "$CYGWIN_FLAG" == "true" ]]; then #" + stty -icanon min 1 -echo > /dev/null 2>&1 + addJava "-Djline.terminal=jline.UnixTerminal" + addJava "-Dsbt.cygwin=true" + fi + + if [[ $print_sbt_version ]]; then + execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]//g' + elif [[ $print_sbt_script_version ]]; then + echo "$init_sbt_version" + elif [[ $print_version ]]; then + execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]/sbt version in this project:/g' + echo "sbt script version: $init_sbt_version" + elif [[ $shutdownall ]]; then + local sbt_processes=( $(jps -v | grep sbt-launch | cut -f1 -d ' ') ) + for procId in "${sbt_processes[@]}"; do + kill -9 $procId + done + echo "shutdown ${#sbt_processes[@]} sbt processes" + else + # run sbt + execRunner "$java_cmd" \ + "${java_args[@]}" \ + "${sbt_options[@]}" \ + "${java_tool_options[@]}" \ + -jar "$sbt_jar" \ + "${sbt_commands[@]}" \ + "${residual_args[@]}" + fi + + exit_code=$? + + # Clean up the terminal from cygwin hacks. + if [[ "$CYGWIN_FLAG" == "true" ]]; then #" + stty icanon echo > /dev/null 2>&1 + fi + exit $exit_code +} + +declare -ra noshare_opts=(-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy) +declare -r sbt_opts_file=".sbtopts" +declare -r build_props_file="$(pwd)/project/build.properties" +declare -r etc_sbt_opts_file="/etc/sbt/sbtopts" +# this allows /etc/sbt/sbtopts location to be changed +declare -r etc_file="${SBT_ETC_FILE:-$etc_sbt_opts_file}" +declare -r dist_sbt_opts_file="${sbt_home}/conf/sbtopts" +declare -r win_sbt_opts_file="${sbt_home}/conf/sbtconfig.txt" +declare sbt_jar="$(jar_file)" + +usage() { + cat < path to global settings/plugins directory (default: ~/.sbt) + --sbt-boot path to shared boot directory (default: ~/.sbt/boot in 0.11 series) + --sbt-cache path to global cache directory (default: operating system specific) + --ivy path to local Ivy repository (default: ~/.ivy2) + --mem set memory options (default: $sbt_default_mem) + --no-share use all local caches; no sharing + --no-global uses global caches, but does not use global ~/.sbt directory. + --jvm-debug Turn on JVM debugging, open at the given port. + --batch disable interactive mode + + # sbt version (default: from project/build.properties if present, else latest release) + --sbt-version use the specified version of sbt + --sbt-jar use the specified jar as the sbt launcher + + --java-home alternate JAVA_HOME + + # jvm options and output control + JAVA_OPTS environment variable, if unset uses "$default_java_opts" + .jvmopts if this file exists in the current directory, its contents + are appended to JAVA_OPTS + SBT_OPTS environment variable, if unset uses "$default_sbt_opts" + .sbtopts if this file exists in the current directory, its contents + are prepended to the runner args + /etc/sbt/sbtopts if this file exists, it is prepended to the runner args + -Dkey=val pass -Dkey=val directly to the java runtime + -J-X pass option -X directly to the java runtime + (-J is stripped) + +In the case of duplicated or conflicting options, the order above +shows precedence: JAVA_OPTS lowest, command line options highest. +EOM +} + +process_my_args () { + while [[ $# -gt 0 ]]; do + case "$1" in + -batch|--batch) exec + + -sbt-create|--sbt-create) sbt_create=true && shift ;; + + new) sbt_new=true && addResidual "$1" && shift ;; + + *) addResidual "$1" && shift ;; + esac + done + + # Now, ensure sbt version is used. + [[ "${sbt_version}XXX" != "XXX" ]] && addJava "-Dsbt.version=$sbt_version" + + # Confirm a user's intent if the current directory does not look like an sbt + # top-level directory and neither the -sbt-create option nor the "new" + # command was given. + [[ -f ./build.sbt || -d ./project || -n "$sbt_create" || -n "$sbt_new" ]] || { + echo "[warn] Neither build.sbt nor a 'project' directory in the current directory: $(pwd)" + while true; do + echo 'c) continue' + echo 'q) quit' + + read -p '? ' || exit 1 + case "$REPLY" in + c|C) break ;; + q|Q) exit 1 ;; + esac + done + } +} + +## map over argument array. this is used to process both command line arguments and SBT_OPTS +map_args () { + local options=() + local commands=() + while [[ $# -gt 0 ]]; do + case "$1" in + -no-colors|--no-colors) options=( "${options[@]}" "-Dsbt.log.noformat=true" ) && shift ;; + -timings|--timings) options=( "${options[@]}" "-Dsbt.task.timings=true" "-Dsbt.task.timings.on.shutdown=true" ) && shift ;; + -traces|--traces) options=( "${options[@]}" "-Dsbt.traces=true" ) && shift ;; + --supershell=*) options=( "${options[@]}" "-Dsbt.supershell=${1:13}" ) && shift ;; + -supershell=*) options=( "${options[@]}" "-Dsbt.supershell=${1:12}" ) && shift ;; + -no-server|--no-server) options=( "${options[@]}" "-Dsbt.io.virtual=false" "-Dsbt.server.autostart=false" ) && shift ;; + --color=*) options=( "${options[@]}" "-Dsbt.color=${1:8}" ) && shift ;; + -color=*) options=( "${options[@]}" "-Dsbt.color=${1:7}" ) && shift ;; + -no-share|--no-share) options=( "${options[@]}" "${noshare_opts[@]}" ) && shift ;; + -no-global|--no-global) options=( "${options[@]}" "-Dsbt.global.base=$(pwd)/project/.sbtboot" ) && shift ;; + -ivy|--ivy) require_arg path "$1" "$2" && options=( "${options[@]}" "-Dsbt.ivy.home=$2" ) && shift 2 ;; + -sbt-boot|--sbt-boot) require_arg path "$1" "$2" && options=( "${options[@]}" "-Dsbt.boot.directory=$2" ) && shift 2 ;; + -sbt-dir|--sbt-dir) require_arg path "$1" "$2" && options=( "${options[@]}" "-Dsbt.global.base=$2" ) && shift 2 ;; + -debug|--debug) commands=( "${commands[@]}" "-debug" ) && shift ;; + -debug-inc|--debug-inc) options=( "${options[@]}" "-Dxsbt.inc.debug=true" ) && shift ;; + *) options=( "${options[@]}" "$1" ) && shift ;; + esac + done + declare -p options + declare -p commands +} + +process_args () { + while [[ $# -gt 0 ]]; do + case "$1" in + -h|-help|--help) usage; exit 1 ;; + -v|-verbose|--verbose) sbt_verbose=1 && shift ;; + -V|-version|--version) print_version=1 && shift ;; + --numeric-version) print_sbt_version=1 && shift ;; + --script-version) print_sbt_script_version=1 && shift ;; + shutdownall) shutdownall=1 && shift ;; + -d|-debug|--debug) sbt_debug=1 && addSbt "-debug" && shift ;; + -client|--client) use_sbtn=1 && shift ;; + --server) use_sbtn=0 && shift ;; + + -mem|--mem) require_arg integer "$1" "$2" && addMemory "$2" && shift 2 ;; + -jvm-debug|--jvm-debug) require_arg port "$1" "$2" && addDebugger $2 && shift 2 ;; + -batch|--batch) exec = 2 )) || ( (( $sbtBinaryV_1 >= 1 )) && (( $sbtBinaryV_2 >= 4 )) ); then + if [[ "$use_sbtn" == "1" ]]; then + echo "true" + else + echo "false" + fi + else + echo "false" + fi +} + +runNativeClient() { + vlog "[debug] running native client" + detectNativeClient + [[ -f "$sbtn_command" ]] || acquire_sbtn "$sbtn_version" || { + exit 1 + } + for i in "${!original_args[@]}"; do + if [[ "${original_args[i]}" = "--client" ]]; then + unset 'original_args[i]' + fi + done + sbt_script=$0 + sbt_script=${sbt_script/ /%20} + execRunner "$sbtn_command" "--sbt-script=$sbt_script" "${original_args[@]}" +} + +original_args=("$@") + +# Here we pull in the default settings configuration. +[[ -f "$dist_sbt_opts_file" ]] && set -- $(loadConfigFile "$dist_sbt_opts_file") "$@" + +# Here we pull in the global settings configuration. +[[ -f "$etc_file" ]] && set -- $(loadConfigFile "$etc_file") "$@" + +# Pull in the project-level config file, if it exists. +[[ -f "$sbt_opts_file" ]] && set -- $(loadConfigFile "$sbt_opts_file") "$@" + +# Pull in the project-level java config, if it exists. +[[ -f ".jvmopts" ]] && export JAVA_OPTS="$JAVA_OPTS $(loadConfigFile .jvmopts)" + +# Pull in default JAVA_OPTS +[[ -z "${JAVA_OPTS// }" ]] && export JAVA_OPTS="$default_java_opts" + +[[ -f "$build_props_file" ]] && loadPropFile "$build_props_file" + +java_args=($JAVA_OPTS) +sbt_options0=(${SBT_OPTS:-$default_sbt_opts}) +java_tool_options=($JAVA_TOOL_OPTIONS) +if [[ "$SBT_NATIVE_CLIENT" == "true" ]]; then + use_sbtn=1 +fi + +# Split SBT_OPTS into options/commands +miniscript=$(map_args "${sbt_options0[@]}") && eval "${miniscript/options/sbt_options}" && \ +eval "${miniscript/commands/sbt_additional_commands}" + +# Combine command line options/commands and commands from SBT_OPTS +miniscript=$(map_args "$@") && eval "${miniscript/options/cli_options}" && eval "${miniscript/commands/cli_commands}" +args1=( "${cli_options[@]}" "${cli_commands[@]}" "${sbt_additional_commands[@]}" ) + +# process the combined args, then reset "$@" to the residuals +process_args "${args1[@]}" +vlog "[sbt_options] $(declare -p sbt_options)" + +if [[ "$(isRunNativeClient)" == "true" ]]; then + set -- "${residual_args[@]}" + argumentCount=$# + runNativeClient +else + java_version="$(jdk_version)" + vlog "[process_args] java_version = '$java_version'" + addDefaultMemory + addSbtScriptProperty + set -- "${residual_args[@]}" + argumentCount=$# + run +fi diff --git a/sbt/bin/sbt-launch.jar b/sbt/bin/sbt-launch.jar new file mode 100755 index 0000000..cb33a10 Binary files /dev/null and b/sbt/bin/sbt-launch.jar differ diff --git a/sbt/bin/sbt.bat b/sbt/bin/sbt.bat new file mode 100755 index 0000000..b76ce9d --- /dev/null +++ b/sbt/bin/sbt.bat @@ -0,0 +1,1036 @@ +@REM SBT launcher script +@REM +@REM Environment: +@REM JAVA_HOME - location of a JDK home dir (mandatory) +@REM SBT_OPTS - JVM options (optional) +@REM Configuration: +@REM sbtconfig.txt found in the SBT_HOME. + +@REM ZOMG! We need delayed expansion to build up CFG_OPTS later +@setlocal enabledelayedexpansion + +@echo off +set SBT_BIN_DIR=%~dp0 +if not defined SBT_HOME for %%I in ("!SBT_BIN_DIR!\..") do set "SBT_HOME=%%~fI" + +set SBT_ARGS= +set _JAVACMD= +set _SBT_OPTS= +set _JAVA_OPTS= + +set init_sbt_version=1.9.7 +set sbt_default_mem=1024 +set default_sbt_opts= +set default_java_opts=-Dfile.encoding=UTF-8 +set sbt_jar= +set build_props_sbt_version= +set run_native_client= +set shutdownall= + +set sbt_args_print_version= +set sbt_args_print_sbt_version= +set sbt_args_print_sbt_script_version= +set sbt_args_verbose= +set sbt_args_debug= +set sbt_args_debug_inc= +set sbt_args_batch= +set sbt_args_color= +set sbt_args_no_colors= +set sbt_args_no_global= +set sbt_args_no_share= +set sbt_args_sbt_jar= +set sbt_args_ivy= +set sbt_args_supershell= +set sbt_args_timings= +set sbt_args_traces= +set sbt_args_sbt_boot= +set sbt_args_sbt_cache= +set sbt_args_sbt_create= +set sbt_args_sbt_dir= +set sbt_args_sbt_version= +set sbt_args_mem= +set sbt_args_client= +set sbt_args_no_server= + +rem users can set SBT_OPTS via .sbtopts +if exist .sbtopts for /F %%A in (.sbtopts) do ( + set _sbtopts_line=%%A + if not "!_sbtopts_line:~0,1!" == "#" ( + if "!_sbtopts_line:~0,2!" == "-J" ( + set _sbtopts_line=!_sbtopts_line:~2,1000! + ) + if defined _SBT_OPTS ( + set _SBT_OPTS=!_SBT_OPTS! !_sbtopts_line! + ) else ( + set _SBT_OPTS=!_sbtopts_line! + ) + ) +) + +rem TODO: remove/deprecate sbtconfig.txt and parse the sbtopts files + +rem FIRST we load the config file of extra options. +set SBT_CONFIG=!SBT_HOME!\conf\sbtconfig.txt +set SBT_CFG_OPTS= +for /F "tokens=* eol=# usebackq delims=" %%i in ("!SBT_CONFIG!") do ( + set DO_NOT_REUSE_ME=%%i + rem ZOMG (Part #2) WE use !! here to delay the expansion of + rem SBT_CFG_OPTS, otherwise it remains "" for this loop. + set SBT_CFG_OPTS=!SBT_CFG_OPTS! !DO_NOT_REUSE_ME! +) + +rem poor man's jenv (which is not available on Windows) +if defined JAVA_HOMES ( + if exist .java-version for /F %%A in (.java-version) do ( + set JAVA_HOME=%JAVA_HOMES%\%%A + set JDK_HOME=%JAVA_HOMES%\%%A + ) +) + +if exist "project\build.properties" ( + for /F "eol=# delims== tokens=1*" %%a in (project\build.properties) do ( + if "%%a" == "sbt.version" if not "%%b" == "" ( + set build_props_sbt_version=%%b + ) + ) +) + +rem must set PATH or wrong javac is used for java projects +if defined JAVA_HOME set "PATH=%JAVA_HOME%\bin;%PATH%" + +rem We use the value of the JAVACMD environment variable if defined +if defined JAVACMD set "_JAVACMD=%JAVACMD%" + +rem remove quotes +if defined _JAVACMD set _JAVACMD=!_JAVACMD:"=! + +if not defined _JAVACMD ( + if not "%JAVA_HOME%" == "" ( + if exist "%JAVA_HOME%\bin\java.exe" set "_JAVACMD=%JAVA_HOME%\bin\java.exe" + ) +) + +if not defined _JAVACMD set _JAVACMD=java + +rem We use the value of the JAVA_OPTS environment variable if defined, rather than the config. +if not defined _JAVA_OPTS if defined JAVA_OPTS set _JAVA_OPTS=%JAVA_OPTS% + +rem users can set JAVA_OPTS via .jvmopts (sbt-extras style) +if exist .jvmopts for /F %%A in (.jvmopts) do ( + set _jvmopts_line=%%A + if not "!_jvmopts_line:~0,1!" == "#" ( + if defined _JAVA_OPTS ( + set _JAVA_OPTS=!_JAVA_OPTS! %%A + ) else ( + set _JAVA_OPTS=%%A + ) + ) +) + +rem If nothing is defined, use the defaults. +if not defined _JAVA_OPTS if defined default_java_opts set _JAVA_OPTS=!default_java_opts! + +rem We use the value of the SBT_OPTS environment variable if defined, rather than the config. +if not defined _SBT_OPTS if defined SBT_OPTS set _SBT_OPTS=%SBT_OPTS% +if not defined _SBT_OPTS if defined SBT_CFG_OPTS set _SBT_OPTS=!SBT_CFG_OPTS! +if not defined _SBT_OPTS if defined default_sbt_opts set _SBT_OPTS=!default_sbt_opts! + +if defined SBT_NATIVE_CLIENT ( + if "%SBT_NATIVE_CLIENT%" == "true" ( + set sbt_args_client=1 + ) +) + +:args_loop +shift + +if "%~0" == "" goto args_end +set g=%~0 + +rem make sure the sbt_args_debug gets set first incase any argument parsing uses :dlog +if "%~0" == "-d" set _debug_arg=true +if "%~0" == "--debug" set _debug_arg=true + +if defined _debug_arg ( + set _debug_arg= + set sbt_args_debug=1 + set SBT_ARGS=-debug !SBT_ARGS! + goto args_loop +) + +if "%~0" == "-h" goto usage +if "%~0" == "-help" goto usage +if "%~0" == "--help" goto usage + +if "%~0" == "-v" set _verbose_arg=true +if "%~0" == "-verbose" set _verbose_arg=true +if "%~0" == "--verbose" set _verbose_arg=true + +if defined _verbose_arg ( + set _verbose_arg= + set sbt_args_verbose=1 + goto args_loop +) + +if "%~0" == "-V" set _version_arg=true +if "%~0" == "-version" set _version_arg=true +if "%~0" == "--version" set _version_arg=true + +if defined _version_arg ( + set _version_arg= + set sbt_args_print_version=1 + goto args_loop +) + +if "%~0" == "--client" set _client_arg=true + +if defined _client_arg ( + set _client_arg= + set sbt_args_client=1 + goto args_loop +) + +if "%~0" == "-batch" set _batch_arg=true +if "%~0" == "--batch" set _batch_arg=true + +if defined _batch_arg ( + set _batch_arg= + set sbt_args_batch=1 + goto args_loop +) + +if "%~0" == "-no-colors" set _no_colors_arg=true +if "%~0" == "--no-colors" set _no_colors_arg=true + +if defined _no_colors_arg ( + set _no_colors_arg= + set sbt_args_no_colors=1 + goto args_loop +) + +if "%~0" == "-no-server" set _no_server_arg=true +if "%~0" == "--no-server" set _no_server_arg=true + +if defined _no_server_arg ( + set _no_server_arg= + set sbt_args_no_server=1 + goto args_loop +) + +if "%~0" == "-no-global" set _no_global_arg=true +if "%~0" == "--no-global" set _no_global_arg=true + +if defined _no_global_arg ( + set _no_global_arg= + set sbt_args_no_global=1 + goto args_loop +) + +if "%~0" == "-traces" set _traces_arg=true +if "%~0" == "--traces" set _traces_arg=true + +if defined _traces_arg ( + set _traces_arg= + set sbt_args_traces=1 + goto args_loop +) + +if "%~0" == "-sbt-create" set _sbt_create_arg=true +if "%~0" == "--sbt-create" set _sbt_create_arg=true + +if defined _sbt_create_arg ( + set _sbt_create_arg= + set sbt_args_sbt_create=1 + goto args_loop +) + +if "%~0" == "-sbt-dir" set _sbt_dir_arg=true +if "%~0" == "--sbt-dir" set _sbt_dir_arg=true + +if defined _sbt_dir_arg ( + set _sbt_dir_arg= + if not "%~1" == "" ( + set sbt_args_sbt_dir=%1 + shift + goto args_loop + ) else ( + echo "%~0" is missing a value + goto error + ) +) + +if "%~0" == "-sbt-boot" set _sbt_boot_arg=true +if "%~0" == "--sbt-boot" set _sbt_boot_arg=true + +if defined _sbt_boot_arg ( + set _sbt_boot_arg= + if not "%~1" == "" ( + set sbt_args_sbt_boot=%1 + shift + goto args_loop + ) else ( + echo "%~0" is missing a value + goto error + ) +) + +if "%~0" == "-sbt-cache" set _sbt_cache_arg=true +if "%~0" == "--sbt-cache" set _sbt_cache_arg=true + +if defined _sbt_cache_arg ( + set _sbt_cache_arg= + if not "%~1" == "" ( + set sbt_args_sbt_cache=%1 + shift + goto args_loop + ) else ( + echo "%~0" is missing a value + goto error + ) +) + +if "%~0" == "-sbt-jar" set _sbt_jar=true +if "%~0" == "--sbt-jar" set _sbt_jar=true + +if defined _sbt_jar ( + set _sbt_jar= + if not "%~1" == "" ( + if exist "%~1" ( + set sbt_args_sbt_jar=%1 + shift + goto args_loop + ) else ( + echo %~1 does not exist + goto error + ) + ) else ( + echo "%~0" is missing a value + goto error + ) +) + +if "%~0" == "-ivy" set _sbt_ivy_arg=true +if "%~0" == "--ivy" set _sbt_ivy_arg=true + +if defined _sbt_ivy_arg ( + set _sbt_ivy_arg= + if not "%~1" == "" ( + set sbt_args_ivy=%1 + shift + goto args_loop + ) else ( + echo "%~0" is missing a value + goto error + ) +) + +if "%~0" == "-debug-inc" set _debug_inc_arg=true +if "%~0" == "--debug-inc" set _debug_inc_arg=true + +if defined _debug_inc_arg ( + set _debug_inc_arg= + set sbt_args_debug_inc=1 + goto args_loop +) + +if "%~0" == "--sbt-version" set _sbt_version_arg=true +if "%~0" == "-sbt-version" set _sbt_version_arg=true + +if defined _sbt_version_arg ( + set _sbt_version_arg= + if not "%~1" == "" ( + set sbt_args_sbt_version=%~1 + shift + goto args_loop + ) else ( + echo "%~0" is missing a value + goto error + ) +) + +if "%~0" == "--mem" set _sbt_mem_arg=true +if "%~0" == "-mem" set _sbt_mem_arg=true + +if defined _sbt_mem_arg ( + set _sbt_mem_arg= + if not "%~1" == "" ( + set sbt_args_mem=%~1 + shift + goto args_loop + ) else ( + echo "%~0" is missing a value + goto error + ) +) + +if "%~0" == "--supershell" set _supershell_arg=true +if "%~0" == "-supershell" set _supershell_arg=true + +if defined _supershell_arg ( + set _supershell_arg= + if not "%~1" == "" ( + set sbt_args_supershell=%~1 + shift + goto args_loop + ) else ( + echo "%~0" is missing a value + goto error + ) +) + +if "%~0" == "--color" set _color_arg=true +if "%~0" == "-color" set _color_arg=true + +if defined _color_arg ( + set _color_arg= + if not "%~1" == "" ( + set sbt_args_color=%~1 + shift + goto args_loop + ) else ( + echo "%~0" is missing a value + goto error + ) + goto args_loop +) + +if "%~0" == "--no-share" set _no_share_arg=true +if "%~0" == "-no-share" set _no_share_arg=true + +if defined _no_share_arg ( + set _no_share_arg= + set sbt_args_no_share=1 + goto args_loop +) + +if "%~0" == "--timings" set _timings_arg=true +if "%~0" == "-timings" set _timings_arg=true + +if defined _timings_arg ( + set _timings_arg= + set sbt_args_timings=1 + goto args_loop +) + +if "%~0" == "shutdownall" ( + set shutdownall=1 + goto args_loop +) + +if "%~0" == "--script-version" ( + set sbt_args_print_sbt_script_version=1 + goto args_loop +) + +if "%~0" == "--numeric-version" ( + set sbt_args_print_sbt_version=1 + goto args_loop +) + +if "%~0" == "-jvm-debug" set _jvm_debug_arg=true +if "%~0" == "--jvm-debug" set _jvm_debug_arg=true + +if defined _jvm_debug_arg ( + set _jvm_debug_arg= + if not "%~1" == "" ( + set /a JVM_DEBUG_PORT=%~1 2>nul >nul + if !JVM_DEBUG_PORT! EQU 0 ( + rem next argument wasn't a port, set a default and process next arg + set /A JVM_DEBUG_PORT=5005 + goto args_loop + ) else ( + shift + goto args_loop + ) + ) +) + +if "%~0" == "-java-home" set _java_home_arg=true +if "%~0" == "--java-home" set _java_home_arg=true + +if defined _java_home_arg ( + set _java_home_arg= + if not "%~1" == "" ( + if exist "%~1\bin\java.exe" ( + set "_JAVACMD=%~1\bin\java.exe" + set "JAVA_HOME=%~1" + set "JDK_HOME=%~1" + shift + goto args_loop + ) else ( + echo Directory "%~1" for JAVA_HOME is not valid + goto error + ) + ) else ( + echo Second argument for --java-home missing + goto error + ) +) + +if "%~0" == "new" ( + if not defined SBT_ARGS ( + set sbt_new=true + ) +) + +if "%g:~0,2%" == "-D" ( + rem special handling for -D since '=' gets parsed away + for /F "tokens=1 delims==" %%a in ("%g%") do ( + rem make sure it doesn't have the '=' already + if "%g%" == "%%a" ( + if not "%~1" == "" ( + call :dlog [args_loop] -D argument %~0=%~1 + set "SBT_ARGS=!SBT_ARGS! %~0=%~1" + shift + goto args_loop + ) else ( + echo %g% is missing a value + goto error + ) + ) else ( + call :dlog [args_loop] -D argument %~0 + set "SBT_ARGS=!SBT_ARGS! %~0" + goto args_loop + ) + ) +) + +if not "%g:~0,5%" == "-XX:+" if not "%g:~0,5%" == "-XX:-" if "%g:~0,3%" == "-XX" ( + rem special handling for -XX since '=' gets parsed away + for /F "tokens=1 delims==" %%a in ("%g%") do ( + rem make sure it doesn't have the '=' already + if "%g%" == "%%a" ( + if not "%~1" == "" ( + call :dlog [args_loop] -XX argument %~0=%~1 + set "SBT_ARGS=!SBT_ARGS! %~0=%~1" + shift + goto args_loop + ) else ( + echo %g% is missing a value + goto error + ) + ) else ( + call :dlog [args_loop] -XX argument %~0 + set "SBT_ARGS=!SBT_ARGS! %~0" + goto args_loop + ) + ) +) + +rem the %0 (instead of %~0) preserves original argument quoting +set SBT_ARGS=!SBT_ARGS! %0 + +goto args_loop +:args_end + +rem Confirm a user's intent if the current directory does not look like an sbt +rem top-level directory and the "new" command was not given. + +if not defined sbt_args_sbt_create if not defined sbt_args_print_version if not defined sbt_args_print_sbt_version if not defined sbt_args_print_sbt_script_version if not defined shutdownall if not exist build.sbt ( + if not exist project\ ( + if not defined sbt_new ( + echo [warn] Neither build.sbt nor a 'project' directory in the current directory: "%CD%" + setlocal +:confirm + echo c^) continue + echo q^) quit + + set /P reply=^? + if /I "!reply!" == "c" ( + goto confirm_end + ) else if /I "!reply!" == "q" ( + exit /B 1 + ) + + goto confirm +:confirm_end + endlocal + ) + ) +) + +call :process + +rem avoid bootstrapping/java version check for script version + +if !shutdownall! equ 1 ( + set count=0 + for /f "tokens=1" %%i in ('jps -lv ^| findstr "xsbt.boot.Boot"') do ( + taskkill /F /PID %%i + set /a count=!count!+1 + ) + echo shutdown !count! sbt processes + goto :eof +) + +if !sbt_args_print_sbt_script_version! equ 1 ( + echo !init_sbt_version! + goto :eof +) + +if !run_native_client! equ 1 ( + goto :runnative !SBT_ARGS! + goto :eof +) + +call :checkjava + +if defined sbt_args_sbt_jar ( + set "sbt_jar=!sbt_args_sbt_jar!" +) else ( + set "sbt_jar=!SBT_HOME!\bin\sbt-launch.jar" +) + +set sbt_jar=!sbt_jar:"=! + +call :copyrt + +if defined JVM_DEBUG_PORT ( + set _JAVA_OPTS=!_JAVA_OPTS! -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=!JVM_DEBUG_PORT! +) + +call :sync_preloaded + +call :run !SBT_ARGS! + +if ERRORLEVEL 1 goto error +goto end + +:run + +rem set arguments + +if defined sbt_args_debug_inc ( + set _SBT_OPTS=-Dxsbt.inc.debug=true !_SBT_OPTS! +) + +if defined sbt_args_no_colors ( + set _SBT_OPTS=-Dsbt.log.noformat=true !_SBT_OPTS! +) + +if defined sbt_args_no_global ( + set _SBT_OPTS=-Dsbt.global.base=project/.sbtboot !_SBT_OPTS! +) + +if defined sbt_args_no_share ( + set _SBT_OPTS=-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy !_SBT_OPTS! +) + +if defined sbt_args_supershell ( + set _SBT_OPTS=-Dsbt.supershell=!sbt_args_supershell! !_SBT_OPTS! +) + +if defined sbt_args_sbt_version ( + set _SBT_OPTS=-Dsbt.version=!sbt_args_sbt_version! !_SBT_OPTS! +) + +if defined sbt_args_sbt_dir ( + set _SBT_OPTS=-Dsbt.global.base=!sbt_args_sbt_dir! !_SBT_OPTS! +) + +if defined sbt_args_sbt_boot ( + set _SBT_OPTS=-Dsbt.boot.directory=!sbt_args_sbt_boot! !_SBT_OPTS! +) + +if defined sbt_args_sbt_cache ( + set _SBT_OPTS=-Dsbt.global.localcache=!sbt_args_sbt_cache! !_SBT_OPTS! +) + +if defined sbt_args_ivy ( + set _SBT_OPTS=-Dsbt.ivy.home=!sbt_args_ivy! !_SBT_OPTS! +) + +if defined sbt_args_color ( + set _SBT_OPTS=-Dsbt.color=!sbt_args_color! !_SBT_OPTS! +) + +if defined sbt_args_mem ( + call :addMemory !sbt_args_mem! +) else ( + call :addDefaultMemory +) + +if defined sbt_args_timings ( + set _SBT_OPTS=-Dsbt.task.timings=true -Dsbt.task.timings.on.shutdown=true !_SBT_OPTS! +) + +if defined sbt_args_traces ( + set _SBT_OPTS=-Dsbt.traces=true !_SBT_OPTS! +) + +if defined sbt_args_no_server ( + set _SBT_OPTS=-Dsbt.io.virtual=false -Dsbt.server.autostart=false !_SBT_OPTS! +) + +rem TODO: _SBT_OPTS needs to be processed as args and diffed against SBT_ARGS + +if !sbt_args_print_sbt_version! equ 1 ( + call :set_sbt_version + echo !sbt_version! + goto :eof +) + +if !sbt_args_print_version! equ 1 ( + call :set_sbt_version + echo sbt version in this project: !sbt_version! + echo sbt script version: !init_sbt_version! + goto :eof +) + +if defined sbt_args_verbose ( + echo # Executing command line: + echo "!_JAVACMD!" + if defined _JAVA_OPTS ( call :echolist !_JAVA_OPTS! ) + if defined _SBT_OPTS ( call :echolist !_SBT_OPTS! ) + if defined JAVA_TOOL_OPTIONS ( call :echolist %JAVA_TOOL_OPTIONS% ) + echo -cp + echo "!sbt_jar!" + echo xsbt.boot.Boot + if not "%~1" == "" ( call :echolist %* ) + echo. +) + +"!_JAVACMD!" !_JAVA_OPTS! !_SBT_OPTS! %JAVA_TOOL_OPTIONS% -cp "!sbt_jar!" xsbt.boot.Boot %* + +goto :eof + +:runnative + +set "_SBTNCMD=!SBT_BIN_DIR!sbtn-x86_64-pc-win32.exe" + +if defined sbt_args_verbose ( + echo # running native client + if not "%~1" == "" ( call :echolist %* ) + set "SBT_ARGS=-v !SBT_ARGS!" +) + +set "SBT_SCRIPT=!SBT_BIN_DIR: =%%20!sbt.bat" +set "SBT_ARGS=--sbt-script=!SBT_SCRIPT! %SBT_ARGS%" + +rem Microsoft Visual C++ 2010 SP1 Redistributable Package (x64) is required +rem https://www.microsoft.com/en-us/download/details.aspx?id=13523 +"!_SBTNCMD!" %SBT_ARGS% + +goto :eof + +rem for expression tries to interpret files, so simply loop over %* instead +rem fixes dealing with quotes after = args: -Dscala.ext.dirs="C:\Users\First Last\.sbt\0.13\java9-rt-ext-adoptopenjdk_11_0_3" +:echolist +rem call method is in first call of %0 +shift + +if "%~0" == "" goto echolist_end +set "p=%~0" + +if "%p:~0,2%" == "-D" ( + rem special handling for -D since '=' gets parsed away + for /F "tokens=1 delims==" %%a in ("%p%") do ( + rem make sure it doesn't have the '=' already + if "%p%" == "%%a" if not "%~1" == "" ( + echo %0=%1 + shift + goto echolist + ) + ) +) + +if not "%p:~0,5%" == "-XX:+" if not "%p:~0,5%" == "-XX:-" if "%p:~0,3%" == "-XX" ( + rem special handling for -XX since '=' gets parsed away + for /F "tokens=1 delims==" %%a in ("%p%") do ( + rem make sure it doesn't have the '=' already + if "%p%" == "%%a" if not "%~1" == "" ( + echo %0=%1 + shift + goto echolist + ) + ) +) + +if "%p:~0,14%" == "-agentlib:jdwp" ( + rem special handling for --jvm-debug since '=' and ',' gets parsed away + for /F "tokens=1 delims==" %%a in ("%p%") do ( + rem make sure it doesn't have the '=' already + if "%p%" == "%%a" if not "%~1" == "" if not "%~2" == "" if not "%~3" == "" if not "%~4" == "" if not "%~5" == "" if not "%~6" == "" if not "%~7" == "" if not "%~8" == "" ( + echo %0=%1=%2,%3=%4,%5=%6,%7=%8 + shift & shift & shift & shift & shift & shift & shift & shift + goto echolist + ) + ) +) + +echo %0 +goto echolist + +:echolist_end + +exit /B 0 + +:addJava + call :dlog [addJava] arg = '%*' + set "_JAVA_OPTS=!_JAVA_OPTS! %*" +exit /B 0 + +:addMemory + call :dlog [addMemory] arg = '%*' + + rem evict memory related options + set _new_java_opts= + set _old_java_opts=!_JAVA_OPTS! +:next_java_opt + if "!_old_java_opts!" == "" goto :done_java_opt + for /F "tokens=1,*" %%g in ("!_old_java_opts!") do ( + set "p=%%g" + if not "!p:~0,4!" == "-Xmx" if not "!p:~0,4!" == "-Xms" if not "!p:~0,4!" == "-Xss" if not "!p:~0,15!" == "-XX:MaxPermSize" if not "!p:~0,20!" == "-XX:MaxMetaspaceSize" if not "!p:~0,25!" == "-XX:ReservedCodeCacheSize" ( + set _new_java_opts=!_new_java_opts! %%g + ) + set "_old_java_opts=%%h" + ) + goto :next_java_opt +:done_java_opt + set _JAVA_OPTS=!_new_java_opts! + + set _new_sbt_opts= + set _old_sbt_opts=!_SBT_OPTS! +:next_sbt_opt + if "!_old_sbt_opts!" == "" goto :done_sbt_opt + for /F "tokens=1,*" %%g in ("!_old_sbt_opts!") do ( + set "p=%%g" + if not "!p:~0,4!" == "-Xmx" if not "!p:~0,4!" == "-Xms" if not "!p:~0,4!" == "-Xss" if not "!p:~0,15!" == "-XX:MaxPermSize" if not "!p:~0,20!" == "-XX:MaxMetaspaceSize" if not "!p:~0,25!" == "-XX:ReservedCodeCacheSize" ( + set _new_sbt_opts=!_new_sbt_opts! %%g + ) + set "_old_sbt_opts=%%h" + ) + goto :next_sbt_opt +:done_sbt_opt + set _SBT_OPTS=!_new_sbt_opts! + + rem a ham-fisted attempt to move some memory settings in concert + set mem=%1 + set /a codecache=!mem! / 8 + if !codecache! GEQ 512 set /a codecache=512 + if !codecache! LEQ 128 set /a codecache=128 + + set /a class_metadata_size=!codecache! * 2 + + call :addJava -Xms!mem!m + call :addJava -Xmx!mem!m + call :addJava -Xss4M + call :addJava -XX:ReservedCodeCacheSize=!codecache!m + + if /I !JAVA_VERSION! LSS 8 ( + call :addJava -XX:MaxPermSize=!class_metadata_size!m + ) + +exit /B 0 + +:addDefaultMemory + rem if we detect any of these settings in ${JAVA_OPTS} or ${JAVA_TOOL_OPTIONS} we need to NOT output our settings. + rem The reason is the Xms/Xmx, if they don't line up, cause errors. + + set _has_memory_args= + + if defined _JAVA_OPTS for %%g in (%_JAVA_OPTS%) do ( + set "p=%%g" + if "!p:~0,4!" == "-Xmx" set _has_memory_args=1 + if "!p:~0,4!" == "-Xms" set _has_memory_args=1 + if "!p:~0,4!" == "-Xss" set _has_memory_args=1 + ) + + if defined JAVA_TOOL_OPTIONS for %%g in (%JAVA_TOOL_OPTIONS%) do ( + set "p=%%g" + if "!p:~0,4!" == "-Xmx" set _has_memory_args=1 + if "!p:~0,4!" == "-Xms" set _has_memory_args=1 + if "!p:~0,4!" == "-Xss" set _has_memory_args=1 + ) + + if defined _SBT_OPTS for %%g in (%_SBT_OPTS%) do ( + set "p=%%g" + if "!p:~0,4!" == "-Xmx" set _has_memory_args=1 + if "!p:~0,4!" == "-Xms" set _has_memory_args=1 + if "!p:~0,4!" == "-Xss" set _has_memory_args=1 + ) + + if not defined _has_memory_args ( + call :addMemory !sbt_default_mem! + ) +exit /B 0 + +:dlog + if defined sbt_args_debug ( + echo %* 1>&2 + ) +exit /B 0 + +:process +rem Parses x out of 1.x; for example 8 out of java version 1.8.0_xx +rem Otherwise, parses the major version; 9 out of java version 9-ea +set JAVA_VERSION=0 + +for /f "tokens=3 usebackq" %%g in (`CALL "!_JAVACMD!" -Xms32M -Xmx32M -version 2^>^&1 ^| findstr /i version`) do ( + set JAVA_VERSION=%%g +) + +rem removes all quotes from JAVA_VERSION +set JAVA_VERSION=!JAVA_VERSION:"=! + +for /f "delims=.-_ tokens=1-2" %%v in ("!JAVA_VERSION!") do ( + if /I "%%v" EQU "1" ( + set JAVA_VERSION=%%w + ) else ( + set JAVA_VERSION=%%v + ) +) + +rem parse the first two segments of sbt.version and set run_native_client to +rem 1 if the user has also indicated they want to use native client. +set sbtV=!build_props_sbt_version! +set sbtBinaryV_1= +set sbtBinaryV_2= +for /F "delims=.-_ tokens=1-2" %%v in ("!sbtV!") do ( + set sbtBinaryV_1=%%v + set sbtBinaryV_2=%%w +) +set native_client_ready= +if !sbtBinaryV_1! geq 2 ( + set native_client_ready=1 +) else ( + if !sbtBinaryV_1! geq 1 ( + if !sbtBinaryV_2! geq 4 ( + set native_client_ready=1 + ) + ) +) +if !native_client_ready! equ 1 ( + if !sbt_args_client! equ 1 ( + set run_native_client=1 + ) +) +set native_client_ready= + +exit /B 0 + +:checkjava +set /a required_version=6 +if /I !JAVA_VERSION! GEQ !required_version! ( + exit /B 0 +) +echo. +echo The Java Development Kit ^(JDK^) installation you have is not up to date. +echo sbt requires at least version !required_version!+, you have +echo version "!JAVA_VERSION!" +echo. +echo Please go to http://www.oracle.com/technetwork/java/javase/downloads/ and download +echo a valid JDK and install before running sbt. +echo. +exit /B 1 + +:copyrt +if /I !JAVA_VERSION! GEQ 9 ( + "!_JAVACMD!" !_JAVA_OPTS! !_SBT_OPTS! -jar "!sbt_jar!" --rt-ext-dir > "%TEMP%.\rtext.txt" + set /p java9_ext= < "%TEMP%.\rtext.txt" + set "java9_rt=!java9_ext!\rt.jar" + + if not exist "!java9_rt!" ( + mkdir "!java9_ext!" + "!_JAVACMD!" !_JAVA_OPTS! !_SBT_OPTS! -jar "!sbt_jar!" --export-rt "!java9_rt!" + ) + set _JAVA_OPTS=!_JAVA_OPTS! -Dscala.ext.dirs="!java9_ext!" +) +exit /B 0 + +:sync_preloaded +if not defined init_sbt_version ( + rem FIXME: better !init_sbt_version! detection + FOR /F "tokens=* usebackq" %%F IN (`dir /b "!SBT_HOME!\lib\local-preloaded\org\scala-sbt\sbt" /B`) DO ( + SET init_sbt_version=%%F + ) +) + +set PRELOAD_SBT_JAR="%UserProfile%\.sbt\preloaded\org\scala-sbt\sbt\!init_sbt_version!\" +if /I !JAVA_VERSION! GEQ 8 ( + where robocopy >nul 2>nul + if %ERRORLEVEL% EQU 0 ( + if not exist !PRELOAD_SBT_JAR! ( + if exist "!SBT_HOME!\lib\local-preloaded\" ( + robocopy "!SBT_HOME!\lib\local-preloaded" "%UserProfile%\.sbt\preloaded" /E >nul 2>nul + ) + ) + ) +) +exit /B 0 + +:usage + +for /f "tokens=3 usebackq" %%g in (`CALL "!_JAVACMD!" -Xms32M -Xmx32M -version 2^>^&1 ^| findstr /i version`) do ( + set FULL_JAVA_VERSION=%%g +) + +echo. +echo Usage: %~n0 [options] +echo. +echo -h ^| --help print this message +echo -v ^| --verbose this runner is chattier +echo -V ^| --version print sbt version information +echo --numeric-version print the numeric sbt version (sbt sbtVersion) +echo --script-version print the version of sbt script +echo -d ^| --debug set sbt log level to debug +echo -debug-inc ^| --debug-inc +echo enable extra debugging for the incremental debugger +echo --no-colors disable ANSI color codes +echo --color=auto^|always^|true^|false^|never +echo enable or disable ANSI color codes ^(sbt 1.3 and above^) +echo --supershell=auto^|always^|true^|false^|never +echo enable or disable supershell ^(sbt 1.3 and above^) +echo --traces generate Trace Event report on shutdown ^(sbt 1.3 and above^) +echo --timings display task timings report on shutdown +echo --sbt-create start sbt even if current directory contains no sbt project +echo --sbt-dir ^ path to global settings/plugins directory ^(default: ~/.sbt^) +echo --sbt-boot ^ path to shared boot directory ^(default: ~/.sbt/boot in 0.11 series^) +echo --sbt-cache ^ path to global cache directory ^(default: operating system specific^) +echo --ivy ^ path to local Ivy repository ^(default: ~/.ivy2^) +echo --mem ^ set memory options ^(default: %sbt_default_mem%^) +echo --no-share use all local caches; no sharing +echo --no-global uses global caches, but does not use global ~/.sbt directory. +echo --jvm-debug ^ enable on JVM debugging, open at the given port. +rem echo --batch disable interactive mode +echo. +echo # sbt version ^(default: from project/build.properties if present, else latest release^) +echo --sbt-version ^ use the specified version of sbt +echo --sbt-jar ^ use the specified jar as the sbt launcher +echo. +echo # java version ^(default: java from PATH, currently !FULL_JAVA_VERSION!^) +echo --java-home ^ alternate JAVA_HOME +echo. +echo # jvm options and output control +echo JAVA_OPTS environment variable, if unset uses "!default_java_opts!" +echo .jvmopts if this file exists in the current directory, its contents +echo are appended to JAVA_OPTS +echo SBT_OPTS environment variable, if unset uses "!default_sbt_opts!" +echo .sbtopts if this file exists in the current directory, its contents +echo are prepended to the runner args +echo !SBT_CONFIG! +echo if this file exists, it is prepended to the runner args +echo -Dkey=val pass -Dkey=val directly to the java runtime +rem echo -J-X pass option -X directly to the java runtime +rem echo ^(-J is stripped^) +rem echo -S-X add -X to sbt's scalacOptions ^(-S is stripped^) +echo. +echo In the case of duplicated or conflicting options, the order above +echo shows precedence: JAVA_OPTS lowest, command line options highest. +echo. + +@endlocal +exit /B 1 + +:set_sbt_version +rem set project sbtVersion +for /F "usebackq tokens=2" %%G in (`CALL "!_JAVACMD!" -jar "!sbt_jar!" "sbtVersion" 2^>^&1`) do set "sbt_version=%%G" +exit /B 0 + +:error +@endlocal +exit /B 1 + +:end +@endlocal +exit /B 0 diff --git a/sbt/bin/sbtn-aarch64-apple-darwin b/sbt/bin/sbtn-aarch64-apple-darwin new file mode 100755 index 0000000..37c9ed7 Binary files /dev/null and b/sbt/bin/sbtn-aarch64-apple-darwin differ diff --git a/sbt/bin/sbtn-aarch64-pc-linux b/sbt/bin/sbtn-aarch64-pc-linux new file mode 100755 index 0000000..0f0f95e Binary files /dev/null and b/sbt/bin/sbtn-aarch64-pc-linux differ diff --git a/sbt/bin/sbtn-x86_64-apple-darwin b/sbt/bin/sbtn-x86_64-apple-darwin new file mode 100755 index 0000000..3a4ce3a Binary files /dev/null and b/sbt/bin/sbtn-x86_64-apple-darwin differ diff --git a/sbt/bin/sbtn-x86_64-pc-linux b/sbt/bin/sbtn-x86_64-pc-linux new file mode 100755 index 0000000..4f6b047 Binary files /dev/null and b/sbt/bin/sbtn-x86_64-pc-linux differ diff --git a/sbt/bin/sbtn-x86_64-pc-win32.exe b/sbt/bin/sbtn-x86_64-pc-win32.exe new file mode 100755 index 0000000..25d69c0 Binary files /dev/null and b/sbt/bin/sbtn-x86_64-pc-win32.exe differ diff --git a/sbt/conf/sbtconfig.txt b/sbt/conf/sbtconfig.txt new file mode 100755 index 0000000..9226e25 --- /dev/null +++ b/sbt/conf/sbtconfig.txt @@ -0,0 +1,14 @@ +# sbt configuration file for Windows + +# Set the java args + +#-mem 1024 was added in sbt.bat as default + +#-Xms1024m +#-Xmx1024m +#-Xss4M +#-XX:ReservedCodeCacheSize=128m + +# Set the extra sbt options + +# -Dsbt.log.format=true diff --git a/sbt/conf/sbtopts b/sbt/conf/sbtopts new file mode 100644 index 0000000..c6f4e7b --- /dev/null +++ b/sbt/conf/sbtopts @@ -0,0 +1,49 @@ +# ------------------------------------------------ # +# The SBT Configuration file. # +# ------------------------------------------------ # + + +# Disable ANSI color codes +# +#-no-colors + +# Starts sbt even if the current directory contains no sbt project. +# +-sbt-create + +# Path to global settings/plugins directory (default: ~/.sbt) +# +#-sbt-dir /etc/sbt + +# Path to shared boot directory (default: ~/.sbt/boot in 0.11 series) +# +#-sbt-boot ~/.sbt/boot + +# Path to local Ivy repository (default: ~/.ivy2) +# +#-ivy ~/.ivy2 + +# set memory options +# +#-mem + +# Use local caches for projects, no sharing. +# +#-no-share + +# Put SBT in offline mode. +# +#-offline + +# Sets the SBT version to use. +#-sbt-version 0.11.3 + +# Scala version (default: latest release) +# +#-scala-home +#-scala-version + +# java version (default: java from PATH, currently $(java -version |& grep version)) +# +#-java-home + diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..36373da --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,34 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + true + true + true + true + * + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/scala/dev/whalenet/leaf_lab/Main.scala b/src/main/scala/dev/whalenet/leaf_lab/Main.scala index 22993d7..dafb5ee 100644 --- a/src/main/scala/dev/whalenet/leaf_lab/Main.scala +++ b/src/main/scala/dev/whalenet/leaf_lab/Main.scala @@ -9,6 +9,7 @@ import org.http4s.circe.* import org.http4s.ember.server.* import com.comcast.ip4s.* import org.typelevel.log4cats.slf4j.Slf4jFactory +import org.typelevel.log4cats.Logger import io.circe.generic.auto._ // TODO - need to move these to another locatioin @@ -26,24 +27,39 @@ object Main extends IOApp { def run(args: List[String]): IO[ExitCode] = { - DBConfig.init() - - // val srRepo = new InMemorySensorResultRepository() - val srRepo = new DBSensorResultRepository() - val sRepo = new DBSensorRepository() - val plRepo = new DBPlantRepository() - val peRepo = new DBPersonRepository() - val service = new Service(srRepo, sRepo, plRepo, peRepo) - - val LeafLabAPIServer = EmberServerBuilder - .default[IO] - .withHost(Host.fromString("0.0.0.0").get) - .withPort(Port.fromInt(8080).get) - .withHttpApp(service.httpApp) - .build - - LeafLabAPIServer - .use(_ => IO.never) // Keeps the server running indefinitely - .as(ExitCode.Success) + implicit val logger: Logger[IO] = Slf4jFactory.create[IO].getLogger + + for { + _ <- logger.info("Starting leaf-lab application") + _ <- IO { + // Initialize OpenTelemetry + OpenTelemetryConfig.init() + } + _ <- logger.info("OpenTelemetry initialized, configuring database") + _ <- IO { + DBConfig.init() + } + _ <- logger.info("Database configured, setting up repositories and service") + + // val srRepo = new InMemorySensorResultRepository() + srRepo = new DBSensorResultRepository() + sRepo = new DBSensorRepository() + plRepo = new DBPlantRepository() + peRepo = new DBPersonRepository() + service = new Service(srRepo, sRepo, plRepo, peRepo) + + _ <- logger.info("Starting HTTP server on 0.0.0.0:8080") + + leafLabAPIServer = EmberServerBuilder + .default[IO] + .withHost(Host.fromString("0.0.0.0").get) + .withPort(Port.fromInt(8080).get) + .withHttpApp(service.httpApp) + .build + + exitCode <- leafLabAPIServer + .use(_ => IO.never) // Keeps the server running indefinitely + .as(ExitCode.Success) + } yield exitCode } } diff --git a/src/main/scala/dev/whalenet/leaf_lab/OpenTelemetryConfig.scala b/src/main/scala/dev/whalenet/leaf_lab/OpenTelemetryConfig.scala new file mode 100644 index 0000000..8151ca2 --- /dev/null +++ b/src/main/scala/dev/whalenet/leaf_lab/OpenTelemetryConfig.scala @@ -0,0 +1,36 @@ +package dev.whalenet.leaf_lab + +import io.opentelemetry.api.OpenTelemetry +import io.opentelemetry.sdk.OpenTelemetrySdk +import io.opentelemetry.sdk.logs.SdkLoggerProvider +import io.opentelemetry.sdk.logs.`export`.BatchLogRecordProcessor +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter + +object OpenTelemetryConfig { + + def init(): OpenTelemetry = { + val otlpEndpoint = "http://0.0.0.0:4317" + + val logRecordExporter = OtlpGrpcLogRecordExporter.builder() + .setEndpoint(otlpEndpoint) + .build() + + val logRecordProcessor = BatchLogRecordProcessor.builder(logRecordExporter) + .build() + + val sdkLoggerProvider = SdkLoggerProvider.builder() + .addLogRecordProcessor(logRecordProcessor) + .build() + + val openTelemetry = OpenTelemetrySdk.builder() + .setLoggerProvider(sdkLoggerProvider) + .buildAndRegisterGlobal() + + // Add shutdown hook to ensure proper cleanup + Runtime.getRuntime.addShutdownHook(new Thread(() => { + sdkLoggerProvider.close() + })) + + openTelemetry + } +} \ No newline at end of file diff --git a/src/main/scala/dev/whalenet/leaf_lab/Service.scala b/src/main/scala/dev/whalenet/leaf_lab/Service.scala index c8f6a44..62d9068 100644 --- a/src/main/scala/dev/whalenet/leaf_lab/Service.scala +++ b/src/main/scala/dev/whalenet/leaf_lab/Service.scala @@ -9,6 +9,7 @@ import org.http4s.ember.server.* import org.http4s.implicits.* import com.comcast.ip4s.* import org.typelevel.log4cats.slf4j.Slf4jFactory +import org.typelevel.log4cats.Logger import io.circe.generic.auto._ @@ -16,6 +17,8 @@ import io.circe.generic.auto._ // maybe forever too class Service(sensorResultRepository: Repository[SensorResult], sensorRepository: Repository[Sensor], plantRepository: Repository[Plant], personRepository: Repository[Person]) { + implicit val logger: Logger[IO] = Slf4jFactory.create[IO].getLogger + val httpApp: HttpApp[IO] = HttpRoutes .of[IO] { case GET -> Root / "hello" / name => @@ -61,8 +64,12 @@ class Service(sensorResultRepository: Repository[SensorResult], sensorRepository // SensorResult def insertSensorResult(result: SensorResult): IO[Response[IO]] = { - val ret_result = sensorResultRepository.insert(result) - Ok(s"$ret_result") + for { + _ <- logger.info(s"Inserting sensor result: plant_id=${result.plant_id}, sensor_id=${result.sensor_id}, value=${result.value}") + ret_result = sensorResultRepository.insert(result) + _ <- logger.info(s"Successfully inserted sensor result with id: ${ret_result.id}") + response <- Ok(s"$ret_result") + } yield response } def findSensorResult(id: Int): IO[Response[IO]] = {