Skip to content

Commit

Permalink
Use coursier-based Mill launchers
Browse files Browse the repository at this point in the history
So that we can bump the coursier version used by Mill, to fix some
snapshot artifacts-related issues.
  • Loading branch information
alexarchambault committed Feb 23, 2022
1 parent b35aeef commit 30df98f
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 69 deletions.
7 changes: 7 additions & 0 deletions .mill-cs-opts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Java 17 required for domain socket stuff
--jvm
temurin:17
# fixes some issues when fetching snapshot artifacts
io.get-coursier::coursier:2.1.0-M2
--scala
2.13.8
202 changes: 187 additions & 15 deletions mill
Original file line number Diff line number Diff line change
@@ -1,25 +1,197 @@
#!/usr/bin/env bash

# This is a wrapper script, that automatically download mill via coursier
# You can give the required mill version with --mill-version parameter
# If no version is given, it falls back to the value of DEFAULT_MILL_VERSION
#
# Project page: https://github.com/coursier/millw
# Original project page: https://github.com/lefou/millw
# Script Version: 0.4.0-cs
#
# If you want to improve this script, please also contribute your changes back!
#
# Licensed under the Apache License, Version 2.0


DEFAULT_MILL_VERSION=0.9.10

set -e

# This script ensures:
# - that we're using the right JVM (currently, temurin:17)
# - that we run the mill launcher script with bash rather than sh,
# as the latter has issues with '+' characters, that can appear
# in the JVM entry put in PATH by 'cs'.
MILL_REPO_URL="https://github.com/com-lihaoyi/mill"

if [ "x${CURL_CMD}" = "x" ] ; then
CURL_CMD=curl
fi

# Explicit commandline argument takes precedence over all other methods
if [ "x$1" = "x--mill-version" ] ; then
shift
if [ "x$1" != "x" ] ; then
MILL_VERSION="$1"
shift
else
echo "You specified --mill-version without a version." 1>&2
echo "Please provide a version that matches one provided on" 1>&2
echo "${MILL_REPO_URL}/releases" 1>&2
false
fi
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 [ "x${MILL_VERSION}" = "x" ] ; then
if [ -f ".mill-version" ] ; then
MILL_VERSION="$(head -n 1 .mill-version 2> /dev/null)"
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"
fi

# If not already set, try to fetch newest from Github
if [ "x${MILL_VERSION}" = "x" ] ; then
# TODO: try to load latest version from release page
echo "No mill version specified." 1>&2
echo "You should provide a version via '.mill-version' file or --mill-version option." 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"
)

if [ "${MILL_DOWNLOAD_PATH}/.latest" -nt "${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 [ "x${MILL_VERSION}" = "x" ] ; 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 [ "x${MILL_VERSION}" = "x" ] ; 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

unset MILL_DOWNLOAD_PATH
unset MILL_OLD_DOWNLOAD_PATH
unset OLD_MILL
unset MILL_VERSION_TAG
unset MILL_REPO_URL

if [ "x$1" == "x-i" -o "x$1" == "x--interactive" ]; then
MILL_APP_NAME="mill-interactive"
else
MILL_APP_NAME="mill"
fi

mill_cs_opts=()

# Adapted from Mill 0.10.0-M5 assembly
init_mill_jvm_opts() {
if [ -z $MILL_JVM_OPTS_PATH ] ; then
mill_jvm_opts_file=".mill-jvm-opts"
else
mill_jvm_opts_file=$MILL_JVM_OPTS_PATH
fi

if [ -f "$mill_jvm_opts_file" ] ; then
while IFS= read line
do
case $line in
"-X"*) mill_cs_opts=("${mill_cs_opts[@]}" "--java-opt" "$line")
esac
done <"$mill_jvm_opts_file"
fi
}

init_mill_cs_opts() {
if [ -z $MILL_CS_OPTS_PATH ] ; then
mill_cs_opts_file=".mill-cs-opts"
else
mill_cs_opts_file=$MILL_CS_OPTS_PATH
fi

if [ -f "$mill_cs_opts_file" ] ; then
while IFS= read line
do
case $line in
"#"*) ;;
*) mill_cs_opts=("${mill_cs_opts[@]}" "$line") ;;
esac
done <"$mill_cs_opts_file"
fi
}

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"

if ! command -v cs >/dev/null; then
cat 1>&2 << EOF
cs command not found.
# Adapted from

Please download a cs launcher from
https://github.com/coursier/coursier/releases/tag/v2.1.0-M2
and install it as 'cs' in your PATH.
EOF
exit 1
coursier_version="2.1.0-M2"

