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(), @r"
46 # `mycli`
47
48 - **Usage**: `mycli [FLAGS] <ARGS>… <SUBCOMMAND>`
49
50 ## Arguments
51
52 ### `<arg1>`
53
54 arg1 description
55
56 ### `[arg2]`
57
58 arg2 description
59
60 **Choices:**
61
62 - `choice1`
63 - `choice2`
64 - `choice3`
65
66 **Default:** `default value`
67
68 ### `<arg3>`
69
70 arg3 long description
71
72 ### `<argrest>…`
73
74 ### `[with-default]`
75
76 **Default:** `default value`
77
78 ## Flags
79
80 ### `--flag1`
81
82 flag1 description
83
84 ### `--flag2`
85
86 flag2 long description
87
88 includes a code block:
89
90 $ echo hello world
91 hello world
92
93 more code
94
95 Examples:
96
97 # run with no arguments to use the interactive selector
98 $ mise use
99
100 # set the current version of node to 20.x in mise.toml of current directory
101 # will write the fuzzy version (e.g.: 20)
102
103 some docs
104
105 $ echo hello world
106 hello world
107
108 ### `--flag3`
109
110 flag3 description
111
112 ### `--with-default`
113
114 **Default:** `default value`
115
116 ### `--shell <shell>`
117
118 **Choices:**
119
120 - `bash`
121 - `zsh`
122 - `fish`
123
124 ## `mycli plugin`
125
126 - **Usage**: `mycli plugin <SUBCOMMAND>`
127 - **Source code**: [`src/cli/plugin.rs`](https://github.com/jdx/mise/blob/main/src/cli/plugin.rs)
128
129 ## `mycli plugin install`
130
131 - **Usage**: `mycli plugin install [FLAGS] <plugin> <version>`
132 - **Source code**: [`src/cli/plugin/install.rs`](https://github.com/jdx/mise/blob/main/src/cli/plugin/install.rs)
133
134 install a plugin
135
136 ### Arguments
137
138 #### `<plugin>`
139
140 #### `<version>`
141
142 ### Flags
143
144 #### `-g --global`
145
146 #### `-d --dir <dir>`
147
148 #### `-f --force`
149 ");
150 }
151
152 #[test]
153 fn package_metadata_reaches_markdown() {
154 let spec: Spec = r#"
155 name "metadata"
156 bin "metadata"
157 author "Example Maintainers"
158 license "MIT OR Apache-2.0"
159 repository "https://example.com/tool"
160 "#
161 .parse()
162 .unwrap();
163 let output = MarkdownRenderer::new(spec).render_spec().unwrap();
164
165 assert!(
166 output.contains("**author**: Example Maintainers"),
167 "{output}"
168 );
169 assert!(
170 output.contains("**license**: MIT OR Apache-2.0"),
171 "{output}"
172 );
173 assert!(
174 output.contains("**repository**: https://example.com/tool"),
175 "{output}"
176 );
177 }
178}