Skip to main content

xil/
man.rs

1//! Man pages from the clap definitions: `xil --generate-man [DIR]` writes
2//! `xil.1` and one `xil-<command>.1` per command, the layout the Python
3//! repo's `man/man1/` uses.
4
5use std::fs;
6use std::path::Path;
7
8use crate::commands::{help_text, COMMANDS};
9
10/// The `xil` dispatcher as a clap command: its subcommands are the table.
11fn dispatcher() -> clap::Command {
12    let mut cmd = clap::Command::new("xil")
13        .version(env!("CARGO_PKG_VERSION"))
14        .about("Unified command-line interface for the xil podcast pipeline")
15        .long_about(help_text())
16        .subcommand_value_name("COMMAND");
17    for c in COMMANDS {
18        cmd = cmd.subcommand(clap::Command::new(c.name).about(c.description));
19    }
20    cmd
21}
22
23fn render(cmd: clap::Command) -> std::io::Result<Vec<u8>> {
24    let mut buf = Vec::new();
25    clap_mangen::Man::new(cmd).render(&mut buf)?;
26    Ok(buf)
27}
28
29/// Write every page into `dir`, creating it. Returns how many were written.
30pub fn generate(dir: &Path) -> std::io::Result<usize> {
31    fs::create_dir_all(dir)?;
32    fs::write(dir.join("xil.1"), render(dispatcher())?)?;
33    for c in COMMANDS {
34        // Named for the `xil-<command>` alias, which is also the clap name.
35        fs::write(
36            dir.join(format!("xil-{}.1", c.name)),
37            render((c.command)())?,
38        )?;
39    }
40    Ok(COMMANDS.len() + 1)
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn one_page_per_command_plus_the_dispatcher() {
49        let tmp = tempfile::tempdir().unwrap();
50        assert_eq!(generate(tmp.path()).unwrap(), 40);
51        let parse = fs::read_to_string(tmp.path().join("xil-parse.1")).unwrap();
52        assert!(parse.starts_with(".ie \\n(.g .ds Aq"), "{}", &parse[..80]);
53        assert!(parse.contains("xil\\-parse"));
54        let xil = fs::read_to_string(tmp.path().join("xil.1")).unwrap();
55        assert!(xil.contains("sfx\\-match"));
56    }
57}