zoi/cmd/
gen_man.rs

1use crate::cli::Cli;
2use clap::{Command, CommandFactory};
3use clap_mangen::Man;
4use std::fs;
5use std::io;
6use std::path::Path;
7
8pub fn run() -> io::Result<()> {
9    let out_path = Path::new("manuals");
10    fs::create_dir_all(out_path)?;
11
12    let app = Cli::command();
13    println!("Generating man pages in {}...", out_path.display());
14
15    generate_man_page(&app, out_path)?;
16
17    for sub_command in app.get_subcommands() {
18        generate_man_pages_recursive(sub_command, out_path, app.get_name())?;
19    }
20
21    println!(
22        "\nSuccessfully generated man pages in '{}'.",
23        out_path.display()
24    );
25    Ok(())
26}
27
28fn generate_man_pages_recursive(
29    cmd: &Command,
30    out_path: &Path,
31    parent_name: &str,
32) -> io::Result<()> {
33    if cmd.is_hide_set() {
34        return Ok(());
35    }
36
37    let full_name = format!("{}-{}", parent_name, cmd.get_name());
38    let leaked_name: &'static str = Box::leak(full_name.into_boxed_str());
39    let new_cmd = cmd.clone().name(leaked_name);
40    generate_man_page(&new_cmd, out_path)?;
41
42    for sub_cmd in new_cmd.get_subcommands() {
43        generate_man_pages_recursive(sub_cmd, out_path, leaked_name)?;
44    }
45
46    Ok(())
47}
48
49fn generate_man_page(app: &Command, out_path: &Path) -> io::Result<()> {
50    let name = app.get_name();
51    let out_file = out_path.join(format!("{}.1", name));
52
53    let man = Man::new(app.clone());
54    let mut buffer = Vec::<u8>::new();
55    man.render(&mut buffer)?;
56
57    fs::write(&out_file, &buffer)?;
58    println!("- {}", out_file.display());
59
60    Ok(())
61}