Skip to content

Commit 1a318b1

Browse files
FranciscoTGouveiarami3l
authored andcommitted
feat(custom-toolchains): target and component list working on custom toolchains
As we cannot assume the existence of a manifest for custom toolchains, we can only report the installed components/targets. Thus, running `rustup target list` or `rustup target list --installed`, will yield the same result. The `list_items()` function was also refactored so that both custom and distributable toolchains can make use of it.
1 parent ffe880b commit 1a318b1

File tree

2 files changed

+70
-43
lines changed

2 files changed

+70
-43
lines changed

src/cli/common.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,12 @@ use super::self_update;
1919
use crate::{
2020
cli::download_tracker::DownloadTracker,
2121
config::Cfg,
22-
dist::{
23-
TargetTriple, ToolchainDesc, manifest::ComponentStatus, notifications as dist_notifications,
24-
},
22+
dist::{TargetTriple, ToolchainDesc, notifications as dist_notifications},
2523
errors::RustupError,
2624
install::UpdateStatus,
2725
notifications::Notification,
2826
process::{Process, terminalsource},
29-
toolchain::{DistributableToolchain, LocalToolchainName, Toolchain, ToolchainName},
27+
toolchain::{LocalToolchainName, Toolchain, ToolchainName},
3028
utils::{self, notifications as util_notifications, notify::NotificationLevel},
3129
};
3230

@@ -380,29 +378,26 @@ where
380378
Ok(utils::ExitCode(0))
381379
}
382380

381+
/// Iterates over pairs representing the name of a target or component and a
382+
/// boolean value indicating whether it is installed or not.
383+
/// The boolean value is needed to determine whether to print "(installed)"
384+
/// next to the target/component name."
383385
pub(super) fn list_items(
384-
distributable: DistributableToolchain<'_>,
385-
f: impl Fn(&ComponentStatus) -> Option<&str>,
386+
items: impl Iterator<Item = (String, bool)>,
386387
installed_only: bool,
387388
quiet: bool,
388389
process: &Process,
389390
) -> Result<utils::ExitCode> {
390391
let mut t = process.stdout().terminal(process);
391-
for component in distributable.components()? {
392-
let Some(name) = f(&component) else { continue };
393-
match (component.available, component.installed, installed_only) {
394-
(false, _, _) | (_, false, true) => continue,
395-
(true, true, false) if !quiet => {
396-
t.attr(terminalsource::Attr::Bold)?;
397-
writeln!(t.lock(), "{name} (installed)")?;
398-
t.reset()?;
399-
}
400-
(true, _, false) | (_, true, true) => {
401-
writeln!(t.lock(), "{name}")?;
402-
}
392+
for (name, installed) in items {
393+
if installed && !installed_only && !quiet {
394+
t.attr(terminalsource::Attr::Bold)?;
395+
writeln!(t.lock(), "{name} (installed)")?;
396+
t.reset()?;
397+
} else if installed || !installed_only {
398+
writeln!(t.lock(), "{name}")?;
403399
}
404400
}
405-
406401
Ok(utils::ExitCode(0))
407402
}
408403

src/cli/rustup_mode.rs

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,22 +1170,37 @@ async fn target_list(
11701170
installed_only: bool,
11711171
quiet: bool,
11721172
) -> Result<utils::ExitCode> {
1173-
// downcasting required because the toolchain files can name any toolchain
1174-
let distributable = DistributableToolchain::from_partial(toolchain, cfg).await?;
1175-
common::list_items(
1176-
distributable,
1177-
|c| {
1178-
(c.component.short_name_in_manifest() == "rust-std").then(|| {
1179-
c.component
1180-
.target
1181-
.as_deref()
1182-
.expect("rust-std should have a target")
1183-
})
1184-
},
1185-
installed_only,
1186-
quiet,
1187-
cfg.process,
1188-
)
1173+
// If a toolchain is Distributable, we can assume it has a manifest and thus print all possible targets and the installed ones.
1174+
// However, if it is a custom toolchain, we can only print the installed targets.
1175+
// NB: this decision is made based on the absence of a manifest in custom toolchains.
1176+
if let Ok(distributable) = DistributableToolchain::from_partial(toolchain.clone(), cfg).await {
1177+
common::list_items(
1178+
distributable.components()?.into_iter().filter_map(|c| {
1179+
if c.component.short_name_in_manifest() == "rust-std" && c.available {
1180+
c.component
1181+
.target
1182+
.as_deref()
1183+
.map(|target| (target.to_string(), c.installed))
1184+
} else {
1185+
None
1186+
}
1187+
}),
1188+
installed_only,
1189+
quiet,
1190+
cfg.process,
1191+
)
1192+
} else {
1193+
let toolchain = cfg.toolchain_from_partial(toolchain).await?;
1194+
common::list_items(
1195+
toolchain
1196+
.installed_targets()?
1197+
.iter()
1198+
.map(|s| (s.to_string(), true)),
1199+
installed_only,
1200+
quiet,
1201+
cfg.process,
1202+
)
1203+
}
11891204
}
11901205

11911206
async fn target_add(
@@ -1280,14 +1295,31 @@ async fn component_list(
12801295
quiet: bool,
12811296
) -> Result<utils::ExitCode> {
12821297
// downcasting required because the toolchain files can name any toolchain
1283-
let distributable = DistributableToolchain::from_partial(toolchain, cfg).await?;
1284-
common::list_items(
1285-
distributable,
1286-
|c| Some(&c.name),
1287-
installed_only,
1288-
quiet,
1289-
cfg.process,
1290-
)
1298+
if let Ok(distributable) = DistributableToolchain::from_partial(toolchain.clone(), cfg).await {
1299+
common::list_items(
1300+
distributable.components()?.into_iter().filter_map(|c| {
1301+
if c.available {
1302+
Some((c.name, c.installed))
1303+
} else {
1304+
None
1305+
}
1306+
}),
1307+
installed_only,
1308+
quiet,
1309+
cfg.process,
1310+
)
1311+
} else {
1312+
let toolchain = cfg.toolchain_from_partial(toolchain).await?;
1313+
common::list_items(
1314+
toolchain
1315+
.installed_components()?
1316+
.iter()
1317+
.map(|s| (s.name().to_string(), true)),
1318+
installed_only,
1319+
quiet,
1320+
cfg.process,
1321+
)
1322+
}
12911323
}
12921324

12931325
async fn component_add(

0 commit comments

Comments
 (0)