Rust rustup¶
- ID
rustup- Home page
- Version requirement
>= 1.28
- Platforms
🐧 Linux · 🍎 macOS · 🪟 Windows
- Operations
installed·outdated·install·upgrade·upgrade_all·remove- purl types
pkg:rustup- CLI name
rustup- Forced environment
RUSTUP_TERM_COLOR=never·RUSTUP_TERM_PROGRESS_WHEN=never- Issues and PRs
- Source
rustup is the Rust toolchain installer (https://rustup.rs).
The packages here are toolchains, not components. rustup exposes both, and
only one can be the inventory: a package is a stable-aarch64-apple-darwin or
a 1.62.0-x86_64-unknown-linux-gnu, which is exactly the string toolchain install, toolchain uninstall and update all accept, so every declared
operation addresses the same object. Components lose that on three counts, any
one of them decisive. They are scoped to a toolchain, so clippy on stable and
clippy on nightly are different installs wearing one name. They carry no
version of their own, being versioned by the toolchain that holds them. And a
bare component list answers for whichever toolchain is active, which would
make mpm’s inventory depend on ambient state rather than on the machine.
installed therefore reports no version, which is deliberate rather than an
omission: a toolchain listing carries none. --verbose appends the install
path, not a version, and the only per-toolchain version rustup will produce
comes from spawning that toolchain’s own rustc once per entry, which is the
per-package follow-up call a definition cannot make. outdated supplies both
versions where it matters, and mpm’s package model treats an installed version
as optional throughout.
rustup check is what outdated runs, and its two quirks are both handled
rather than worked around. It exits 100 when updates exist, which needs no
declaration: mpm only counts a non-zero exit as a failure for a read-only query
when stderr is also non-empty, and a successful check writes nothing there.
And it appends a line for rustup’s own binary, which the pattern excludes by
requiring a hyphen in the first field, a shape every toolchain triple has and
the bare rustup of that line does not.
Every mutating operation forces --no-self-update. rustup otherwise replaces
its own binary as a side effect of installing or updating a toolchain, on all
three branches, which is not what a user asking mpm to upgrade a package
expects. Two exposures stay outside that flag’s reach, both being global user
state rather than per-invocation: an auto-self-update = check-only setting is
consulted before the flag, and a non-empty CI disables self-update outright.
No search: rustup has no registry to search, its channel names being a fixed
vocabulary. No sync and no cleanup: neither command exists. Purging the
download cache happens only as a side effect of an argument-less rustup update, and cannot be invoked on its own.
No escalation. rustup installs under $RUSTUP_HOME (~/.rustup by default),
has no system-wide mode, and actively refuses to run under sudo.
Caution
rustup’s output has no stability guarantee, and its maintainers say so plainly:
the 1.28.0 reformatting of rustup show broke downstream parsers, and a
further restyling of rustup check is proposed in
rust-lang/rustup#4574. The
outdated pattern below is deliberately tolerant of both the Update available : spelling of 1.28.x and the update available: of 1.29.0, so a wrapper
does not break on the next rename the way mise’s did.
Note
Listing toolchains is not a read-only operation at the filesystem level: rustup
writes its settings file while doing it, so installed fails on a host whose
$RUSTUP_HOME is mounted read-only.
What mpm adds to rustup¶
mpm reaches across every manager at once, not rustup alone: mpm installed and mpm outdated cover rustup alongside every other manager you run in one table, mpm upgrade --all updates them together, and mpm sbom exports the whole machine as one bill of materials.
Every mpm command also gains --dry-run and --plan previews, cross-scheme version comparison and purl identifiers. See manager augmentations for how each one is built.
Your rustup commands, in mpm¶
You already know rustup: each operation maps one-to-one onto mpm, in an interface shared by every manager.
To… |
With |
With |
|---|---|---|
List what’s installed |
|
|
List outdated packages |
|
|
Install a package |
|
|
Upgrade one package |
|
|
Upgrade everything |
|
|
Remove a package |
|
|
Prefix any command above with --dry-run to simulate the underlying manager calls without touching the system: the safe way to watch what mpm would do before trusting it.
Operations¶
Operation |
Supported |
|---|---|
|
✓ |
|
✓ |
|
|
|
|
|
✓ |
|
✓ |
|
✓ |
|
✓ |
|
|
|
|
|
Selecting and configuring rustup¶
Deselect rustup for a single run with --no-rustup, or persist the choice in your configuration:
[mpm]
rustup = false
The arguments and environment variables listed in the box atop this page are forced on every rustup call, so runs stay quiet, non-interactive and reproducible: the defaults you would set in CI anyway.
Keep it enabled but tune how mpm drives it with a per-manager override:
[mpm.managers.rustup]
timeout = 900
mpm config-template rustup prints every overridable attribute as a ready-to-paste block.
Recipes¶
A few jobs you would otherwise script around rustup, one mpm command each:
Snapshot and clone a machine:
mpm --rustup dump rustup.toml, thenmpm restore rustup.tomlon the next one.Export a compliance SBOM:
mpm --rustup sbom(CycloneDX by default,--spdxfor SPDX).
Privilege escalation¶
mpm runs this manager as the current user and never prepends sudo by default. Flip the policy for its privileged operations with --sudo or the per-manager sudo override.
None of its operations needs root.
See privilege escalation for the full policy.
Cooldown¶
State of Rust rustup’s release-age gating, from the cooldown support table:
Status: ❌ None
A cooldown only pays off where a compromised release can be withdrawn while the clock runs, and can only be emulated where the registry dates its releases. From the retraction table:
Registry: Rust release channels (
pkg:cargotoolchains)Retraction: None published: releases are static artifacts on the project’s own distribution host, with no yank, unlist or delete surface exposed to anyone outside the Rust release team; a withdrawal is a change to the channel manifest that host serves
Publish date: ✅ every channel manifest carries the release date of the toolchain it describes, which
rustup checkreports alongside the version
With --cooldown set, mpm skips this manager’s install and upgrade operations rather than run them unguarded (fail-closed); --allow-unsupported-managers opts back in.
Version probe¶
The version is probed by running:
$ rustup --version
rustup 1.29.0 (28d1352db 2026-03-05)
and extracted with:
r"^rustup (?P<version>\S+)"
Reference traces¶
Raw native outputs captured in the bundled definition: the reference mpm’s parsers were written against. If you know Rust rustup well and a transcript below looks wrong, or a newer release changed its output format, report it.
$ rustup toolchain list
stable-x86_64-unknown-linux-gnu (active, default)
nightly-x86_64-unknown-linux-gnu
1.14-x86_64-unknown-linux-gnu
1.62.0-x86_64-unknown-linux-gnu
1.71-x86_64-unknown-linux-gnu
$ rustup check
stable-x86_64-unknown-linux-gnu - update available: 1.0.0 (hash-stable-1.0.0) -> 1.1.0 (hash-stable-1.1.0)
nightly-x86_64-unknown-linux-gnu - up to date: 1.1.0 (hash-nightly-1.1.0)
Feed any of these through mpm and the raw output becomes one uniform table, the same shape for every manager: filter it, project columns, or export it (mpm --rustup installed --output json, or csv, toml, yaml), each package carrying a purl and a version comparable across managers.
Changelog¶
7.7.0.dev0(unreleased)Add the Rust rustup toolchain installer with
installed,outdated,install,upgradeandremovesupport, shipped as a bundled definition. Toolchains are the packages: components are scoped to a toolchain and a bare component listing answers for whichever one is active. Every mutating call forces--no-self-update, so upgrading a toolchain no longer replaces therustupbinary as a side effect. Installed toolchains carry no version, which onlyoutdatedreports.