Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/project-model/src/toolchain_info/version.rs')
| -rw-r--r-- | crates/project-model/src/toolchain_info/version.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/crates/project-model/src/toolchain_info/version.rs b/crates/project-model/src/toolchain_info/version.rs new file mode 100644 index 0000000000..e795fdf1d6 --- /dev/null +++ b/crates/project-model/src/toolchain_info/version.rs @@ -0,0 +1,58 @@ +//! Get the version string of the toolchain. + +use anyhow::Context; +use rustc_hash::FxHashMap; +use semver::Version; +use toolchain::Tool; + +use crate::{toolchain_info::QueryConfig, utf8_stdout}; + +pub(crate) fn get( + config: QueryConfig<'_>, + extra_env: &FxHashMap<String, String>, +) -> Result<Option<Version>, anyhow::Error> { + let (mut cmd, prefix) = match config { + QueryConfig::Cargo(sysroot, cargo_toml) => { + (sysroot.tool(Tool::Cargo, cargo_toml.parent()), "cargo ") + } + QueryConfig::Rustc(sysroot, current_dir) => { + (sysroot.tool(Tool::Rustc, current_dir), "rustc ") + } + }; + cmd.envs(extra_env); + cmd.arg("--version"); + let out = utf8_stdout(&mut cmd).with_context(|| format!("Failed to query rust toolchain version via `{cmd:?}`, is your toolchain setup correctly?"))?; + + let version = + out.strip_prefix(prefix).and_then(|it| Version::parse(it.split_whitespace().next()?).ok()); + if version.is_none() { + tracing::warn!("Failed to parse `{cmd:?}` output `{out}` as a semver version"); + } + anyhow::Ok(version) +} + +#[cfg(test)] +mod tests { + use paths::{AbsPathBuf, Utf8PathBuf}; + + use crate::{ManifestPath, Sysroot}; + + use super::*; + + #[test] + fn cargo() { + let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml"); + let sysroot = Sysroot::empty(); + let manifest_path = + ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap(); + let cfg = QueryConfig::Cargo(&sysroot, &manifest_path); + assert!(get(cfg, &FxHashMap::default()).is_ok()); + } + + #[test] + fn rustc() { + let sysroot = Sysroot::empty(); + let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref()); + assert!(get(cfg, &FxHashMap::default()).is_ok()); + } +} |