1use std::path::{Path, PathBuf};
6use std::{env, fs, io};
7
8use clap::{Command, CommandFactory};
9use clap_mangen::Man;
10
11use crate::cli::Cli;
12
13pub fn run() -> io::Result<()> {
23 let out_dir = env::var("OUT_DIR").unwrap_or_else(|_| "manuals".to_string());
24 let out_path = PathBuf::from(out_dir);
25 fs::create_dir_all(&out_path)?;
26
27 let app = Cli::command();
28 println!("Generating man pages in {}...", out_path.display());
29
30 generate_man_page(&app, &out_path)?;
31
32 for sub_command in app.get_subcommands() {
33 generate_man_pages_recursive(sub_command, &out_path, app.get_name())?;
34 }
35
36 println!(
37 "\nSuccessfully generated man pages in '{}'.",
38 out_path.display()
39 );
40 Ok(())
41}
42
43fn generate_man_pages_recursive(
45 cmd: &Command,
46 out_path: &Path,
47 parent_name: &str
48) -> io::Result<()> {
49 if cmd.is_hide_set() {
50 return Ok(());
51 }
52
53 let full_name = format!("{}-{}", parent_name, cmd.get_name());
54 let leaked_name: &'static str = Box::leak(full_name.into_boxed_str());
55 let new_cmd = cmd.clone().name(leaked_name);
56 generate_man_page(&new_cmd, out_path)?;
57
58 for sub_cmd in new_cmd.get_subcommands() {
59 generate_man_pages_recursive(sub_cmd, out_path, leaked_name)?;
60 }
61
62 Ok(())
63}
64
65fn generate_man_page(app: &Command, out_path: &Path) -> io::Result<()> {
67 let name = app.get_name();
68 let out_file = out_path.join(format!("{name}.1"));
69
70 let man = Man::new(app.clone());
71 let mut buffer = Vec::<u8>::new();
72 man.render(&mut buffer)?;
73
74 fs::write(&out_file, &buffer)?;
75 println!("- {}", out_file.display());
76
77 Ok(())
78}