From 79d18ab6560ac4b164a731919a26469b2d447643 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 4 Mar 2023 18:23:33 +0100 Subject: [PATCH] generate manpages --- Cargo.lock | 17 +++++++++++++++++ Cargo.toml | 4 +++- GNUmakefile | 2 ++ src/bin/coreutils.rs | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 89d67bf81..e4f489eae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,6 +267,16 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "clap_mangen" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0f09a0ca8f0dd8ac92c546b426f466ef19828185c6d504c80c48c9c2768ed9" +dependencies = [ + "clap", + "roff", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -324,6 +334,7 @@ dependencies = [ "chrono", "clap", "clap_complete", + "clap_mangen", "conv", "filetime", "glob", @@ -1874,6 +1885,12 @@ dependencies = [ "libc", ] +[[package]] +name = "roff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" + [[package]] name = "rstest" version = "0.16.0" diff --git a/Cargo.toml b/Cargo.toml index 61a461deb..d8d43b252 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ # coreutils (uutils) # * see the repository LICENSE, README, and CONTRIBUTING files for more information -# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu +# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen [package] name = "coreutils" @@ -271,6 +271,7 @@ byteorder = "1.3.2" chrono = { version="^0.4.23", default-features=false, features=["std", "alloc", "clock"]} clap = { version = "4.0", features = ["wrap_help", "cargo"] } clap_complete = "4.0" +clap_mangen = "0.2" compare = "0.1.0" coz = { version = "0.1.3" } crossterm = ">=0.19" @@ -352,6 +353,7 @@ clap = { workspace=true } once_cell = { workspace=true } uucore = { workspace=true } clap_complete = { workspace=true } +clap_mangen = { workspace=true } phf = { workspace=true } selinux = { workspace=true, optional = true } textwrap = { workspace=true } diff --git a/GNUmakefile b/GNUmakefile index b242bc8ce..81b90d32f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -349,10 +349,12 @@ endif mkdir -p $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions mkdir -p $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions mkdir -p $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d + mkdir -p $(DESTDIR)$(DATAROOTDIR)/man/man1 $(foreach prog, $(INSTALLEES), \ $(BUILDDIR)/coreutils completion $(prog) zsh > $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions/_$(PROG_PREFIX)$(prog); \ $(BUILDDIR)/coreutils completion $(prog) bash > $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions/$(PROG_PREFIX)$(prog); \ $(BUILDDIR)/coreutils completion $(prog) fish > $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d/$(PROG_PREFIX)$(prog).fish; \ + $(BUILDDIR)/coreutils manpage $(prog) > $(DESTDIR)$(DATAROOTDIR)/man/man1/$(PROG_PREFIX)$(prog).1; \ ) uninstall: diff --git a/src/bin/coreutils.rs b/src/bin/coreutils.rs index 08c0774ba..ac9750f93 100644 --- a/src/bin/coreutils.rs +++ b/src/bin/coreutils.rs @@ -5,6 +5,8 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. +// spell-checker:ignore manpages mangen + use clap::{Arg, Command}; use clap_complete::Shell; use std::cmp; @@ -90,6 +92,10 @@ fn main() { gen_completions(args, &utils); } + if util == "manpage" { + gen_manpage(args, &utils); + } + match utils.get(util) { Some(&(uumain, _)) => { process::exit(uumain((vec![util_os].into_iter()).chain(args))); @@ -167,6 +173,39 @@ fn gen_completions( process::exit(0); } +/// Generate the manpage for the utility in the first parameter +fn gen_manpage( + args: impl Iterator, + util_map: &UtilityMap, +) -> ! { + let all_utilities: Vec<_> = std::iter::once("coreutils") + .chain(util_map.keys().copied()) + .collect(); + + let matches = Command::new("manpage") + .about("Prints manpage to stdout") + .arg( + Arg::new("utility") + .value_parser(clap::builder::PossibleValuesParser::new(all_utilities)) + .required(true), + ) + .get_matches_from(std::iter::once(OsString::from("manpage")).chain(args)); + + let utility = matches.get_one::("utility").unwrap(); + + let command = if utility == "coreutils" { + gen_coreutils_app(util_map) + } else { + util_map.get(utility).unwrap().1() + }; + + let man = clap_mangen::Man::new(command); + man.render(&mut io::stdout()) + .expect("Man page generation failed"); + io::stdout().flush().unwrap(); + process::exit(0); +} + fn gen_coreutils_app(util_map: &UtilityMap) -> Command { let mut command = Command::new("coreutils"); for (_, (_, sub_app)) in util_map {