22
22
# Unless the --disable-confirmation flag is set, this script will allow the runner to
23
23
# configure either of those two directory paths.
24
24
#
25
+ # Unless the --no-install-system-deps flag is set, this script will attempt to install Swift's
26
+ # system dependencies using the system package manager.
27
+ #
25
28
# curl is required to run this script.
26
29
27
30
set -o errexit
@@ -48,6 +51,47 @@ read_input_with_default () {
48
51
fi
49
52
}
50
53
54
+ yn_prompt () {
55
+ if [[ " $1 " == " true" ]]; then
56
+ echo " (Y/n)"
57
+ else
58
+ echo " (y/N)"
59
+ fi
60
+ }
61
+
62
+ # Read a y/n input.
63
+ # First argument is the default value (must be "true" or "false").
64
+ #
65
+ # Sets READ_INPUT_RETURN to "true" for an input of "y" or "Y", "false" for an input
66
+ # of "n" or "N", or the default value for a blank input
67
+ #
68
+ # For all other inputs, a message is printed and the user is prompted again.
69
+ read_yn_input () {
70
+ while [[ true ]]; do
71
+ read_input_with_default " $1 "
72
+
73
+ case " $READ_INPUT_RETURN " in
74
+ " y" | " Y" )
75
+ READ_INPUT_RETURN=" true"
76
+ return
77
+ ;;
78
+
79
+ " n" | " N" )
80
+ READ_INPUT_RETURN=" false"
81
+ return
82
+ ;;
83
+
84
+ " $1 " )
85
+ return
86
+ ;;
87
+
88
+ * )
89
+ echo " Please input either \" y\" or \" n\" , or press ENTER to use the default."
90
+ ;;
91
+ esac
92
+ done
93
+ }
94
+
51
95
# Replaces the actual path to $HOME at the beginning of the provided string argument with
52
96
# the string "$HOME". This is used when printing to stdout.
53
97
# e.g. "home/user/.local/bin" => "$HOME/.local/bin"
@@ -71,9 +115,68 @@ bold () {
71
115
echo " $( tput bold) $1 $( tput sgr0) "
72
116
}
73
117
118
+ # Fetch the list of required system dependencies from the apple/swift-docker
119
+ # repository and attempt to install them using the system's package manager.
120
+ #
121
+ # $docker_platform_name, $docker_platform_version, and $package manager need
122
+ # to be set before calling this function.
123
+ install_system_deps () {
124
+ if [[ " $( id --user) " != " 0" ]] && ! has_command sudo ; then
125
+ echo " Warning: sudo not installed and current user is not root, skipping system dependency installation."
126
+ return
127
+ elif ! has_command " $package_manager " ; then
128
+ echo " Warning: package manager \" $package_manager \" not found, skipping system dependency installation."
129
+ return
130
+ fi
131
+
132
+ dockerfile_url=" https://raw.githubusercontent.com/apple/swift-docker/main/nightly-main/$docker_platform_name /$docker_platform_version /Dockerfile"
133
+ dockerfile=" $( curl --silent --retry 3 --location --fail $dockerfile_url ) "
134
+ if [[ " $? " -ne 0 ]]; then
135
+ echo " Error enumerating system dependencies, skipping installation of system dependencies."
136
+ fi
137
+
138
+ # Find the line number of the RUN command associated with installing system dependencies.
139
+ beg_line_num=$( printf " $dockerfile " | grep -n --max-count=1 " $package_manager .*install" | cut -d " :" -f1)
140
+
141
+ # Starting from there, find the first line that starts with an & or doesn't end in a backslash.
142
+ relative_end_line_num=$( printf " $dockerfile " |
143
+ tail --lines=+" $(( beg_line_num + 1 )) " |
144
+ grep -n --max-count=1 --invert-match ' [[:space:]]*[^&].*\\$' | cut -d " :" -f1)
145
+ end_line_num=$(( beg_line_num + relative_end_line_num))
146
+
147
+ # Read the lines between those two, deleting any spaces and backslashes.
148
+ readarray -t package_list < <( printf " $dockerfile " | sed -n " $(( beg_line_num + 1 )) ,${end_line_num} p" | sed -r ' s/[\ ]//g' )
149
+
150
+ # If the installation command from the Dockerfile included some cleanup as part of a second command, drop that.
151
+ if [[ " ${package_list[-1]} " =~ ^\&\& ]]; then
152
+ unset ' package_list[-1]'
153
+ fi
154
+
155
+ install_args=(--quiet)
156
+ if [[ " $DISABLE_CONFIRMATION " == " true" ]]; then
157
+ install_args+=(-y)
158
+ fi
159
+
160
+ # Disable errexit since failing to install system dependencies is not swiftly installation-fatal.
161
+ set +o errexit
162
+ if [[ " $( id --user) " == " 0" ]]; then
163
+ " $package_manager " install " ${install_args[@]} " " ${package_list[@]} "
164
+ else
165
+ sudo " $package_manager " install " ${install_args[@]} " " ${package_list[@]} "
166
+ fi
167
+ if [[ " $? " -ne 0 ]]; then
168
+ echo " System dependency installation failed."
169
+ if [[ " $package_manager " == " apt-get" ]]; then
170
+ echo " You may need to run apt-get update before installing system dependencies."
171
+ fi
172
+ fi
173
+ set -o errexit
174
+ }
175
+
74
176
SWIFTLY_INSTALL_VERSION=" 0.1.0"
75
177
76
178
MODIFY_PROFILE=" true"
179
+ SWIFTLY_INSTALL_SYSTEM_DEPS=" true"
77
180
78
181
for arg in " $@ " ; do
79
182
case " $arg " in
@@ -89,6 +192,7 @@ FLAGS:
89
192
-y, --disable-confirmation Disable confirmation prompt.
90
193
--no-modify-profile Do not attempt to modify the profile file to set environment
91
194
variables (e.g. PATH) on login.
195
+ --no-install-system-deps Do not attempt to install Swift's required system dependencies.
92
196
-h, --help Prints help information.
93
197
--version Prints version information.
94
198
EOF
103
207
MODIFY_PROFILE=" false"
104
208
;;
105
209
210
+ " --no-install-system-deps" )
211
+ SWIFTLY_INSTALL_SYSTEM_DEPS=" false"
212
+ ;;
213
+
106
214
" --version" )
107
215
echo " $SWIFTLY_INSTALL_VERSION "
108
216
exit 0
@@ -134,23 +242,31 @@ case "$ID" in
134
242
fi
135
243
PLATFORM_NAME=" amazonlinux2"
136
244
PLATFORM_NAME_FULL=" amazonlinux2"
245
+ docker_platform_name=" amazonlinux"
246
+ docker_platform_version=" 2"
247
+ package_manager=" yum"
137
248
;;
138
249
139
250
" ubuntu" )
251
+ docker_platform_name=" ubuntu"
252
+ package_manager=" apt-get"
140
253
case " $UBUNTU_CODENAME " in
141
254
" jammy" )
142
255
PLATFORM_NAME=" ubuntu2204"
143
256
PLATFORM_NAME_FULL=" ubuntu22.04"
257
+ docker_platform_version=" 22.04"
144
258
;;
145
259
146
260
" focal" )
147
261
PLATFORM_NAME=" ubuntu2004"
148
262
PLATFORM_NAME_FULL=" ubuntu20.04"
263
+ docker_platform_version=" 20.04"
149
264
;;
150
265
151
266
" bionic" )
152
267
PLATFORM_NAME=" ubuntu1804"
153
268
PLATFORM_NAME_FULL=" ubuntu18.04"
269
+ docker_platform_version=" 18.04"
154
270
;;
155
271
156
272
* )
@@ -167,6 +283,9 @@ case "$ID" in
167
283
fi
168
284
PLATFORM_NAME=" ubi9"
169
285
PLATFORM_NAME_FULL=" ubi9"
286
+ docker_platform_name=" rhel-ubi"
287
+ docker_platform_version=" 9"
288
+ package_manager=" yum"
170
289
;;
171
290
172
291
* )
@@ -243,6 +362,7 @@ while [ -z "$DISABLE_CONFIRMATION" ]; do
243
362
printf " %40s: $( bold $( replace_home_path $HOME_DIR ) ) \n" " Data and configuration files directory"
244
363
printf " %40s: $( bold $( replace_home_path $BIN_DIR ) ) \n" " Executables installation directory"
245
364
printf " %40s: $( bold $MODIFY_PROFILE ) \n" " Modify login config ($( replace_home_path $PROFILE_FILE ) )"
365
+ printf " %40s: $( bold $SWIFTLY_INSTALL_SYSTEM_DEPS ) \n" " Install system dependencies"
246
366
echo " "
247
367
echo " Select one of the following:"
248
368
echo " 1) Proceed with the installation (default)"
@@ -265,30 +385,17 @@ while [ -z "$DISABLE_CONFIRMATION" ]; do
265
385
read_input_with_default " $BIN_DIR "
266
386
BIN_DIR=" $( expand_home_path $READ_INPUT_RETURN ) "
267
387
268
- if [[ " $MODIFY_PROFILE " == " true" ]]; then
269
- MODIFY_PROFILE_PROMPT=" (Y/n)"
270
- else
271
- MODIFY_PROFILE_PROMPT=" (y/N)"
272
- fi
273
- echo " Modify login config ($( replace_home_path $PROFILE_FILE ) )? $MODIFY_PROFILE_PROMPT "
274
- read_input_with_default " $MODIFY_PROFILE "
275
-
276
- case " $READ_INPUT_RETURN " in
277
- " y" | " Y" )
278
- MODIFY_PROFILE=" true"
279
- ;;
280
-
281
- " n" | " N" )
282
- MODIFY_PROFILE=" false"
283
- ;;
388
+ echo " Modify login config ($( replace_home_path $PROFILE_FILE ) )? $( yn_prompt $MODIFY_PROFILE ) "
389
+ read_yn_input " $MODIFY_PROFILE "
390
+ MODIFY_PROFILE=" $READ_INPUT_RETURN "
284
391
285
- * )
286
- ;;
287
- esac
392
+ echo " Install system dependencies? $( yn_prompt $SWIFTLY_INSTALL_SYSTEM_DEPS ) "
393
+ read_yn_input " $SWIFTLY_INSTALL_SYSTEM_DEPS "
394
+ SWIFTLY_INSTALL_SYSTEM_DEPS= " $READ_INPUT_RETURN "
288
395
;;
289
396
290
397
* )
291
- echo " Cancelling installation"
398
+ echo " Cancelling installation. "
292
399
exit 0
293
400
;;
294
401
esac
@@ -300,23 +407,11 @@ if [[ -d "$HOME_DIR" ]]; then
300
407
else
301
408
echo " Existing swiftly installation detected at $( replace_home_path $HOME_DIR ) , overwrite? (Y/n)"
302
409
303
- while [[ true ]]; do
304
- read_input_with_default " y"
305
- case " $READ_INPUT_RETURN " in
306
- " y" | " Y" )
307
- break
308
- ;;
309
-
310
- " n" | " N" | " q" )
311
- echo " Cancelling installation"
312
- exit 0
313
- ;;
314
-
315
- * )
316
- echo " Please input \" y\" or \" n\" ."
317
- ;;
318
- esac
319
- done
410
+ read_yn_input " true"
411
+ if [[ " $READ_INPUT_RETURN " == " false" ]]; then
412
+ echo " Cancelling installation."
413
+ exit 0
414
+ fi
320
415
fi
321
416
322
417
rm -r $HOME_DIR
@@ -343,10 +438,6 @@ echo "$JSON_OUT" > "$HOME_DIR/config.json"
343
438
# Verify the downloaded executable works. The script will exit if this fails due to errexit.
344
439
SWIFTLY_HOME_DIR=" $HOME_DIR " SWIFTLY_BIN_DIR=" $BIN_DIR " " $BIN_DIR /swiftly" --version > /dev/null
345
440
346
- echo " "
347
- echo " swiftly has been succesfully installed!"
348
- echo " "
349
-
350
441
ENV_OUT=$( cat << EOF
351
442
export SWIFTLY_HOME_DIR="$( replace_home_path $HOME_DIR ) "
352
443
export SWIFTLY_BIN_DIR="$( replace_home_path $BIN_DIR ) "
@@ -367,6 +458,16 @@ if [[ "$MODIFY_PROFILE" == "true" ]]; then
367
458
fi
368
459
fi
369
460
461
+ if [[ " $SWIFTLY_INSTALL_SYSTEM_DEPS " != " false" ]]; then
462
+ echo " "
463
+ echo " Installing Swift's system dependencies via $package_manager (note: this may require root access)..."
464
+ install_system_deps
465
+ fi
466
+
467
+ echo " "
468
+ echo " swiftly has been succesfully installed!"
469
+ echo " "
470
+
370
471
if ! has_command " swiftly" || [[ " $HOME_DIR " != " $DEFAULT_HOME_DIR " || " $BIN_DIR " != " $DEFAULT_BIN_DIR " ]] ; then
371
472
echo " Once you log in again, swiftly should be accessible from your PATH."
372
473
echo " To begin using swiftly from your current shell, first run the following command:"
0 commit comments