Skip to content

Commit 218b968

Browse files
committed
Update format of show and show active-toolchain
This changes the format of `rustup show` to be in a more logical order, and changes the format of `rustup show active-toolchain` to match. Also, as suggested in a comment, these commands will no longer install the active toolchain if it is not already installed, as they now call `cfg.find_active_toolchain()` instead of `cfg.find_or_install_active_toolchain()`. This fixes rust-lang#1397
1 parent c65e5f8 commit 218b968

File tree

5 files changed

+284
-219
lines changed

5 files changed

+284
-219
lines changed

doc/user-guide/src/overrides.md

+1-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ the directory tree toward the filesystem root, and a `rust-toolchain.toml` file
1919
that is closer to the current directory will be preferred over a directory
2020
override that is further away.
2121

22-
To verify which toolchain is active, you can use `rustup show`,
23-
which will also try to install the corresponding
24-
toolchain if the current one has not been installed according to the above rules.
25-
(Please note that this behavior is subject to change, as detailed in issue [#1397].)
22+
To verify which toolchain is active, you can use `rustup show`.
2623

2724
[toolchain]: concepts/toolchains.md
2825
[toolchain override shorthand]: #toolchain-override-shorthand

src/cli/rustup_mode.rs

+113-124
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use clap::{
1111
};
1212
use clap_complete::Shell;
1313

14+
use crate::config::new_toolchain_with_reason;
1415
use crate::{
1516
cli::{
1617
common::{self, PackageUpdate},
@@ -39,8 +40,9 @@ use crate::{
3940
names::{
4041
custom_toolchain_name_parser, maybe_resolvable_toolchainame_parser,
4142
partial_toolchain_desc_parser, resolvable_local_toolchainame_parser,
42-
resolvable_toolchainame_parser, CustomToolchainName, MaybeResolvableToolchainName,
43-
ResolvableLocalToolchainName, ResolvableToolchainName, ToolchainName,
43+
resolvable_toolchainame_parser, CustomToolchainName, LocalToolchainName,
44+
MaybeResolvableToolchainName, ResolvableLocalToolchainName, ResolvableToolchainName,
45+
ToolchainName,
4446
},
4547
toolchain::Toolchain,
4648
},
@@ -1081,127 +1083,112 @@ fn show(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
10811083

10821084
let cwd = utils::current_dir()?;
10831085
let installed_toolchains = cfg.list_toolchains()?;
1084-
// XXX: we may want a find_without_install capability for show.
1085-
let active_toolchain = cfg.find_or_install_active_toolchain(&cwd);
1086-
1087-
// active_toolchain will carry the reason we don't have one in its detail.
1088-
let active_targets = if let Ok(ref at) = active_toolchain {
1089-
if let Ok(distributable) = DistributableToolchain::try_from(&at.0) {
1090-
let components = (|| {
1091-
let manifestation = distributable.get_manifestation()?;
1092-
let config = manifestation.read_config()?.unwrap_or_default();
1093-
let manifest = distributable.get_manifest()?;
1094-
manifest.query_components(distributable.desc(), &config)
1095-
})();
1096-
1097-
match components {
1098-
Ok(cs_vec) => cs_vec
1099-
.into_iter()
1100-
.filter(|c| c.component.short_name_in_manifest() == "rust-std")
1101-
.filter(|c| c.installed)
1102-
.collect(),
1103-
Err(_) => vec![],
1104-
}
1086+
let active_toolchain_and_reason: Option<(ToolchainName, ActiveReason)> =
1087+
if let Ok(Some((LocalToolchainName::Named(toolchain_name), reason))) =
1088+
cfg.find_active_toolchain(&cwd)
1089+
{
1090+
Some((toolchain_name, reason))
11051091
} else {
1106-
// These three vec![] could perhaps be reduced with and_then on active_toolchain.
1107-
vec![]
1108-
}
1109-
} else {
1110-
vec![]
1111-
};
1092+
None
1093+
};
1094+
1095+
let (active_toolchain_name, _active_reason) = active_toolchain_and_reason
1096+
.as_ref()
1097+
.map(|atar| (&atar.0, &atar.1))
1098+
.unzip();
11121099

1113-
let show_installed_toolchains = installed_toolchains.len() > 1;
1114-
let show_active_targets = active_targets.len() > 1;
1115-
let show_active_toolchain = true;
1116-
1117-
// Only need to display headers if we have multiple sections
1118-
let show_headers = [
1119-
show_installed_toolchains,
1120-
show_active_targets,
1121-
show_active_toolchain,
1122-
]
1123-
.iter()
1124-
.filter(|x| **x)
1125-
.count()
1126-
> 1;
1127-
1128-
if show_installed_toolchains {
1100+
let active_targets: Vec<ComponentStatus> = active_toolchain_name
1101+
.and_then(|atn| match atn {
1102+
ToolchainName::Official(desc) => DistributableToolchain::new(cfg, desc.clone()).ok(),
1103+
_ => None,
1104+
})
1105+
.and_then(|distributable| {
1106+
let manifestation = distributable.get_manifestation().ok()?;
1107+
let config = manifestation.read_config().ok()?.unwrap_or_default();
1108+
let manifest = distributable.get_manifest().ok()?;
1109+
manifest
1110+
.query_components(distributable.desc(), &config)
1111+
.ok()
1112+
})
1113+
.map(|cs_vec| {
1114+
cs_vec
1115+
.into_iter()
1116+
.filter(|c| c.component.short_name_in_manifest() == "rust-std")
1117+
.filter(|c| c.installed)
1118+
.collect()
1119+
})
1120+
.unwrap_or_default();
1121+
1122+
// show installed toolchains
1123+
{
11291124
let mut t = process().stdout().terminal();
11301125

1131-
if show_headers {
1132-
print_header::<Error>(&mut t, "installed toolchains")?;
1133-
}
1134-
let default_name = cfg
1135-
.get_default()?
1136-
.ok_or_else(|| anyhow!("no default toolchain configured"))?;
1137-
for it in installed_toolchains {
1138-
if default_name == it {
1139-
writeln!(t.lock(), "{it} (default)")?;
1140-
} else {
1141-
writeln!(t.lock(), "{it}")?;
1142-
}
1126+
print_header::<Error>(&mut t, "installed toolchains")?;
1127+
1128+
let default_toolchain_name = cfg.get_default()?;
1129+
1130+
let last_index = installed_toolchains.len().wrapping_sub(1);
1131+
for (n, toolchain_name) in installed_toolchains.into_iter().enumerate() {
1132+
let is_default_toolchain = default_toolchain_name.as_ref() == Some(&toolchain_name);
1133+
let is_active_toolchain = active_toolchain_name == Some(&toolchain_name);
1134+
1135+
let status_str = match (is_default_toolchain, is_active_toolchain) {
1136+
(true, true) => " (default, active)",
1137+
(true, false) => " (default)",
1138+
(false, true) => " (active)",
1139+
(false, false) => "",
1140+
};
1141+
1142+
writeln!(t.lock(), "{toolchain_name}{status_str}")?;
1143+
11431144
if verbose {
1144-
let toolchain = Toolchain::new(cfg, it.into())?;
1145-
writeln!(process().stdout().lock(), "{}", toolchain.rustc_version())?;
1146-
// To make it easy to see what rustc that belongs to what
1147-
// toolchain we separate each pair with an extra newline
1148-
writeln!(process().stdout().lock())?;
1145+
let toolchain = Toolchain::new(cfg, toolchain_name.into())?;
1146+
writeln!(process().stdout().lock(), " {}", toolchain.rustc_version())?;
1147+
// To make it easy to see which rustc belongs to which
1148+
// toolchain, we separate each pair with an extra newline.
1149+
if n != last_index {
1150+
writeln!(process().stdout().lock())?;
1151+
}
11491152
}
11501153
}
1151-
if show_headers {
1152-
writeln!(t.lock())?
1153-
};
11541154
}
11551155

1156-
if show_active_targets {
1156+
// show active toolchain
1157+
{
11571158
let mut t = process().stdout().terminal();
11581159

1159-
if show_headers {
1160-
print_header::<Error>(&mut t, "installed targets for active toolchain")?;
1161-
}
1162-
for at in active_targets {
1163-
writeln!(
1164-
t.lock(),
1165-
"{}",
1166-
at.component
1167-
.target
1168-
.as_ref()
1169-
.expect("rust-std should have a target")
1170-
)?;
1171-
}
1172-
if show_headers {
1173-
writeln!(t.lock())?;
1174-
};
1175-
}
1176-
1177-
if show_active_toolchain {
1178-
let mut t = process().stdout().terminal();
1160+
writeln!(t.lock())?;
11791161

1180-
if show_headers {
1181-
print_header::<Error>(&mut t, "active toolchain")?;
1182-
}
1162+
print_header::<Error>(&mut t, "active toolchain")?;
11831163

1184-
match active_toolchain {
1185-
Ok((ref toolchain, ref reason)) => {
1186-
writeln!(t.lock(), "{} ({})", toolchain.name(), reason)?;
1187-
writeln!(t.lock(), "{}", toolchain.rustc_version())?;
1188-
}
1189-
Err(err) => {
1190-
let root_cause = err.root_cause();
1191-
if let Some(RustupError::ToolchainNotSelected) =
1192-
root_cause.downcast_ref::<RustupError>()
1193-
{
1194-
writeln!(t.lock(), "no active toolchain")?;
1195-
} else if let Some(cause) = err.source() {
1196-
writeln!(t.lock(), "(error: {err}, {cause})")?;
1197-
} else {
1198-
writeln!(t.lock(), "(error: {err})")?;
1164+
match active_toolchain_and_reason {
1165+
Some((active_toolchain_name, active_reason)) => {
1166+
let active_toolchain = new_toolchain_with_reason(
1167+
cfg,
1168+
active_toolchain_name.clone().into(),
1169+
&active_reason,
1170+
)?;
1171+
writeln!(t.lock(), "name: {}", active_toolchain.name())?;
1172+
writeln!(t.lock(), "compiler: {}", active_toolchain.rustc_version())?;
1173+
writeln!(t.lock(), "active because: {}", active_reason.to_string())?;
1174+
1175+
// show installed targets for the active toolchain
1176+
writeln!(t.lock(), "installed targets:")?;
1177+
1178+
for at in active_targets {
1179+
writeln!(
1180+
t.lock(),
1181+
" {}",
1182+
at.component
1183+
.target
1184+
.as_ref()
1185+
.expect("rust-std should have a target")
1186+
)?;
11991187
}
12001188
}
1201-
}
1202-
1203-
if show_headers {
1204-
writeln!(t.lock())?
1189+
None => {
1190+
writeln!(t.lock(), "no active toolchain")?;
1191+
}
12051192
}
12061193
}
12071194

@@ -1210,9 +1197,11 @@ fn show(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
12101197
E: From<std::io::Error>,
12111198
{
12121199
t.attr(terminalsource::Attr::Bold)?;
1213-
writeln!(t.lock(), "{s}")?;
1214-
writeln!(t.lock(), "{}", "-".repeat(s.len()))?;
1215-
writeln!(t.lock())?;
1200+
{
1201+
let mut term_lock = t.lock();
1202+
writeln!(term_lock, "{s}")?;
1203+
writeln!(term_lock, "{}", "-".repeat(s.len()))?;
1204+
} // drop the term_lock
12161205
t.reset()?;
12171206
Ok(())
12181207
}
@@ -1224,27 +1213,27 @@ fn show(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
12241213
fn show_active_toolchain(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
12251214
let verbose = m.get_flag("verbose");
12261215
let cwd = utils::current_dir()?;
1227-
match cfg.find_or_install_active_toolchain(&cwd) {
1228-
Err(e) => {
1229-
let root_cause = e.root_cause();
1230-
if let Some(RustupError::ToolchainNotSelected) =
1231-
root_cause.downcast_ref::<RustupError>()
1232-
{
1233-
} else {
1234-
return Err(e);
1235-
}
1236-
}
1237-
Ok((toolchain, reason)) => {
1216+
match cfg.find_active_toolchain(&cwd)? {
1217+
Some((toolchain_name, reason)) => {
1218+
let toolchain = new_toolchain_with_reason(cfg, toolchain_name.clone().into(), &reason)?;
12381219
writeln!(
12391220
process().stdout().lock(),
1240-
"{} ({})",
1221+
"{}\nactive because: {}",
12411222
toolchain.name(),
12421223
reason
12431224
)?;
12441225
if verbose {
1245-
writeln!(process().stdout().lock(), "{}", toolchain.rustc_version())?;
1226+
writeln!(
1227+
process().stdout().lock(),
1228+
"compiler: {}",
1229+
toolchain.rustc_version()
1230+
)?;
12461231
}
12471232
}
1233+
None => writeln!(
1234+
process().stdout().lock(),
1235+
"no default toolchain is configured"
1236+
)?,
12481237
}
12491238
Ok(utils::ExitCode(0))
12501239
}

src/config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ pub(crate) enum ActiveReason {
109109
impl Display for ActiveReason {
110110
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
111111
match self {
112-
Self::Default => write!(f, "default"),
113-
Self::Environment => write!(f, "environment override by RUSTUP_TOOLCHAIN"),
112+
Self::Default => write!(f, "it's the default toolchain"),
113+
Self::Environment => write!(f, "overriden by environment variable RUSTUP_TOOLCHAIN"),
114114
Self::CommandLine => write!(f, "overridden by +toolchain on the command line"),
115115
Self::OverrideDB(path) => write!(f, "directory override for '{}'", path.display()),
116116
Self::ToolchainFile(path) => write!(f, "overridden by '{}'", path.display()),

tests/suite/cli_misc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ fn override_by_toolchain_on_the_command_line() {
930930
config.expect_stdout_ok(&["rustup", "+nightly", "which", "rustc"], "/bin/rustc");
931931
config.expect_stdout_ok(
932932
&["rustup", "+nightly", "show"],
933-
"(overridden by +toolchain on the command line)",
933+
"active because: overridden by +toolchain on the command line",
934934
);
935935
config.expect_err(
936936
&["rustup", "+foo", "which", "rustc"],

0 commit comments

Comments
 (0)