71 lines
2.6 KiB
Rust
71 lines
2.6 KiB
Rust
//! man: generate roff man pages from the clap definition (issue #41).
|
|
//! 'am man' prints am.1 for the whole CLI; 'am man <command>' prints one
|
|
//! page; '--output DIR' writes am.1 plus one am-<command>.1 per command.
|
|
|
|
use super::*;
|
|
use anyhow::Context;
|
|
use clap::CommandFactory;
|
|
use std::io::Write;
|
|
use std::path::Path;
|
|
|
|
pub fn run(app: &App, command: Option<&str>, output: Option<&Path>) -> Result<i32> {
|
|
let mut cmd = crate::cli::Cli::command();
|
|
if app.dry_run() {
|
|
app.log.dry("would generate man pages");
|
|
return Ok(0);
|
|
}
|
|
match command {
|
|
Some(name) => {
|
|
let sub = cmd.find_subcommand_mut(name).ok_or_else(|| {
|
|
anyhow!(
|
|
"unknown command '{name}' — 'am help commands' lists every command"
|
|
)
|
|
})?;
|
|
let man = clap_mangen::Man::new(sub.clone()).title(format!("am-{name}"));
|
|
match output {
|
|
Some(dir) => {
|
|
write_page(dir, &format!("am-{name}"), &man)?;
|
|
app.log.success(&format!(
|
|
"man page written to {}",
|
|
dir.join(format!("am-{name}.1")).display()
|
|
));
|
|
}
|
|
None => man.render(&mut std::io::stdout())?,
|
|
}
|
|
}
|
|
None => match output {
|
|
Some(dir) => {
|
|
let main = clap_mangen::Man::new(cmd.clone());
|
|
write_page(dir, "am", &main)?;
|
|
for sub in cmd.get_subcommands() {
|
|
if sub.is_hide_set() {
|
|
continue;
|
|
}
|
|
let name = format!("am-{}", sub.get_name());
|
|
let m = clap_mangen::Man::new(sub.clone()).title(name.clone());
|
|
write_page(dir, &name, &m)?;
|
|
}
|
|
app.log.success(&format!(
|
|
"man pages written to {} (am.1 + {} pages)",
|
|
dir.display(),
|
|
cmd.get_subcommands().count()
|
|
));
|
|
}
|
|
None => clap_mangen::Man::new(cmd).render(&mut std::io::stdout())?,
|
|
},
|
|
}
|
|
Ok(0)
|
|
}
|
|
|
|
fn write_page(dir: &Path, name: &str, man: &clap_mangen::Man) -> Result<()> {
|
|
std::fs::create_dir_all(dir)
|
|
.with_context(|| format!("cannot create {}", dir.display()))?;
|
|
let path = dir.join(format!("{name}.1"));
|
|
let mut file = std::fs::File::create(&path)
|
|
.with_context(|| format!("cannot create {}", path.display()))?;
|
|
man.render(&mut file)
|
|
.with_context(|| format!("cannot render {}", path.display()))?;
|
|
file.flush().ok();
|
|
Ok(())
|
|
}
|