forked from DGNum/colmena
manual: Fix colorized CLI help
In clap 3.0, it's no longer possible to get `App::write_long_help` to output colorized text (it doesn't invoke the Colorizer at all). So let's move the generation outside of Rust.
This commit is contained in:
parent
d2762757f0
commit
f234e16e80
7 changed files with 49 additions and 96 deletions
31
Cargo.lock
generated
31
Cargo.lock
generated
|
@ -11,16 +11,6 @@ dependencies = [
|
||||||
"memchr",
|
"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]]
|
[[package]]
|
||||||
name = "async-stream"
|
name = "async-stream"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
@ -134,7 +124,6 @@ dependencies = [
|
||||||
name = "colmena"
|
name = "colmena"
|
||||||
version = "0.3.0-pre"
|
version = "0.3.0-pre"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi-to-html",
|
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"atty",
|
"atty",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -835,26 +824,6 @@ version = "0.14.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
||||||
|
|
||||||
[[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]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
|
|
@ -7,7 +7,6 @@ edition = "2018"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ansi-to-html = "0.1.0"
|
|
||||||
async-trait = "0.1.42"
|
async-trait = "0.1.42"
|
||||||
atty = "0.2"
|
atty = "0.2"
|
||||||
clap = "3.0.0"
|
clap = "3.0.0"
|
||||||
|
|
|
@ -17,7 +17,7 @@ in rustPlatform.buildRustPackage rec {
|
||||||
src = lib.cleanSource ./.;
|
src = lib.cleanSource ./.;
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoSha256 = "sha256-FVHNtgOZCC2aC2ilt1UreDidhiAuunPOO3E9ejJzwmw=";
|
cargoSha256 = "sha256-rJnPo8xmasRNOYttDuG80QqfKyeEcl7gn85dvYgeOpw=";
|
||||||
|
|
||||||
nativeBuildInputs = [ installShellFiles ];
|
nativeBuildInputs = [ installShellFiles ];
|
||||||
|
|
||||||
|
|
30
manual/colorized-help.nix
Normal file
30
manual/colorized-help.nix
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{ runCommand, colmena, ansi2html }:
|
||||||
|
|
||||||
|
with builtins;
|
||||||
|
|
||||||
|
let
|
||||||
|
subcommands = [
|
||||||
|
null
|
||||||
|
"apply"
|
||||||
|
"apply-local"
|
||||||
|
"build"
|
||||||
|
"upload-keys"
|
||||||
|
"eval"
|
||||||
|
"exec"
|
||||||
|
"nix-info"
|
||||||
|
];
|
||||||
|
renderHelp = subcommand: let
|
||||||
|
fullCommand = if subcommand == null then "colmena" else "colmena ${subcommand}";
|
||||||
|
in ''
|
||||||
|
(
|
||||||
|
echo '## `${fullCommand}`'
|
||||||
|
echo -n '<pre><div class="hljs">'
|
||||||
|
TERM=xterm-256color CLICOLOR_FORCE=1 ${fullCommand} --help | ansi2html -p
|
||||||
|
echo '</div></pre>'
|
||||||
|
)>>$out
|
||||||
|
'';
|
||||||
|
in runCommand "colmena-colorized-help" {
|
||||||
|
nativeBuildInputs = [ colmena ansi2html ];
|
||||||
|
} (''
|
||||||
|
ansi2html -H > $out
|
||||||
|
'' + concatStringsSep "\n" (map renderHelp subcommands))
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, stdenv, nix-gitignore, mdbook, python3, writeScript
|
{ lib, stdenv, nix-gitignore, mdbook, python3, callPackage, writeScript
|
||||||
, deploymentOptionsMd ? null
|
, deploymentOptionsMd ? null
|
||||||
, metaOptionsMd ? null
|
, metaOptionsMd ? null
|
||||||
, colmena ? null
|
, colmena ? null
|
||||||
|
@ -13,6 +13,12 @@
|
||||||
let
|
let
|
||||||
apiVersion = builtins.concatStringsSep "." (lib.take 2 (lib.splitString "." version));
|
apiVersion = builtins.concatStringsSep "." (lib.take 2 (lib.splitString "." version));
|
||||||
|
|
||||||
|
colorizedHelp = let
|
||||||
|
help = callPackage ./colorized-help.nix {
|
||||||
|
inherit colmena;
|
||||||
|
};
|
||||||
|
in if colmena != null then help else null;
|
||||||
|
|
||||||
redirectTemplate = lib.escapeShellArg ''
|
redirectTemplate = lib.escapeShellArg ''
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -28,7 +34,7 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in stdenv.mkDerivation {
|
in stdenv.mkDerivation {
|
||||||
inherit version deploymentOptionsMd metaOptionsMd;
|
inherit version deploymentOptionsMd metaOptionsMd colorizedHelp;
|
||||||
|
|
||||||
pname = "colmena-manual" + (if unstable then "-unstable" else "");
|
pname = "colmena-manual" + (if unstable then "-unstable" else "");
|
||||||
|
|
||||||
|
@ -48,9 +54,8 @@ in stdenv.mkDerivation {
|
||||||
'';
|
'';
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
if [ -n "${toString colmena}" ]; then
|
if [[ -n "$colorizedHelp" ]]; then
|
||||||
echo "Generating CLI help text"
|
cat "$colorizedHelp" >> src/reference/cli.md
|
||||||
${toString colmena}/bin/colmena gen-help-markdown >> src/reference/cli.md
|
|
||||||
else
|
else
|
||||||
echo "Error: No colmena executable passed to the builder" >> src/reference/cli.md
|
echo "Error: No colmena executable passed to the builder" >> src/reference/cli.md
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Command Line Arguments
|
# Command Line Options
|
||||||
|
|
||||||
<!-- UNSTABLE_BEGIN -->
|
<!-- UNSTABLE_BEGIN -->
|
||||||
You are currently reading **the unstable version** of the Colmena Manual, built against the tip of [the development branch](https://github.com/zhaofengli/colmena).
|
You are currently reading **the unstable version** of the Colmena Manual, built against the tip of [the development branch](https://github.com/zhaofengli/colmena).
|
||||||
|
|
62
src/cli.rs
62
src/cli.rs
|
@ -140,10 +140,6 @@ It's also possible to specify the preference using environment variables. See <h
|
||||||
.required(true)
|
.required(true)
|
||||||
.takes_value(true)));
|
.takes_value(true)));
|
||||||
|
|
||||||
app = app.subcommand(App::new("gen-help-markdown")
|
|
||||||
.about("Generate CLI usage guide as Markdown (Internal)")
|
|
||||||
.setting(AppSettings::Hidden));
|
|
||||||
|
|
||||||
// deprecated alias
|
// deprecated alias
|
||||||
app = app.subcommand(command::eval::deprecated_alias());
|
app = app.subcommand(command::eval::deprecated_alias());
|
||||||
|
|
||||||
|
@ -160,8 +156,14 @@ It's also possible to specify the preference using environment variables. See <h
|
||||||
register_command!(exec, app);
|
register_command!(exec, app);
|
||||||
register_command!(nix_info, app);
|
register_command!(nix_info, app);
|
||||||
|
|
||||||
|
// This does _not_ take the --color flag into account (haven't
|
||||||
|
// parsed yet), only the CLICOLOR environment variable.
|
||||||
|
if clicolors_control::colors_enabled() {
|
||||||
|
app.color(ColorChoice::Always)
|
||||||
|
} else {
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn run() {
|
pub async fn run() {
|
||||||
let mut app = build_cli(true);
|
let mut app = build_cli(true);
|
||||||
|
@ -186,10 +188,6 @@ pub async fn run() {
|
||||||
return gen_completions(args);
|
return gen_completions(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches.subcommand_matches("gen-help-markdown").is_some() {
|
|
||||||
return gen_help_markdown();
|
|
||||||
};
|
|
||||||
|
|
||||||
// deprecated alias
|
// deprecated alias
|
||||||
handle_command!("introspect", eval, matches);
|
handle_command!("introspect", eval, matches);
|
||||||
|
|
||||||
|
@ -204,54 +202,6 @@ fn gen_completions(args: &ArgMatches) {
|
||||||
clap_complete::generate(shell, &mut app, "colmena", &mut std::io::stdout());
|
clap_complete::generate(shell, &mut app, "colmena", &mut std::io::stdout());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_help_markdown() {
|
|
||||||
// This is tailered only for the manual, with output injected to `reference/cli.md`.
|
|
||||||
// <pre><div class="hljs">
|
|
||||||
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
|
|
||||||
.color(ColorChoice::Always);
|
|
||||||
|
|
||||||
if full_command != "colmena" {
|
|
||||||
c.bin_name(&full_command)
|
|
||||||
} else {
|
|
||||||
c
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("## `{}`", full_command);
|
|
||||||
print!("<pre><div class=\"hljs\">");
|
|
||||||
|
|
||||||
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!("</div></pre>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_color_pref(cli: &str) {
|
fn set_color_pref(cli: &str) {
|
||||||
if cli != "auto" {
|
if cli != "auto" {
|
||||||
clicolors_control::set_colors_enabled(cli == "always");
|
clicolors_control::set_colors_enabled(cli == "always");
|
||||||
|
|
Loading…
Reference in a new issue