From 4f0e9766a9a65cbac598d0fe5b7204f215be769a Mon Sep 17 00:00:00 2001 From: Jeff Dickey <216188+jdx@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:22:37 -0600 Subject: [PATCH] wip --- Cargo.lock | 1 + Cargo.toml | 1 + cli/src/cli/generate/markdown.rs | 58 +++++++++++++++++++++++++------- examples/MISE_README.md | 31 ++++++++++------- src/error.rs | 3 ++ src/parse/config.rs | 12 ++++--- src/parse/data_types.rs | 11 ++++++ src/parse/mod.rs | 1 + 8 files changed, 88 insertions(+), 30 deletions(-) create mode 100644 src/parse/data_types.rs diff --git a/Cargo.lock b/Cargo.lock index c48532c..00314a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -733,6 +733,7 @@ dependencies = [ "miette", "once_cell", "shell-escape", + "strum", "thiserror", "xx", ] diff --git a/Cargo.toml b/Cargo.toml index 6f38159..dd26b07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ log = "0.4" itertools = "0.12.0" once_cell = "1.19.0" xx = "0.2" +strum = { version = "0.25.0", features = ["derive"] } [features] default = ["clap"] diff --git a/cli/src/cli/generate/markdown.rs b/cli/src/cli/generate/markdown.rs index a830433..a7ec944 100644 --- a/cli/src/cli/generate/markdown.rs +++ b/cli/src/cli/generate/markdown.rs @@ -148,6 +148,7 @@ impl Markdown { } #[derive(Debug, EnumIs)] +#[strum(serialize_all = "snake_case")] enum UsageMdDirective { Load { file: PathBuf }, Title, @@ -294,7 +295,7 @@ impl UsageMdDirective { ctx.plain = false; let spec = ctx.spec.as_ref().unwrap(); ctx.push(self.to_string()); - print_config(&ctx, &spec.config)?; + ctx.push(print_config(&spec.config)?); ctx.push("".to_string()); } UsageMdDirective::EndToken => { @@ -360,24 +361,55 @@ fn print_commands(ctx: &UsageMdContext, cmds: &[&SchemaCmd]) -> miette::Result<( Ok(()) } -fn print_config(ctx: &UsageMdContext, config: &SpecConfig) -> miette::Result<()> { +static CONFIG_TEMPLATE: &str = r#" +### `!KEY!` + +!ENV! +!DEFAULT! + +!HELP! +!LONG_HELP! +"#; + +fn print_config(config: &SpecConfig) -> miette::Result { + let mut all = vec![]; for (key, prop) in &config.props { - ctx.push(format!("### `{key}`", key = key)); + let mut out = CONFIG_TEMPLATE.to_string(); + let mut tmpl = |k, d: String| { + out = out.replace(k, &d); + }; + tmpl("!KEY!", key.to_string()); + // out = out.replace("!KEY!", &format!("### `{key}`")); if let Some(env) = &prop.env { - ctx.push(format!("env: `{env}`", env = env)); + tmpl("!ENV!", format!("* env: `{env}`")); + // out = out.replace("!ENV!", &format!("* env: `{env}`")); } - if !prop.default.is_null() { - ctx.push(format!("default: `{default}`", default = prop.default)); + if let Some(default) = prop + .default_note + .clone() + .or_else(|| match prop.default.is_null() { + true => None, + false => Some(prop.default.to_string()), + }) + { + tmpl("!DEFAULT!", format!("* default: `{default}`")); + // out = out.replace("!DEFAULT!", &format!("* default: `{default}`")); } - if let Some(help) = &prop.help { - ctx.push(help.to_string()); + if let Some(help) = prop.long_help.clone().or(prop.help.clone()) { + // out = out.replace("!HELP!", &format!("* help: `{help}`")); + tmpl("!HELP!", help); } - if let Some(long_help) = &prop.long_help { - ctx.push(long_help.to_string()); - } - ctx.push("Used by commnds: global|*".to_string()); + out = regex!(r#"!.+!\n"#) + .replace_all(&out, "") + .trim_start() + .trim_end() + .to_string() + + "\n"; + all.push(out) + // TODO: data type + // TODO: show which commands use this prop ctx.push("Used by commnds: global|*".to_string()); } - Ok(()) + Ok(all.join("\n")) } #[derive(Error, Diagnostic, Debug)] diff --git a/examples/MISE_README.md b/examples/MISE_README.md index fc83297..797927d 100644 --- a/examples/MISE_README.md +++ b/examples/MISE_README.md @@ -151,22 +151,27 @@ mise.usage.kdl [flags] [args] ## Config ### `activate_accessive` -env: `MISE_ACTIVATE_ACCESSIVE` -default: `false` -Pushes tools' bin-paths to the front of PATH instead of allowing modifications of PATH after activation to take precedence. + +* env: `MISE_ACTIVATE_ACCESSIVE` +* default: `false` + foooooooo -Used by commnds: global|* + ### `color` -env: `MISE_COLOR` -default: `true` -Used by commnds: global|* + +* env: `MISE_COLOR` +* default: `true` + ### `jobs` -default: `4` -Used by commnds: global|* + +* default: `4` + ### `timeout` -default: `1.5` -Used by commnds: global|* + +* default: `1.5` + ### `user` -default: `"admin"` -Used by commnds: global|* + +* default: `"admin"` + diff --git a/src/error.rs b/src/error.rs index 988f61c..b4076f9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -17,6 +17,9 @@ pub enum UsageErr { #[error(transparent)] IO(#[from] std::io::Error), + #[error(transparent)] + Strum(#[from] strum::ParseError), + #[error(transparent)] #[diagnostic(transparent)] KdlError(#[from] kdl::KdlError), diff --git a/src/parse/config.rs b/src/parse/config.rs index 288d176..b91aaf0 100644 --- a/src/parse/config.rs +++ b/src/parse/config.rs @@ -4,10 +4,10 @@ use kdl::{KdlDocument, KdlEntry, KdlNode, KdlValue}; use crate::bail_parse; use crate::error::UsageErr; +use crate::parse::data_types::SpecDataTypes; use crate::parse::helpers::NodeHelper; -#[derive(Debug)] -#[derive(Default)] +#[derive(Debug, Default)] pub struct SpecConfig { pub props: BTreeMap, } @@ -21,6 +21,8 @@ impl SpecConfig { #[derive(Debug)] pub struct SpecConfigProp { pub default: KdlValue, + pub default_note: Option, + pub data_type: SpecDataTypes, pub env: Option, pub help: Option, pub long_help: Option, @@ -62,6 +64,8 @@ impl TryFrom<&KdlNode> for SpecConfig { for (k, v) in ph.props() { match k { "default" => prop.default = v.value.clone(), + "default_note" => prop.default_note = Some(v.ensure_string()?), + "data_type" => prop.data_type = v.ensure_string()?.parse()?, "env" => prop.env = v.ensure_string()?.to_string().into(), "help" => prop.help = v.ensure_string()?.to_string().into(), "long_help" => { @@ -80,12 +84,12 @@ impl TryFrom<&KdlNode> for SpecConfig { } } - - impl Default for SpecConfigProp { fn default() -> Self { Self { default: KdlValue::Null, + default_note: None, + data_type: SpecDataTypes::Null, env: None, help: None, long_help: None, diff --git a/src/parse/data_types.rs b/src/parse/data_types.rs new file mode 100644 index 0000000..4802180 --- /dev/null +++ b/src/parse/data_types.rs @@ -0,0 +1,11 @@ +use strum::EnumString; + +#[derive(Debug, EnumString)] +#[strum(serialize_all = "snake_case")] +pub enum SpecDataTypes { + Null, + String, + Integer, + Float, + Boolean, +} diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 6633ee1..db0dcea 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -1,6 +1,7 @@ pub mod arg; pub mod cmd; pub mod config; +mod data_types; pub mod flag; pub(crate) mod helpers; pub mod spec;