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.12.5
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=" ${MILL_DOWNLOAD_PATH} /${MILL_VERSION} "
105+
106+ try_to_use_system_mill () {
107+ if [ " $( uname) " != " Linux" ]; then
108+ return 0
109+ fi
110+
111+ MILL_IN_PATH=" $( command -v mill || true) "
112+
113+ if [ -z " ${MILL_IN_PATH} " ]; then
114+ return 0
115+ fi
116+
117+ SYSTEM_MILL_FIRST_TWO_BYTES=$( head --bytes=2 " ${MILL_IN_PATH} " )
118+ if [ " ${SYSTEM_MILL_FIRST_TWO_BYTES} " = " #!" ]; then
119+ # MILL_IN_PATH is (very likely) a shell script and not the mill
120+ # executable, ignore it.
121+ return 0
122+ fi
123+
124+ SYSTEM_MILL_PATH=$( readlink -e " ${MILL_IN_PATH} " )
125+ SYSTEM_MILL_SIZE=$( stat --format=%s " ${SYSTEM_MILL_PATH} " )
126+ SYSTEM_MILL_MTIME=$( stat --format=%y " ${SYSTEM_MILL_PATH} " )
127+
128+ if [ ! -d " ${MILL_USER_CACHE_DIR} " ]; then
129+ mkdir -p " ${MILL_USER_CACHE_DIR} "
130+ fi
131+
132+ SYSTEM_MILL_INFO_FILE=" ${MILL_USER_CACHE_DIR} /system-mill-info"
133+ if [ -f " ${SYSTEM_MILL_INFO_FILE} " ]; then
134+ parseSystemMillInfo () {
135+ LINE_NUMBER=" ${1} "
136+ # Select the line number of the SYSTEM_MILL_INFO_FILE, cut the
137+ # variable definition in that line in two halves and return
138+ # the value, and finally remove the quotes.
139+ sed -n " ${LINE_NUMBER} p" " ${SYSTEM_MILL_INFO_FILE} " | \
140+ cut -d= -f2 | \
141+ sed ' s/"\(.*\)"/\1/'
142+ }
143+
144+ CACHED_SYSTEM_MILL_PATH=$( parseSystemMillInfo 1)
145+ CACHED_SYSTEM_MILL_VERSION=$( parseSystemMillInfo 2)
146+ CACHED_SYSTEM_MILL_SIZE=$( parseSystemMillInfo 3)
147+ CACHED_SYSTEM_MILL_MTIME=$( parseSystemMillInfo 4)
148+
149+ if [ " ${SYSTEM_MILL_PATH} " = " ${CACHED_SYSTEM_MILL_PATH} " ] \
150+ && [ " ${SYSTEM_MILL_SIZE} " = " ${CACHED_SYSTEM_MILL_SIZE} " ] \
151+ && [ " ${SYSTEM_MILL_MTIME} " = " ${CACHED_SYSTEM_MILL_MTIME} " ]; then
152+ if [ " ${CACHED_SYSTEM_MILL_VERSION} " = " ${MILL_VERSION} " ]; then
153+ MILL=" ${SYSTEM_MILL_PATH} "
154+ return 0
155+ else
156+ return 0
157+ fi
158+ fi
159+ fi
160+
161+ SYSTEM_MILL_VERSION=$( ${SYSTEM_MILL_PATH} --version | head -n1 | sed -n ' s/^Mill.*version \(.*\)/\1/p' )
162+
163+ cat << EOF > "${SYSTEM_MILL_INFO_FILE} "
164+ CACHED_SYSTEM_MILL_PATH="${SYSTEM_MILL_PATH} "
165+ CACHED_SYSTEM_MILL_VERSION="${SYSTEM_MILL_VERSION} "
166+ CACHED_SYSTEM_MILL_SIZE="${SYSTEM_MILL_SIZE} "
167+ CACHED_SYSTEM_MILL_MTIME="${SYSTEM_MILL_MTIME} "
168+ EOF
169+
170+ if [ " ${SYSTEM_MILL_VERSION} " = " ${MILL_VERSION} " ]; then
171+ MILL=" ${SYSTEM_MILL_PATH} "
172+ fi
173+ }
174+ try_to_use_system_mill
175+
176+ # If not already downloaded, download it
177+ if [ ! -s " ${MILL} " ] ; then
178+
179+ # support old non-XDG download dir
180+ MILL_OLD_DOWNLOAD_PATH=" ${HOME} /.mill/download"
181+ OLD_MILL=" ${MILL_OLD_DOWNLOAD_PATH} /${MILL_VERSION} "
182+ if [ -x " ${OLD_MILL} " ] ; then
183+ MILL=" ${OLD_MILL} "
184+ else
185+ case $MILL_VERSION in
186+ 0.0.* | 0.1.* | 0.2.* | 0.3.* | 0.4.* )
187+ DOWNLOAD_SUFFIX=" "
188+ DOWNLOAD_FROM_MAVEN=0
189+ ;;
190+ 0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.0-M* )
191+ DOWNLOAD_SUFFIX=" -assembly"
192+ DOWNLOAD_FROM_MAVEN=0
193+ ;;
194+ * )
195+ DOWNLOAD_SUFFIX=" -assembly"
196+ DOWNLOAD_FROM_MAVEN=1
197+ ;;
198+ esac
199+
200+ DOWNLOAD_FILE=$( mktemp mill.XXXXXX)
201+
202+ if [ " $DOWNLOAD_FROM_MAVEN " = " 1" ] ; then
203+ DOWNLOAD_URL=" https://repo1.maven.org/maven2/com/lihaoyi/mill-dist/${MILL_VERSION} /mill-dist-${MILL_VERSION} .jar"
204+ else
205+ MILL_VERSION_TAG=$( echo " $MILL_VERSION " | sed -E ' s/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/' )
206+ DOWNLOAD_URL=" ${GITHUB_RELEASE_CDN}${MILL_REPO_URL} /releases/download/${MILL_VERSION_TAG} /${MILL_VERSION}${DOWNLOAD_SUFFIX} "
207+ unset MILL_VERSION_TAG
208+ fi
209+
210+ # TODO: handle command not found
211+ echo " Downloading mill ${MILL_VERSION} from ${DOWNLOAD_URL} ..." 1>&2
212+ ${CURL_CMD} -f -L -o " ${DOWNLOAD_FILE} " " ${DOWNLOAD_URL} "
213+ chmod +x " ${DOWNLOAD_FILE} "
214+ mkdir -p " ${MILL_DOWNLOAD_PATH} "
215+ mv " ${DOWNLOAD_FILE} " " ${MILL} "
216+
217+ unset DOWNLOAD_FILE
218+ unset DOWNLOAD_SUFFIX
219+ fi
220+ fi
221+
222+ if [ -z " $MILL_MAIN_CLI " ] ; then
223+ MILL_MAIN_CLI=" ${0} "
224+ fi
225+
226+ MILL_FIRST_ARG=" "
227+ if [ " $1 " = " --bsp" ] || [ " $1 " = " -i" ] || [ " $1 " = " --interactive" ] || [ " $1 " = " --no-server" ] || [ " $1 " = " --repl" ] || [ " $1 " = " --help" ] ; then
228+ # Need to preserve the first position of those listed options
229+ MILL_FIRST_ARG=$1
230+ shift
231+ fi
232+
233+ unset MILL_DOWNLOAD_PATH
234+ unset MILL_OLD_DOWNLOAD_PATH
235+ unset OLD_MILL
236+ unset MILL_VERSION
237+ unset MILL_REPO_URL
238+
239+ # We don't quote MILL_FIRST_ARG on purpose, so we can expand the empty value without quotes
240+ # shellcheck disable=SC2086
241+ exec " ${MILL} " $MILL_FIRST_ARG -D " mill.main.cli=${MILL_MAIN_CLI} " " $@ "
0 commit comments