1+ #! /usr/bin/env sh
2+
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
6+ #
7+ # Original Project page: https://github.com/lefou/millw
8+ # Script Version: 0.4.12
9+ #
10+ # If you want to improve this script, please also contribute your changes back!
11+ #
12+ # Licensed under the Apache License, Version 2.0
13+
14+ set -e
15+
16+ if [ -z " ${DEFAULT_MILL_VERSION} " ] ; then
17+ DEFAULT_MILL_VERSION=" 0.11.4"
18+ fi
19+
20+
21+ if [ -z " ${GITHUB_RELEASE_CDN} " ] ; then
22+ GITHUB_RELEASE_CDN=" "
23+ fi
24+
25+
26+ MILL_REPO_URL=" https://github.com/com-lihaoyi/mill"
27+
28+ if [ -z " ${CURL_CMD} " ] ; then
29+ CURL_CMD=curl
30+ fi
31+
32+ # Explicit commandline argument takes precedence over all other methods
33+ if [ " $1 " = " --mill-version" ] ; then
34+ shift
35+ if [ " x$1 " != " x" ] ; then
36+ MILL_VERSION=" $1 "
37+ shift
38+ else
39+ echo " You specified --mill-version without a version." 1>&2
40+ echo " Please provide a version that matches one provided on" 1>&2
41+ echo " ${MILL_REPO_URL} /releases" 1>&2
42+ false
43+ fi
44+ fi
45+
46+ # Please note, that if a MILL_VERSION is already set in the environment,
47+ # We reuse it's value and skip searching for a value.
48+
49+ # If not already set, read .mill-version file
50+ if [ -z " ${MILL_VERSION} " ] ; then
51+ if [ -f " .mill-version" ] ; then
52+ MILL_VERSION=" $( tr ' \r' ' \n' < .mill-version | head -n 1 2> /dev/null) "
53+ elif [ -f " .config/mill-version" ] ; then
54+ MILL_VERSION=" $( tr ' \r' ' \n' < .config/mill-version | head -n 1 2> /dev/null) "
55+ fi
56+ fi
57+
58+ MILL_USER_CACHE_DIR=" ${XDG_CACHE_HOME:- ${HOME} / .cache} /mill"
59+
60+ if [ -z " ${MILL_DOWNLOAD_PATH} " ] ; then
61+ MILL_DOWNLOAD_PATH=" ${MILL_USER_CACHE_DIR} /download"
62+ fi
63+
64+ # If not already set, try to fetch newest from Github
65+ if [ -z " ${MILL_VERSION} " ] ; then
66+ # TODO: try to load latest version from release page
67+ echo " No mill version specified." 1>&2
68+ echo " You should provide a version via '.mill-version' file or --mill-version option." 1>&2
69+
70+ mkdir -p " ${MILL_DOWNLOAD_PATH} "
71+ LANG=C touch -d ' 1 hour ago' " ${MILL_DOWNLOAD_PATH} /.expire_latest" 2> /dev/null || (
72+ # we might be on OSX or BSD which don't have -d option for touch
73+ # but probably a -A [-][[hh]mm]SS
74+ touch " ${MILL_DOWNLOAD_PATH} /.expire_latest" ; touch -A -010000 " ${MILL_DOWNLOAD_PATH} /.expire_latest"
75+ ) || (
76+ # in case we still failed, we retry the first touch command with the intention
77+ # to show the (previously suppressed) error message
78+ LANG=C touch -d ' 1 hour ago' " ${MILL_DOWNLOAD_PATH} /.expire_latest"
79+ )
80+
81+ # POSIX shell variant of bash's -nt operator, see https://unix.stackexchange.com/a/449744/6993
82+ # if [ "${MILL_DOWNLOAD_PATH}/.latest" -nt "${MILL_DOWNLOAD_PATH}/.expire_latest" ] ; then
83+ if [ -n " $( find -L " ${MILL_DOWNLOAD_PATH} /.latest" -prune -newer " ${MILL_DOWNLOAD_PATH} /.expire_latest" ) " ]; then
84+ # we know a current latest version
85+ MILL_VERSION=$( head -n 1 " ${MILL_DOWNLOAD_PATH} " /.latest 2> /dev/null)
86+ fi
87+
88+ if [ -z " ${MILL_VERSION} " ] ; then
89+ # we don't know a current latest version
90+ echo " Retrieving latest mill version ..." 1>&2
91+ 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"
92+ MILL_VERSION=$( head -n 1 " ${MILL_DOWNLOAD_PATH} " /.latest 2> /dev/null)
93+ fi
94+
95+ if [ -z " ${MILL_VERSION} " ] ; then
96+ # Last resort
97+ MILL_VERSION=" ${DEFAULT_MILL_VERSION} "
98+ echo " Falling back to hardcoded mill version ${MILL_VERSION} " 1>&2
99+ else
100+ echo " Using mill version ${MILL_VERSION} " 1>&2
101+ fi
102+ fi
103+
104+ MILL_NATIVE_SUFFIX=" -native"
105+ FULL_MILL_VERSION=$MILL_VERSION
106+ ARTIFACT_SUFFIX=" "
107+ case " $MILL_VERSION " in
108+ * " $MILL_NATIVE_SUFFIX " )
109+ MILL_VERSION=${MILL_VERSION% " $MILL_NATIVE_SUFFIX " }
110+ if [ " $( expr substr $( uname -s) 1 5 2> /dev/null) " = " Linux" ]; then
111+ if [ " $( uname -m) " = " aarch64" ]; then
112+ ARTIFACT_SUFFIX=" -native-linux-aarch64"
113+ else
114+ ARTIFACT_SUFFIX=" -native-linux-amd64"
115+ fi
116+ elif [ " $( uname) " = " Darwin" ]; then
117+ if [ " $( uname -m) " = " arm64" ]; then
118+ ARTIFACT_SUFFIX=" -native-mac-aarch64"
119+ else
120+ ARTIFACT_SUFFIX=" -native-mac-amd64"
121+ fi
122+ else
123+ echo " This native mill launcher supports only Linux and macOS." 1>&2
124+ exit 1
125+ fi
126+ esac
127+
128+ MILL=" ${MILL_DOWNLOAD_PATH} /${FULL_MILL_VERSION} "
129+
130+ try_to_use_system_mill () {
131+ if [ " $( uname) " != " Linux" ]; then
132+ return 0
133+ fi
134+
135+ MILL_IN_PATH=" $( command -v mill || true) "
136+
137+ if [ -z " ${MILL_IN_PATH} " ]; then
138+ return 0
139+ fi
140+
141+ SYSTEM_MILL_FIRST_TWO_BYTES=$( head --bytes=2 " ${MILL_IN_PATH} " )
142+ if [ " ${SYSTEM_MILL_FIRST_TWO_BYTES} " = " #!" ]; then
143+ # MILL_IN_PATH is (very likely) a shell script and not the mill
144+ # executable, ignore it.
145+ return 0
146+ fi
147+
148+ SYSTEM_MILL_PATH=$( readlink -e " ${MILL_IN_PATH} " )
149+ SYSTEM_MILL_SIZE=$( stat --format=%s " ${SYSTEM_MILL_PATH} " )
150+ SYSTEM_MILL_MTIME=$( stat --format=%y " ${SYSTEM_MILL_PATH} " )
151+
152+ if [ ! -d " ${MILL_USER_CACHE_DIR} " ]; then
153+ mkdir -p " ${MILL_USER_CACHE_DIR} "
154+ fi
155+
156+ SYSTEM_MILL_INFO_FILE=" ${MILL_USER_CACHE_DIR} /system-mill-info"
157+ if [ -f " ${SYSTEM_MILL_INFO_FILE} " ]; then
158+ parseSystemMillInfo () {
159+ LINE_NUMBER=" ${1} "
160+ # Select the line number of the SYSTEM_MILL_INFO_FILE, cut the
161+ # variable definition in that line in two halves and return
162+ # the value, and finally remove the quotes.
163+ sed -n " ${LINE_NUMBER} p" " ${SYSTEM_MILL_INFO_FILE} " | \
164+ cut -d= -f2 | \
165+ sed ' s/"\(.*\)"/\1/'
166+ }
167+
168+ CACHED_SYSTEM_MILL_PATH=$( parseSystemMillInfo 1)
169+ CACHED_SYSTEM_MILL_VERSION=$( parseSystemMillInfo 2)
170+ CACHED_SYSTEM_MILL_SIZE=$( parseSystemMillInfo 3)
171+ CACHED_SYSTEM_MILL_MTIME=$( parseSystemMillInfo 4)
172+
173+ if [ " ${SYSTEM_MILL_PATH} " = " ${CACHED_SYSTEM_MILL_PATH} " ] \
174+ && [ " ${SYSTEM_MILL_SIZE} " = " ${CACHED_SYSTEM_MILL_SIZE} " ] \
175+ && [ " ${SYSTEM_MILL_MTIME} " = " ${CACHED_SYSTEM_MILL_MTIME} " ]; then
176+ if [ " ${CACHED_SYSTEM_MILL_VERSION} " = " ${MILL_VERSION} " ]; then
177+ MILL=" ${SYSTEM_MILL_PATH} "
178+ return 0
179+ else
180+ return 0
181+ fi
182+ fi
183+ fi
184+
185+ SYSTEM_MILL_VERSION=$( ${SYSTEM_MILL_PATH} --version | head -n1 | sed -n ' s/^Mill.*version \(.*\)/\1/p' )
186+
187+ cat << EOF > "${SYSTEM_MILL_INFO_FILE} "
188+ CACHED_SYSTEM_MILL_PATH="${SYSTEM_MILL_PATH} "
189+ CACHED_SYSTEM_MILL_VERSION="${SYSTEM_MILL_VERSION} "
190+ CACHED_SYSTEM_MILL_SIZE="${SYSTEM_MILL_SIZE} "
191+ CACHED_SYSTEM_MILL_MTIME="${SYSTEM_MILL_MTIME} "
192+ EOF
193+
194+ if [ " ${SYSTEM_MILL_VERSION} " = " ${MILL_VERSION} " ]; then
195+ MILL=" ${SYSTEM_MILL_PATH} "
196+ fi
197+ }
198+ try_to_use_system_mill
199+
200+ # If not already downloaded, download it
201+ if [ ! -s " ${MILL} " ] ; then
202+
203+ # support old non-XDG download dir
204+ MILL_OLD_DOWNLOAD_PATH=" ${HOME} /.mill/download"
205+ OLD_MILL=" ${MILL_OLD_DOWNLOAD_PATH} /${MILL_VERSION} "
206+ if [ -x " ${OLD_MILL} " ] ; then
207+ MILL=" ${OLD_MILL} "
208+ else
209+ case $MILL_VERSION in
210+ 0.0.* | 0.1.* | 0.2.* | 0.3.* | 0.4.* )
211+ DOWNLOAD_SUFFIX=" "
212+ DOWNLOAD_FROM_MAVEN=0
213+ ;;
214+ 0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.0-M* )
215+ DOWNLOAD_SUFFIX=" -assembly"
216+ DOWNLOAD_FROM_MAVEN=0
217+ ;;
218+ * )
219+ DOWNLOAD_SUFFIX=" -assembly"
220+ DOWNLOAD_FROM_MAVEN=1
221+ ;;
222+ esac
223+
224+ DOWNLOAD_FILE=$( mktemp mill.XXXXXX)
225+
226+ if [ " $DOWNLOAD_FROM_MAVEN " = " 1" ] ; then
227+ DOWNLOAD_URL=" https://repo1.maven.org/maven2/com/lihaoyi/mill-dist${ARTIFACT_SUFFIX} /${MILL_VERSION} /mill-dist${ARTIFACT_SUFFIX} -${MILL_VERSION} .jar"
228+ else
229+ MILL_VERSION_TAG=$( echo " $MILL_VERSION " | sed -E ' s/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/' )
230+ DOWNLOAD_URL=" ${GITHUB_RELEASE_CDN}${MILL_REPO_URL} /releases/download/${MILL_VERSION_TAG} /${MILL_VERSION}${DOWNLOAD_SUFFIX} "
231+ unset MILL_VERSION_TAG
232+ fi
233+
234+ # TODO: handle command not found
235+ echo " Downloading mill ${MILL_VERSION} from ${DOWNLOAD_URL} ..." 1>&2
236+ ${CURL_CMD} -f -L -o " ${DOWNLOAD_FILE} " " ${DOWNLOAD_URL} "
237+ chmod +x " ${DOWNLOAD_FILE} "
238+ mkdir -p " ${MILL_DOWNLOAD_PATH} "
239+ mv " ${DOWNLOAD_FILE} " " ${MILL} "
240+
241+ unset DOWNLOAD_FILE
242+ unset DOWNLOAD_SUFFIX
243+ fi
244+ fi
245+
246+ if [ -z " $MILL_MAIN_CLI " ] ; then
247+ MILL_MAIN_CLI=" ${0} "
248+ fi
249+
250+ MILL_FIRST_ARG=" "
251+ if [ " $1 " = " --bsp" ] || [ " $1 " = " -i" ] || [ " $1 " = " --interactive" ] || [ " $1 " = " --no-server" ] || [ " $1 " = " --repl" ] || [ " $1 " = " --help" ] ; then
252+ # Need to preserve the first position of those listed options
253+ MILL_FIRST_ARG=$1
254+ shift
255+ fi
256+
257+ unset MILL_DOWNLOAD_PATH
258+ unset MILL_OLD_DOWNLOAD_PATH
259+ unset OLD_MILL
260+ unset MILL_VERSION
261+ unset MILL_REPO_URL
262+
263+ # We don't quote MILL_FIRST_ARG on purpose, so we can expand the empty value without quotes
264+ # shellcheck disable=SC2086
265+ exec " ${MILL} " $MILL_FIRST_ARG -D " mill.main.cli=${MILL_MAIN_CLI} " " $@ "
0 commit comments