diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 05c9d01f..bd8004e5 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -18,13 +18,10 @@ jobs: - uses: coursier/cache-action@v6 - uses: actions/setup-java@v3 with: - java-version: "8" + java-version: "11" distribution: "temurin" - name: Run tests - run: | - echo '-XX:MaxRAMPercentage=95.0' >> .mill-jvm-opts - ./mill -i --disable-ticker __.js.__.resolvedIvyDeps - ./mill -i --disable-ticker __.js.__.publishArtifacts + __.js.__.compile + __.js.__.fastOpt + __.js.__.test + run: ./mill -i __.js.__.test test-native: runs-on: ubuntu-22.04 steps: @@ -32,13 +29,10 @@ jobs: - uses: coursier/cache-action@v6 - uses: actions/setup-java@v3 with: - java-version: "8" + java-version: "11" distribution: "temurin" - name: Run tests - run: | - echo '-XX:MaxRAMPercentage=95.0' >> .mill-jvm-opts - ./mill -i --disable-ticker __.native.__.resolvedIvyDeps - ./mill -i --disable-ticker __.native.__.publishArtifacts + __.native.__.compile + __.native.__.test + run: ./mill -i __.native.__.test test-jvm: runs-on: ubuntu-22.04 steps: @@ -46,13 +40,10 @@ jobs: - uses: coursier/cache-action@v6 - uses: actions/setup-java@v3 with: - java-version: "8" + java-version: "11" distribution: "temurin" - name: Run tests - run: | - echo '-XX:MaxRAMPercentage=95.0' >> .mill-jvm-opts - ./mill -i --disable-ticker __.jvm.__.resolvedIvyDeps - ./mill -i --disable-ticker __.jvm.__.publishArtifacts + __.jvm.__.compile + __.jvm.__.test + run: ./mill -i __.jvm.__.test check-binary-compatibility: runs-on: ubuntu-22.04 steps: @@ -62,10 +53,10 @@ jobs: - uses: coursier/cache-action@v6 - uses: actions/setup-java@v3 with: - java-version: "8" + java-version: "11" distribution: "temurin" - name: Check Binary Compatibility - run: ./mill -i --disable-ticker __.mimaReportBinaryIssues + run: ./mill -i __.mimaReportBinaryIssues publish-sonatype: if: github.repository == 'com-lihaoyi/fastparse' && contains(github.ref, 'refs/tags/') @@ -73,7 +64,7 @@ jobs: - test-jvm - test-js - test-native - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest env: MILL_SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} MILL_SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} @@ -90,4 +81,14 @@ jobs: distribution: 'temurin' java-version: 11 - name: Publish to Maven Central - run: ./mill -i mill.scalalib.PublishModule/ + run: ./mill -i mill.scalalib.SonatypeCentralPublishModule/ + + - name: Create GitHub Release + id: create_gh_release + uses: actions/create-release@v1.1.4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: ${{ github.ref }} + release_name: ${{ github.ref }} + draft: false diff --git a/.mill-version b/.mill-version deleted file mode 100644 index ac454c6a..00000000 --- a/.mill-version +++ /dev/null @@ -1 +0,0 @@ -0.12.0 diff --git a/build.mill b/build.mill index 219dce07..73a8a176 100644 --- a/build.mill +++ b/build.mill @@ -1,3 +1,7 @@ +//| mill-version: 1.0.0 +//| mill-jvm-opts: ["-XX:NonProfiledCodeHeapSize=500m", "-XX:ReservedCodeCacheSize=1000m"] +//| mvnDeps: +//| - com.github.lolgab::mill-mima_mill1:0.2.0 package build import mill._ import scalalib._ @@ -5,13 +9,11 @@ import scalajslib._ import scalanativelib._ import publish._ import mill.api.Result -import mill.modules.Jvm.createJar +import mill.util.Jvm.createJar -import mill.scalalib.api.ZincWorkerUtil.isScala3 -import $ivy.`de.tototec::de.tobiasroeser.mill.vcs.version::0.4.0` -import $ivy.`com.github.lolgab::mill-mima::0.0.23` +import mill.javalib.api.JvmWorkerUtil.isScala3 -import de.tobiasroeser.mill.vcs.version.VcsVersion +import mill.util.VcsVersion import com.github.lolgab.mill.mima._ val scala3 = "3.3.3" @@ -30,13 +32,13 @@ object fastparse extends Module{ object js extends Cross[fastparseJsModule](crossVersions) trait fastparseJsModule extends FastparseModule with ScalaJSModule { def scalaJSVersion = scalaJS1 - private def sourceMapOptions = T.task { + private def sourceMapOptions = Task.Anon { val vcsState = VcsVersion.vcsState() vcsState.lastTag.collect { case tag if vcsState.commitsSinceLastTag == 0 => val baseUrl = pomSettings().url.replace("github.com", "raw.githubusercontent.com") val sourcesOptionName = if(isScala3(crossScalaVersion)) "-scalajs-mapSourceURI" else "-P:scalajs:mapSourceURI" - s"$sourcesOptionName:${T.workspace.toIO.toURI}->$baseUrl/$tag/" + s"$sourcesOptionName:${mill.api.BuildCtx.workspaceRoot.toIO.toURI}->$baseUrl/$tag/" } } @@ -55,17 +57,17 @@ object fastparse extends Module{ } trait FastparseModule extends CommonCrossModule with Mima{ - def ivyDeps = Agg( - ivy"com.lihaoyi::sourcecode::0.4.0", - ivy"com.lihaoyi::geny::1.1.0" + def mvnDeps = Seq( + mvn"com.lihaoyi::sourcecode::0.4.0", + mvn"com.lihaoyi::geny::1.1.0" ) - def compileIvyDeps = - if(isScala3(crossScalaVersion)) Agg.empty[Dep] - else Agg(ivy"org.scala-lang:scala-reflect:$crossScalaVersion") + def compileMvnDeps = + if(isScala3(crossScalaVersion)) Seq.empty[Dep] + else Seq(mvn"org.scala-lang:scala-reflect:$crossScalaVersion") - def generatedSources = T{ - val dir = T.ctx().dest + def generatedSources = Task { + val dir = Task.ctx().dest val file = dir/"fastparse"/"SequencerGen.scala" // Only go up to 21, because adding the last element makes it 22 val tuples = (2 to 21).map{ i => @@ -99,14 +101,14 @@ trait FastparseModule extends CommonCrossModule with Mima{ override def scalacOptions = super.scalacOptions() ++ - Agg.when(scalaVersion() != scala3)( + Seq( "-Xfatal-warnings", "-Xlint:unused", "-Wconf:cat=feature:s,cat=deprecation:s" - ) + ).filter(_ => scalaVersion() != scala3) def mimaReportBinaryIssues() = - if (this.isInstanceOf[ScalaNativeModule] || this.isInstanceOf[ScalaJSModule]) T.command() + if (this.isInstanceOf[ScalaNativeModule] || this.isInstanceOf[ScalaJSModule]) Task.Command {} else super.mimaReportBinaryIssues() def mimaPreviousVersions = Seq( @@ -117,7 +119,7 @@ trait FastparseModule extends CommonCrossModule with Mima{ ) def mimaPreviousArtifacts = - if (isScala3(crossScalaVersion)) Agg.empty[Dep] + if (isScala3(crossScalaVersion)) Seq.empty[Dep] else super.mimaPreviousArtifacts() def mimaBinaryIssueFilters = super.mimaBinaryIssueFilters() ++ Seq( @@ -170,10 +172,10 @@ trait ExampleParseJvmModule extends CommonCrossModule{ def moduleDeps = Seq(fastparse.jvm()) object test extends ScalaTests with CommonTestModule{ - def ivyDeps = super.ivyDeps() ++ Agg( - ivy"net.sourceforge.cssparser:cssparser:0.9.18", - ) ++ Agg.when(!isScala3(crossScalaVersion))( - ivy"org.scala-lang:scala-compiler:$crossScalaVersion" + def mvnDeps = super.mvnDeps() ++ Seq( + mvn"net.sourceforge.cssparser:cssparser:0.9.18", + ) ++ Option.when(!isScala3(crossScalaVersion))( + mvn"org.scala-lang:scala-compiler:$crossScalaVersion" ) } } @@ -202,24 +204,22 @@ trait CommonCrossModule extends CrossScalaModule with PublishModule with Platfor ) ) - def scalaDocPluginClasspath = T{ Agg[PathRef]() } + def scalaDocPluginClasspath = Task { Seq[PathRef]() } - def sources = T.sources { - super.sources() ++ - Agg(PathRef(millSourcePath / "src-2.12+")) - } + def newSources = Task.Sources("src-2.12+") + def sources = Task { super.sources() ++ newSources() } } -trait CommonTestModule extends ScalaModule with TestModule.Utest{ - def ivyDeps = Agg(ivy"com.lihaoyi::utest::0.8.3") +trait CommonTestModule extends ScalaModule with TestModule.Utest { + def mvnDeps = Seq(mvn"com.lihaoyi::utest::0.8.3") override def scalacOptions = super.scalacOptions() ++ - Agg.when(scalaVersion() != scala3)( + Seq( "-Xfatal-warnings", "-Xlint:unused", "-Wconf:cat=feature:s,cat=deprecation:s" - ) + ).filter(_ => scalaVersion() != scala3) } object perftests extends Module{ @@ -235,7 +235,7 @@ object perftests extends Module{ object benchScala33 extends PerfTestModule { def scalaVersion0 = scala3 - def sources = T.sources { bench2.sources() } + def sources = Task { bench2.sources() } def moduleDeps = Seq( scalaparse.jvm(scala3).test, pythonparse.jvm(scala3).test, @@ -253,30 +253,30 @@ object perftests extends Module{ pythonparse.jvm(scala212).test ) - def ivyDeps = super.ivyDeps() ++ Agg( - ivy"org.json4s::json4s-ast:3.6.0", - ivy"org.json4s::json4s-native:3.6.0", - ivy"org.json4s::json4s-jackson:3.6.0", - ivy"io.circe::circe-parser:0.9.1", - ivy"io.argonaut::argonaut:6.2", - ivy"com.typesafe.play::play-json:2.6.9", - ivy"com.fasterxml.jackson.core:jackson-databind:2.9.4", - ivy"com.lihaoyi::ujson:1.1.0", - ivy"org.scala-lang.modules::scala-parser-combinators:1.1.1", - ivy"org.python:jython:2.7.1b3" + def mvnDeps = super.mvnDeps() ++ Seq( + mvn"org.json4s::json4s-ast:3.6.0", + mvn"org.json4s::json4s-native:3.6.0", + mvn"org.json4s::json4s-jackson:3.6.0", + mvn"io.circe::circe-parser:0.9.1", + mvn"io.argonaut::argonaut:6.2", + mvn"com.typesafe.play::play-json:2.6.9", + mvn"com.fasterxml.jackson.core:jackson-databind:2.9.4", + mvn"com.lihaoyi::ujson:1.1.0", + mvn"org.scala-lang.modules::scala-parser-combinators:1.1.1", + mvn"org.python:jython:2.7.1b3" ) } - trait PerfTestModule extends ScalaModule with TestModule.Utest{ + trait PerfTestModule extends ScalaModule with TestModule.Utest { def scalaVersion0: String def scalaVersion = scalaVersion0 def scalacOptions = Seq("-opt:l:method") - def resources = T.sources{ - Seq(PathRef(perftests.millSourcePath / "resources")) ++ - fastparse.jvm(scalaVersion0).test.resources() + def newResources = Task.Sources(perftests.moduleDir / "resources") + def resources = Task { + newResources() ++ fastparse.jvm(scalaVersion0).test.resources() } - def ivyDeps = Agg(ivy"com.lihaoyi::utest::0.8.3") + def mvnDeps = Seq(mvn"com.lihaoyi::utest::0.8.3") } } @@ -290,8 +290,8 @@ object demo extends ScalaJSModule{ fastparse.js(scala213).test, ) - def ivyDeps = Agg( - ivy"org.scala-js::scalajs-dom::0.9.8", - ivy"com.lihaoyi::scalatags::0.9.3" + def mvnDeps = Seq( + mvn"org.scala-js::scalajs-dom::0.9.8", + mvn"com.lihaoyi::scalatags::0.9.3" ) } diff --git a/mill b/mill index d03a045c..22777fc7 100755 --- a/mill +++ b/mill @@ -1,51 +1,307 @@ #!/usr/bin/env sh -# This is a wrapper script, that automatically download mill from GitHub release pages -# You can give the required mill version with MILL_VERSION env variable -# If no version is given, it falls back to the value of DEFAULT_MILL_VERSION +# 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 [ -z "${DEFAULT_MILL_VERSION}" ] ; then - DEFAULT_MILL_VERSION=0.11.12 + DEFAULT_MILL_VERSION=1.0.0-RC1 fi -if [ -z "$MILL_VERSION" ] ; then + +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="$(head -n 1 .mill-version 2> /dev/null)" + MILL_VERSION="$(tr '\r' '\n' < .mill-version | head -n 1 2> /dev/null)" elif [ -f ".config/mill-version" ] ; then - MILL_VERSION="$(head -n 1 .config/mill-version 2> /dev/null)" - elif [ -f "mill" ] && [ "$0" != "mill" ] ; then - MILL_VERSION=$(grep -F "DEFAULT_MILL_VERSION=" "mill" | head -n 1 | cut -d= -f2) - else - MILL_VERSION=$DEFAULT_MILL_VERSION + 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 -if [ "x${XDG_CACHE_HOME}" != "x" ] ; then - MILL_DOWNLOAD_PATH="${XDG_CACHE_HOME}/mill/download" -else - MILL_DOWNLOAD_PATH="${HOME}/.cache/mill/download" +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 -MILL_EXEC_PATH="${MILL_DOWNLOAD_PATH}/${MILL_VERSION}" -version_remainder="$MILL_VERSION" -MILL_MAJOR_VERSION="${version_remainder%%.*}"; version_remainder="${version_remainder#*.}" -MILL_MINOR_VERSION="${version_remainder%%.*}"; version_remainder="${version_remainder#*.}" +# 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 -if [ ! -s "$MILL_EXEC_PATH" ] ; then - mkdir -p "$MILL_DOWNLOAD_PATH" - if [ "$MILL_MAJOR_VERSION" -gt 0 ] || [ "$MILL_MINOR_VERSION" -ge 5 ] ; then - ASSEMBLY="-assembly" +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 - DOWNLOAD_FILE=$MILL_EXEC_PATH-tmp-download - MILL_VERSION_TAG=$(echo $MILL_VERSION | sed -E 's/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/') - MILL_DOWNLOAD_URL="https://repo1.maven.org/maven2/com/lihaoyi/mill-dist/$MILL_VERSION/mill-dist-$MILL_VERSION.jar" - curl --fail -L -o "$DOWNLOAD_FILE" "$MILL_DOWNLOAD_URL" - chmod +x "$DOWNLOAD_FILE" - mv "$DOWNLOAD_FILE" "$MILL_EXEC_PATH" +} + +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 MILL_DOWNLOAD_URL + unset DOWNLOAD_SUFFIX fi if [ -z "$MILL_MAIN_CLI" ] ; then @@ -53,15 +309,19 @@ if [ -z "$MILL_MAIN_CLI" ] ; then fi MILL_FIRST_ARG="" - - # first arg is a long flag for "--interactive" or starts with "-i" -if [ "$1" = "--bsp" ] || [ "${1#"-i"}" != "$1" ] || [ "$1" = "--interactive" ] || [ "$1" = "--no-server" ] || [ "$1" = "--repl" ] || [ "$1" = "--help" ] ; then +if [ "$1" = "--bsp" ] || [ "$1" = "-i" ] || [ "$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 -exec $MILL_EXEC_PATH $MILL_FIRST_ARG -D "mill.main.cli=${MILL_MAIN_CLI}" "$@" +# -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}" "$@"