dev_prune/commands/
man.rs1use std::fs;
12use std::path::Path;
13
14use anyhow::{Context, Result};
15use clap::CommandFactory;
16use clap_mangen::Man;
17
18use crate::Cli;
19use crate::output;
20
21pub fn run(dir: Option<&str>) -> Result<()> {
25 let mut command = Cli::command().name("devp");
26 command.build();
27
28 let Some(dir) = dir else {
29 let mut out = Vec::new();
32 Man::new(command).render(&mut out)?;
33 use std::io::Write;
34 std::io::stdout().write_all(&out)?;
35 return Ok(());
36 };
37
38 let dir = Path::new(dir);
39 fs::create_dir_all(dir)
40 .with_context(|| format!("could not create {}", output::clean_path(dir)))?;
41
42 let mut written = 0usize;
43 let mut render_to = |name: &str, man: Man| -> Result<()> {
44 let path = dir.join(format!("{name}.1"));
45 let mut buf = Vec::new();
46 man.render(&mut buf)?;
47 fs::write(&path, buf)
48 .with_context(|| format!("could not write {}", output::clean_path(&path)))?;
49 written += 1;
50 Ok(())
51 };
52
53 for sub in command.get_subcommands() {
54 if sub.get_name() == "help" {
56 continue;
57 }
58 let name = format!("devp-{}", sub.get_name());
59 render_to(
62 &name,
63 Man::new(sub.clone().name(name.clone().leak() as &str)),
64 )?;
65 }
66 render_to("devp", Man::new(command.clone()))?;
67 render_to("dev-prune", Man::new(command.clone().name("dev-prune")))?;
70
71 output::print_success(&format!(
72 "{written} man pages written to {}",
73 output::clean_path(dir)
74 ));
75 output::print_info(
76 "Install them by copying into a directory on `manpath`, e.g. `/usr/local/share/man/man1/`.",
77 );
78 Ok(())
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn the_full_set_covers_every_subcommand() {
87 let tmp = tempfile::tempdir().unwrap();
88 run(Some(tmp.path().to_str().unwrap())).unwrap();
89
90 let mut command = Cli::command();
92 command.build();
93 for sub in command.get_subcommands() {
94 if sub.get_name() == "help" {
95 continue;
96 }
97 let page = tmp.path().join(format!("devp-{}.1", sub.get_name()));
98 assert!(page.exists(), "missing {}", page.display());
99 }
100 assert!(tmp.path().join("devp.1").exists());
101 assert!(tmp.path().join("dev-prune.1").exists());
102 }
103
104 #[test]
105 fn a_page_carries_the_long_about_text() {
106 let tmp = tempfile::tempdir().unwrap();
107 run(Some(tmp.path().to_str().unwrap())).unwrap();
108 let run_page = fs::read_to_string(tmp.path().join("devp-run.1")).unwrap();
109 assert!(run_page.contains("gauntlet"), "{run_page}");
111 }
112}