From c42c97d2f6f1d3212eae0c59bf8c1282e87d9575 Mon Sep 17 00:00:00 2001 From: Zhaofeng Li Date: Wed, 17 Nov 2021 22:21:00 -0800 Subject: [PATCH] Add internal command to render CLI usage text for manual --- Cargo.lock | 31 +++++++++++++++++++++++++++++ Cargo.toml | 1 + src/cli.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 32b9ea2..9ab0cdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi-to-html" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ee82de0545b181a17cbdef44fce80ecaf394e001da7ea279008bf2e0944bee" +dependencies = [ + "regex", + "thiserror", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -112,6 +122,7 @@ dependencies = [ name = "colmena" version = "0.1.0" dependencies = [ + "ansi-to-html", "async-trait", "atty", "clap", @@ -781,6 +792,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tinyvec" version = "1.5.0" diff --git a/Cargo.toml b/Cargo.toml index 2b6bf2c..eb696c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +ansi-to-html = "0.1.0" async-trait = "0.1.42" atty = "0.2" clap = "2.33.3" diff --git a/src/cli.rs b/src/cli.rs index e2c87ff..720b99a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -66,6 +66,10 @@ For a sample configuration, see . .required(true) .takes_value(true))); + app = app.subcommand(SubCommand::with_name("gen-help-markdown") + .about("Generate CLI usage guide as Markdown (Internal)") + .setting(AppSettings::Hidden)); + // deprecated alias app = app.subcommand(command::eval::deprecated_alias()); @@ -104,6 +108,10 @@ pub async fn run() { return gen_completions(args); } + if let Some(_) = matches.subcommand_matches("gen-help-markdown") { + return gen_help_markdown(); + }; + app.print_long_help().unwrap(); println!(); } @@ -115,3 +123,52 @@ fn gen_completions(args: &ArgMatches<'_>) { app.gen_completions_to("colmena", shell, &mut std::io::stdout()); } + +fn gen_help_markdown() { + // This is tailered only for the manual, with output injected to `reference/cli.md`. + //
+ let mut commands = vec![ + build_cli(false), + command::apply::subcommand(), + command::apply_local::subcommand(), + command::build::subcommand(), + command::upload_keys::subcommand(), + command::eval::subcommand(), + command::exec::subcommand(), + command::nix_info::subcommand(), + ]; + + for command in commands.drain(..) { + let full_command = match command.get_name() { + "Colmena" => "colmena".to_string(), + sub => format!("colmena {}", sub), + }; + + let mut command = { + let c = command + .setting(AppSettings::ColoredHelp) + .setting(AppSettings::ColorAlways); + + if full_command != "colmena" { + c.bin_name(&full_command) + } else { + c + } + }; + + println!("## `{}`", full_command); + print!("
"); + + let help_message = { + let mut bytes = Vec::new(); + command.write_long_help(&mut bytes).unwrap(); + String::from_utf8(bytes).unwrap() + }; + + let help_html = ansi_to_html::convert(&help_message, true, true) + .expect("Could not convert terminal output to HTML"); + + print!("{}", help_html); + println!("
"); + } +}