summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Nakamura <dnaka91@gmail.com>2020-11-30 21:52:55 +0900
committerGitHub <noreply@github.com>2020-11-30 13:52:55 +0100
commitabfe4324e0383b313840b6fd55f775d7551a73b2 (patch)
treedfe630e14a83b9787321b0d7cdcacdbd6a9512b8
parent389e006c00fe50aac98c7ca9e3cbdee6dab2e35e (diff)
feat(rust): Support new rust-toolchain format (#1938)
* feat(rust): Support new rust-toolchain format * Match file parsing with rustup and update link * Use cargo to deserialize the rust-toolchain file * Filter empty channel strings after extraction * Use the option value instead of rewrapping
-rw-r--r--Cargo.lock10
-rw-r--r--Cargo.toml4
-rw-r--r--src/modules/rust.rs80
3 files changed, 80 insertions, 14 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0ded37a95..bdae9630c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1122,18 +1122,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.116"
+version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
+checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.116"
+version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
+checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
dependencies = [
"proc-macro2",
"quote 1.0.7",
@@ -1210,7 +1210,7 @@ dependencies = [
"rayon",
"regex",
"rust-ini",
- "serde_derive",
+ "serde",
"serde_json",
"shell-words",
"starship_module_config_derive",
diff --git a/Cargo.toml b/Cargo.toml
index 23facdb84..5e348a9b8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,7 +33,7 @@ ansi_term = "0.12.1"
dirs-next = "2.0.0"
git2 = { version = "0.13.12", default-features = false }
toml = { version = "0.5.7", features = ["preserve_order"] }
-rust-ini = "0.16"
+rust-ini = "0.16"
serde_json = "1.0.59"
rayon = "1.5.0"
log = { version = "0.4.11", features = ["std"] }
@@ -59,7 +59,7 @@ unicode-width = "0.1.8"
term_size = "0.3.2"
quick-xml = "0.20.0"
rand = "0.7.3"
-serde_derive = "1.0.115"
+serde = { version = "1.0.117", features = ["derive"] }
indexmap = "1.6.0"
notify-rust = { version = "4.0.0", optional = true }
diff --git a/src/modules/rust.rs b/src/modules/rust.rs
index c72be0ec8..00b029a82 100644
--- a/src/modules/rust.rs
+++ b/src/modules/rust.rs
@@ -2,6 +2,8 @@ use std::fs;
use std::path::Path;
use std::process::{Command, Output};
+use serde::Deserialize;
+
use super::{Context, Module, RootModuleConfig};
use crate::configs::rust::RustConfig;
@@ -125,26 +127,47 @@ fn extract_toolchain_from_rustup_override_list(stdout: &str, cwd: &Path) -> Opti
fn find_rust_toolchain_file(context: &Context) -> Option<String> {
// Look for 'rust-toolchain' as rustup does.
- // https://github.com/rust-lang/rustup.rs/blob/d84e6e50126bccd84649e42482fc35a11d019401/src/config.rs#L320-L358
+ // https://github.com/rust-lang/rustup/blob/89912c4cf51645b9c152ab7380fd07574fec43a3/src/config.rs#L546-L616
+
+ #[derive(Deserialize)]
+ struct OverrideFile {
+ toolchain: ToolchainSection,
+ }
- fn read_first_line(path: &Path) -> Option<String> {
- let content = fs::read_to_string(path).ok()?;
- let line = content.lines().next()?;
- Some(line.trim().to_owned())
+ #[derive(Deserialize)]
+ struct ToolchainSection {
+ channel: Option<String>,
+ }
+
+ fn read_channel(path: &Path) -> Option<String> {
+ let contents = fs::read_to_string(path).ok()?;
+
+ match contents.lines().count() {
+ 0 => None,
+ 1 => Some(contents),
+ _ => {
+ toml::from_str::<OverrideFile>(&contents)
+ .ok()?
+ .toolchain
+ .channel
+ }
+ }
+ .filter(|c| !c.trim().is_empty())
+ .map(|c| c.trim().to_owned())
}
if let Ok(true) = context
.dir_contents()
.map(|dir| dir.has_file("rust-toolchain"))
{
- if let Some(toolchain) = read_first_line(Path::new("rust-toolchain")) {
+ if let Some(toolchain) = read_channel(Path::new("rust-toolchain")) {
return Some(toolchain);
}
}
let mut dir = &*context.current_dir;
loop {
- if let Some(toolchain) = read_first_line(&dir.join("rust-toolchain")) {
+ if let Some(toolchain) = read_channel(&dir.join("rust-toolchain")) {
return Some(toolchain);
}
dir = dir.parent()?;
@@ -200,6 +223,7 @@ enum RustupRunRustcVersionOutcome {
#[cfg(test)]
mod tests {
use once_cell::sync::Lazy;
+ use std::io;
use std::process::{ExitStatus, Output};
use super::*;
@@ -309,4 +333,46 @@ mod tests {
let version_without_hash = String::from("rustc 1.34.0");
assert_eq!(format_rustc_version(version_without_hash), "v1.34.0");
}
+
+ #[test]
+ fn test_find_rust_toolchain_file() -> io::Result<()> {
+ let dir = tempfile::tempdir()?;
+ fs::write(dir.path().join("rust-toolchain"), "1.34.0")?;
+
+ let context = Context::new_with_dir(Default::default(), dir.path());
+
+ assert_eq!(
+ find_rust_toolchain_file(&context),
+ Some("1.34.0".to_owned())
+ );
+ dir.close()?;
+
+ let dir = tempfile::tempdir()?;
+ fs::write(
+ dir.path().join("rust-toolchain"),
+ "[toolchain]\nchannel = \"1.34.0\"",
+ )?;
+
+ let context = Context::new_with_dir(Default::default(), dir.path());
+
+ assert_eq!(
+ find_rust_toolchain_file(&context),
+ Some("1.34.0".to_owned())
+ );
+ dir.close()?;
+
+ let dir = tempfile::tempdir()?;
+ fs::write(
+ dir.path().join("rust-toolchain"),
+ "\n\n[toolchain]\n\n\nchannel = \"1.34.0\"",
+ )?;
+
+ let context = Context::new_with_dir(Default::default(), dir.path());
+
+ assert_eq!(
+ find_rust_toolchain_file(&context),
+ Some("1.34.0".to_owned())
+ );
+ dir.close()
+ }
}