From c4f55892fc75a5c23abe97e5acf42c6a14f5574a Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Tue, 19 Jan 2021 11:22:31 +0100 Subject: sq: Generate usage documentation in build script. - Unfortunately, we still need to commit the result. Once the external doc feature is merged, we can avoid this. See https://github.com/rust-lang/rust/issues/44732. --- .gitlab-ci.yml | 3 +-- sq/Makefile | 9 ------- sq/build.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- sq/make-usage.sh | 54 ------------------------------------- sq/src/sq-usage.rs | 22 +++++++-------- sq/src/sq_cli.rs | 4 --- 6 files changed, 88 insertions(+), 82 deletions(-) delete mode 100644 sq/make-usage.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ea7db163..2c7038a4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,8 +28,7 @@ bullseye: - cargo test --all --exclude sequoia-openpgp-ffi - make - if ! git diff --quiet Cargo.lock ; then echo "Cargo.lock changed. Please add the change to the corresponding commit." ; false ; fi - - make -C sq update-usage - - if ! git diff --quiet sq ; then echo "Please run 'make -C sq update-usage' and commit the result." ; false ; fi + - if ! git diff --quiet sq ; then echo "Please commit the changes to sq/src/sq-usage.rs." ; false ; fi - make -C sqv update-usage - if ! git diff --quiet sqv ; then echo "Please run 'make -C sqv update-usage' and commit the result." ; false ; fi - if ! git diff --quiet ; then echo "The build changed the source. Please investigate." ; git diff ; fi diff --git a/sq/Makefile b/sq/Makefile index 74a0c512..d3fd4fc7 100644 --- a/sq/Makefile +++ b/sq/Makefile @@ -13,8 +13,6 @@ else INSTALL ?= install endif -all: src/sq-usage.rs - # Installation. .PHONY: build-release build-release: @@ -36,10 +34,3 @@ install: build-release $(INSTALL) -t $(DESTDIR)$(PREFIX)/share/fish/completions \ $(CARGO_TARGET_DIR)/sq.fish $(MAKE) -C../store install - -# Maintenance. -.PHONY: update-usage -update-usage: src/sq-usage.rs - -src/sq-usage.rs: make-usage.sh $(SQ) - sh make-usage.sh $(SQ) >$@~ && mv $@~ $@ diff --git a/sq/build.rs b/sq/build.rs index b7d3147d..25a9af8d 100644 --- a/sq/build.rs +++ b/sq/build.rs @@ -1,7 +1,6 @@ -use clap; - use std::env; use std::fs; +use std::io::{self, Write}; use clap::Shell; mod sq_cli { @@ -9,6 +8,19 @@ mod sq_cli { } fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + // XXX: Revisit once + // https://github.com/rust-lang/rust/issues/44732 is stabilized. + + let mut sq = sq_cli::build(); + let mut main = fs::File::create("src/sq-usage.rs").unwrap(); + dump_help(&mut main, + &mut sq, + vec![], + "#").unwrap(); + writeln!(main, "\ninclude!(\"sq.rs\");").unwrap(); + let outdir = match env::var_os("CARGO_TARGET_DIR") { None => return, Some(outdir) => outdir, @@ -20,3 +32,65 @@ fn main() { sq.gen_completions("sq", *shell, &outdir); } } + +fn dump_help(sink: &mut dyn io::Write, + sq: &mut clap::App, + cmd: Vec, + heading: &str) + -> io::Result<()> +{ + + if cmd.is_empty() { + writeln!(sink, "//! A command-line frontend for Sequoia.")?; + writeln!(sink, "//!")?; + writeln!(sink, "//! # Usage")?; + } else { + writeln!(sink, "//!")?; + writeln!(sink, "//! {} Subcommand {}", heading, cmd.join(" "))?; + } + + writeln!(sink, "//!")?; + + let args = std::iter::once("sq") + .chain(cmd.iter().map(|s| s.as_str())) + .chain(std::iter::once("--help")) + .collect::>(); + + let help = sq.get_matches_from_safe_borrow(&args) + .unwrap_err().to_string(); + + writeln!(sink, "//! ```text")?; + for line in help.trim_end().split("\n").skip(1) { + if line == "" { + writeln!(sink, "//!")?; + } else { + writeln!(sink, "//! {}", line.trim_end())?; + } + } + writeln!(sink, "//! ```")?; + + // Recurse. + let mut found_subcommands = false; + for subcmd in help.split("\n").filter_map(move |line| { + if line == "SUBCOMMANDS:" { + found_subcommands = true; + None + } else if found_subcommands { + if line.chars().nth(4).map(|c| ! c.is_ascii_whitespace()) + .unwrap_or(false) + { + line.trim_start().split(" ").nth(0) + } else { + None + } + } else { + None + } + }).filter(|subcmd| *subcmd != "help") { + let mut c = cmd.clone(); + c.push(subcmd.into()); + dump_help(sink, sq, c, &format!("{}#", heading))?; + } + + Ok(()) +} diff --git a/sq/make-usage.sh b/sq/make-usage.sh deleted file mode 100644 index 7bcbfcf2..00000000 --- a/sq/make-usage.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh - -tool=$1 - -quote() { - sed 's@^@//! @' | sed 's/ $//' -} - -begin_code() { - printf '```text\n' -} - -end_code() { - printf '```\n' -} - -dump_help() { # subcommand, indentation - if [ -z "$1" ] - then - printf "\n# Usage\n\n" - set "" "#" - else - printf "\n$2 Subcommand$1\n\n" - fi - - help="`$tool $1 --help`" - - begin_code - printf "$help\n" | tail -n +2 - end_code - - if echo $help | fgrep -q SUBCOMMANDS - then - printf "$help\n" | - sed -n '/^SUBCOMMANDS:/,$p' | - tail -n+2 | - grep '^ [^ ]' | - while read subcommand desc - do - if [ "$subcommand" = help ]; then - continue - fi - - dump_help "$1 $subcommand" "#$2" - done - fi -} - -( - printf "A command-line frontend for Sequoia.\n" - dump_help -) | quote - -printf '\ninclude!("'"$(basename $tool)"'.rs");\n' diff --git a/sq/src/sq-usage.rs b/sq/src/sq-usage.rs index 808d01bd..761b7aab 100644 --- a/sq/src/sq-usage.rs +++ b/sq/src/sq-usage.rs @@ -294,10 +294,10 @@ //! sq certring //! //! FLAGS: -//! -h, --help +//! -h, --help //! Prints help information //! -//! -V, --version +//! -V, --version //! Prints version information //! //! @@ -319,35 +319,35 @@ //! sq certring filter [FLAGS] [OPTIONS] [--] [FILE]... //! //! FLAGS: -//! -B, --binary +//! -B, --binary //! Don't ASCII-armor the certring //! -//! -h, --help +//! -h, --help //! Prints help information //! -//! -P, --prune-certs +//! -P, --prune-certs //! Remove certificate components not matching the filter //! -//! -V, --version +//! -V, --version //! Prints version information //! //! //! OPTIONS: -//! --domain ... +//! --domain ... //! Match on this email domain name //! -//! --email
... +//! --email
... //! Match on this email address //! -//! --name ... +//! --name ... //! Match on this name //! -//! -o, --output +//! -o, --output //! Sets the output file to use //! //! //! ARGS: -//! ... +//! ... //! Sets the input files to use //! ``` //! diff --git a/sq/src/sq_cli.rs b/sq/src/sq_cli.rs index 814cde8d..d2c527ef 100644 --- a/sq/src/sq_cli.rs +++ b/sq/src/sq_cli.rs @@ -1,8 +1,4 @@ /// Command-line parser for sq. -/// -/// If you change this file, please rebuild `sq`, run `make -C tool -/// update-usage`, and commit the resulting changes to -/// `sq/src/sq-usage.rs`. use clap::{App, Arg, ArgGroup, SubCommand, AppSettings}; -- cgit v1.2.3