Skip to content

Commit 9712cbb

Browse files
committed
Move list_components to DistributableToolchain
1 parent 16dc703 commit 9712cbb

File tree

3 files changed

+117
-141
lines changed

3 files changed

+117
-141
lines changed

src/cli/common.rs

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::term2;
66
use git_testament::{git_testament, render_testament};
77
use lazy_static::lazy_static;
88
use rustup::dist::notifications as dist_notifications;
9+
use rustup::toolchain::DistributableToolchain;
910
use rustup::utils::notifications as util_notifications;
1011
use rustup::utils::notify::NotificationLevel;
1112
use rustup::utils::utils;
@@ -346,16 +347,9 @@ where
346347

347348
pub fn list_targets(toolchain: &Toolchain<'_>) -> Result<()> {
348349
let mut t = term2::stdout();
349-
let components = match toolchain.list_components()? {
350-
// XXX: long term move this error to cli ? the normal .into doesn't work
351-
// because Result here is the wrong sort and expression type ascription
352-
// isn't a feature yet.
353-
None => Err(rustup::Error(
354-
rustup::ErrorKind::ComponentsUnsupported(toolchain.name().to_string()),
355-
error_chain::State::default(),
356-
)),
357-
Some(components) => Ok(components),
358-
}?;
350+
let distributable = DistributableToolchain::new(&toolchain)
351+
.chain_err(|| rustup::ErrorKind::ComponentsUnsupported(toolchain.name().to_string()))?;
352+
let components = distributable.list_components()?;
359353
for component in components {
360354
if component.component.short_name_in_manifest() == "rust-std" {
361355
let target = component
@@ -378,16 +372,9 @@ pub fn list_targets(toolchain: &Toolchain<'_>) -> Result<()> {
378372

379373
pub fn list_installed_targets(toolchain: &Toolchain<'_>) -> Result<()> {
380374
let mut t = term2::stdout();
381-
let components = match toolchain.list_components()? {
382-
// XXX: long term move this error to cli ? the normal .into doesn't work
383-
// because Result here is the wrong sort and expression type ascription
384-
// isn't a feature yet.
385-
None => Err(rustup::Error(
386-
rustup::ErrorKind::ComponentsUnsupported(toolchain.name().to_string()),
387-
error_chain::State::default(),
388-
)),
389-
Some(components) => Ok(components),
390-
}?;
375+
let distributable = DistributableToolchain::new(&toolchain)
376+
.chain_err(|| rustup::ErrorKind::ComponentsUnsupported(toolchain.name().to_string()))?;
377+
let components = distributable.list_components()?;
391378
for component in components {
392379
if component.component.short_name_in_manifest() == "rust-std" {
393380
let target = component
@@ -405,16 +392,9 @@ pub fn list_installed_targets(toolchain: &Toolchain<'_>) -> Result<()> {
405392

406393
pub fn list_components(toolchain: &Toolchain<'_>) -> Result<()> {
407394
let mut t = term2::stdout();
408-
let components = match toolchain.list_components()? {
409-
// XXX: long term move this error to cli ? the normal .into doesn't work
410-
// because Result here is the wrong sort and expression type ascription
411-
// isn't a feature yet.
412-
None => Err(rustup::Error(
413-
rustup::ErrorKind::ComponentsUnsupported(toolchain.name().to_string()),
414-
error_chain::State::default(),
415-
)),
416-
Some(components) => Ok(components),
417-
}?;
395+
let distributable = DistributableToolchain::new(&toolchain)
396+
.chain_err(|| rustup::ErrorKind::ComponentsUnsupported(toolchain.name().to_string()))?;
397+
let components = distributable.list_components()?;
418398
for component in components {
419399
let name = component.name;
420400
if component.installed {
@@ -431,16 +411,9 @@ pub fn list_components(toolchain: &Toolchain<'_>) -> Result<()> {
431411

432412
pub fn list_installed_components(toolchain: &Toolchain<'_>) -> Result<()> {
433413
let mut t = term2::stdout();
434-
let components = match toolchain.list_components()? {
435-
// XXX: long term move this error to cli ? the normal .into doesn't work
436-
// because Result here is the wrong sort and expression type ascription
437-
// isn't a feature yet.
438-
None => Err(rustup::Error(
439-
rustup::ErrorKind::ComponentsUnsupported(toolchain.name().to_string()),
440-
error_chain::State::default(),
441-
)),
442-
Some(components) => Ok(components),
443-
}?;
414+
let distributable = DistributableToolchain::new(&toolchain)
415+
.chain_err(|| rustup::ErrorKind::ComponentsUnsupported(toolchain.name().to_string()))?;
416+
let components = distributable.list_components()?;
444417
for component in components {
445418
if component.installed {
446419
writeln!(t, "{}", component.name)?;

src/cli/rustup_mode.rs

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -936,14 +936,18 @@ fn show(cfg: &Cfg) -> Result<()> {
936936

937937
// active_toolchain will carry the reason we don't have one in its detail.
938938
let active_targets = if let Ok(ref at) = active_toolchain {
939-
match at.0.list_components() {
940-
Ok(None) => vec![],
941-
Ok(Some(cs_vec)) => cs_vec
942-
.into_iter()
943-
.filter(|c| c.component.short_name_in_manifest() == "rust-std")
944-
.filter(|c| c.installed)
945-
.collect(),
946-
Err(_) => vec![],
939+
if let Ok(distributable) = DistributableToolchain::new(&at.0) {
940+
match distributable.list_components() {
941+
Ok(cs_vec) => cs_vec
942+
.into_iter()
943+
.filter(|c| c.component.short_name_in_manifest() == "rust-std")
944+
.filter(|c| c.installed)
945+
.collect(),
946+
Err(_) => vec![],
947+
}
948+
} else {
949+
// These three vec![] could perhaps be reduced with and_then on active_toolchain.
950+
vec![]
947951
}
948952
} else {
949953
vec![]
@@ -1109,7 +1113,8 @@ fn target_add(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
11091113
}
11101114

11111115
targets.clear();
1112-
for component in toolchain.list_components()?.unwrap() {
1116+
let distributable = DistributableToolchain::new(&toolchain)?;
1117+
for component in distributable.list_components()? {
11131118
if component.component.short_name_in_manifest() == "rust-std"
11141119
&& component.available
11151120
&& !component.installed
@@ -1333,28 +1338,26 @@ const DOCS_DATA: &[(&str, &str, &str,)] = &[
13331338

13341339
fn doc(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
13351340
let toolchain = explicit_or_dir_toolchain(cfg, m)?;
1336-
match toolchain.list_components()? {
1337-
None => { /* custom - no validation */ }
1338-
Some(components) => {
1339-
if let [_] = components
1340-
.into_iter()
1341-
.filter(|cstatus| {
1342-
cstatus.component.short_name_in_manifest() == "rust-docs" && !cstatus.installed
1343-
})
1344-
.take(1)
1345-
.collect::<Vec<ComponentStatus>>()
1346-
.as_slice()
1347-
{
1348-
info!(
1349-
"`rust-docs` not installed in toolchain `{}`",
1350-
toolchain.name()
1351-
);
1352-
info!(
1353-
"To install, try `rustup component add --toolchain {} rust-docs`",
1354-
toolchain.name()
1355-
);
1356-
return Err("unable to view documentation which is not installed".into());
1357-
}
1341+
if let Ok(distributable) = DistributableToolchain::new(&toolchain) {
1342+
let components = distributable.list_components()?;
1343+
if let [_] = components
1344+
.into_iter()
1345+
.filter(|cstatus| {
1346+
cstatus.component.short_name_in_manifest() == "rust-docs" && !cstatus.installed
1347+
})
1348+
.take(1)
1349+
.collect::<Vec<ComponentStatus>>()
1350+
.as_slice()
1351+
{
1352+
info!(
1353+
"`rust-docs` not installed in toolchain `{}`",
1354+
toolchain.name()
1355+
);
1356+
info!(
1357+
"To install, try `rustup component add --toolchain {} rust-docs`",
1358+
toolchain.name()
1359+
);
1360+
return Err("unable to view documentation which is not installed".into());
13581361
}
13591362
}
13601363
let topical_path: PathBuf;

src/toolchain.rs

Lines changed: 70 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -496,74 +496,6 @@ impl<'a> Toolchain<'a> {
496496
})
497497
}
498498
// Distributable only. Installed only.
499-
pub fn list_components(&self) -> Result<Option<Vec<ComponentStatus>>> {
500-
if !self.exists() {
501-
return Err(ErrorKind::ToolchainNotInstalled(self.name.to_owned()).into());
502-
}
503-
504-
let toolchain = &self.name;
505-
let toolchain = match ToolchainDesc::from_str(toolchain).ok() {
506-
None => return Ok(None),
507-
Some(toolchain) => toolchain,
508-
};
509-
510-
let prefix = InstallPrefix::from(self.path.to_owned());
511-
let manifestation = Manifestation::open(prefix, toolchain.target.clone())?;
512-
513-
if let Some(manifest) = manifestation.load_manifest()? {
514-
let config = manifestation.read_config()?;
515-
516-
// Return all optional components of the "rust" package for the
517-
// toolchain's target triple.
518-
let mut res = Vec::new();
519-
520-
let rust_pkg = manifest
521-
.packages
522-
.get("rust")
523-
.expect("manifest should contain a rust package");
524-
let targ_pkg = rust_pkg
525-
.targets
526-
.get(&toolchain.target)
527-
.expect("installed manifest should have a known target");
528-
529-
for component in &targ_pkg.components {
530-
let installed = config
531-
.as_ref()
532-
.map(|c| component.contained_within(&c.components))
533-
.unwrap_or(false);
534-
535-
let component_target = TargetTriple::new(&component.target());
536-
537-
// Get the component so we can check if it is available
538-
let component_pkg = manifest
539-
.get_package(&component.short_name_in_manifest())
540-
.unwrap_or_else(|_| {
541-
panic!(
542-
"manifest should contain component {}",
543-
&component.short_name(&manifest)
544-
)
545-
});
546-
let component_target_pkg = component_pkg
547-
.targets
548-
.get(&component_target)
549-
.expect("component should have target toolchain");
550-
551-
res.push(ComponentStatus {
552-
component: component.clone(),
553-
name: component.name(&manifest),
554-
installed,
555-
available: component_target_pkg.available(),
556-
});
557-
}
558-
559-
res.sort_by(|a, b| a.component.cmp(&b.component));
560-
561-
Ok(Some(res))
562-
} else {
563-
Err(ErrorKind::ComponentsUnsupported(self.name.to_string()).into())
564-
}
565-
}
566-
// Distributable only. Installed only.
567499
fn get_component_suggestion(
568500
&self,
569501
component: &Component,
@@ -576,8 +508,9 @@ impl<'a> Toolchain<'a> {
576508
// High number can result in inaccurate suggestions for short queries e.g. `rls`
577509
const MAX_DISTANCE: usize = 3;
578510

579-
let components = self.list_components();
580-
if let Ok(Some(components)) = components {
511+
let distributable = DistributableToolchain::new(&self);
512+
let components = distributable.ok().map(|d| d.list_components());
513+
if let Some(Ok(components)) = components {
581514
let short_name_distance = components
582515
.iter()
583516
.filter(|c| !only_installed || c.installed)
@@ -825,6 +758,73 @@ impl<'a> DistributableToolchain<'a> {
825758
))
826759
}
827760

761+
// Installed only.
762+
pub fn list_components(&self) -> Result<Vec<ComponentStatus>> {
763+
if !self.0.exists() {
764+
return Err(ErrorKind::ToolchainNotInstalled(self.0.name.to_owned()).into());
765+
}
766+
767+
let toolchain = &self.0.name;
768+
let toolchain = ToolchainDesc::from_str(toolchain)
769+
.chain_err(|| ErrorKind::ComponentsUnsupported(self.0.name.to_string()))?;
770+
771+
let prefix = InstallPrefix::from(self.0.path.to_owned());
772+
let manifestation = Manifestation::open(prefix, toolchain.target.clone())?;
773+
774+
if let Some(manifest) = manifestation.load_manifest()? {
775+
let config = manifestation.read_config()?;
776+
777+
// Return all optional components of the "rust" package for the
778+
// toolchain's target triple.
779+
let mut res = Vec::new();
780+
781+
let rust_pkg = manifest
782+
.packages
783+
.get("rust")
784+
.expect("manifest should contain a rust package");
785+
let targ_pkg = rust_pkg
786+
.targets
787+
.get(&toolchain.target)
788+
.expect("installed manifest should have a known target");
789+
790+
for component in &targ_pkg.components {
791+
let installed = config
792+
.as_ref()
793+
.map(|c| component.contained_within(&c.components))
794+
.unwrap_or(false);
795+
796+
let component_target = TargetTriple::new(&component.target());
797+
798+
// Get the component so we can check if it is available
799+
let component_pkg = manifest
800+
.get_package(&component.short_name_in_manifest())
801+
.unwrap_or_else(|_| {
802+
panic!(
803+
"manifest should contain component {}",
804+
&component.short_name(&manifest)
805+
)
806+
});
807+
let component_target_pkg = component_pkg
808+
.targets
809+
.get(&component_target)
810+
.expect("component should have target toolchain");
811+
812+
res.push(ComponentStatus {
813+
component: component.clone(),
814+
name: component.name(&manifest),
815+
installed,
816+
available: component_target_pkg.available(),
817+
});
818+
}
819+
820+
res.sort_by(|a, b| a.component.cmp(&b.component));
821+
822+
Ok(res)
823+
} else {
824+
Err(ErrorKind::ComponentsUnsupported(self.0.name.to_string()).into())
825+
}
826+
}
827+
828828
// Installed only.
829829
pub fn remove_component(&self, mut component: Component) -> Result<()> {
830830
// Overlapping code with get_manifest :/.

0 commit comments

Comments
 (0)