From 02f9de09b7e5b5a9c8b24895200591c59a4c0016 Mon Sep 17 00:00:00 2001 From: Godzilla675 <131464726+Godzilla675@users.noreply.github.com> Date: Fri, 20 Feb 2026 02:29:34 +0000 Subject: [PATCH 1/3] Install ZIO SBT CI Plugin - Added `zio-sbt-ci` plugin to `project/plugins.sbt`. - Enabled `ZioSbtCiPlugin` in `build.sbt` for the root project. - Added `lint` command alias to `build.sbt`. - Generated `.github/workflows/ci.yml` using `sbt ciGenerateGithubWorkflow` to standardize CI configuration, including documentation checks and publishing. --- .github/workflows/ci.yml | 396 ++++++++++-------- build.sbt | 3 + project/plugins.sbt | 1 + sbt | 869 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 1107 insertions(+), 162 deletions(-) create mode 100755 sbt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eba5c39a91..5f3355c917 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,196 +1,268 @@ -name: CI +# This file was autogenerated using `zio-sbt-ci` plugin via `sbt ciGenerateGithubWorkflow` +# task and should be included in the git repository. Please do not edit it manually. +name: CI env: - JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags -Djava.locale.providers=CLDR,JRE # JDK_JAVA_OPTIONS is _the_ env. variable to use for modern Java - JVM_OPTS: -XX:+PrintCommandLineFlags -Djava.locale.providers=CLDR,JRE # for Java 8 only (sadly, it is not modern enough for JDK_JAVA_OPTIONS) - -on: - pull_request: - push: - branches: ['main'] + JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags +'on': + workflow_dispatch: {} release: types: - - published + - published + push: {} + pull_request: + branches-ignore: + - gh-pages +permissions: + id-token: write + contents: read concurrency: - group: ci-pr-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.ref }} + group: ${{ github.workflow }}-${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.run_id || github.ref }} cancel-in-progress: true - jobs: - buildDocs: - name: Build Docs + build: + name: Build runs-on: ubuntu-latest - timeout-minutes: 10 + continue-on-error: true steps: - - name: Git Checkout - uses: actions/checkout@v6.0.2 - with: - fetch-depth: '0' - - name: Install libuv - run: sudo apt-get update && sudo apt-get install -y libuv1-dev - - name: Setup Scala - uses: actions/setup-java@v5 - with: - distribution: corretto - java-version: '17' - check-latest: true - - name: Setup SBT - uses: sbt/setup-sbt@v1 - - name: Cache Dependencies - uses: coursier/cache-action@v8 - - name: Check website build process - run: sbt docs/clean docs/buildWebsite - + - name: Git Checkout + uses: actions/checkout@v6 + with: + fetch-depth: '0' + - name: Install libuv + run: sudo apt-get update && sudo apt-get install -y libuv1-dev + - name: Setup Scala + uses: actions/setup-java@v5 + with: + distribution: corretto + java-version: '17' + check-latest: true + - name: Setup SBT + uses: sbt/setup-sbt@v1 + - name: Cache Dependencies + uses: coursier/cache-action@v7 + - name: Check all code compiles + run: sbt +Test/compile + - name: Check artifacts build process + run: sbt +publishLocal + - name: Check website build process + run: sbt docs/clean; sbt docs/buildWebsite lint: + name: Lint runs-on: ubuntu-latest - timeout-minutes: 10 + continue-on-error: false steps: - - name: Install locale data - run: | - sudo apt-get update - sudo apt-get install -y locales - sudo locale-gen en_US.UTF-8 - - name: Checkout current branch - uses: actions/checkout@v6.0.2 - with: - fetch-depth: 0 - - name: Setup Action - uses: coursier/setup-action@v2 - with: - jvm: temurin:11 - apps: sbt - - name: Cache scala dependencies - uses: coursier/cache-action@v8 - - name: Lint code - run: sbt "++2.13; check; ++3.7; check" - - testJVM: + - name: Git Checkout + uses: actions/checkout@v6 + with: + fetch-depth: '0' + - name: Install libuv + run: sudo apt-get update && sudo apt-get install -y libuv1-dev + - name: Setup Scala + uses: actions/setup-java@v5 + with: + distribution: corretto + java-version: '17' + check-latest: true + - name: Setup SBT + uses: sbt/setup-sbt@v1 + - name: Cache Dependencies + uses: coursier/cache-action@v7 + - name: Check if the site workflow is up to date + run: sbt ciCheckGithubWorkflow + - name: Lint + run: sbt lint + test: + name: Test runs-on: ubuntu-latest - timeout-minutes: 25 + continue-on-error: false strategy: fail-fast: false matrix: - java: [11, 25] - platform: ['JVM'] - scala: ['2.13.x', '3.3.x', '3.7.x'] + java: + - '11' + - '17' + - '21' steps: - - name: Checkout current branch - uses: actions/checkout@v6.0.2 - with: - fetch-depth: 0 - - name: Set JVM options for JDK 25+ - if: matrix.java >= 25 - run: echo "JAVA_TOOL_OPTIONS=-XX:+UseCompactObjectHeaders" >> $GITHUB_ENV - shell: bash - - name: Setup Action - uses: coursier/setup-action@v2 - with: - jvm: temurin:${{ matrix.java }} - jvm-index: https://raw.githubusercontent.com/coursier/jvm-index/refs/heads/master/index.json - apps: sbt - - name: Cache scala dependencies - uses: coursier/cache-action@v8 - - name: Run Scala 2 tests and compile Scala 2 docs - if: ${{ startsWith(matrix.scala, '2.') }} - run: sbt ++${{ matrix.scala }} test${{ matrix.platform }} doc${{ matrix.platform }} - - name: Run Scala 3 tests with test coverage and docs (JDK 11) - if: ${{ startsWith(matrix.scala, '3.') && matrix.java == 11 }} - run: sbt ++${{ matrix.scala }} coverage test${{ matrix.platform }} coverageReport doc${{ matrix.platform }} - - name: Run Scala 3 tests with test coverage (JDK 25, skip docs due to scaladoc bug) - if: ${{ startsWith(matrix.scala, '3.') && matrix.java >= 25 }} - run: sbt ++${{ matrix.scala }} coverage test${{ matrix.platform }} coverageReport - - name: Run Scala Next tests - if: ${{ matrix.scala == '3.7.x' }} - run: sbt ++3.7.4 scalaNextTests${{ matrix.platform }}/test benchmarks/test - - name: Compile example project - run: sbt ++${{ matrix.scala }} examples/compile - - testJS: + - name: Install libuv + run: sudo apt-get update && sudo apt-get install -y libuv1-dev + - name: Setup Scala + uses: actions/setup-java@v5 + with: + distribution: corretto + java-version: ${{ matrix.java }} + check-latest: true + - name: Setup SBT + uses: sbt/setup-sbt@v1 + - name: Cache Dependencies + uses: coursier/cache-action@v7 + - name: Git Checkout + uses: actions/checkout@v6 + with: + fetch-depth: '0' + - name: Test + run: sbt +test + update-readme: + name: Update README runs-on: ubuntu-latest - timeout-minutes: 20 - strategy: - fail-fast: false - matrix: - java: [11] - platform: ['JS'] - # Note: 3.7.x excluded due to Scala.js compiler bug (URISyntaxException in genSJSIR) - scala: ['2.13.x', '3.3.x'] + continue-on-error: false + if: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} steps: - - name: Checkout current branch - uses: actions/checkout@v6.0.2 - with: - fetch-depth: 0 - - name: Setup Action - uses: coursier/setup-action@v2 - with: - jvm: temurin:${{ matrix.java }} - jvm-index: https://raw.githubusercontent.com/coursier/jvm-index/refs/heads/master/index.json - apps: sbt - - name: Cache scala dependencies - uses: coursier/cache-action@v8 - - name: Run tests and compile docs - run: sbt ++${{ matrix.scala }} test${{ matrix.platform }} doc${{ matrix.platform }} + - name: Git Checkout + uses: actions/checkout@v6 + with: + fetch-depth: '0' + - name: Install libuv + run: sudo apt-get update && sudo apt-get install -y libuv1-dev + - name: Setup Scala + uses: actions/setup-java@v5 + with: + distribution: corretto + java-version: '17' + check-latest: true + - name: Setup SBT + uses: sbt/setup-sbt@v1 + - name: Cache Dependencies + uses: coursier/cache-action@v7 + - name: Generate Readme + run: sbt docs/generateReadme + - name: Commit Changes + run: | + git config --local user.email "zio-assistant[bot]@users.noreply.github.com" + git config --local user.name "ZIO Assistant" + git add README.md + git commit -m "Update README.md" || echo "No changes to commit" + - name: Generate Token + id: generate-token + uses: zio/generate-github-app-token@v1.0.0 + with: + app_id: ${{ secrets.APP_ID }} + app_private_key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v8 + with: + body: |- + Autogenerated changes after running the `sbt docs/generateReadme` command of the [zio-sbt-website](https://zio.dev/zio-sbt) plugin. + I will automatically update the README.md file whenever there is new change for README.md, e.g. + - After each release, I will update the version in the installation section. + - After any changes to the "docs/index.md" file, I will update the README.md file accordingly. + branch: zio-sbt-website/update-readme + commit-message: Update README.md + token: ${{ steps.generate-token.outputs.token }} + delete-branch: true + title: Update README.md + - name: Approve PR + if: ${{ steps.cpr.outputs.pull-request-number }} + run: gh pr review "$PR_URL" --approve + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_URL: ${{ steps.cpr.outputs.pull-request-url }} + - name: Enable Auto-Merge + if: ${{ steps.cpr.outputs.pull-request-number }} + run: gh pr merge --auto --squash "$PR_URL" || gh pr merge --squash "$PR_URL" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_URL: ${{ steps.cpr.outputs.pull-request-url }} ci: + name: ci runs-on: ubuntu-latest - needs: [lint, testJVM, testJS, buildDocs] + continue-on-error: false + needs: + - lint + - test + - build steps: - - name: Aggregate of lint, and all tests - run: echo "ci passed" - + - name: Report Successful CI + run: echo "ci passed" release: + name: Release runs-on: ubuntu-latest - timeout-minutes: 30 - needs: [ci] + continue-on-error: false + needs: + - ci if: ${{ github.event_name != 'pull_request' }} steps: - - name: Checkout current branch - uses: actions/checkout@v6.0.2 - with: - fetch-depth: 0 - - name: Setup Action - uses: coursier/setup-action@v2 - with: - jvm: temurin:11 - apps: sbt - - name: Release - run: sbt ci-release - env: - PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} - PGP_SECRET: ${{ secrets.PGP_SECRET }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - + - name: Git Checkout + uses: actions/checkout@v6 + with: + fetch-depth: '0' + - name: Install libuv + run: sudo apt-get update && sudo apt-get install -y libuv1-dev + - name: Setup Scala + uses: actions/setup-java@v5 + with: + distribution: corretto + java-version: '17' + check-latest: true + - name: Setup SBT + uses: sbt/setup-sbt@v1 + - name: Cache Dependencies + uses: coursier/cache-action@v7 + - name: Release + run: sbt ci-release + env: + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + PGP_SECRET: ${{ secrets.PGP_SECRET }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} release-docs: name: Release Docs runs-on: ubuntu-latest continue-on-error: false needs: - - release + - release if: ${{ ((github.event_name == 'release') && (github.event.action == 'published')) || (github.event_name == 'workflow_dispatch') }} - permissions: - id-token: write - contents: read steps: - - name: Git Checkout - uses: actions/checkout@v6 - with: - fetch-depth: '0' - - name: Install libuv - run: sudo apt-get update && sudo apt-get install -y libuv1-dev - - name: Setup Scala - uses: actions/setup-java@v5 - with: - distribution: corretto - java-version: '17' - check-latest: true - - name: Setup SBT - uses: sbt/setup-sbt@v1 - - name: Cache Dependencies - uses: coursier/cache-action@v8 - - name: Setup NodeJs - uses: actions/setup-node@v6 - with: - node-version: 24.12.0 - registry-url: https://registry.npmjs.org - - name: Publish Docs to NPM Registry - run: sbt docs/publishToNpm + - name: Git Checkout + uses: actions/checkout@v6 + with: + fetch-depth: '0' + - name: Install libuv + run: sudo apt-get update && sudo apt-get install -y libuv1-dev + - name: Setup Scala + uses: actions/setup-java@v5 + with: + distribution: corretto + java-version: '17' + check-latest: true + - name: Setup SBT + uses: sbt/setup-sbt@v1 + - name: Cache Dependencies + uses: coursier/cache-action@v7 + - name: Setup NodeJs + uses: actions/setup-node@v6 + with: + node-version: 24.12.0 + registry-url: https://registry.npmjs.org + - name: Publish Docs to NPM Registry + run: sbt docs/publishToNpm + notify-docs-release: + name: Notify Docs Release + runs-on: ubuntu-latest + continue-on-error: false + needs: + - release-docs + if: ${{ (github.event_name == 'release') && (github.event.action == 'published') }} + steps: + - name: Git Checkout + uses: actions/checkout@v6 + with: + fetch-depth: '0' + - name: notify the main repo about the new release of docs package + run: | + PACKAGE_NAME=$(cat docs/package.json | grep '"name"' | awk -F'"' '{print $4}') + PACKAGE_VERSION=$(npm view $PACKAGE_NAME version) + curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: token ${{ secrets.PAT_TOKEN }}"\ + https://api.github.com/repos/zio/zio/dispatches \ + -d '{ + "event_type":"update-docs", + "client_payload":{ + "package_name":"'"${PACKAGE_NAME}"'", + "package_version": "'"${PACKAGE_VERSION}"'" + } + }' diff --git a/build.sbt b/build.sbt index c7b282443f..b25ec278d8 100644 --- a/build.sbt +++ b/build.sbt @@ -30,6 +30,7 @@ addCommandAlias("build", "; fmt; coverage; root/test; coverageReport") addCommandAlias("fmt", "all root/scalafmtSbt root/scalafmtAll") addCommandAlias("fmtCheck", "all root/scalafmtSbtCheck root/scalafmtCheckAll") addCommandAlias("check", "; scalafmtSbtCheck; scalafmtCheckAll") +addCommandAlias("lint", "check") addCommandAlias("mimaChecks", "all schemaJVM/mimaReportBinaryIssues") addCommandAlias( "testJVM", @@ -54,6 +55,7 @@ lazy val root = project .settings( publish / skip := true ) + .enablePlugins(ZioSbtCiPlugin) .aggregate( typeid.jvm, typeid.js, @@ -492,6 +494,7 @@ lazy val examples = project .settings( publish / skip := true ) + .enablePlugins(ZioSbtCiPlugin) .dependsOn( schema.jvm, markdown.jvm, diff --git a/project/plugins.sbt b/project/plugins.sbt index dda7a65ea1..98d08f65cb 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,6 @@ lazy val zioSbtVersion = "0.4.10" addSbtPlugin("dev.zio" % "zio-sbt-website" % zioSbtVersion) +addSbtPlugin("dev.zio" % "zio-sbt-ci" % zioSbtVersion) addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.6.4") addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.8") diff --git a/sbt b/sbt new file mode 100755 index 0000000000..d5312ce355 --- /dev/null +++ b/sbt @@ -0,0 +1,869 @@ +#!/usr/bin/env bash + +set +e +declare builtin_sbt_version="1.10.11" +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=_to_be_replaced +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.10.8" +declare use_colors=1 +declare is_this_dir_sbt="" + +### ------------------------------- ### +### 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 +} + +# Trim leading and trailing spaces from a string. +# Echos the new trimmed string. +trimString() { + local inputStr="$*" + local modStr="${inputStr#"${inputStr%%[![:space:]]*}"}" + modStr="${modStr%"${modStr##*[![:space:]]}"}" + echo "$modStr" +} + +declare -r sbt_bin_dir="$(dirname "$(realpathish "$0")")" +declare -r sbt_home="$(dirname "$sbt_bin_dir")" + +echoerr () { + echo 1>&2 "$@" +} +RED='\033[0;31m' +NC='\033[0m' # No Color +echoerr_error () { + if [[ $use_colors == "1" ]]; then + echoerr -e "[${RED}error${NC}] $@" + else + echoerr "[error] $@" + fi +} +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") + dlog "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"* ]]; 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_error "sbtn is not supported on $arch" + exit 2 + fi + elif [[ "$OSTYPE" == "darwin"* ]]; then + arch="universal" + archive_target="$p/sbtn-universal-apple-darwin-${sbtn_v}.tar.gz" + url="https://github.com/sbt/sbtn-dist/releases/download/v${sbtn_v}/sbtn-universal-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_error "sbtn is not supported on $OSTYPE" + exit 2 + fi + + if [[ -f "$target" ]]; then + sbtn_command="$target" + else + dlog "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 + echoerr "$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 + echoerr + echoerr "No Java Development Kit (JDK) installation was detected." + echoerr Go to https://adoptium.net/ etc and download. + echoerr + exit 1 + elif [[ "$good_enough" != "1" ]]; then + echoerr + echoerr "The Java Development Kit (JDK) installation you have is not up to date." + echoerr $script_name requires at least version $required_version+, you have + echoerr version $java_version + echoerr + echoerr Go to https://adoptium.net/ etc and download + echoerr 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 + 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 +} + +detect_working_directory() { + if [[ -f ./build.sbt || -f ./project/build.properties ]]; then + is_this_dir_sbt=1 + fi +} + +# Confirm a user's intent if the current directory does not look like an sbt +# top-level directory and neither the --allow-empty option nor the "new" command was given. +checkWorkingDirectory() { + if [[ ! -n "$allow_empty" ]]; then + [[ -n "$is_this_dir_sbt" || -n "$sbt_new" ]] || { + echoerr_error "Neither build.sbt nor a 'project' directory in the current directory: $(pwd)" + echoerr_error "run 'sbt new', touch build.sbt, or run 'sbt --allow-empty'." + echoerr_error "" + echoerr_error "To opt out of this check, create ${config_home}/sbtopts with:" + echoerr_error "--allow-empty" + exit 1 + } + 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 "8" + + # 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 + + detect_working_directory + 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 + if [[ -n "$is_this_dir_sbt" ]]; then + execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]/sbt version in this project:/g' + fi + echo "sbt runner version: $init_sbt_version" + echoerr "" + echoerr "[info] sbt runner (sbt-the-shell-script) is a runner to run any declared version of sbt." + echoerr "[info] Actual version of the sbt is declared using project/build.properties for each build." + elif [[ $shutdownall ]]; then + local sbt_processes=( $(jps -v | grep sbt-launch | cut -f1 -d ' ') ) + for procId in "${sbt_processes[@]}"; do + kill -9 $procId + done + echoerr "shutdown ${#sbt_processes[@]} sbt processes" + else + checkWorkingDirectory + # 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 machine_sbt_opts_file="${etc_sbt_opts_file}" +declare config_home="${XDG_CONFIG_HOME:-$HOME/.config}/sbt" +[[ -f "${config_home}/sbtopts" ]] && machine_sbt_opts_file="${config_home}/sbtopts" +[[ -f "$SBT_ETC_FILE" ]] && machine_sbt_opts_file="$SBT_ETC_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 + + -allow-empty|--allow-empty|-sbt-create|--sbt-create) allow_empty=true && shift ;; + + new|init) 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" +} + +## 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 )); then + if [[ "$use_sbtn" == "0" ]]; then + echo "false" + else + echo "true" + fi + elif ( (( $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 + + if [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then + sbt_script="$0.bat" + else + sbt_script="$0" + fi + sbt_script=${sbt_script/ /%20} + execRunner "$sbtn_command" "--sbt-script=$sbt_script" "${original_args[@]}" +} + +original_args=("$@") + +# Pull in the machine-wide settings configuration. +if [[ -f "$machine_sbt_opts_file" ]]; then + set -- $(loadConfigFile "$machine_sbt_opts_file") "$@" +else + # Otherwise pull in the default settings configuration. + [[ -f "$dist_sbt_opts_file" ]] && set -- $(loadConfigFile "$dist_sbt_opts_file") "$@" +fi + +# 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 From 67807a1141530c8620bd03f07838c159ba4cacfb Mon Sep 17 00:00:00 2001 From: Godzilla675 <131464726+Godzilla675@users.noreply.github.com> Date: Fri, 20 Feb 2026 12:14:32 +0000 Subject: [PATCH 2/3] Fix CI configuration - Configure `ciJvmOptions` to include `-Djava.locale.providers=CLDR,JRE` for locale-sensitive tests. - Update `ciPostReleaseJobs` to inject `NODE_AUTH_TOKEN` environment variable into the `release-docs` job. - Regenerate `.github/workflows/ci.yml` with the correct settings. --- .github/workflows/ci.yml | 4 +++- build.sbt | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f3355c917..eb217d5084 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: CI env: - JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags + JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags -Djava.locale.providers=CLDR,JRE -XX:+PrintCommandLineFlags 'on': workflow_dispatch: {} release: @@ -238,6 +238,8 @@ jobs: registry-url: https://registry.npmjs.org - name: Publish Docs to NPM Registry run: sbt docs/publishToNpm + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} notify-docs-release: name: Notify Docs Release runs-on: ubuntu-latest diff --git a/build.sbt b/build.sbt index b25ec278d8..09f821a966 100644 --- a/build.sbt +++ b/build.sbt @@ -531,3 +531,32 @@ lazy val docs = project mediatype.jvm ) .enablePlugins(WebsitePlugin) + +import zio.sbt.githubactions._ + +import zio.sbt.githubactions.Step + + +ThisBuild / ciJvmOptions := Seq("-Djava.locale.providers=CLDR,JRE", "-XX:+PrintCommandLineFlags") + +ThisBuild / ciPostReleaseJobs := { + import zio.sbt.githubactions._ + + def updateStep(step: Step): Step = step match { + case s: Step.SingleStep if s.name == "Publish Docs to NPM Registry" => + s.copy(env = s.env + ("NODE_AUTH_TOKEN" -> "${{ secrets.NPM_TOKEN }}")) + case s: Step.StepSequence => + val updatedSteps = s.steps.map(updateStep) + s.copy(steps = updatedSteps) + case other => other + } + + (ThisBuild / ciPostReleaseJobs).value.map { job => + if (job.id == "release-docs") { + val updatedSteps = job.steps.map(updateStep) + job.copy(steps = updatedSteps) + } else { + job + } + } +} From 081bac80ce981203fb3450f5ec4d657b23a9cf10 Mon Sep 17 00:00:00 2001 From: Godzilla675 <131464726+Godzilla675@users.noreply.github.com> Date: Fri, 20 Feb 2026 12:26:47 +0000 Subject: [PATCH 3/3] Install and Configure ZIO SBT CI Plugin - Add `zio-sbt-ci` plugin to `project/plugins.sbt`. - Enable `ZioSbtCiPlugin` in `build.sbt`. - Configure `ciJvmOptions` to include `-Djava.locale.providers=CLDR,JRE` for locale-sensitive tests on Java 17+. - Inject `NODE_AUTH_TOKEN` into the `release-docs` job via `ciPostReleaseJobs` to enable NPM publishing. - Generate `.github/workflows/ci.yml` using `sbt ciGenerateGithubWorkflow`. - Add `lint` alias to `build.sbt` as required by the CI workflow. --- .github/workflows/ci.yml | 2 +- build.sbt | 2 +- sbt | 869 --------------------------------------- 3 files changed, 2 insertions(+), 871 deletions(-) delete mode 100755 sbt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb217d5084..4f2ac685e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: CI env: - JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags -Djava.locale.providers=CLDR,JRE -XX:+PrintCommandLineFlags + JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags -Djava.locale.providers=CLDR,JRE 'on': workflow_dispatch: {} release: diff --git a/build.sbt b/build.sbt index 09f821a966..2511705ad3 100644 --- a/build.sbt +++ b/build.sbt @@ -537,7 +537,7 @@ import zio.sbt.githubactions._ import zio.sbt.githubactions.Step -ThisBuild / ciJvmOptions := Seq("-Djava.locale.providers=CLDR,JRE", "-XX:+PrintCommandLineFlags") +ThisBuild / ciJvmOptions := Seq("-Djava.locale.providers=CLDR,JRE") ThisBuild / ciPostReleaseJobs := { import zio.sbt.githubactions._ diff --git a/sbt b/sbt deleted file mode 100755 index d5312ce355..0000000000 --- a/sbt +++ /dev/null @@ -1,869 +0,0 @@ -#!/usr/bin/env bash - -set +e -declare builtin_sbt_version="1.10.11" -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=_to_be_replaced -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.10.8" -declare use_colors=1 -declare is_this_dir_sbt="" - -### ------------------------------- ### -### 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 -} - -# Trim leading and trailing spaces from a string. -# Echos the new trimmed string. -trimString() { - local inputStr="$*" - local modStr="${inputStr#"${inputStr%%[![:space:]]*}"}" - modStr="${modStr%"${modStr##*[![:space:]]}"}" - echo "$modStr" -} - -declare -r sbt_bin_dir="$(dirname "$(realpathish "$0")")" -declare -r sbt_home="$(dirname "$sbt_bin_dir")" - -echoerr () { - echo 1>&2 "$@" -} -RED='\033[0;31m' -NC='\033[0m' # No Color -echoerr_error () { - if [[ $use_colors == "1" ]]; then - echoerr -e "[${RED}error${NC}] $@" - else - echoerr "[error] $@" - fi -} -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") - dlog "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"* ]]; 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_error "sbtn is not supported on $arch" - exit 2 - fi - elif [[ "$OSTYPE" == "darwin"* ]]; then - arch="universal" - archive_target="$p/sbtn-universal-apple-darwin-${sbtn_v}.tar.gz" - url="https://github.com/sbt/sbtn-dist/releases/download/v${sbtn_v}/sbtn-universal-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_error "sbtn is not supported on $OSTYPE" - exit 2 - fi - - if [[ -f "$target" ]]; then - sbtn_command="$target" - else - dlog "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 - echoerr "$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 - echoerr - echoerr "No Java Development Kit (JDK) installation was detected." - echoerr Go to https://adoptium.net/ etc and download. - echoerr - exit 1 - elif [[ "$good_enough" != "1" ]]; then - echoerr - echoerr "The Java Development Kit (JDK) installation you have is not up to date." - echoerr $script_name requires at least version $required_version+, you have - echoerr version $java_version - echoerr - echoerr Go to https://adoptium.net/ etc and download - echoerr 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 - 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 -} - -detect_working_directory() { - if [[ -f ./build.sbt || -f ./project/build.properties ]]; then - is_this_dir_sbt=1 - fi -} - -# Confirm a user's intent if the current directory does not look like an sbt -# top-level directory and neither the --allow-empty option nor the "new" command was given. -checkWorkingDirectory() { - if [[ ! -n "$allow_empty" ]]; then - [[ -n "$is_this_dir_sbt" || -n "$sbt_new" ]] || { - echoerr_error "Neither build.sbt nor a 'project' directory in the current directory: $(pwd)" - echoerr_error "run 'sbt new', touch build.sbt, or run 'sbt --allow-empty'." - echoerr_error "" - echoerr_error "To opt out of this check, create ${config_home}/sbtopts with:" - echoerr_error "--allow-empty" - exit 1 - } - 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 "8" - - # 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 - - detect_working_directory - 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 - if [[ -n "$is_this_dir_sbt" ]]; then - execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]/sbt version in this project:/g' - fi - echo "sbt runner version: $init_sbt_version" - echoerr "" - echoerr "[info] sbt runner (sbt-the-shell-script) is a runner to run any declared version of sbt." - echoerr "[info] Actual version of the sbt is declared using project/build.properties for each build." - elif [[ $shutdownall ]]; then - local sbt_processes=( $(jps -v | grep sbt-launch | cut -f1 -d ' ') ) - for procId in "${sbt_processes[@]}"; do - kill -9 $procId - done - echoerr "shutdown ${#sbt_processes[@]} sbt processes" - else - checkWorkingDirectory - # 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 machine_sbt_opts_file="${etc_sbt_opts_file}" -declare config_home="${XDG_CONFIG_HOME:-$HOME/.config}/sbt" -[[ -f "${config_home}/sbtopts" ]] && machine_sbt_opts_file="${config_home}/sbtopts" -[[ -f "$SBT_ETC_FILE" ]] && machine_sbt_opts_file="$SBT_ETC_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 - - -allow-empty|--allow-empty|-sbt-create|--sbt-create) allow_empty=true && shift ;; - - new|init) 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" -} - -## 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 )); then - if [[ "$use_sbtn" == "0" ]]; then - echo "false" - else - echo "true" - fi - elif ( (( $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 - - if [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then - sbt_script="$0.bat" - else - sbt_script="$0" - fi - sbt_script=${sbt_script/ /%20} - execRunner "$sbtn_command" "--sbt-script=$sbt_script" "${original_args[@]}" -} - -original_args=("$@") - -# Pull in the machine-wide settings configuration. -if [[ -f "$machine_sbt_opts_file" ]]; then - set -- $(loadConfigFile "$machine_sbt_opts_file") "$@" -else - # Otherwise pull in the default settings configuration. - [[ -f "$dist_sbt_opts_file" ]] && set -- $(loadConfigFile "$dist_sbt_opts_file") "$@" -fi - -# 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