use crate::cli::Cli;
use crate::utils::ensure_dir;
use anyhow::{Context, Result};
use clap::{Command, CommandFactory};
use std::fs;
use std::path::Path;
pub fn write_manpages(dir: &Path) -> Result<()> {
ensure_dir(dir)?;
let cmd = Cli::command();
let mut count: usize = 0;
write_subtree(&cmd, dir, "", &mut count)?;
println!("{} man page(s) written to: {}", count, dir.display());
Ok(())
}
fn write_subtree(cmd: &Command, dir: &Path, prefix: &str, count: &mut usize) -> Result<()> {
let leaf_name = cmd.get_name();
let file_stem = if prefix.is_empty() {
leaf_name.to_string()
} else {
format!("{}-{}", prefix, leaf_name)
};
let file_path = dir.join(format!("{}.1", file_stem));
let man = clap_mangen::Man::new(cmd.clone()).title(file_stem.to_uppercase());
let mut buffer: Vec<u8> = Vec::new();
man.render(&mut buffer)
.with_context(|| format!("rendering {}", file_path.display()))?;
fs::write(&file_path, &buffer)
.with_context(|| format!("writing {}", file_path.display()))?;
*count += 1;
for sub in cmd.get_subcommands() {
if sub.get_name() == "help" {
continue;
}
write_subtree(sub, dir, &file_stem, count)?;
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::write_manpages;
#[test]
fn writes_root_and_subcommand_pages() {
let dir = tempfile::tempdir().expect("tempdir");
write_manpages(dir.path()).expect("write_manpages");
assert!(dir.path().join("dsc.1").exists());
assert!(dir.path().join("dsc-tag.1").exists());
assert!(dir.path().join("dsc-setting.1").exists());
assert!(dir.path().join("dsc-config.1").exists());
assert!(dir.path().join("dsc-tag-pull.1").exists());
assert!(dir.path().join("dsc-setting-diff.1").exists());
assert!(!dir.path().join("dsc-help.1").exists());
}
#[test]
fn root_page_contains_command_name_and_synopsis() {
let dir = tempfile::tempdir().expect("tempdir");
write_manpages(dir.path()).unwrap();
let body = std::fs::read_to_string(dir.path().join("dsc.1")).unwrap();
assert!(body.contains(".TH"));
assert!(body.contains("DSC"));
assert!(body.contains("SYNOPSIS"));
}
}