Merge pull request #4459 from sylvestre/manpages

Generate manpages and check them in the CI
This commit is contained in:
Sylvestre Ledru 2023-03-05 15:37:44 +01:00 committed by GitHub
commit 494b6f46e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 4 deletions

View file

@ -408,6 +408,16 @@ jobs:
make test make test
env: env:
RUST_BACKTRACE: "1" RUST_BACKTRACE: "1"
- name: "`make install`"
shell: bash
run: |
DESTDIR=/tmp/ make PROFILE=release install
# Check that the manpage is present
test -f /tmp/usr/local/share/man/man1/whoami.1
# Check that the completion is present
test -f /tmp/usr/local/share/zsh/site-functions/_install
env:
RUST_BACKTRACE: "1"
build_rust_stable: build_rust_stable:

17
Cargo.lock generated
View file

@ -267,6 +267,16 @@ dependencies = [
"os_str_bytes", "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]] [[package]]
name = "codespan-reporting" name = "codespan-reporting"
version = "0.11.1" version = "0.11.1"
@ -324,6 +334,7 @@ dependencies = [
"chrono", "chrono",
"clap", "clap",
"clap_complete", "clap_complete",
"clap_mangen",
"conv", "conv",
"filetime", "filetime",
"glob", "glob",
@ -1874,6 +1885,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "roff"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
[[package]] [[package]]
name = "rstest" name = "rstest"
version = "0.16.0" version = "0.16.0"

View file

@ -1,7 +1,7 @@
# coreutils (uutils) # coreutils (uutils)
# * see the repository LICENSE, README, and CONTRIBUTING files for more information # * 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] [package]
name = "coreutils" name = "coreutils"
@ -271,6 +271,7 @@ byteorder = "1.3.2"
chrono = { version="^0.4.23", default-features=false, features=["std", "alloc", "clock"]} chrono = { version="^0.4.23", default-features=false, features=["std", "alloc", "clock"]}
clap = { version = "4.0", features = ["wrap_help", "cargo"] } clap = { version = "4.0", features = ["wrap_help", "cargo"] }
clap_complete = "4.0" clap_complete = "4.0"
clap_mangen = "0.2"
compare = "0.1.0" compare = "0.1.0"
coz = { version = "0.1.3" } coz = { version = "0.1.3" }
crossterm = ">=0.19" crossterm = ">=0.19"
@ -352,6 +353,7 @@ clap = { workspace=true }
once_cell = { workspace=true } once_cell = { workspace=true }
uucore = { workspace=true } uucore = { workspace=true }
clap_complete = { workspace=true } clap_complete = { workspace=true }
clap_mangen = { workspace=true }
phf = { workspace=true } phf = { workspace=true }
selinux = { workspace=true, optional = true } selinux = { workspace=true, optional = true }
textwrap = { workspace=true } textwrap = { workspace=true }

View file

@ -349,10 +349,12 @@ endif
mkdir -p $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions mkdir -p $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions
mkdir -p $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions mkdir -p $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions
mkdir -p $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d mkdir -p $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d
mkdir -p $(DESTDIR)$(DATAROOTDIR)/man/man1
$(foreach prog, $(INSTALLEES), \ $(foreach prog, $(INSTALLEES), \
$(BUILDDIR)/coreutils completion $(prog) zsh > $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions/_$(PROG_PREFIX)$(prog); \ $(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) 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 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: uninstall:

View file

@ -12,7 +12,7 @@
----------------------------------------------- -----------------------------------------------
<!-- markdownlint-disable commands-show-output no-duplicate-heading --> <!-- markdownlint-disable commands-show-output no-duplicate-heading -->
<!-- spell-checker:ignore markdownlint ; (options) DESTDIR RUNTEST UTILNAME --> <!-- spell-checker:ignore markdownlint ; (options) DESTDIR RUNTEST UTILNAME manpages -->
uutils is an attempt at writing universal (as in cross-platform) CLI uutils is an attempt at writing universal (as in cross-platform) CLI
utilities in [Rust](http://www.rust-lang.org). utilities in [Rust](http://www.rust-lang.org).
@ -145,8 +145,8 @@ $ cargo install --path .
This command will install uutils into Cargo's *bin* folder (*e.g.* `$HOME/.cargo/bin`). This command will install uutils into Cargo's *bin* folder (*e.g.* `$HOME/.cargo/bin`).
This does not install files necessary for shell completion. For shell completion to work, This does not install files necessary for shell completion or manpages.
use `GNU Make` or see `Manually install shell completions`. For manpages or shell completion to work, use `GNU Make` or see `Manually install shell completions`/`Manually install manpages`.
### GNU Make ### GNU Make
@ -214,6 +214,20 @@ run:
cargo run completion ls bash > /usr/local/share/bash-completion/completions/ls cargo run completion ls bash > /usr/local/share/bash-completion/completions/ls
``` ```
### Manually install manpages
To generate manpages, the syntax is:
```bash
cargo run manpage <utility>
```
So, to install the manpage for `ls` to `/usr/local/share/man/man1/ls.1`
run:
```bash
cargo run manpage ls > /usr/local/share/man/man1/ls.1
```
## Un-installation ## Un-installation
Un-installation differs depending on how you have installed uutils. If you used Un-installation differs depending on how you have installed uutils. If you used

View file

@ -5,6 +5,8 @@
// For the full copyright and license information, please view the LICENSE // For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code. // file that was distributed with this source code.
// spell-checker:ignore manpages mangen
use clap::{Arg, Command}; use clap::{Arg, Command};
use clap_complete::Shell; use clap_complete::Shell;
use std::cmp; use std::cmp;
@ -90,6 +92,10 @@ fn main() {
gen_completions(args, &utils); gen_completions(args, &utils);
} }
if util == "manpage" {
gen_manpage(args, &utils);
}
match utils.get(util) { match utils.get(util) {
Some(&(uumain, _)) => { Some(&(uumain, _)) => {
process::exit(uumain((vec![util_os].into_iter()).chain(args))); process::exit(uumain((vec![util_os].into_iter()).chain(args)));
@ -167,6 +173,39 @@ fn gen_completions<T: uucore::Args>(
process::exit(0); process::exit(0);
} }
/// Generate the manpage for the utility in the first parameter
fn gen_manpage<T: uucore::Args>(
args: impl Iterator<Item = OsString>,
util_map: &UtilityMap<T>,
) -> ! {
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::<String>("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<T: uucore::Args>(util_map: &UtilityMap<T>) -> Command { fn gen_coreutils_app<T: uucore::Args>(util_map: &UtilityMap<T>) -> Command {
let mut command = Command::new("coreutils"); let mut command = Command::new("coreutils");
for (_, (_, sub_app)) in util_map { for (_, (_, sub_app)) in util_map {