diff --git a/crates/pacdef_core/src/backend/actual/rustup.rs b/crates/pacdef_core/src/backend/actual/rustup.rs index 682429b..8c57826 100644 --- a/crates/pacdef_core/src/backend/actual/rustup.rs +++ b/crates/pacdef_core/src/backend/actual/rustup.rs @@ -26,13 +26,26 @@ impl Backend for Rustup { impl_backend_constants!(); fn get_all_installed_packages(&self) -> anyhow::Result> { - let mut cmd = Command::new(self.get_binary()); - let packages: HashSet = run_rustup_command(&mut cmd, SWITCHES_INFO) + let mut toolchains_vec = self + .run_toolchain_command(&[&"toolchain", &"list"]) + .context("Getting installed toolchains")?; + + let mut toolchains: HashSet = toolchains_vec + .iter() + .map(|name| ["toolchain", name].join("/").into()) + .collect(); + + let packages: HashSet = self + .run_component_command( + &[&"component", &"list", &"--installed", &"--toolchain"], + &mut toolchains_vec, + ) .context("Getting installed components")? .iter() - .map(|name| ["component/", name].join("").into()) + .map(|name| ["component", name].join("/").into()) .collect(); - Ok(packages) + toolchains.extend(packages.into_iter()); + Ok(toolchains) } fn get_explicitly_installed_packages(&self) -> anyhow::Result> { @@ -43,27 +56,56 @@ impl Backend for Rustup { fn make_dependency(&self, _: &[Package]) -> anyhow::Result { panic!("Not supported by {}", BINARY) } -} -fn run_rustup_command(cmd: &mut Command, args: &[&str]) -> Result, anyhow::Error> { - cmd.args(args); - let output = String::from_utf8(cmd.output()?.stdout)?; - let mut val = Vec::new(); - for i in output.lines() { - let mut it = i.splitn(3, "-"); - let component = it.next().expect("Component name is empty!"); - match component { - "cargo" | "rustfmt" | "clippy" | "miri" | "rls" | "rustc" => { - val.push(component.to_string()); - } - _ => { - val.push( - component.to_string() - + "-" - + it.next().expect("No such component is managed by rustup"), - ); } + +impl Rustup { + pub(crate) fn new() -> Self { + Self { + packages: HashSet::new(), } } - Ok(val) + + fn run_component_command( + &self, + args: &[&str], + toolchains: &mut Vec, + ) -> Result, anyhow::Error> { + let mut val = Vec::new(); + for toolchain in toolchains { + let mut cmd = Command::new(self.get_binary()); + cmd.args(args); + cmd.arg(&toolchain); + let output = String::from_utf8(cmd.output()?.stdout)?; + for i in output.lines() { + let mut it = i.splitn(3, "-"); + let component = it.next().expect("Component name is empty!"); + match component { + "cargo" | "rustfmt" | "clippy" | "miri" | "rls" | "rustc" => { + val.push([toolchain, component].join("/")); + } + _ => { + let component = [ + component, + it.next().expect("No such component is managed by rustup"), + ] + .join("-"); + val.push([toolchain, component.as_str()].join("/")); + } + } + } + } + Ok(val) + } + fn run_toolchain_command(&self, args: &[&str]) -> Result, anyhow::Error> { + let mut cmd = Command::new(self.get_binary()); + cmd.args(args); + let output = String::from_utf8(cmd.output()?.stdout)?; + let mut val = Vec::new(); + for i in output.lines() { + let mut it = i.splitn(2, "-"); + val.push(it.next().expect("Toolchain name is empty.").to_string()); + } + Ok(val) + } }