# https://stackoverflow.com/questions/3466166/how-to-check-if-running-in-cygwin-mac-or-linux/17072017#17072017
if [ "$(expr substr $(uname -s) 1 5 2>/dev/null)" == "Linux" ]; then
cs_url="https://github.com/coursier/coursier/releases/download/v$coursier_version/cs-x86_64-pc-linux.gz"
cache_base="$HOME/.cache/coursier/v1"
elif [ "$(uname)" == "Darwin" ]; then
cs_url="https://github.com/coursier/coursier/releases/download/v$coursier_version/cs-x86_64-apple-darwin.gz"
cache_base="$HOME/Library/Caches/Coursier/v1"
else
# assuming Windows…
cs_url="https://github.com/coursier/coursier/releases/download/v$coursier_version/cs-x86_64-pc-win32.zip"
cache_base="$LOCALAPPDATA/Coursier/v1" # TODO Check that
ext=".exe"
do_chmod="0"
fi

cache_dest="$cache_base/$(echo "$cs_url" | sed 's@://@/@')"

if [ ! -f "$cache_dest" ]; then
mkdir -p "$(dirname "$cache_dest")"
tmp_dest="$cache_dest.tmp-setup"
echo "Downloading $cs_url"
curl -fLo "$tmp_dest" "$cs_url"
mv "$tmp_dest" "$cache_dest"
fi

if [[ "$cache_dest" == *.gz ]]; then
cs="$(dirname "$cache_dest")/$(basename "$cache_dest" .gz)"
if [ ! -f "$cs" ]; then
gzip -d < "$cache_dest" > "$cs"
fi
if [ ! -x "$cs" ]; then
chmod +x "$cs"
fi
elif [[ "$cache_dest" == *.zip ]]; then
cs="$(dirname "$cache_dest")/$(basename "$cache_dest" .zip).exe"
if [ ! -f "$cs" ]; then
unzip -p "$cache_dest" "$(basename "$cache_dest" .zip).exe" > "$cs"
fi
fi

eval "$(cs java --env --jvm temurin:17 || cs java --env --jvm openjdk:1.17.0)"
export PATH=".:$PATH"



init_mill_jvm_opts
init_mill_cs_opts

exec /usr/bin/env bash "$DIR/millw" "$@"
exec "$cs" launch "$MILL_APP_NAME:$MILL_VERSION" "${mill_cs_opts[@]}" -- "$@"
121 changes: 67 additions & 54 deletions mill.bat
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
@echo off

rem This is a wrapper script, that automatically download mill from GitHub release pages
rem This is a wrapper script, that automatically download mill via coursier
rem You can give the required mill version with --mill-version parameter
rem If no version is given, it falls back to the value of DEFAULT_MILL_VERSION
rem
rem Project page: https://github.com/lefou/millw
rem Project page: https://github.com/coursier/millw
rem Original project page: https://github.com/lefou/millw
rem Script Version: 0.4.0-cs
rem
rem If you want to improve this script, please also contribute your changes back!
rem
Expand Down Expand Up @@ -42,57 +44,6 @@ if [!MILL_VERSION!]==[] (
set MILL_VERSION=%DEFAULT_MILL_VERSION%
)

set MILL_DOWNLOAD_PATH=%USERPROFILE%\.mill\download

rem without bat file extension, cmd doesn't seem to be able to run it
set MILL=%MILL_DOWNLOAD_PATH%\!MILL_VERSION!.bat

if not exist "%MILL%" (
set VERSION_PREFIX=%MILL_VERSION:~0,4%
set DOWNLOAD_SUFFIX=-assembly
if [!VERSION_PREFIX!]==[0.0.] set DOWNLOAD_SUFFIX=
if [!VERSION_PREFIX!]==[0.1.] set DOWNLOAD_SUFFIX=
if [!VERSION_PREFIX!]==[0.2.] set DOWNLOAD_SUFFIX=
if [!VERSION_PREFIX!]==[0.3.] set DOWNLOAD_SUFFIX=
if [!VERSION_PREFIX!]==[0.4.] set DOWNLOAD_SUFFIX=
set VERSION_PREFIX=

for /F "delims=-" %%A in ("!MILL_VERSION!") do (
set MILL_BASE_VERSION=%%A
)

rem there seems to be no way to generate a unique temporary file path (on native Windows)
set DOWNLOAD_FILE=%MILL%.tmp

set DOWNLOAD_URL=%MILL_REPO_URL%/releases/download/!MILL_BASE_VERSION!/!MILL_VERSION!!DOWNLOAD_SUFFIX!

echo Downloading mill %MILL_VERSION% from %MILL_REPO_URL%/releases ...

if not exist "%MILL_DOWNLOAD_PATH%" mkdir "%MILL_DOWNLOAD_PATH%"
rem curl is bundled with recent Windows 10
rem but I don't think we can expect all the users to have it in 2019
where /Q curl
if %ERRORLEVEL% EQU 0 (
curl -L "!DOWNLOAD_URL!" -o "!DOWNLOAD_FILE!"
) else (
rem bitsadmin seems to be available on Windows 7
rem without /dynamic, github returns 403
rem bitsadmin is sometimes needlessly slow but it looks better with /priority foreground
bitsadmin /transfer millDownloadJob /dynamic /priority foreground "!DOWNLOAD_URL!" "!DOWNLOAD_FILE!"
)
if not exist "!DOWNLOAD_FILE!" (
echo Could not download mill %MILL_VERSION%
exit /b 1
)

move /y "!DOWNLOAD_FILE!" "%MILL%"

set DOWNLOAD_FILE=
set DOWNLOAD_SUFFIX=
)

