3a60ac00
Add auto-generated man pages via clap_mangen
a73x 2026-03-21 09:40
Man pages are generated at build time from clap derive definitions, so they stay in sync with the CLI automatically. Adds make targets: make man, make install-man, make clean-man. Resolves: 31543ca5 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
diff --git a/.gitignore b/.gitignore index ea8c4bf..eaeddaf 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target /man diff --git a/Cargo.lock b/Cargo.lock index 537c260..e969d1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,6 +239,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "clap_mangen" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e30ffc187e2e3aeafcd1c6e2aa416e29739454c0ccaa419226d5ecd181f2d78" dependencies = [ "clap", "roff", ] [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -574,6 +584,7 @@ version = "0.1.0" dependencies = [ "chrono", "clap", "clap_mangen", "crossterm", "git2", "ratatui", @@ -1445,6 +1456,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "roff" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf2048e0e979efb2ca7b91c4f1a8d77c91853e9b987c94c555668a8994915ad" [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 3f520d0..04364be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,5 +13,9 @@ thiserror = "2" ratatui = "0.30.0" crossterm = "0.29.0" [build-dependencies] clap = { version = "4", features = ["derive"] } clap_mangen = "0.2" [dev-dependencies] tempfile = "3" diff --git a/Makefile b/Makefile index 11fc2dc..b614f8f 100644 --- a/Makefile +++ b/Makefile @@ -30,15 +30,31 @@ ci: lint test build # --- Install --- install: PROFILE := release install: build install: build install-man install -Dm755 target/release/$(BIN) $(PREFIX)/bin/$(BIN) uninstall: rm -f $(PREFIX)/bin/$(BIN) clean: clean: clean-man $(CARGO) clean # --- Man pages --- MAN_DIR := man/man1 .PHONY: man install-man clean-man man: MAN_OUT_DIR=$(MAN_DIR) $(CARGO) build @echo "Man pages written to $(MAN_DIR)/" install-man: man install -d $(PREFIX)/share/man/man1 install -m644 $(MAN_DIR)/*.1 $(PREFIX)/share/man/man1/ clean-man: rm -rf man/ # --- Dev helpers --- .PHONY: run dev dashboard diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..518588b --- /dev/null +++ b/build.rs @@ -0,0 +1,36 @@ use std::env; use std::fs; use std::path::PathBuf; include!("src/cli.rs"); fn main() { let out = PathBuf::from( env::var("MAN_OUT_DIR").unwrap_or_else(|_| { env::var("OUT_DIR").expect("OUT_DIR not set") }), ); let cmd = <Cli as clap::CommandFactory>::command(); generate_manpages(&cmd, &out); } fn generate_manpages(cmd: &clap::Command, out: &PathBuf) { let man = clap_mangen::Man::new(cmd.clone()); let name = cmd.get_name().to_string(); let mut buf = Vec::new(); man.render(&mut buf).expect("failed to render man page"); fs::create_dir_all(out).expect("failed to create man output dir"); fs::write(out.join(format!("{name}.1")), buf) .expect("failed to write man page"); for sub in cmd.get_subcommands() { if sub.is_hide_set() { continue; } let sub_name = format!("{}-{}", cmd.get_name(), sub.get_name()); let sub_name: &'static str = Box::leak(sub_name.into_boxed_str()); let sub_cmd = sub.clone().name(sub_name); generate_manpages(&sub_cmd, out); } }