diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 923a595..01a5355 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,49 +1,28 @@ name: build - on: [ push ] - jobs: - server: runs-on: ubuntu-latest steps: - - - uses: actions/checkout@v1 - - - uses: actions/cache@v4 - with: - path: ~/.cache/coursier/v1 - key: ${{ runner.os }}-coursier-${{ hashFiles('**/build.sbt') }} - - - name: Set up java - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 21 - - - name: Set up sbt - uses: sbt/setup-sbt@v1 - - - name: Build - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: sbt server/stage - + - uses: actions/checkout@v3 + - name: Compile + run: ./mill __.compile + - name: Build distributable + run: ./mill server.assembly - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@master - - name: Login to GitHub Container Registry uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Push images uses: docker/build-push-action@v2 with: context: . + file: Dockerfile platforms: linux/amd64,linux/arm64 push: true tags: ghcr.io/torrentdam/server:${{ github.sha }}, ghcr.io/torrentdam/server:latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3a2ca54..76de7c7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,32 +1,21 @@ name: release - on: push: tags: - 'v*' - jobs: - release: if: startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest steps: - - - uses: actions/checkout@v1 - - - name: Set up java - uses: actions/setup-java@v2.1.0 - with: - distribution: adopt - java-version: 17 - java-package: jre - - - name: Publish + - uses: actions/checkout@v3 + - name: Release env: - SONATYPE_CREDS: ${{ secrets.SONATYPE_CREDS }} - PGP_SECRET_KEY: ${{ secrets.PGP_SECRET_KEY }} + MILL_SONATYPE_USERNAME: ${{ secrets.MILL_SONATYPE_USERNAME }} + MILL_SONATYPE_PASSWORD: ${{ secrets.MILL_SONATYPE_PASSWORD }} + MILL_PGP_SECRET_BASE64: ${{ secrets.MILL_PGP_SECRET_BASE64 }} + MILL_PGP_PASSPHRASE: ${{ secrets.MILL_PGP_PASSPHRASE }} run: | - echo ${PGP_SECRET_KEY} | base64 --decode | gpg --import - export VERSION=${GITHUB_REF#*/v} + export VERSION=${GITHUB_REF#*/v} echo Publishing $VERSION - sbt protocolJS/publishSigned + ./mill mill.javalib.SonatypeCentralPublishModule/ diff --git a/.gitignore b/.gitignore index 48d0944..f5b03a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,7 @@ -target +out .idea .idea_modules .metals .bloop .bsp -.vscode -node_modules -package-lock.json +logs diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..6912837 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,23 @@ +# Build/Test Commands + +```bash +# Compile all modules +./mill __.compile + +# Run the server +./mill server.run + +# Build executable server JAR +./mill server.assembly + +# Format code with Scalafmt +./mill mill.scalalib.scalafmt.ScalafmtModule/reformatAll __.sources +``` + +## Project Structure + +- **build.mill**: Mill build definition (primary) +- **protocol/**: Protocol message types shared with the web client +- **server/**: HTTP server entry point + +Each module has `src/main/scala/` diff --git a/Dockerfile b/Dockerfile index de5cf74..33749d3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,8 @@ FROM eclipse-temurin:25-jre-noble - -COPY ./server/target/universal/stage /opt/bittorrent-server - -ENTRYPOINT ["/opt/bittorrent-server/bin/server", "-Dcats.effect.tracing.mode=none", "-J-XX:+UnlockExperimentalVMOptions", "-J-XX:+UseCompactObjectHeaders"] +COPY ./out/server/assembly.dest/out.jar /opt/torrentdam/server.jar +ENTRYPOINT ["java", \ + "-Dcats.effect.tracing.mode=none", \ + "-XX:+UnlockExperimentalVMOptions", \ + "-XX:+UseCompactObjectHeaders", \ + "-jar", \ + "/opt/torrentdam/server.jar"] diff --git a/build.mill b/build.mill new file mode 100644 index 0000000..3301848 --- /dev/null +++ b/build.mill @@ -0,0 +1,85 @@ +//| mill-version: 1.1.8 +//| mill-jvm-version: temurin:21.0.6 +import mill.*, scalalib.*, publish.* + +object protocol extends CommonSettings { + def mvnDeps = Seq( + Deps.bittorrent.common, + Deps.upickle, + Deps.`scodec-bits`, + ) +} + +object server extends CommonSettings { + def moduleDeps = Seq(protocol) + def mvnDeps = Seq( + Deps.bittorrent.bittorrent, + Deps.bittorrent.dht, + Deps.`cats-effect`, + Deps.`fs2-io`, + Deps.http4s.core, + Deps.http4s.dsl, + Deps.http4s.server, + Deps.http4s.client, + Deps.`woof-core`, + Deps.`woof-slf4j`, + Deps.`cats-effect-cps`, + ) +} + +trait CommonSettings extends ScalaModule, PublishModule { + def scalaVersion = "3.8.3" + def scalacOptions = Seq( + "-source:future", + "-Xkind-projector:underscores", + ) + def sources = Task.Sources( + moduleDir / "src" / "main" / "scala" + ) + def resources = Task.Sources( + moduleDir / "src" / "main" / "resources" + ) + def publishVersion = sys.env.getOrElse("VERSION", "SNAPSHOT") + def pomSettings = PomSettings( + description = "Bittorrent server protocol", + organization = "io.github.torrentdam.server", + url = "https://github.com/TorrentDam/server", + licenses = Seq(License.`Unlicense`), + versionControl = VersionControl.github("TorrentDam", "server"), + developers = Seq( + Developer("lavrov", "Vitaly Lavrov", "https://github.com/lavrov") + ) + ) +} + +object Deps { + object Versions { + val bittorrent = "3.8.0" + val `cats-effect` = "3.6.0" + val fs2 = "3.12.2" + val `scodec-bits` = "1.2.4" + val upickle = "2.0.0" + val http4s = "1.0.0-M40" + val `cats-effect-cps` = "0.9.21" + val woof = "0.9.0" + } + object bittorrent { + private val org = "io.github.torrentdam.bittorrent" + val common = mvn"${org}::common::${Versions.bittorrent}" + val bittorrent = mvn"${org}::bittorrent::${Versions.bittorrent}" + val dht = mvn"${org}::dht::${Versions.bittorrent}" + } + val `cats-effect` = mvn"org.typelevel::cats-effect::${Versions.`cats-effect`}" + val `fs2-io` = mvn"co.fs2::fs2-io::${Versions.fs2}" + val `scodec-bits` = mvn"org.scodec::scodec-bits::${Versions.`scodec-bits`}" + val upickle = mvn"com.lihaoyi::upickle::${Versions.upickle}" + object http4s { + val core = mvn"org.http4s::http4s-core::${Versions.http4s}" + val dsl = mvn"org.http4s::http4s-dsl::${Versions.http4s}" + val server = mvn"org.http4s::http4s-ember-server::${Versions.http4s}" + val client = mvn"org.http4s::http4s-ember-client::${Versions.http4s}" + } + val `cats-effect-cps` = mvn"com.github.rssh::cps-async-connect-cats-effect::${Versions.`cats-effect-cps`}" + val `woof-core` = mvn"org.legogroup::woof-core::${Versions.woof}" + val `woof-slf4j` = mvn"org.legogroup::woof-slf4j::${Versions.woof}" +} diff --git a/build.sbt b/build.sbt deleted file mode 100644 index 6106df6..0000000 --- a/build.sbt +++ /dev/null @@ -1,127 +0,0 @@ -import sbt.Keys.credentials - -lazy val root = project.in(file(".")).aggregate(server) - -lazy val protocol = crossProject(JSPlatform, JVMPlatform).crossType(CrossType.Pure) - .settings(commonSettings ++ publishSettings) - .settings( - description := "Bittorrent server protocol", - libraryDependencies ++= List( - Deps.bittorrent.common.value, - Deps.upickle.value, - Deps.`scodec-bits`.value, - ) - ) - -lazy val server = project - .dependsOn(protocol.jvm) - .settings(commonSettings) - .settings( - libraryDependencies ++= List( - Deps.bittorrent.bittorrent, - Deps.bittorrent.dht, - Deps.`cats-effect`, - Deps.`fs2-io`, - Deps.http4s.core, - Deps.http4s.dsl, - Deps.http4s.server, - Deps.http4s.client, - Deps.`woof-core`, - Deps.`woof-slf4j`, - ), - ) - .enablePlugins(JavaAppPackaging) - -lazy val commonSettings: List[Setting[_]] = List( - organization := "io.github.torrentdam.server", - version := sys.env.getOrElse("VERSION", "SNAPSHOT"), - scalaVersion := "3.8.3", - scalacOptions ++= List( - "-source:future", - "-Xkind-projector:underscores", - ), - libraryDependencies ++= List( - Deps.`cps-async-cats-effect`, - Deps.`munit-cats-effect` % Test - ) -) - -lazy val publishSettings: List[Setting[_]] = List( - publishTo := { - val nexus = "https://s01.oss.sonatype.org/" - Some("releases" at nexus + "service/local/staging/deploy/maven2") - }, - credentials ++= { - sys.env.get("SONATYPE_CREDS") match { - case Some(credentials) => - val Array(username, password) = credentials.split(':') - List( - Credentials( - "Sonatype Nexus Repository Manager", - "s01.oss.sonatype.org", - username, - password - ) - ) - case None => List.empty[Credentials] - } - }, - developers := List( - Developer( - id = "lavrov", - name = "Vitaly Lavrov", - email = "lavrovvv@gmail.com", - url = url("https://github.com/lavrov") - ) - ), - scmInfo := Some( - ScmInfo( - url("https://github.com/TorrentDam/server"), - "scm:git@github.com:TorrentDam/server.git" - ) - ), - licenses := List("Unlicense" -> url("https://unlicense.org/")), - homepage := Some(url("https://torrentdam.github.io/")) -) - -lazy val Deps = new { - - val bittorrent = new { - private val org = "io.github.torrentdam.bittorrent" - val common = Def.setting { org %%% "common" % Versions.bittorrent } - val bittorrent = org %% "bittorrent" % Versions.bittorrent - val dht = org %% "dht" % Versions.bittorrent - } - - val `scodec-bits` = Def.setting {"org.scodec" %%% "scodec-bits" % Versions.`scodec-bits` } - - val `cats-effect` = "org.typelevel" %% "cats-effect" % Versions.`cats-effect` - val `fs2-io` = "co.fs2" %% "fs2-io" % Versions.fs2 - - val http4s = new { - val core = "org.http4s" %% "http4s-core" % Versions.http4s - val dsl = "org.http4s" %% "http4s-dsl" % Versions.http4s - val server = "org.http4s" %% "http4s-ember-server" % Versions.http4s - val client = "org.http4s" %% "http4s-ember-client" % Versions.http4s - } - - val `woof-core` = "org.legogroup" %% "woof-core" % Versions.woof - val `woof-slf4j` = "org.legogroup" %% "woof-slf4j" % Versions.woof - - val upickle = Def.setting {"com.lihaoyi" %%% "upickle" % Versions.upickle } - - val `munit-cats-effect` = "org.typelevel" %% "munit-cats-effect-3" % "1.0.7" - - val `cps-async-cats-effect` = "com.github.rssh" %% "cps-async-connect-cats-effect" % Versions.`cps-async` -} - -lazy val Versions = new { - val bittorrent = "3.8.0" - val `cats-effect` = "3.6.0" - val fs2 = "3.12.2" - val `scodec-bits` = "1.2.4" - val upickle = "2.0.0" - val http4s = "1.0.0-M40" - val `cps-async` = "0.9.21" - val woof = "0.9.0" -} diff --git a/mill b/mill new file mode 100755 index 0000000..8475523 --- /dev/null +++ b/mill @@ -0,0 +1,333 @@ +#!/usr/bin/env sh + +# This is a wrapper script, that automatically selects or downloads Mill from Maven Central or GitHub release pages. +# +# This script determines the Mill version to use by trying these sources +# - env-variable `MILL_VERSION` +# - local file `.mill-version` +# - local file `.config/mill-version` +# - `mill-version` from YAML fronmatter of current buildfile +# - if accessible, find the latest stable version available on Maven Central (https://repo1.maven.org/maven2) +# - env-variable `DEFAULT_MILL_VERSION` +# +# If a version has the suffix '-native' a native binary will be used. +# If a version has the suffix '-jvm' an executable jar file will be used, requiring an already installed Java runtime. +# If no such suffix is found, the script will pick a default based on version and platform. +# +# Once a version was determined, it tries to use either +# - a system-installed mill, if found and it's version matches +# - an already downloaded version under ~/.cache/mill/download +# +# If no working mill version was found on the system, +# this script downloads a binary file from Maven Central or Github Pages (this is version dependent) +# into a cache location (~/.cache/mill/download). +# +# Mill Project URL: https://github.com/com-lihaoyi/mill +# Script Version: 1.0.0-M1-21-7b6fae-DIRTY892b63e8 +# +# If you want to improve this script, please also contribute your changes back! +# This script was generated from: dist/scripts/src/mill.sh +# +# Licensed under the Apache License, Version 2.0 + +set -e + +if [ "$1" = "--setup-completions" ] ; then + # Need to preserve the first position of those listed options + MILL_FIRST_ARG=$1 + shift +fi + +if [ -z "${DEFAULT_MILL_VERSION}" ] ; then + DEFAULT_MILL_VERSION=1.0.1 +fi + + +if [ -z "${GITHUB_RELEASE_CDN}" ] ; then + GITHUB_RELEASE_CDN="" +fi + + +MILL_REPO_URL="https://github.com/com-lihaoyi/mill" + +if [ -z "${CURL_CMD}" ] ; then + CURL_CMD=curl +fi + +# Explicit commandline argument takes precedence over all other methods +if [ "$1" = "--mill-version" ] ; then + echo "The --mill-version option is no longer supported." 1>&2 +fi + +MILL_BUILD_SCRIPT="" + +if [ -f "build.mill" ] ; then + MILL_BUILD_SCRIPT="build.mill" +elif [ -f "build.mill.scala" ] ; then + MILL_BUILD_SCRIPT="build.mill.scala" +elif [ -f "build.sc" ] ; then + MILL_BUILD_SCRIPT="build.sc" +fi + +# Please note, that if a MILL_VERSION is already set in the environment, +# We reuse it's value and skip searching for a value. + +# If not already set, read .mill-version file +if [ -z "${MILL_VERSION}" ] ; then + if [ -f ".mill-version" ] ; then + MILL_VERSION="$(tr '\r' '\n' < .mill-version | head -n 1 2> /dev/null)" + elif [ -f ".config/mill-version" ] ; then + MILL_VERSION="$(tr '\r' '\n' < .config/mill-version | head -n 1 2> /dev/null)" + elif [ -n "${MILL_BUILD_SCRIPT}" ] ; then + MILL_VERSION="$(cat ${MILL_BUILD_SCRIPT} | grep '//[|] *mill-version: *' | sed 's;//| *mill-version: *;;')" + fi +fi + +MILL_USER_CACHE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/mill" + +if [ -z "${MILL_DOWNLOAD_PATH}" ] ; then + MILL_DOWNLOAD_PATH="${MILL_USER_CACHE_DIR}/download" +fi + +# If not already set, try to fetch newest from Github +if [ -z "${MILL_VERSION}" ] ; then + # TODO: try to load latest version from release page + echo "No mill version specified." 1>&2 + echo "You should provide a version via a '//| mill-version: ' comment or a '.mill-version' file." 1>&2 + + mkdir -p "${MILL_DOWNLOAD_PATH}" + LANG=C touch -d '1 hour ago' "${MILL_DOWNLOAD_PATH}/.expire_latest" 2>/dev/null || ( + # we might be on OSX or BSD which don't have -d option for touch + # but probably a -A [-][[hh]mm]SS + touch "${MILL_DOWNLOAD_PATH}/.expire_latest"; touch -A -010000 "${MILL_DOWNLOAD_PATH}/.expire_latest" + ) || ( + # in case we still failed, we retry the first touch command with the intention + # to show the (previously suppressed) error message + LANG=C touch -d '1 hour ago' "${MILL_DOWNLOAD_PATH}/.expire_latest" + ) + + # POSIX shell variant of bash's -nt operator, see https://unix.stackexchange.com/a/449744/6993 + # if [ "${MILL_DOWNLOAD_PATH}/.latest" -nt "${MILL_DOWNLOAD_PATH}/.expire_latest" ] ; then + if [ -n "$(find -L "${MILL_DOWNLOAD_PATH}/.latest" -prune -newer "${MILL_DOWNLOAD_PATH}/.expire_latest")" ]; then + # we know a current latest version + MILL_VERSION=$(head -n 1 "${MILL_DOWNLOAD_PATH}"/.latest 2> /dev/null) + fi + + if [ -z "${MILL_VERSION}" ] ; then + # we don't know a current latest version + echo "Retrieving latest mill version ..." 1>&2 + LANG=C ${CURL_CMD} -s -i -f -I ${MILL_REPO_URL}/releases/latest 2> /dev/null | grep --ignore-case Location: | sed s'/^.*tag\///' | tr -d '\r\n' > "${MILL_DOWNLOAD_PATH}/.latest" + MILL_VERSION=$(head -n 1 "${MILL_DOWNLOAD_PATH}"/.latest 2> /dev/null) + fi + + if [ -z "${MILL_VERSION}" ] ; then + # Last resort + MILL_VERSION="${DEFAULT_MILL_VERSION}" + echo "Falling back to hardcoded mill version ${MILL_VERSION}" 1>&2 + else + echo "Using mill version ${MILL_VERSION}" 1>&2 + fi +fi + +MILL_NATIVE_SUFFIX="-native" +MILL_JVM_SUFFIX="-jvm" +FULL_MILL_VERSION=$MILL_VERSION +ARTIFACT_SUFFIX="" +set_artifact_suffix(){ + if [ "$(expr substr $(uname -s) 1 5 2>/dev/null)" = "Linux" ]; then + if [ "$(uname -m)" = "aarch64" ]; then + ARTIFACT_SUFFIX="-native-linux-aarch64" + else + ARTIFACT_SUFFIX="-native-linux-amd64" + fi + elif [ "$(uname)" = "Darwin" ]; then + if [ "$(uname -m)" = "arm64" ]; then + ARTIFACT_SUFFIX="-native-mac-aarch64" + else + ARTIFACT_SUFFIX="-native-mac-amd64" + fi + else + echo "This native mill launcher supports only Linux and macOS." 1>&2 + exit 1 + fi +} + +case "$MILL_VERSION" in + *"$MILL_NATIVE_SUFFIX") + MILL_VERSION=${MILL_VERSION%"$MILL_NATIVE_SUFFIX"} + set_artifact_suffix + ;; + + *"$MILL_JVM_SUFFIX") + MILL_VERSION=${MILL_VERSION%"$MILL_JVM_SUFFIX"} + ;; + + *) + case "$MILL_VERSION" in + 0.1.*) ;; + 0.2.*) ;; + 0.3.*) ;; + 0.4.*) ;; + 0.5.*) ;; + 0.6.*) ;; + 0.7.*) ;; + 0.8.*) ;; + 0.9.*) ;; + 0.10.*) ;; + 0.11.*) ;; + 0.12.*) ;; + *) + set_artifact_suffix + esac + ;; +esac + +MILL="${MILL_DOWNLOAD_PATH}/$MILL_VERSION$ARTIFACT_SUFFIX" + +try_to_use_system_mill() { + if [ "$(uname)" != "Linux" ]; then + return 0 + fi + + MILL_IN_PATH="$(command -v mill || true)" + + if [ -z "${MILL_IN_PATH}" ]; then + return 0 + fi + + SYSTEM_MILL_FIRST_TWO_BYTES=$(head --bytes=2 "${MILL_IN_PATH}") + if [ "${SYSTEM_MILL_FIRST_TWO_BYTES}" = "#!" ]; then + # MILL_IN_PATH is (very likely) a shell script and not the mill + # executable, ignore it. + return 0 + fi + + SYSTEM_MILL_PATH=$(readlink -e "${MILL_IN_PATH}") + SYSTEM_MILL_SIZE=$(stat --format=%s "${SYSTEM_MILL_PATH}") + SYSTEM_MILL_MTIME=$(stat --format=%y "${SYSTEM_MILL_PATH}") + + if [ ! -d "${MILL_USER_CACHE_DIR}" ]; then + mkdir -p "${MILL_USER_CACHE_DIR}" + fi + + SYSTEM_MILL_INFO_FILE="${MILL_USER_CACHE_DIR}/system-mill-info" + if [ -f "${SYSTEM_MILL_INFO_FILE}" ]; then + parseSystemMillInfo() { + LINE_NUMBER="${1}" + # Select the line number of the SYSTEM_MILL_INFO_FILE, cut the + # variable definition in that line in two halves and return + # the value, and finally remove the quotes. + sed -n "${LINE_NUMBER}p" "${SYSTEM_MILL_INFO_FILE}" |\ + cut -d= -f2 |\ + sed 's/"\(.*\)"/\1/' + } + + CACHED_SYSTEM_MILL_PATH=$(parseSystemMillInfo 1) + CACHED_SYSTEM_MILL_VERSION=$(parseSystemMillInfo 2) + CACHED_SYSTEM_MILL_SIZE=$(parseSystemMillInfo 3) + CACHED_SYSTEM_MILL_MTIME=$(parseSystemMillInfo 4) + + if [ "${SYSTEM_MILL_PATH}" = "${CACHED_SYSTEM_MILL_PATH}" ] \ + && [ "${SYSTEM_MILL_SIZE}" = "${CACHED_SYSTEM_MILL_SIZE}" ] \ + && [ "${SYSTEM_MILL_MTIME}" = "${CACHED_SYSTEM_MILL_MTIME}" ]; then + if [ "${CACHED_SYSTEM_MILL_VERSION}" = "${MILL_VERSION}" ]; then + MILL="${SYSTEM_MILL_PATH}" + return 0 + else + return 0 + fi + fi + fi + + SYSTEM_MILL_VERSION=$(${SYSTEM_MILL_PATH} --version | head -n1 | sed -n 's/^Mill.*version \(.*\)/\1/p') + + cat < "${SYSTEM_MILL_INFO_FILE}" +CACHED_SYSTEM_MILL_PATH="${SYSTEM_MILL_PATH}" +CACHED_SYSTEM_MILL_VERSION="${SYSTEM_MILL_VERSION}" +CACHED_SYSTEM_MILL_SIZE="${SYSTEM_MILL_SIZE}" +CACHED_SYSTEM_MILL_MTIME="${SYSTEM_MILL_MTIME}" +EOF + + if [ "${SYSTEM_MILL_VERSION}" = "${MILL_VERSION}" ]; then + MILL="${SYSTEM_MILL_PATH}" + fi +} +try_to_use_system_mill + +# If not already downloaded, download it +if [ ! -s "${MILL}" ] || [ "$MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT" = "1" ] ; then + case $MILL_VERSION in + 0.0.* | 0.1.* | 0.2.* | 0.3.* | 0.4.* ) + DOWNLOAD_SUFFIX="" + DOWNLOAD_FROM_MAVEN=0 + ;; + 0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.0-M* ) + DOWNLOAD_SUFFIX="-assembly" + DOWNLOAD_FROM_MAVEN=0 + ;; + *) + DOWNLOAD_SUFFIX="-assembly" + DOWNLOAD_FROM_MAVEN=1 + ;; + esac + case $MILL_VERSION in + 0.12.0 | 0.12.1 | 0.12.2 | 0.12.3 | 0.12.4 | 0.12.5 | 0.12.6 | 0.12.7 | 0.12.8 | 0.12.9 | 0.12.10 | 0.12.11 ) + DOWNLOAD_EXT="jar" + ;; + 0.12.* ) + DOWNLOAD_EXT="exe" + ;; + 0.* ) + DOWNLOAD_EXT="jar" + ;; + *) + DOWNLOAD_EXT="exe" + ;; + esac + + DOWNLOAD_FILE=$(mktemp mill.XXXXXX) + if [ "$DOWNLOAD_FROM_MAVEN" = "1" ] ; then + DOWNLOAD_URL="https://repo1.maven.org/maven2/com/lihaoyi/mill-dist${ARTIFACT_SUFFIX}/${MILL_VERSION}/mill-dist${ARTIFACT_SUFFIX}-${MILL_VERSION}.${DOWNLOAD_EXT}" + else + MILL_VERSION_TAG=$(echo "$MILL_VERSION" | sed -E 's/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/') + DOWNLOAD_URL="${GITHUB_RELEASE_CDN}${MILL_REPO_URL}/releases/download/${MILL_VERSION_TAG}/${MILL_VERSION}${DOWNLOAD_SUFFIX}" + unset MILL_VERSION_TAG + fi + + if [ "$MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT" = "1" ] ; then + echo $DOWNLOAD_URL + echo $MILL + exit 0 + fi + # TODO: handle command not found + echo "Downloading mill ${MILL_VERSION} from ${DOWNLOAD_URL} ..." 1>&2 + ${CURL_CMD} -f -L -o "${DOWNLOAD_FILE}" "${DOWNLOAD_URL}" + chmod +x "${DOWNLOAD_FILE}" + mkdir -p "${MILL_DOWNLOAD_PATH}" + mv "${DOWNLOAD_FILE}" "${MILL}" + + unset DOWNLOAD_FILE + unset DOWNLOAD_SUFFIX +fi + +if [ -z "$MILL_MAIN_CLI" ] ; then + MILL_MAIN_CLI="${0}" +fi + +MILL_FIRST_ARG="" +if [ "$1" = "--bsp" ] || [ "${1#"-i"}" != "$1" ] || [ "$1" = "--interactive" ] || [ "$1" = "--no-server" ] || [ "$1" = "--no-daemon" ] || [ "$1" = "--repl" ] || [ "$1" = "--help" ] ; then + # Need to preserve the first position of those listed options + MILL_FIRST_ARG=$1 + shift +fi + +unset MILL_DOWNLOAD_PATH +unset MILL_OLD_DOWNLOAD_PATH +unset OLD_MILL +unset MILL_VERSION +unset MILL_REPO_URL + +# -D mill.main.cli is for compatibility with Mill 0.10.9 - 0.13.0-M2 +# We don't quote MILL_FIRST_ARG on purpose, so we can expand the empty value without quotes +# shellcheck disable=SC2086 +exec "${MILL}" $MILL_FIRST_ARG -D "mill.main.cli=${MILL_MAIN_CLI}" "$@" diff --git a/project/build.properties b/project/build.properties deleted file mode 100644 index ee4c672..0000000 --- a/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=1.10.1 diff --git a/project/plugins.sbt b/project/plugins.sbt deleted file mode 100644 index 5ff8e92..0000000 --- a/project/plugins.sbt +++ /dev/null @@ -1,4 +0,0 @@ -addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.8.0") -addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.9") -addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2")