1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
use std::env;
use std::fs;
use std::io::{self, Write};
use clap::Shell;
mod sq_cli {
include!("src/sq_cli.rs");
}
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::configure(clap::App::new("sq").set_term_width(80));
let mut main = fs::File::create("src/sq-usage.rs").unwrap();
dump_help(&mut main,
&mut sq,
vec![],
"#").unwrap();
writeln!(main, "\n#![doc(html_favicon_url = \"https://docs.sequoia-pgp.org/favicon.png\")]")
.unwrap();
writeln!(main, "#![doc(html_logo_url = \"https://docs.sequoia-pgp.org/logo.svg\")]")
.unwrap();
writeln!(main, "\ninclude!(\"sq.rs\");").unwrap();
let outdir = match env::var_os("CARGO_TARGET_DIR") {
None => return,
Some(outdir) => outdir,
};
fs::create_dir_all(&outdir).unwrap();
let mut sq = sq_cli::build();
for shell in &[Shell::Bash, Shell::Fish, Shell::Zsh, Shell::PowerShell,
Shell::Elvish] {
sq.gen_completions("sq", *shell, &outdir);
}
}
fn dump_help(sink: &mut dyn io::Write,
sq: &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("sq")
.chain(cmd.iter().map(|s| s.as_str()))
.chain(std::iter::once("--help"))
.collect::<Vec<_>>();
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(())
}
|