summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2021-01-19 11:27:53 +0100
committerJustus Winter <justus@sequoia-pgp.org>2021-01-19 12:19:58 +0100
commit17fb5f0e37fa77c5e801fed6049422c2f99103a8 (patch)
treeb96a57213729e1cad85e128d5bf486f56ae957d1
parente6541f1c2991fb00ea6cea67783529055dbb9634 (diff)
sqv: 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.
-rw-r--r--.gitlab-ci.yml3
-rw-r--r--sqv/Makefile9
-rw-r--r--sqv/build.rs78
-rw-r--r--sqv/make-usage.sh53
-rw-r--r--sqv/src/sqv_cli.rs4
5 files changed, 77 insertions, 70 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2c7038a4..0be763c2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -29,8 +29,7 @@ bullseye:
- make
- if ! git diff --quiet Cargo.lock ; then echo "Cargo.lock changed. Please add the change to the corresponding commit." ; 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 sqv ; then echo "Please commit the changes to sqv/src/sqv-usage.rs." ; false ; fi
- if ! git diff --quiet ; then echo "The build changed the source. Please investigate." ; git diff ; fi
variables:
diff --git a/sqv/Makefile b/sqv/Makefile
index 08aab1de..1ec2c975 100644
--- a/sqv/Makefile
+++ b/sqv/Makefile
@@ -13,8 +13,6 @@ else
INSTALL ?= install
endif
-all: src/sqv-usage.rs
-
# Installation.
.PHONY: build-release
build-release:
@@ -34,10 +32,3 @@ install: build-release
$(INSTALL) -d $(DESTDIR)$(PREFIX)/share/fish/completions
$(INSTALL) -t $(DESTDIR)$(PREFIX)/share/fish/completions \
$(CARGO_TARGET_DIR)/sqv.fish
-
-# Maintenance.
-.PHONY: update-usage
-update-usage: src/sqv-usage.rs
-
-src/sqv-usage.rs: make-usage.sh $(SQV)
- sh make-usage.sh $(SQV) >$@
diff --git a/sqv/build.rs b/sqv/build.rs
index 7c1eda1c..b53caa33 100644
--- a/sqv/build.rs
+++ b/sqv/build.rs
@@ -1,7 +1,6 @@
-use clap;
-
use std::env;
use std::fs;
+use std::io::{self, Write};
use clap::Shell;
mod sqv_cli {
@@ -9,6 +8,19 @@ mod sqv_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 sqv = sqv_cli::build();
+ let mut main = fs::File::create("src/sqv-usage.rs").unwrap();
+ dump_help(&mut main,
+ &mut sqv,
+ vec![],
+ "#").unwrap();
+ writeln!(main, "\ninclude!(\"sqv.rs\");").unwrap();
+
let outdir = match env::var_os("CARGO_TARGET_DIR") {
None => return,
Some(outdir) => outdir,
@@ -20,3 +32,65 @@ fn main() {
sqv.gen_completions("sqv", *shell, &outdir);
}
}
+
+fn dump_help(sink: &mut dyn io::Write,
+ sqv: &mut clap::App,
+ cmd: Vec<String>,
+ 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("sqv")
+ .chain(cmd.iter().map(|s| s.as_str()))
+ .chain(std::iter::once("--help"))
+ .collect::<Vec<_>>();
+
+ let help = sqv.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, sqv, c, &format!("{}#", heading))?;
+ }
+
+ Ok(())
+}
diff --git a/sqv/make-usage.sh b/sqv/make-usage.sh
deleted file mode 100644
index 87971c5b..00000000
--- a/sqv/make-usage.sh
+++ /dev/null
@@ -1,53 +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 |
- 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/sqv/src/sqv_cli.rs b/sqv/src/sqv_cli.rs
index a351cead..8b85dc92 100644
--- a/sqv/src/sqv_cli.rs
+++ b/sqv/src/sqv_cli.rs
@@ -1,8 +1,4 @@
/// Command-line parser for sqv.
-///
-/// If you change this file, please rebuild `sqv`, run `make -C tool
-/// update-usage`, and commit the resulting changes to
-/// `sqv/src/sqv-usage.rs`.
use clap::{App, Arg, AppSettings};