7
7
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/rust.md
8
8
# Maintainer: The VS Code and Codespaces Teams
9
9
#
10
- # Syntax: ./rust-debian.sh [CARGO_HOME] [RUSTUP_HOME] [non-root user] [add CARGO/RUSTUP_HOME to rc files flag] [whether to update rust]
10
+ # Syntax: ./rust-debian.sh [CARGO_HOME] [RUSTUP_HOME] [non-root user] [add CARGO/RUSTUP_HOME to rc files flag] [whether to update rust] [Rust version] [rustup install profile]
11
11
12
12
export CARGO_HOME=${1:- " /usr/local/cargo" }
13
13
export RUSTUP_HOME=${2:- " /usr/local/rustup" }
14
14
USERNAME=${3:- " automatic" }
15
15
UPDATE_RC=${4:- " true" }
16
- UPDATE_RUST=${5:- " true" }
16
+ UPDATE_RUST=${5:- " false" }
17
+ RUST_VERSION=${6:- " latest" }
18
+ RUSTUP_PROFILE=${7:- " minimal" }
17
19
18
20
set -e
19
21
@@ -44,6 +46,55 @@ elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
44
46
USERNAME=root
45
47
fi
46
48
49
+ # Get central common setting
50
+ get_common_setting () {
51
+ if [ " ${common_settings_file_loaded} " != " true" ]; then
52
+ curl -sfL " https://aka.ms/vscode-dev-containers/script-library/settings.env" 2> /dev/null -o /tmp/vsdc-settings.env || echo " Could not download settings file. Skipping."
53
+ common_settings_file_loaded=true
54
+ fi
55
+ if [ -f " /tmp/vsdc-settings.env" ]; then
56
+ local multi_line=" "
57
+ if [ " $2 " = " true" ]; then multi_line=" -z" ; fi
58
+ local result=" $( grep ${multi_line} -oP " $1 =\" ?\K[^\" ]+" /tmp/vsdc-settings.env | tr -d ' \0' ) "
59
+ if [ ! -z " ${result} " ]; then declare -g $1 =" ${result} " ; fi
60
+ fi
61
+ echo " $1 =${! 1} "
62
+ }
63
+
64
+ # Figure out correct version of a three part version number is not passed
65
+ find_version_from_git_tags () {
66
+ local variable_name=$1
67
+ local requested_version=${! variable_name}
68
+ if [ " ${requested_version} " = " none" ]; then return ; fi
69
+ local repository=$2
70
+ local prefix=${3:- " tags/v" }
71
+ local separator=${4:- " ." }
72
+ local last_part_optional=${5:- " false" }
73
+ if [ " $( echo " ${requested_version} " | grep -o " ." | wc -l) " != " 2" ]; then
74
+ local escaped_separator=${separator// ./ \\ .}
75
+ local last_part
76
+ if [ " ${last_part_optional} " = " true" ]; then
77
+ last_part=" (${escaped_separator} [0-9]+)?"
78
+ else
79
+ last_part=" ${escaped_separator} [0-9]+"
80
+ fi
81
+ local regex=" ${prefix} \\ K[0-9]+${escaped_separator} [0-9]+${last_part} $"
82
+ local version_list=" $( git ls-remote --tags ${repository} | grep -oP " ${regex} " | tr -d ' ' | tr " ${separator} " " ." | sort -rV) "
83
+ if [ " ${requested_version} " = " latest" ] || [ " ${requested_version} " = " current" ] || [ " ${requested_version} " = " lts" ]; then
84
+ declare -g ${variable_name} =" $( echo " ${version_list} " | head -n 1) "
85
+ else
86
+ set +e
87
+ declare -g ${variable_name} =" $( echo " ${version_list} " | grep -E -m 1 " ^${requested_version// ./ \\ .} ([\\ .\\ s]|$)" ) "
88
+ set -e
89
+ fi
90
+ fi
91
+ if [ -z " ${! variable_name} " ] || ! echo " ${version_list} " | grep " ^${! variable_name// ./ \\ .} $" > /dev/null 2>&1 ; then
92
+ echo -e " Invalid ${variable_name} value: ${requested_version} \nValid values:\n${version_list} " >&2
93
+ exit 1
94
+ fi
95
+ echo " ${variable_name} =${! variable_name} "
96
+ }
97
+
47
98
updaterc () {
48
99
if [ " ${UPDATE_RC} " = " true" ]; then
49
100
echo " Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
@@ -70,44 +121,79 @@ apt_get_update_if_needed()
70
121
export DEBIAN_FRONTEND=noninteractive
71
122
72
123
# Install curl, lldb, python3-minimal,libpython and rust dependencies if missing
73
- if ! dpkg -s curl ca-certificates lldb python3-minimal gcc libc6-dev > /dev/null 2>&1 ; then
124
+ if ! dpkg -s curl ca-certificates gnupg2 lldb python3-minimal gcc libc6-dev > /dev/null 2>&1 ; then
74
125
apt_get_update_if_needed
75
126
apt-get -y install --no-install-recommends curl ca-certificates gcc libc6-dev
76
127
apt-get -y install lldb python3-minimal libpython3.?
77
128
fi
78
129
130
+ architecture=" $( dpkg --print-architecture) "
131
+ download_architecture=" ${architecture} "
132
+ case ${download_architecture} in
133
+ amd64)
134
+ download_architecture=" x86_64"
135
+ ;;
136
+ arm64)
137
+ download_architecture=" aarch64"
138
+ ;;
139
+ * ) echo " (!) Architecture ${architecture} not supported."
140
+ exit 1
141
+ ;;
142
+ esac
143
+
79
144
# Install Rust
80
- if ! type rustup > /dev/null 2>&1 ; then
145
+ umask 0002
146
+ if ! cat /etc/group | grep -e " ^rustlang:" > /dev/null 2>&1 ; then
147
+ groupadd -r rustlang
148
+ fi
149
+ usermod -a -G rustlang " ${USERNAME} "
150
+ mkdir -p " ${CARGO_HOME} " " ${RUSTUP_HOME} "
151
+ chown :rustlang " ${RUSTUP_HOME} " " ${CARGO_HOME} "
152
+ chmod g+r+w+s " ${RUSTUP_HOME} " " ${CARGO_HOME} "
153
+
154
+ if [ " ${RUST_VERSION} " = " none" ] || type rustup > /dev/null 2>&1 ; then
155
+ echo " Rust already installed. Skipping..."
156
+ else
157
+ if [ " ${RUST_VERSION} " != " latest" ] && [ " ${RUST_VERSION} " != " lts" ] && [ " ${RUST_VERSION} " != " stable" ]; then
158
+ # Find version using soft match
159
+ if ! type git > /dev/null 2>&1 ; then
160
+ apt_get_update_if_needed
161
+ apt-get -y install --no-install-recommends git
162
+ fi
163
+ find_version_from_git_tags RUST_VERSION " https://github.com/rust-lang/rust" " tags/"
164
+ default_toolchain_arg=" --default-toolchain ${RUST_VERSION} "
165
+ fi
81
166
echo " Installing Rust..."
82
- mkdir -p " ${CARGO_HOME} " " ${RUSTUP_HOME} "
83
- chown ${USERNAME} " ${CARGO_HOME} " " ${RUSTUP_HOME} "
84
- su ${USERNAME} -c " curl --tlsv1.2 https://sh.rustup.rs -sSf | bash -s -- -y --no-modify-path --profile minimal 2>&1"
85
- else
86
- echo " Rust already installed. Skipping."
167
+ # Download and verify rustup sha
168
+ mkdir -p /tmp/rustup/target/x86_64-unknown-linux-gnu/release/
169
+ curl -sSL --proto ' =https' --tlsv1.2 " https://static.rust-lang.org/rustup/dist/${download_architecture} -unknown-linux-gnu/rustup-init" -o /tmp/rustup/target/${download_architecture} -unknown-linux-gnu/release/rustup-init
170
+ curl -sSL --proto ' =https' --tlsv1.2 " https://static.rust-lang.org/rustup/dist/${download_architecture} -unknown-linux-gnu/rustup-init.sha256" -o /tmp/rustup/rustup-init.sha256
171
+ cd /tmp/rustup
172
+ sha256sum -c rustup-init.sha256
173
+ chmod +x target/x86_64-unknown-linux-gnu/release/rustup-init
174
+ target/x86_64-unknown-linux-gnu/release/rustup-init -y --no-modify-path --profile ${RUSTUP_PROFILE} ${default_toolchain_arg}
175
+ cd ~
176
+ rm -rf /tmp/rustup
87
177
fi
88
178
89
- su ${USERNAME} -c " $( cat << EOF
90
- set -e
91
- export PATH=${PATH} :${CARGO_HOME} /bin
92
- if [ "${UPDATE_RUST} " = "true" ]; then
93
- echo "Updating Rust..."
94
- rustup update 2>&1
95
- fi
96
- echo "Installing common Rust dependencies..."
97
- rustup component add rls rust-analysis rust-src rustfmt clippy 2>&1
98
- EOF
99
- ) "
179
+ export PATH=${CARGO_HOME} /bin:${PATH}
180
+ if [ " ${UPDATE_RUST} " = " true" ]; then
181
+ echo " Updating Rust..."
182
+ rustup update 2>&1
183
+ fi
184
+ echo " Installing common Rust dependencies..."
185
+ rustup component add rls rust-analysis rust-src rustfmt clippy 2>&1
100
186
101
187
# Add CARGO_HOME, RUSTUP_HOME and bin directory into bashrc/zshrc files (unless disabled)
102
- updaterc " export CARGO_HOME=\" ${CARGO_HOME} \" \nexport RUSTUP_HOME=\" ${RUSTUP_HOME} \" \nexport PATH=\"\$ {CARGO_HOME}/bin:\$ {PATH}\" "
103
-
104
188
updaterc " $( cat << EOF
105
189
export RUSTUP_HOME="${RUSTUP_HOME} "
106
190
export CARGO_HOME="${CARGO_HOME} "
107
- if [[ "\$ {PATH}" != *"\$ {CARGO_HOME}/bin"* ]]; then export PATH="\$ {PATH} :\$ {CARGO_HOME}/bin "; fi
191
+ if [[ "\$ {PATH}" != *"\$ {CARGO_HOME}/bin"* ]]; then export PATH="\$ {CARGO_HOME}/bin :\$ {PATH} "; fi
108
192
EOF
109
193
) "
110
194
195
+ # Make files writable for rustlang group
196
+ chmod -R g+r+w " ${RUSTUP_HOME} " " ${CARGO_HOME} "
111
197
112
198
echo " Done!"
113
199
0 commit comments