usage/docs/markdown/
spec.rs1use crate::docs::markdown::renderer::MarkdownRenderer;
2use crate::error::UsageErr;
3
4impl MarkdownRenderer {
5 pub fn render_spec(&self) -> Result<String, UsageErr> {
6 let all_commands = self.spec.cmd.all_subcommands();
7 let mut config = crate::docs::models::SpecConfig::from(&self.raw_config);
10 config.render_md(self);
11 self.render_with("spec_template.md.tera", |ctx| {
12 ctx.insert("all_commands", &all_commands);
13 ctx.insert("config", &config);
14 })
15 }
16
17 pub fn render_index(&self) -> Result<String, UsageErr> {
18 let all_commands = self.spec.cmd.all_subcommands();
19 let config = crate::docs::models::SpecConfig::from(&self.raw_config);
23 self.render_with("index_template.md.tera", |ctx| {
26 ctx.insert("multi", &false);
28 ctx.insert("all_commands", &all_commands);
29 ctx.insert("config", &config);
30 ctx.insert("config_page", &self.config_page());
31 })
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use crate::docs::markdown::renderer::MarkdownRenderer;
38 use crate::test::SPEC_KITCHEN_SINK;
39 use crate::Spec;
40 use insta::assert_snapshot;
41
42 #[test]
43 fn test_render_markdown_spec() {
44 let ctx = MarkdownRenderer::new(SPEC_KITCHEN_SINK.clone());
45 assert_snapshot!(ctx.render_spec().unwrap(), @"
46 # `mycli`
47
48 - **Usage:** `mycli [FLAGS] <ARGS>… <SUBCOMMAND>`
49
50 ## Arguments
51 - **`<arg1>`** — arg1 description
52 - **`[arg2]`** — arg2 description
53
54 **Choices:** `choice1`, `choice2`, `choice3`
55
56 **Default:** `default value`
57 - **`<arg3>`** — arg3 long description
58 - **`<argrest>…`**
59 - **`[with-default]`**
60
61 **Default:** `default value`
62
63 ## Flags
64 - **`--flag1`** — flag1 description
65 - **`--flag2`** — flag2 long description
66
67 includes a code block:
68
69 $ echo hello world
70 hello world
71
72 more code
73
74 Examples:
75
76 # run with no arguments to use the interactive selector
77 $ mise use
78
79 # set the current version of node to 20.x in mise.toml of current directory
80 # will write the fuzzy version (e.g.: 20)
81
82 some docs
83
84 $ echo hello world
85 hello world
86 - **`--flag3`** — flag3 description
87 - **`--with-default`**
88
89 **Default:** `default value`
90 - **`--shell <shell>`**
91
92 **Choices:** `bash`, `zsh`, `fish`
93
94 ## `mycli plugin`
95
96 - **Usage:** `mycli plugin <SUBCOMMAND>`
97 - **Source code:** [`src/cli/plugin.rs`](https://github.com/jdx/mise/blob/main/src/cli/plugin.rs)
98
99 ## `mycli plugin install`
100
101 - **Usage:** `mycli plugin install [FLAGS] <plugin> <version>`
102 - **Source code:** [`src/cli/plugin/install.rs`](https://github.com/jdx/mise/blob/main/src/cli/plugin/install.rs)
103
104 install a plugin
105
106 ### Arguments
107 - **`<plugin>`**
108 - **`<version>`**
109
110 ### Flags
111 - **`-g --global`**
112 - **`-d --dir <dir>`**
113 - **`-f --force`**
114 ");
115 }
116
117 #[test]
118 fn package_metadata_reaches_markdown() {
119 let spec: Spec = r#"
120 name "metadata"
121 bin "metadata"
122 author "Example Maintainers"
123 license "MIT OR Apache-2.0"
124 repository "https://example.com/tool"
125 "#
126 .parse()
127 .unwrap();
128 let output = MarkdownRenderer::new(spec).render_spec().unwrap();
129
130 assert!(
131 output.contains("**Author:** Example Maintainers"),
132 "{output}"
133 );
134 assert!(
135 output.contains("**License:** MIT OR Apache-2.0"),
136 "{output}"
137 );
138 assert!(
139 output.contains("**Repository:** https://example.com/tool"),
140 "{output}"
141 );
142 }
143}