Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Jan 13, 2024
1 parent 8bfed7a commit 7944f05
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 34 deletions.
106 changes: 73 additions & 33 deletions cli/src/cli/generate/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::io::Write;
use std::iter::once;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::sync::Mutex;
use std::{env, fs};

use clap::Args;
Expand Down Expand Up @@ -57,6 +58,8 @@ impl Markdown {
.into_iter()
.try_fold(UsageMdContext::new(root), |ctx, d| d.run(ctx))?
.out
.lock()
.unwrap()
.join("\n");
env::set_current_dir(cwd).into_diagnostic()?;
println!("{}", out);
Expand Down Expand Up @@ -147,7 +150,11 @@ impl Markdown {

enum UsageMdDirective {
Load { file: PathBuf },
UsageOverview,
GlobalArgs,
GlobalFlags,
CommandIndex,
Commands,
EndToken,
Plain(String),
}
Expand All @@ -156,7 +163,7 @@ struct UsageMdContext {
_root: PathBuf,
plain: bool,
spec: Option<Spec>,
out: Vec<String>,
out: Mutex<Vec<String>>,
}

impl UsageMdContext {
Expand All @@ -165,9 +172,13 @@ impl UsageMdContext {
_root,
plain: true,
spec: None,
out: vec![],
out: Mutex::new(vec![]),
}
}

fn push(&self, line: String) {
self.out.lock().unwrap().push(line);
}
}

impl UsageMdDirective {
Expand All @@ -179,94 +190,119 @@ impl UsageMdDirective {
// false => file.clone(),
// };
ctx.spec = Some(fs::read_to_string(file).into_diagnostic()?.parse()?);
ctx.out
.push(format!("<!-- [USAGE] load file=\"{}\" -->", file.display()));
ctx.push(format!("<!-- [USAGE] load file=\"{}\" -->", file.display()));
}
UsageMdDirective::UsageOverview => {
ctx.plain = false;
let spec = ctx.spec.as_ref().unwrap();

Ok(ctx)
ctx.push("<!-- [USAGE] usage_overview -->".to_string());
ctx.push(format!("# {name}", name = spec.name));
ctx.push("## Usage".to_string());
ctx.push("```".to_string());
ctx.push(format!("{bin} [flags] [args]", bin = spec.bin));
ctx.push("```".to_string());
ctx.push("\n<!-- [USAGE] -->".to_string());
}
UsageMdDirective::CommandIndex => {
UsageMdDirective::GlobalArgs => {
ctx.plain = false;
let spec = ctx.spec.as_ref().unwrap();
let mut out = vec![];
out.push(format!("<!-- [USAGE] command_index -->"));
out.push(format!("# {name}", name = spec.name));
out.push(format!("## Usage"));
out.push(format!("```"));
out.push(format!("{bin} [flags] [args]", bin = spec.bin));
out.push(format!("```"));

ctx.push("<!-- [USAGE] global_args -->".to_string());
let args = spec.cmd.args.iter().filter(|a| !a.hide).collect::<Vec<_>>();
if !args.is_empty() {
out.push(format!("## Args"));
ctx.push(format!("## Args"));
for arg in args {
let name = &arg.usage();
if let Some(about) = &arg.long_help {
out.push(format!("### {name}", name = name));
out.push(format!("{about}", about = about));
ctx.push(format!("### {name}", name = name));
ctx.push(format!("{about}", about = about));
} else if let Some(about) = &arg.help {
out.push(format!("- `{name}`: {about}", name = name, about = about));
ctx.push(format!("- `{name}`: {about}", name = name, about = about));
} else {
out.push(format!("- `{name}`", name = name));
ctx.push(format!("- `{name}`", name = name));
}
}
}
ctx.push(format!("\n<!-- [USAGE] -->"));
}
UsageMdDirective::GlobalFlags => {
ctx.plain = false;
let spec = ctx.spec.as_ref().unwrap();

ctx.push("<!-- [USAGE] global_flags -->".to_string());
let flags = spec
.cmd
.flags
.iter()
.filter(|f| !f.hide)
.collect::<Vec<_>>();
if !flags.is_empty() {
out.push(format!("## Flags"));
ctx.push(format!("## Flags"));
for flag in flags {
let name = flag.usage();
if let Some(about) = &flag.long_help {
out.push(format!("### {name}", name = name));
out.push(format!("{about}", about = about));
ctx.push(format!("### {name}", name = name));
ctx.push(format!("{about}", about = about));
} else if let Some(about) = &flag.help {
out.push(format!("- `{name}`: {about}", name = name, about = about));
ctx.push(format!("- `{name}`: {about}", name = name, about = about));
} else {
out.push(format!("- `{name}`", name = name));
ctx.push(format!("- `{name}`", name = name));
}
}
}
ctx.push(format!("\n<!-- [USAGE] -->"));
}
UsageMdDirective::CommandIndex => {
ctx.plain = false;
let spec = ctx.spec.as_ref().unwrap();
ctx.push(format!("<!-- [USAGE] command_index -->"));

let subcommands = spec
.cmd
.subcommands
.values()
.filter(|c| !c.hide)
.collect::<Vec<_>>();
if !subcommands.is_empty() {
out.push(format!("## Commands"));
ctx.push(format!("## Commands"));
for cmd in subcommands {
let name = cmd.name.as_str();
if let Some(about) = &cmd.help {
out.push(format!(
ctx.push(format!(
"- [`{name}`](./{name}): {about}",
name = name,
about = about
));
} else {
out.push(format!("- [`{name}`](./{name})", name = name));
ctx.push(format!("- [`{name}`](./{name})", name = name));
}
}
}

out.push(format!("<!-- [USAGE] -->"));
ctx.out.push(out.join("\n"));
Ok(ctx)
ctx.push(format!("\n<!-- [USAGE] -->"));
}
UsageMdDirective::Commands => {
ctx.plain = false;
let spec = ctx.spec.as_ref().unwrap();
ctx.push(format!("<!-- [USAGE] commands -->"));
ctx.push(format!("# {name}", name = spec.name));
ctx.push(format!("## Usage"));
ctx.push(format!("```"));
ctx.push(format!("{bin} [flags] [args]", bin = spec.bin));
ctx.push(format!("```"));
ctx.push(format!("\n<!-- [USAGE] -->"));
}
UsageMdDirective::EndToken => {
ctx.plain = true;
Ok(ctx)
}
UsageMdDirective::Plain(line) => {
if ctx.plain {
ctx.out.push(line.clone());
ctx.push(line.clone());
}
Ok(ctx)
}
}
};
Ok(ctx)
}
}

Expand Down Expand Up @@ -312,7 +348,11 @@ impl FromStr for UsageMdDirective {
"load" => UsageMdDirective::Load {
file: PathBuf::from(get_string(node, "file")?),
},
"usage_overview" => UsageMdDirective::UsageOverview,
"global_args" => UsageMdDirective::GlobalArgs,
"global_flags" => UsageMdDirective::GlobalFlags,
"command_index" => UsageMdDirective::CommandIndex,
"commands" => UsageMdDirective::Commands,
_ => Err(err("unknown directive type".into(), *node.name().span()))?,
}
} else {
Expand Down
21 changes: 20 additions & 1 deletion examples/MISE_README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
# mise-en-place

<!-- [USAGE] load file="./mise.usage.kdl" -->
<!-- [USAGE] command_index -->
<!-- [USAGE] usage_overview -->
# mise
## Usage
```
[flags] [args]
```

<!-- [USAGE] -->

<!-- [USAGE] global_args -->

<!-- [USAGE] -->
<!-- [USAGE] global_flags -->
## Flags
- `-C,--cd <DIR>`: Change directory before running command
- `-q,--quiet`: Suppress non-error messages
- `-v,--verbose`: Show extra output (use -vv for even more)
- `-y,--yes`: Answer yes to all confirmation prompts

<!-- [USAGE] -->
<!-- [USAGE] command_index -->
## Commands
- [`activate`](./activate)
- [`alias`](./alias)
Expand Down Expand Up @@ -52,4 +62,13 @@
- [`watch`](./watch)
- [`where`](./where)
- [`which`](./which)

<!-- [USAGE] -->
<!-- [USAGE] commands -->
# mise
## Usage
```
[flags] [args]
```

<!-- [USAGE] -->

0 comments on commit 7944f05

Please sign in to comment.