11#! /usr/bin/env sh
22
3- # This is a wrapper script, that automatically download mill from GitHub release pages
4- # You can give the required mill version with --mill-version parameter
5- # If no version is given, it falls back to the value of DEFAULT_MILL_VERSION
3+ # This is a wrapper script, that automatically selects or downloads Mill from Maven Central or GitHub release pages.
64#
7- # Project page: https://github.com/lefou/millw
8- # Script Version: 0.4.2
5+ # This script determines the Mill version to use by trying these sources
6+ # - env-variable `MILL_VERSION`
7+ # - local file `.mill-version`
8+ # - local file `.config/mill-version`
9+ # - `mill-version` from YAML fronmatter of current buildfile
10+ # - if accessible, find the latest stable version available on Maven Central (https://repo1.maven.org/maven2)
11+ # - env-variable `DEFAULT_MILL_VERSION`
12+ #
13+ # If a version has the suffix '-native' a native binary will be used.
14+ # If a version has the suffix '-jvm' an executable jar file will be used, requiring an already installed Java runtime.
15+ # If no such suffix is found, the script will pick a default based on version and platform.
16+ #
17+ # Once a version was determined, it tries to use either
18+ # - a system-installed mill, if found and it's version matches
19+ # - an already downloaded version under ~/.cache/mill/download
20+ #
21+ # If no working mill version was found on the system,
22+ # this script downloads a binary file from Maven Central or Github Pages (this is version dependent)
23+ # into a cache location (~/.cache/mill/download).
24+ #
25+ # Mill Project URL: https://github.com/com-lihaoyi/mill
26+ # Script Version: 0.13.0-M2-63-e8edbd
927#
1028# If you want to improve this script, please also contribute your changes back!
29+ # This script was generated from: scripts/src/mill.sh
1130#
1231# Licensed under the Apache License, Version 2.0
1332
33+ set -e
34+
35+ if [ -z " ${DEFAULT_MILL_VERSION} " ] ; then
36+ DEFAULT_MILL_VERSION=" 0.11.13"
37+ fi
1438
15- DEFAULT_MILL_VERSION=0.11.13
1639
17- set -e
40+ if [ -z " ${GITHUB_RELEASE_CDN} " ] ; then
41+ GITHUB_RELEASE_CDN=" "
42+ fi
43+
1844
1945MILL_REPO_URL=" https://github.com/com-lihaoyi/mill"
2046
2450
2551# Explicit commandline argument takes precedence over all other methods
2652if [ " $1 " = " --mill-version" ] ; then
27- shift
28- if [ " x$1 " != " x" ] ; then
29- MILL_VERSION=" $1 "
30- shift
31- else
32- echo " You specified --mill-version without a version." 1>&2
33- echo " Please provide a version that matches one provided on" 1>&2
34- echo " ${MILL_REPO_URL} /releases" 1>&2
35- false
36- fi
53+ echo " The --mill-version option is no longer supported." 1>&2
54+ fi
55+
56+ MILL_BUILD_SCRIPT=" "
57+
58+ if [ -f " build.mill" ] ; then
59+ MILL_BUILD_SCRIPT=" build.mill"
60+ elif [ -f " build.mill.scala" ] ; then
61+ MILL_BUILD_SCRIPT=" build.mill.scala"
62+ elif [ -f " build.sc" ] ; then
63+ MILL_BUILD_SCRIPT=" build.sc"
3764fi
3865
3966# Please note, that if a MILL_VERSION is already set in the environment,
4269# If not already set, read .mill-version file
4370if [ -z " ${MILL_VERSION} " ] ; then
4471 if [ -f " .mill-version" ] ; then
45- MILL_VERSION=" $( head -n 1 .mill-version 2> /dev/null) "
72+ MILL_VERSION=" $( tr ' \r' ' \n' < .mill-version | head -n 1 2> /dev/null) "
73+ elif [ -f " .config/mill-version" ] ; then
74+ MILL_VERSION=" $( tr ' \r' ' \n' < .config/mill-version | head -n 1 2> /dev/null) "
75+ elif [ -n " ${MILL_BUILD_SCRIPT} " ] ; then
76+ MILL_VERSION=" $( cat ${MILL_BUILD_SCRIPT} | grep ' //[|] *mill-version: *' | sed ' s;//| *mill-version: *;;' ) "
4677 fi
4778fi
4879
49- if [ -n " ${XDG_CACHE_HOME} " ] ; then
50- MILL_DOWNLOAD_PATH= " ${XDG_CACHE_HOME} /mill/download "
51- else
52- MILL_DOWNLOAD_PATH=" ${HOME} /.cache/mill /download"
80+ MILL_USER_CACHE_DIR= " ${XDG_CACHE_HOME:- ${HOME} / .cache} /mill "
81+
82+ if [ -z " ${MILL_DOWNLOAD_PATH} " ] ; then
83+ MILL_DOWNLOAD_PATH=" ${MILL_USER_CACHE_DIR} /download"
5384fi
5485
5586# If not already set, try to fetch newest from Github
5687if [ -z " ${MILL_VERSION} " ] ; then
5788 # TODO: try to load latest version from release page
5889 echo " No mill version specified." 1>&2
59- echo " You should provide a version via '. mill-version' file or -- mill-version option ." 1>&2
90+ echo " You should provide a version via a '//| mill-version: ' comment or a '. mill-version' file ." 1>&2
6091
6192 mkdir -p " ${MILL_DOWNLOAD_PATH} "
6293 LANG=C touch -d ' 1 hour ago' " ${MILL_DOWNLOAD_PATH} /.expire_latest" 2> /dev/null || (
@@ -92,37 +123,127 @@ if [ -z "${MILL_VERSION}" ] ; then
92123 fi
93124fi
94125
95- MILL=" ${MILL_DOWNLOAD_PATH} /${MILL_VERSION} "
126+ MILL_NATIVE_SUFFIX=" -native"
127+ MILL_JVM_SUFFIX=" -jvm"
128+ FULL_MILL_VERSION=$MILL_VERSION
129+ ARTIFACT_SUFFIX=" "
130+ set_artifact_suffix (){
131+ if [ " $( expr substr $( uname -s) 1 5 2> /dev/null) " = " Linux" ]; then
132+ if [ " $( uname -m) " = " aarch64" ]; then
133+ ARTIFACT_SUFFIX=" -native-linux-aarch64"
134+ else
135+ ARTIFACT_SUFFIX=" -native-linux-amd64"
136+ fi
137+ elif [ " $( uname) " = " Darwin" ]; then
138+ if [ " $( uname -m) " = " arm64" ]; then
139+ ARTIFACT_SUFFIX=" -native-mac-aarch64"
140+ else
141+ ARTIFACT_SUFFIX=" -native-mac-amd64"
142+ fi
143+ else
144+ echo " This native mill launcher supports only Linux and macOS." 1>&2
145+ exit 1
146+ fi
147+ }
148+
149+ case " $MILL_VERSION " in
150+ * " $MILL_NATIVE_SUFFIX " )
151+ MILL_VERSION=${MILL_VERSION% " $MILL_NATIVE_SUFFIX " }
152+ set_artifact_suffix
153+ ;;
154+
155+ * " $MILL_JVM_SUFFIX " )
156+ MILL_VERSION=${MILL_VERSION% " $MILL_JVM_SUFFIX " }
157+ ;;
158+
159+ * )
160+ case " $MILL_VERSION " in
161+ 0.1.* ) ;;
162+ 0.2.* ) ;;
163+ 0.3.* ) ;;
164+ 0.4.* ) ;;
165+ 0.5.* ) ;;
166+ 0.6.* ) ;;
167+ 0.7.* ) ;;
168+ 0.8.* ) ;;
169+ 0.9.* ) ;;
170+ 0.10.* ) ;;
171+ 0.11.* ) ;;
172+ 0.12.* ) ;;
173+ * )
174+ set_artifact_suffix
175+ esac
176+ ;;
177+ esac
178+
179+ MILL=" ${MILL_DOWNLOAD_PATH} /$MILL_VERSION$ARTIFACT_SUFFIX "
96180
97181try_to_use_system_mill () {
182+ if [ " $( uname) " != " Linux" ]; then
183+ return 0
184+ fi
185+
98186 MILL_IN_PATH=" $( command -v mill || true) "
99187
100188 if [ -z " ${MILL_IN_PATH} " ]; then
101- return
189+ return 0
102190 fi
103191
104- UNIVERSAL_SCRIPT_MAGIC=" @ 2>/dev/null # 2>nul & echo off & goto BOF"
192+ SYSTEM_MILL_FIRST_TWO_BYTES=$( head --bytes=2 " ${MILL_IN_PATH} " )
193+ if [ " ${SYSTEM_MILL_FIRST_TWO_BYTES} " = " #!" ]; then
194+ # MILL_IN_PATH is (very likely) a shell script and not the mill
195+ # executable, ignore it.
196+ return 0
197+ fi
105198
106- if ! head -c 128 " ${MILL_IN_PATH} " | grep -qF " ${UNIVERSAL_SCRIPT_MAGIC} " ; then
107- if [ -n " ${MILLW_VERBOSE} " ]; then
108- echo " Could not determine mill version of ${MILL_IN_PATH} , as it does not start with the universal script magic2" 1>&2
109- fi
110- return
199+ SYSTEM_MILL_PATH=$( readlink -e " ${MILL_IN_PATH} " )
200+ SYSTEM_MILL_SIZE=$( stat --format=%s " ${SYSTEM_MILL_PATH} " )
201+ SYSTEM_MILL_MTIME=$( stat --format=%y " ${SYSTEM_MILL_PATH} " )
202+
203+ if [ ! -d " ${MILL_USER_CACHE_DIR} " ]; then
204+ mkdir -p " ${MILL_USER_CACHE_DIR} "
111205 fi
112206
113- # Roughly the size of the universal script.
114- MILL_VERSION_SEARCH_RANGE=" 2403"
115- MILL_IN_PATH_VERSION=$( head -c " ${MILL_VERSION_SEARCH_RANGE} " " ${MILL_IN_PATH} " | \
116- sed -n ' s/^.*-DMILL_VERSION=\([^\s]*\) .*$/\1/p' | \
117- head -n 1)
207+ SYSTEM_MILL_INFO_FILE=" ${MILL_USER_CACHE_DIR} /system-mill-info"
208+ if [ -f " ${SYSTEM_MILL_INFO_FILE} " ]; then
209+ parseSystemMillInfo () {
210+ LINE_NUMBER=" ${1} "
211+ # Select the line number of the SYSTEM_MILL_INFO_FILE, cut the
212+ # variable definition in that line in two halves and return
213+ # the value, and finally remove the quotes.
214+ sed -n " ${LINE_NUMBER} p" " ${SYSTEM_MILL_INFO_FILE} " | \
215+ cut -d= -f2 | \
216+ sed ' s/"\(.*\)"/\1/'
217+ }
218+
219+ CACHED_SYSTEM_MILL_PATH=$( parseSystemMillInfo 1)
220+ CACHED_SYSTEM_MILL_VERSION=$( parseSystemMillInfo 2)
221+ CACHED_SYSTEM_MILL_SIZE=$( parseSystemMillInfo 3)
222+ CACHED_SYSTEM_MILL_MTIME=$( parseSystemMillInfo 4)
118223
119- if [ -z " ${MILL_IN_PATH_VERSION} " ]; then
120- echo " Could not determine mill version, even though ${MILL_IN_PATH} has the universal script magic" 1>&2
121- return
224+ if [ " ${SYSTEM_MILL_PATH} " = " ${CACHED_SYSTEM_MILL_PATH} " ] \
225+ && [ " ${SYSTEM_MILL_SIZE} " = " ${CACHED_SYSTEM_MILL_SIZE} " ] \
226+ && [ " ${SYSTEM_MILL_MTIME} " = " ${CACHED_SYSTEM_MILL_MTIME} " ]; then
227+ if [ " ${CACHED_SYSTEM_MILL_VERSION} " = " ${MILL_VERSION} " ]; then
228+ MILL=" ${SYSTEM_MILL_PATH} "
229+ return 0
230+ else
231+ return 0
232+ fi
233+ fi
122234 fi
123235
124- if [ " ${MILL_IN_PATH_VERSION} " = " ${MILL_VERSION} " ]; then
125- MILL=" ${MILL_IN_PATH} "
236+ SYSTEM_MILL_VERSION=$( ${SYSTEM_MILL_PATH} --version | head -n1 | sed -n ' s/^Mill.*version \(.*\)/\1/p' )
237+
238+ cat << EOF > "${SYSTEM_MILL_INFO_FILE} "
239+ CACHED_SYSTEM_MILL_PATH="${SYSTEM_MILL_PATH} "
240+ CACHED_SYSTEM_MILL_VERSION="${SYSTEM_MILL_VERSION} "
241+ CACHED_SYSTEM_MILL_SIZE="${SYSTEM_MILL_SIZE} "
242+ CACHED_SYSTEM_MILL_MTIME="${SYSTEM_MILL_MTIME} "
243+ EOF
244+
245+ if [ " ${SYSTEM_MILL_VERSION} " = " ${MILL_VERSION} " ]; then
246+ MILL=" ${SYSTEM_MILL_PATH} "
126247 fi
127248}
128249try_to_use_system_mill
@@ -136,22 +257,34 @@ if [ ! -s "${MILL}" ] ; then
136257 if [ -x " ${OLD_MILL} " ] ; then
137258 MILL=" ${OLD_MILL} "
138259 else
139- VERSION_PREFIX=" $( echo $MILL_VERSION | cut -b -4) "
140- case $VERSION_PREFIX in
141- 0.0. | 0.1. | 0.2. | 0.3. | 0.4. )
260+ case $MILL_VERSION in
261+ 0.0.* | 0.1.* | 0.2.* | 0.3.* | 0.4.* )
142262 DOWNLOAD_SUFFIX=" "
263+ DOWNLOAD_FROM_MAVEN=0
264+ ;;
265+ 0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.0-M* )
266+ DOWNLOAD_SUFFIX=" -assembly"
267+ DOWNLOAD_FROM_MAVEN=0
143268 ;;
144269 * )
145270 DOWNLOAD_SUFFIX=" -assembly"
271+ DOWNLOAD_FROM_MAVEN=1
146272 ;;
147273 esac
148- unset VERSION_PREFIX
149274
150275 DOWNLOAD_FILE=$( mktemp mill.XXXXXX)
276+
277+ if [ " $DOWNLOAD_FROM_MAVEN " = " 1" ] ; then
278+ DOWNLOAD_URL=" https://repo1.maven.org/maven2/com/lihaoyi/mill-dist${ARTIFACT_SUFFIX} /${MILL_VERSION} /mill-dist${ARTIFACT_SUFFIX} -${MILL_VERSION} .jar"
279+ else
280+ MILL_VERSION_TAG=$( echo " $MILL_VERSION " | sed -E ' s/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/' )
281+ DOWNLOAD_URL=" ${GITHUB_RELEASE_CDN}${MILL_REPO_URL} /releases/download/${MILL_VERSION_TAG} /${MILL_VERSION}${DOWNLOAD_SUFFIX} "
282+ unset MILL_VERSION_TAG
283+ fi
284+
151285 # TODO: handle command not found
152- echo " Downloading mill ${MILL_VERSION} from ${MILL_REPO_URL} /releases ..." 1>&2
153- MILL_VERSION_TAG=$( echo $MILL_VERSION | sed -E ' s/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/' )
154- ${CURL_CMD} -f -L -o " ${DOWNLOAD_FILE} " " ${MILL_REPO_URL} /releases/download/${MILL_VERSION_TAG} /${MILL_VERSION}${DOWNLOAD_SUFFIX} "
286+ echo " Downloading mill ${MILL_VERSION} from ${DOWNLOAD_URL} ..." 1>&2
287+ ${CURL_CMD} -f -L -o " ${DOWNLOAD_FILE} " " ${DOWNLOAD_URL} "
155288 chmod +x " ${DOWNLOAD_FILE} "
156289 mkdir -p " ${MILL_DOWNLOAD_PATH} "
157290 mv " ${DOWNLOAD_FILE} " " ${MILL} "
@@ -161,11 +294,24 @@ if [ ! -s "${MILL}" ] ; then
161294 fi
162295fi
163296
297+ if [ -z " $MILL_MAIN_CLI " ] ; then
298+ MILL_MAIN_CLI=" ${0} "
299+ fi
300+
301+ MILL_FIRST_ARG=" "
302+ if [ " $1 " = " --bsp" ] || [ " $1 " = " -i" ] || [ " $1 " = " --interactive" ] || [ " $1 " = " --no-server" ] || [ " $1 " = " --repl" ] || [ " $1 " = " --help" ] ; then
303+ # Need to preserve the first position of those listed options
304+ MILL_FIRST_ARG=$1
305+ shift
306+ fi
307+
164308unset MILL_DOWNLOAD_PATH
165309unset MILL_OLD_DOWNLOAD_PATH
166310unset OLD_MILL
167311unset MILL_VERSION
168- unset MILL_VERSION_TAG
169312unset MILL_REPO_URL
170313
171- exec " ${MILL} " " $@ "
314+ # -D mill.main.cli is for compatibility with Mill 0.10.9 - 0.13.0-M2
315+ # We don't quote MILL_FIRST_ARG on purpose, so we can expand the empty value without quotes
316+ # shellcheck disable=SC2086
317+ exec " ${MILL} " $MILL_FIRST_ARG -D " mill.main.cli=${MILL_MAIN_CLI} " " $@ "
0 commit comments