set MILL_DOWNLOAD_PATH=
set MILL_VERSION=
set MILL_REPO_URL=

set MILL_PARAMS=%*
Expand All @@ -106,4 +57,66 @@ if defined STRIP_VERSION_PARAMS (
)
)

"%MILL%" %MILL_PARAMS%
if "%1" == "-i" set _I_=true
if "%1" == "--interactive" set _I_=true
if defined _I_ (
set MILL_APP_NAME="mill-interactive"
) else (
set MILL_APP_NAME="mill"
)

set "mill_cs_opts="

set "mill_jvm_opts_file=.mill-jvm-opts"
if not "%MILL_JVM_OPTS_PATH%"=="" set "mill_jvm_opts_file=%MILL_JVM_OPTS_PATH%"
if exist %mill_jvm_opts_file% (
for /f "delims=" %%G in (%mill_jvm_opts_file%) do (
set line=%%G
if "!line:~0,2!"=="-X" set "mill_cs_opts=!mill_cs_opts! --java-opt !line!"
)
)

set "mill_cs_opts_file=.mill-cs-opts"
if not "%MILL_CS_OPTS_PATH%"=="" set "mill_cs_opts_file=%MILL_CS_OPTS_PATH%"
if exist %mill_cs_opts_file% (
for /f "delims=" %%G in (%mill_cs_opts_file%) do (
set line=%%G
if not "!line:~0,1!"=="#" set "mill_cs_opts=!mill_cs_opts! !line!"
)
)

rem Disabled for now, having issues with 'tar', that seems to use a Git Bash-provided (?)
rem binary rather than a Windows-provided one, when run from Git Bash. The latter accepts
rem zip files, while the former doesn't.

rem Adapted from the Mill 0.10.0-M5 assembly header
rem set "CS_DOWNLOAD_PATH=out"
rem set "CS_VERSION=2.1.0-M2"
rem set "CS=%CS_DOWNLOAD_PATH%\cs-%CS_VERSION%.exe"
rem set "DOWNLOAD_URL=https://github.com/coursier/coursier/releases/download/v%CS_VERSION%/cs-x86_64-pc-win32.zip"
rem set "DOWNLOAD_FILE=%CS_DOWNLOAD_PATH%\cs-%CS_VERSION%.zip"
rem if not exist "%CS_DOWNLOAD_PATH%" mkdir "%CS_DOWNLOAD_PATH%"
rem if not exist "%CS%" (
rem rem curl is bundled with recent Windows 10
rem rem but I don't think we can expect all the users to have it in 2019
rem where /Q curl
rem if %ERRORLEVEL% EQU 0 (
rem curl -f -L "!DOWNLOAD_URL!" -o "!DOWNLOAD_FILE!"
rem ) else (
rem rem bitsadmin seems to be available on Windows 7
rem rem without /dynamic, github returns 403
rem rem bitsadmin is sometimes needlessly slow but it looks better with /priority foreground
rem bitsadmin /transfer millDownloadJob /dynamic /priority foreground "!DOWNLOAD_URL!" "!DOWNLOAD_FILE!"
rem )
rem if not exist "!DOWNLOAD_FILE!" (
rem echo Could not download cs %CS_VERSION% 1>&2
rem exit /b 1 REM Seems this doesn't actually make the script exit with an error code…
rem )
rem
rem tar -xf "!DOWNLOAD_FILE!"
rem move /y "cs-x86_64-pc-win32.exe" "%CS%"
rem )

echo Using system found cs command. If anything goes wrong, ensure it's at least coursier 2.1.0-M2. 1>&2

cs launch --shared org.scala-lang:scala-library "%MILL_APP_NAME%:%MILL_VERSION%" !mill_cs_opts! -- %MILL_PARAMS%

0 comments on commit 30df98f

Please sign in to comment.