use anyhow::Result;
use clap::{CommandFactory, Parser};
use clap_mangen::Man;
use log::info;
use shellexpand_utils::{canonicalize, expand};
use std::{fs, path::PathBuf};
use crate::{cli::Cli, printer::Printer};
#[derive(Debug, Parser)]
pub struct ManualGenerateCommand {
#[arg(value_parser = dir_parser)]
pub dir: PathBuf,
}
impl ManualGenerateCommand {
pub async fn execute(self, printer: &mut impl Printer) -> Result<()> {
info!("executing manual generate command");
let cmd = Cli::command();
let cmd_name = cmd.get_name().to_string();
let subcmds = cmd.get_subcommands().cloned().collect::<Vec<_>>();
let subcmds_len = subcmds.len() + 1;
let mut buffer = Vec::new();
Man::new(cmd).render(&mut buffer)?;
fs::create_dir_all(&self.dir)?;
printer.print_log(format!("Generating man page for command {cmd_name}…"))?;
fs::write(self.dir.join(format!("{}.1", cmd_name)), buffer)?;
for subcmd in subcmds {
let subcmd_name = subcmd.get_name().to_string();
let mut buffer = Vec::new();
Man::new(subcmd).render(&mut buffer)?;
printer.print_log(format!("Generating man page for subcommand {subcmd_name}…"))?;
fs::write(
self.dir.join(format!("{}-{}.1", cmd_name, subcmd_name)),
buffer,
)?;
}
printer.print(format!(
"{subcmds_len} man page(s) successfully generated in {:?}!",
self.dir
))?;
Ok(())
}
}
fn dir_parser(path: &str) -> Result<PathBuf, String> {
expand::try_path(path)
.map(canonicalize::path)
.map_err(|err| err.to_string())
}