Skip to content

Instantly share code, notes, and snippets.

@jun-sheaf
Last active September 20, 2023 05:37
Show Gist options
  • Save jun-sheaf/fc76a995307445161ef313280e18a39b to your computer and use it in GitHub Desktop.
Save jun-sheaf/fc76a995307445161ef313280e18a39b to your computer and use it in GitHub Desktop.
Installs rustup as a system-wide toolchain manager
#!/bin/zsh
# Rustup doesn't have an easy "system-wide" approach to installation since it
# requires $CARGO_HOME for locating the binary folder. Here, we define
# `system-wide` as requiring `sudo-only` permission, i.e. `rustup install
# toolchain ...` breaks without `sudo`.
#
# The trick is thus to somehow "envelope" Rustup in another script so that it
# uses a "system-wide" cargo home instead of the default one whenever it's
# called.
#
# This script also does some other convenient tasks such as adding the real
# Cargo home to profiles.
#
# This script is configurable:
#
# - Set `RUST_HOME` to the directory you want rustup to install toolchains and binaries to. [default=/usr/local/rust]
# - Set `CARGO_HOME` to the home directory you want Cargo to use. [default=Cargo's default]
# - Set `NO_PATH` to disable adding the Cargo home to the path. Only bash and zsh are supported. [default=false]
#
# This script must be run in sudo mode.
#
set -e
########################
# System installations #
########################
if [ -z ${RUST_HOME+x} ]; then
rust_home=/usr/local/rust
else
rust_home=$RUST_HOME
fi
# Add system-wide rust home to profile.
for profile in /etc/zshrc /etc/bashrc /etc/profile; do
if ! grep -q "RUSTUP_HOME" $profile; then
cat <<EOF >>$profile
# Set system-wide rust home
RUSTUP_HOME=$rust_home; export RUSTUP_HOME
EOF
fi
done
# Source the profile.
source /etc/zshrc
# Add system-wide rust home to sudo.
cat <<EOF >/etc/sudoers.d/cargo
Defaults env_keep += "RUSTUP_HOME"
EOF
# Add system-wide rust home to paths.
cat <<EOF >/etc/paths.d/cargo
$rust_home/bin
EOF
# Install rustup.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | env CARGO_HOME=$rust_home sh -s -- -y --no-modify-path --profile minimal
# Envelope rustup.
cat <<EOF >/usr/local/bin/rustup
#!/bin/sh
CARGO_HOME=$rust_home exec $rust_home/bin/rustup "\$@"
EOF
chmod +x /usr/local/bin/rustup
######################
# User installations #
######################
# Set up user Cargo home.
if [ -z ${CARGO_HOME+x} ]; then
user_cargo_home="\$HOME/.cargo" # This is the default Cargo home used by Cargo.
else
user_cargo_home=$CARGO_HOME
fi
# Either we are using zsh or bash
if [ -z ${BASH+x} ]; then
user_profile=$HOME/.zshrc
else
user_profile=$HOME/.bashrc
fi
# Add user Cargo home to profile.
if [ -z ${NO_PATH+x} ]; then
# Set up user bin directory.
cat <<EOF >>$user_profile
export PATH=$user_cargo_home/bin:\$PATH
EOF
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment