feat(config): print a suggestion for unknown fields (#2560)
* feat(config): print a suggestion for unknown fields * Fix typo Co-authored-by: Thomas O'Donnell <andytom@users.noreply.github.com> Co-authored-by: Thomas O'Donnell <andytom@users.noreply.github.com>
This commit is contained in:
parent
a2cdc912e7
commit
8af677c811
|
@ -247,7 +247,7 @@ dependencies = [
|
||||||
"ansi_term 0.11.0",
|
"ansi_term 0.11.0",
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags 1.2.1",
|
"bitflags 1.2.1",
|
||||||
"strsim",
|
"strsim 0.8.0",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"vec_map",
|
"vec_map",
|
||||||
|
@ -1614,6 +1614,7 @@ dependencies = [
|
||||||
"shadow-rs",
|
"shadow-rs",
|
||||||
"shell-words",
|
"shell-words",
|
||||||
"starship_module_config_derive",
|
"starship_module_config_derive",
|
||||||
|
"strsim 0.10.0",
|
||||||
"sys-info",
|
"sys-info",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"term_size",
|
"term_size",
|
||||||
|
@ -1628,7 +1629,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "starship_module_config_derive"
|
name = "starship_module_config_derive"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote 1.0.9",
|
"quote 1.0.9",
|
||||||
|
@ -1641,6 +1642,12 @@ version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
|
@ -49,7 +49,7 @@ once_cell = "1.7.2"
|
||||||
chrono = "0.4.19"
|
chrono = "0.4.19"
|
||||||
sys-info = "0.8.0"
|
sys-info = "0.8.0"
|
||||||
byte-unit = "4.0.10"
|
byte-unit = "4.0.10"
|
||||||
starship_module_config_derive = { version = "0.2.0", path = "starship_module_config_derive" }
|
starship_module_config_derive = { version = "0.2.1", path = "starship_module_config_derive" }
|
||||||
yaml-rust = "0.4.5"
|
yaml-rust = "0.4.5"
|
||||||
pest = "2.1.3"
|
pest = "2.1.3"
|
||||||
pest_derive = "2.1.0"
|
pest_derive = "2.1.0"
|
||||||
|
@ -67,6 +67,7 @@ notify-rust = { version = "4.3.0", optional = true }
|
||||||
semver = "0.11.0"
|
semver = "0.11.0"
|
||||||
which = "4.1.0"
|
which = "4.1.0"
|
||||||
shadow-rs = "0.5.25"
|
shadow-rs = "0.5.25"
|
||||||
|
strsim = "0.10.0"
|
||||||
|
|
||||||
process_control = { version = "3.0.1", features = ["crossbeam-channel"] }
|
process_control = { version = "3.0.1", features = ["crossbeam-channel"] }
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{config::ModuleConfig, module::ALL_MODULES};
|
use crate::{config::ModuleConfig, module::ALL_MODULES};
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
// On changes please also update the `FullConfig` struct in `mod.rs`
|
// On changes please also update the `FullConfig` struct in `mod.rs`
|
||||||
#[derive(Clone, Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
|
@ -100,6 +101,31 @@ impl<'a> ModuleConfig<'a> for StarshipRootConfig<'a> {
|
||||||
unknown => {
|
unknown => {
|
||||||
if !ALL_MODULES.contains(&unknown) && unknown != "custom" {
|
if !ALL_MODULES.contains(&unknown) && unknown != "custom" {
|
||||||
log::warn!("Unknown config key '{}'", unknown);
|
log::warn!("Unknown config key '{}'", unknown);
|
||||||
|
|
||||||
|
let did_you_mean = &[
|
||||||
|
// Root options
|
||||||
|
"format",
|
||||||
|
"scan_timeout",
|
||||||
|
"command_timeout",
|
||||||
|
"add_newline",
|
||||||
|
// Modules
|
||||||
|
"custom",
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.chain(ALL_MODULES.iter())
|
||||||
|
.filter_map(|field| {
|
||||||
|
let score = strsim::jaro_winkler(unknown, field);
|
||||||
|
(score > 0.8).then(|| (score, field))
|
||||||
|
})
|
||||||
|
.max_by(
|
||||||
|
|(score_a, _field_a), (score_b, _field_b)| {
|
||||||
|
score_a.partial_cmp(score_b).unwrap_or(Ordering::Equal)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some((_score, field)) = did_you_mean {
|
||||||
|
log::warn!("Did you mean '{}'?", field);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "starship_module_config_derive"
|
name = "starship_module_config_derive"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["Matan Kushner <hello@matchai.me>"]
|
authors = ["Matan Kushner <hello@matchai.me>"]
|
||||||
homepage = "https://starship.rs"
|
homepage = "https://starship.rs"
|
||||||
|
|
|
@ -18,6 +18,7 @@ fn impl_module_config(dinput: DeriveInput) -> proc_macro::TokenStream {
|
||||||
if let syn::Data::Struct(data) = dinput.data {
|
if let syn::Data::Struct(data) = dinput.data {
|
||||||
if let syn::Fields::Named(fields_named) = data.fields {
|
if let syn::Fields::Named(fields_named) = data.fields {
|
||||||
let mut load_tokens = quote! {};
|
let mut load_tokens = quote! {};
|
||||||
|
let mut fields = quote! {};
|
||||||
|
|
||||||
for field in fields_named.named.iter() {
|
for field in fields_named.named.iter() {
|
||||||
let ident = field.ident.as_ref().unwrap();
|
let ident = field.ident.as_ref().unwrap();
|
||||||
|
@ -26,10 +27,19 @@ fn impl_module_config(dinput: DeriveInput) -> proc_macro::TokenStream {
|
||||||
stringify!(#ident) => self.#ident.load_config(v),
|
stringify!(#ident) => self.#ident.load_config(v),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let new_field = quote! {
|
||||||
|
stringify!(#ident),
|
||||||
|
};
|
||||||
|
|
||||||
load_tokens = quote! {
|
load_tokens = quote! {
|
||||||
#load_tokens
|
#load_tokens
|
||||||
#new_load_tokens
|
#new_load_tokens
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fields = quote! {
|
||||||
|
#fields
|
||||||
|
#new_field
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
load_config = quote! {
|
load_config = quote! {
|
||||||
|
@ -40,6 +50,21 @@ fn impl_module_config(dinput: DeriveInput) -> proc_macro::TokenStream {
|
||||||
#load_tokens
|
#load_tokens
|
||||||
unknown => {
|
unknown => {
|
||||||
::log::warn!("Unknown config key '{}'", unknown);
|
::log::warn!("Unknown config key '{}'", unknown);
|
||||||
|
|
||||||
|
let did_you_mean = ::std::array::IntoIter::new([#fields])
|
||||||
|
.filter_map(|field| {
|
||||||
|
let score = ::strsim::jaro_winkler(unknown, field);
|
||||||
|
(score > 0.8).then(|| (score, field))
|
||||||
|
})
|
||||||
|
.max_by(
|
||||||
|
|(score_a, _field_a), (score_b, _field_b)| {
|
||||||
|
score_a.partial_cmp(score_b).unwrap_or(::std::cmp::Ordering::Equal)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some((_score, field)) = did_you_mean {
|
||||||
|
::log::warn!("Did you mean '{}'?", field);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue