From 91a5818110427ad7a7819da2b2410c74127f773e Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 9 Jan 2024 04:35:03 +0000 Subject: [PATCH] rage: Build manpages in the build script --- .github/workflows/release.yml | 3 - Cargo.lock | 25 ++-- rage/Cargo.toml | 10 +- rage/build.rs | 161 +++++++++++++++++++++++ rage/examples/generate-docs.rs | 223 -------------------------------- rage/i18n/en-US/rage.ftl | 29 ++++- rage/i18n/es-AR/rage.ftl | 7 +- rage/i18n/it/rage.ftl | 7 +- rage/i18n/zh-CN/rage.ftl | 7 +- rage/i18n/zh-TW/rage.ftl | 7 +- rage/src/bin/rage-keygen/cli.rs | 2 +- rage/src/bin/rage-mount/cli.rs | 2 +- rage/src/bin/rage/cli.rs | 28 ++-- supply-chain/config.toml | 12 +- 14 files changed, 249 insertions(+), 274 deletions(-) delete mode 100644 rage/examples/generate-docs.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3bc36a4f..bb841285 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -190,9 +190,6 @@ jobs: run: cargo build --release --locked --target ${{ matrix.target }} ${{ matrix.build_flags }} working-directory: ./rage - - name: Generate manpages - run: cargo run --example generate-docs - - name: Update Debian package config for cross-compile run: sed -i '/\/rage-mount/d' rage/Cargo.toml if: matrix.name != 'linux' diff --git a/Cargo.lock b/Cargo.lock index 5721935d..d4182fd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -540,6 +540,16 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +[[package]] +name = "clap_mangen" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2e32b579dae093c2424a8b7e2bea09c89da01e1ce5065eb2f0a6f1cc15cc1f" +dependencies = [ + "clap", + "roff", +] + [[package]] name = "colorchoice" version = "1.0.0" @@ -1472,15 +1482,6 @@ dependencies = [ "libc", ] -[[package]] -name = "man" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebf5fa795187a80147b1ac10aaedcf5ffd3bbeb1838bda61801a1c9ad700a1c9" -dependencies = [ - "roff", -] - [[package]] name = "memchr" version = "2.7.1" @@ -1998,6 +1999,7 @@ dependencies = [ "chrono", "clap", "clap_complete", + "clap_mangen", "console", "ctrlc", "env_logger", @@ -2009,7 +2011,6 @@ dependencies = [ "lazy_static", "libc", "log", - "man", "pinentry", "rust-embed", "tar", @@ -2126,9 +2127,9 @@ dependencies = [ [[package]] name = "roff" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33e4fb37ba46888052c763e4ec2acfedd8f00f62897b630cadb6298b833675e" +checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rpassword" diff --git a/rage/Cargo.toml b/rage/Cargo.toml index d79854f1..f3c1ece3 100644 --- a/rage/Cargo.toml +++ b/rage/Cargo.toml @@ -33,9 +33,9 @@ assets = [ ["target/release/completions/_rage", "usr/share/zsh/functions/Completion/Debian/", "644"], ["target/release/completions/_rage-keygen", "usr/share/zsh/functions/Completion/Debian/", "644"], ["target/release/completions/_rage-mount", "usr/share/zsh/functions/Completion/Debian/", "644"], - ["../target/manpages/rage.1.gz", "usr/share/man/man1/", "644"], - ["../target/manpages/rage-keygen.1.gz", "usr/share/man/man1/", "644"], - ["../target/manpages/rage-mount.1.gz", "usr/share/man/man1/", "644"], + ["target/release/manpages/rage.1.gz", "usr/share/man/man1/", "644"], + ["target/release/manpages/rage-keygen.1.gz", "usr/share/man/man1/", "644"], + ["target/release/manpages/rage-mount.1.gz", "usr/share/man/man1/", "644"], ["../README.md", "usr/share/doc/rage/README.md", "644"], ] features = ["mount"] @@ -78,14 +78,14 @@ zip = { version = "0.6.2", optional = true } [build-dependencies] clap = { workspace = true, features = ["string", "unstable-styles"] } clap_complete = "4" +clap_mangen = "0.2" +flate2 = "1" i18n-embed = { workspace = true, features = ["desktop-requester"] } i18n-embed-fl.workspace = true lazy_static.workspace = true rust-embed.workspace = true [dev-dependencies] -flate2 = "1" -man = "0.3" trycmd = "0.14" [features] diff --git a/rage/build.rs b/rage/build.rs index dfabe856..53ebe178 100644 --- a/rage/build.rs +++ b/rage/build.rs @@ -6,6 +6,11 @@ use std::path::PathBuf; use clap::{Command, CommandFactory, ValueEnum}; use clap_complete::{generate_to, Shell}; +use clap_mangen::{ + roff::{Inline, Roff}, + Man, +}; +use flate2::{write::GzEncoder, Compression}; mod i18n { include!("src/bin/rage/i18n.rs"); @@ -31,6 +36,47 @@ macro_rules! fl { }}; } +struct Example { + text: String, + cmd: &'static str, + output: Option, +} + +impl Example { + const fn new(text: String, cmd: &'static str, output: Option) -> Self { + Self { text, cmd, output } + } +} + +struct Examples([Example; N]); + +impl Examples { + fn render(self, w: &mut impl io::Write) -> io::Result<()> { + let mut roff = Roff::default(); + roff.control("SH", ["EXAMPLES"]); + for example in self.0 { + roff.control("TP", []); + roff.text( + [ + Inline::Roman(format!("{}:", example.text)), + Inline::LineBreak, + Inline::Bold(format!("$ {}", example.cmd)), + Inline::LineBreak, + ] + .into_iter() + .chain( + example + .output + .into_iter() + .flat_map(|output| [Inline::Roman(output), Inline::LineBreak]), + ) + .collect::>(), + ); + } + roff.to_writer(w) + } +} + #[derive(Clone)] struct Cli { rage: Command, @@ -58,6 +104,120 @@ impl Cli { Ok(()) } + + fn generate_manpages(self, out_dir: &Path) -> io::Result<()> { + fs::create_dir_all(out_dir)?; + + fn generate_manpage( + out_dir: &Path, + name: &str, + cmd: Command, + custom: impl FnOnce(&Man, &mut GzEncoder) -> io::Result<()>, + ) -> io::Result<()> { + let file = fs::File::create(out_dir.join(format!("{}.1.gz", name)))?; + let mut w = GzEncoder::new(file, Compression::best()); + + let man = Man::new(cmd); + man.render_title(&mut w)?; + man.render_name_section(&mut w)?; + man.render_synopsis_section(&mut w)?; + man.render_options_section(&mut w)?; + custom(&man, &mut w)?; + man.render_version_section(&mut w)?; + man.render_authors_section(&mut w) + } + + generate_manpage( + out_dir, + "rage", + self.rage + .about(fl!("man-rage-about")) + .after_help(rage::after_help_content("rage-keygen")), + |man, w| { + man.render_extra_section(w)?; + Examples([ + Example::new( + fl!("man-rage-example-enc-single"), + "echo \"_o/\" | rage -o hello.age -r age1uvscypafkkxt6u2gkguxet62cenfmnpc0smzzlyun0lzszfatawq4kvf2u", + None, + ), + Example::new( + fl!("man-rage-example-enc-multiple"), + "echo \"_o/\" | rage -r age1uvscypafkkxt6u2gkguxet62cenfmnpc0smzzlyun0lzszfatawq4kvf2u \ + -r age1ex4ty8ppg02555at009uwu5vlk5686k3f23e7mac9z093uvzfp8sxr5jum > hello.age", + None, + ), + Example::new( + fl!("man-rage-example-enc-password"), + "rage -p -o hello.txt.age hello.txt", + Some(format!("{}:", fl!("type-passphrase"))), + ), + Example::new( + fl!("man-rage-example-enc-list"), + "tar cv ~/xxx | rage -R recipients.txt > xxx.tar.age", + None, + ), + Example::new( + fl!("man-rage-example-enc-identities"), + "tar cv ~/xxx | rage -e -i keyA.txt -i keyB.txt > xxx.tar.age", + None, + ), + Example::new( + fl!("man-rage-example-enc-url"), + "echo \"_o/\" | rage -o hello.age -R <(curl https://github.com/str4d.keys)", + None, + ), + Example::new( + fl!("man-rage-example-dec-identities"), + "rage -d -o hello -i keyA.txt -i keyB.txt hello.age", + None, + ), + ]) + .render(w) + }, + )?; + generate_manpage( + out_dir, + "rage-keygen", + self.rage_keygen.about(fl!("man-keygen-about")), + |_, w| { + Examples([ + Example::new(fl!("man-keygen-example-stdout"), "rage-keygen", None), + Example::new( + fl!("man-keygen-example-file"), + "rage-keygen -o key.txt", + Some(format!( + "{}: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p", + fl!("tty-pubkey") + )), + ), + ]) + .render(w) + }, + )?; + generate_manpage( + out_dir, + "rage-mount", + self.rage_mount.about(fl!("man-mount-about")), + |_, w| { + Examples([ + Example::new( + fl!("man-mount-example-identity"), + "rage-mount -t tar -i key.txt encrypted.tar.age ./tmp", + None, + ), + Example::new( + fl!("man-mount-example-passphrase"), + "rage-mount -t zip encrypted.zip.age ./tmp", + Some(format!("{}:", fl!("type-passphrase"))), + ), + ]) + .render(w) + }, + )?; + + Ok(()) + } } fn main() -> io::Result<()> { @@ -77,6 +237,7 @@ fn main() -> io::Result<()> { let mut cli = Cli::build(); cli.generate_completions(&out_dir.join("completions"))?; + cli.generate_manpages(&out_dir.join("manpages"))?; Ok(()) } diff --git a/rage/examples/generate-docs.rs b/rage/examples/generate-docs.rs deleted file mode 100644 index d29ab3f6..00000000 --- a/rage/examples/generate-docs.rs +++ /dev/null @@ -1,223 +0,0 @@ -use flate2::{write::GzEncoder, Compression}; -use man::prelude::*; -use std::fs::{create_dir_all, File}; -use std::io::prelude::*; - -const MANPAGES_DIR: &str = "./target/manpages"; - -fn generate_manpage(page: String, name: &str) { - let file = File::create(format!("{}/{}.1.gz", MANPAGES_DIR, name)) - .expect("Should be able to open file in target directory"); - let mut encoder = GzEncoder::new(file, Compression::best()); - encoder - .write_all(page.as_bytes()) - .expect("Should be able to write to file in target directory"); -} - -fn rage_page() { - let builder = Manual::new("rage") - .about("A simple, secure, and modern encryption tool") - .author(Author::new("Jack Grigg").email("thestr4d@gmail.com")) - .flag( - Flag::new() - .short("-h") - .long("--help") - .help("Display help text and exit."), - ) - .flag( - Flag::new() - .short("-V") - .long("--version") - .help("Display version info and exit."), - ) - .flag( - Flag::new() - .short("-e") - .long("--encrypt") - .help("Encrypt the input. By default, the input is encrypted."), - ) - .flag( - Flag::new() - .short("-d") - .long("--decrypt") - .help("Decrypt the input. By default, the input is encrypted."), - ) - .flag( - Flag::new() - .short("-p") - .long("--passphrase") - .help("Encrypt with a passphrase instead of recipients."), - ) - .flag( - Flag::new() - .short("-a") - .long("--armor") - .help("Encrypt to a PEM encoded format."), - ) - .option( - Opt::new("RECIPIENT") - .short("-r") - .long("--recipient") - .help("Encrypt to the specified RECIPIENT. May be repeated."), - ) - .option( - Opt::new("PATH") - .short("-R") - .long("--recipients-file") - .help("Encrypt to the recipients listed at PATH. May be repeated."), - ) - .option( - Opt::new("IDENTITY") - .short("-i") - .long("--identity") - .help("Use the identity file at IDENTITY. May be repeated."), - ) - .option( - Opt::new("OUTPUT") - .short("-o") - .long("--output") - .help("Write the result to the file at path OUTPUT. Defaults to standard output."), - ) - .option( - Opt::new("WF") - .long("--max-work-factor") - .help("The maximum work factor to allow for passphrase decryption."), - ) - .arg(Arg::new("[INPUT_FILE (defaults to stdin)]")) - .example(Example::new().text("Encryption to a recipient").command( - "echo \"_o/\" | rage -o hello.age -r age1uvscypafkkxt6u2gkguxet62cenfmnpc0smzzlyun0lzszfatawq4kvf2u", - )) - .example( - Example::new() - .text("Encryption to multiple recipients (with default output to stdout)") - .command( - "echo \"_o/\" | rage -r age1uvscypafkkxt6u2gkguxet62cenfmnpc0smzzlyun0lzszfatawq4kvf2u \ - -r age1ex4ty8ppg02555at009uwu5vlk5686k3f23e7mac9z093uvzfp8sxr5jum > hello.age", - ), - ) - .example( - Example::new() - .text("Encryption with a password (interactive only, use recipients for batch!)") - .command("rage -p -o hello.txt.age hello.txt") - .output("Type passphrase:"), - ) - .example( - Example::new() - .text("Encryption to a list of recipients in a file") - .command("tar cv ~/xxx | rage -R recipients.txt > xxx.tar.age"), - ) - .example( - Example::new() - .text("Encryption to several identities") - .command("tar cv ~/xxx | rage -e -i keyA.txt -i keyB.txt > xxx.tar.age"), - ) - .example( - Example::new() - .text("Encryption to a list of recipients at an HTTPS URL") - .command( - "echo \"_o/\" | rage -o hello.age -R <(curl https://github.com/str4d.keys)", - ), - ) - .example( - Example::new() - .text("Decryption with identities") - .command("rage -d -o hello -i keyA.txt -i keyB.txt hello.age"), - ); - let page = builder.render(); - - generate_manpage(page, "rage"); -} - -fn rage_keygen_page() { - let page = Manual::new("rage-keygen") - .about("Generate age-compatible encryption key pairs") - .author(Author::new("Jack Grigg").email("thestr4d@gmail.com")) - .flag( - Flag::new() - .short("-h") - .long("--help") - .help("Display help text and exit."), - ) - .flag( - Flag::new() - .short("-V") - .long("--version") - .help("Display version info and exit."), - ) - .option( - Opt::new("OUTPUT").short("-o").long("--output").help( - "Write the key pair to the file at path OUTPUT. Defaults to standard output.", - ), - ) - .example( - Example::new() - .text("Generate a new key pair") - .command("rage-keygen"), - ) - .example( - Example::new() - .text("Generate a new key pair and save it to a file") - .command("rage-keygen -o key.txt") - .output( - "Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p", - ), - ) - .render(); - - generate_manpage(page, "rage-keygen"); -} - -fn rage_mount_page() { - let page = Manual::new("rage-mount") - .about("Mount an age-encrypted filesystem") - .author(Author::new("Jack Grigg").email("thestr4d@gmail.com")) - .flag( - Flag::new() - .short("-h") - .long("--help") - .help("Display help text and exit."), - ) - .flag( - Flag::new() - .short("-V") - .long("--version") - .help("Display version info and exit."), - ) - .flag( - Flag::new() - .short("-t") - .long("--types") - .help("The type of the filesystem (one of \"tar\", \"zip\")."), - ) - .option( - Opt::new("IDENTITY") - .short("-i") - .long("--identity") - .help("Use the private key file at IDENTITY. May be repeated."), - ) - .arg(Arg::new("filename")) - .arg(Arg::new("mountpoint")) - .example( - Example::new() - .text("Mounting an archive encrypted to a recipient") - .command("rage-mount -t tar -i key.txt encrypted.tar.age ./tmp"), - ) - .example( - Example::new() - .text("Mounting an archive encrypted with a passphrase") - .command("rage-mount -t zip encrypted.zip.age ./tmp") - .output("Type passphrase:"), - ) - .render(); - - generate_manpage(page, "rage-mount"); -} - -fn main() { - // Create the target directory if it does not exist. - let _ = create_dir_all(MANPAGES_DIR); - - rage_page(); - rage_keygen_page(); - rage_mount_page(); -} diff --git a/rage/i18n/en-US/rage.ftl b/rage/i18n/en-US/rage.ftl index 04952016..4070790b 100644 --- a/rage/i18n/en-US/rage.ftl +++ b/rage/i18n/en-US/rage.ftl @@ -56,12 +56,12 @@ help-flag-identity = Use the identity file at {identity}. May be repeated. help-flag-plugin-name = Use {-age-plugin-}{plugin-name} in its default mode as an identity. help-flag-output = Write the result to the file at path {output}. -rage-after-help = +rage-after-help-content = {input} defaults to standard input, and {output} defaults to standard output. {recipient} can be: - - An {-age} public key, as generated by {$keygen_name} ("age1..."). - - An SSH public key ("ssh-ed25519 AAAA...", "ssh-rsa AAAA..."). + - An {-age} public key, as generated by {$keygen_name} ({$example_age_pubkey}). + - An SSH public key ({$example_ssh_pubkey}). {recipients-file} is a path to a file containing {-age} recipients, one per line (ignoring "#" prefixed comments and empty lines). @@ -71,6 +71,7 @@ rage-after-help = Passphrase-encrypted {-age} identity files can be used as identity files. Multiple identities may be provided, and any unused ones will be ignored. +rage-after-help-example = Example: {" "}{$example_a} {" "}{tty-pubkey}: {$example_a_output} @@ -197,3 +198,25 @@ err-mnt-unknown-type = Unknown filesystem type "{$fs_type}" ## Unstable features test-unstable = To test this, build {-rage} with {-flag-unstable}. + +## Manpages + +man-rage-about = A simple, secure, and modern encryption tool + +man-rage-example-enc-single = Encryption to a recipient +man-rage-example-enc-multiple = Encryption to multiple recipients (with default output to stdout) +man-rage-example-enc-password = Encryption with a password (interactive only, use recipients for batch!) +man-rage-example-enc-list = Encryption to a list of recipients in a file +man-rage-example-enc-identities = Encryption to several identities +man-rage-example-enc-url = Encryption to a list of recipients at an HTTPS URL +man-rage-example-dec-identities = Decryption with identities + +man-keygen-about = Generate age-compatible encryption key pairs + +man-keygen-example-stdout = Generate a new key pair +man-keygen-example-file = Generate a new key pair and save it to a file + +man-mount-about = Mount an age-encrypted filesystem + +man-mount-example-identity = Mounting an archive encrypted to a recipient +man-mount-example-passphrase = Mounting an archive encrypted with a passphrase diff --git a/rage/i18n/es-AR/rage.ftl b/rage/i18n/es-AR/rage.ftl index fec5a5df..24c6b399 100644 --- a/rage/i18n/es-AR/rage.ftl +++ b/rage/i18n/es-AR/rage.ftl @@ -37,12 +37,12 @@ plugin-name = PLUGIN-NAME input = INPUT output = OUTPUT -rage-after-help = +rage-after-help-content = {input} por defecto a standard input, y {output} por defecto standard output. {recipient} puede ser: - - Una clave pública {-age}, como es generada por {$keygen_name} ("age1..."). - - Una clave pública SSH ("ssh-ed25519 AAAA...", "ssh-rsa AAAA..."). + - Una clave pública {-age}, como es generada por {$keygen_name} ({$example_age_pubkey}). + - Una clave pública SSH ({$example_ssh_pubkey}). {recipients-file} es una ruta a un archivo que contenga un destinatario {-age} por línea (ignorando comentarios con el prefijo "#" y líneas vacías). @@ -54,6 +54,7 @@ rage-after-help = Pueden proveerse múltiples idendidades, cualquiera que no sea utilizada será ignorada. +rage-after-help-example = Ejemplo: {" "}{$example_a} {" "}{tty-pubkey}: {$example_a_output} diff --git a/rage/i18n/it/rage.ftl b/rage/i18n/it/rage.ftl index da7305ce..e2bfce1d 100644 --- a/rage/i18n/it/rage.ftl +++ b/rage/i18n/it/rage.ftl @@ -37,13 +37,13 @@ plugin-name = PLUGIN-NAME input = INPUT output = OUTPUT -rage-after-help = +rage-after-help-content = {input} ha come valore predefinito lo standard input, e {output} ha come valore predefinito lo standard output. {recipient} può essere: - - Una chiave pubblica {-age}, come generata da {$keygen_name} ("age1..."). - - Una chiave pubblica SSH ("ssh-ed25519 AAAA...", "ssh-rsa AAAA..."). + - Una chiave pubblica {-age}, come generata da {$keygen_name} ({$example_age_pubkey}). + - Una chiave pubblica SSH ({$example_ssh_pubkey}). {recipients-file} è il percorso ad un file contenente dei destinatari {-age}, uno per riga (ignorando i commenti che iniziano con "#" e le righe vuote). @@ -54,6 +54,7 @@ rage-after-help = I file di identità possono essere cifrati con {-age} e una passphrase. Possono essere fornite più identità, quelle inutilizzate verranno ignorate. +rage-after-help-example = Esempio: {" "}{$example_a} {" "}{tty-pubkey}: {$example_a_output} diff --git a/rage/i18n/zh-CN/rage.ftl b/rage/i18n/zh-CN/rage.ftl index 558b4c23..a62562ee 100644 --- a/rage/i18n/zh-CN/rage.ftl +++ b/rage/i18n/zh-CN/rage.ftl @@ -37,12 +37,12 @@ plugin-name = PLUGIN-NAME input = INPUT output = OUTPUT -rage-after-help = +rage-after-help-content = {input} 默认为标准输入 (stdin), 而 {output} 默认为标准输出 (stdout) 。 {recipient} 可为: - - 一把以 {$keygen_name} 生成的 {-age} 公钥 ("age1...")。 - - 一把 SSH 公钥 ("ssh-ed25519 AAAA...", "ssh-rsa AAAA...")。 + - 一把以 {$keygen_name} 生成的 {-age} 公钥 ({$example_age_pubkey})。 + - 一把 SSH 公钥 ({$example_ssh_pubkey})。 {recipients-file} 是一个文件路径。该文件应含有 {-age} 接收方, 每行一个 (前缀为 "#" 的注释以及空行将被忽略)。 @@ -52,6 +52,7 @@ rage-after-help = Passphrase-encrypted {-age} identity files can be used as identity files. 您可提供多份身份, 未使用的身份将被忽略。 +rage-after-help-example = Example: {" "}{$example_a} {" "}{tty-pubkey}: {$example_a_output} diff --git a/rage/i18n/zh-TW/rage.ftl b/rage/i18n/zh-TW/rage.ftl index 72206a6e..1ac2fc90 100644 --- a/rage/i18n/zh-TW/rage.ftl +++ b/rage/i18n/zh-TW/rage.ftl @@ -37,12 +37,12 @@ plugin-name = PLUGIN-NAME input = INPUT output = OUTPUT -rage-after-help = +rage-after-help-content = {input} 默認為標準輸入 (stdin), 而 {output} 默認為標準輸出 (stdout) 。 {recipient} 可為: - - 一把以 {$keygen_name} 生成的 {-age} 公鑰 ("age1...")。 - - 一把 SSH 公鑰 ("ssh-ed25519 AAAA...", "ssh-rsa AAAA...")。 + - 一把以 {$keygen_name} 生成的 {-age} 公鑰 ({$example_age_pubkey})。 + - 一把 SSH 公鑰 ({$example_ssh_pubkey})。 {recipients-file} 是一個文件路徑。該文件應含有 {-age} 接收方, 每行一個 (前綴為 "#" 的注釋以及空行將被忽略)。 @@ -52,6 +52,7 @@ rage-after-help = Passphrase-encrypted {-age} identity files can be used as identity files. 您可提供多份身份, 未使用的身份將被忽略。 +rage-after-help-example = Example: {" "}{$example_a} {" "}{tty-pubkey}: {$example_a_output} diff --git a/rage/src/bin/rage-keygen/cli.rs b/rage/src/bin/rage-keygen/cli.rs index 60b43724..aa6c5aa7 100644 --- a/rage/src/bin/rage-keygen/cli.rs +++ b/rage/src/bin/rage-keygen/cli.rs @@ -5,7 +5,7 @@ use crate::fl; #[derive(Debug, Parser)] #[command(display_name = "rage-keygen")] #[command(name = "rage-keygen")] -#[command(version)] +#[command(author, version)] #[command(help_template = format!("\ {{before-help}}{{about-with-newline}} {}{}:{} {{usage}} diff --git a/rage/src/bin/rage-mount/cli.rs b/rage/src/bin/rage-mount/cli.rs index f2b44fc3..5da4e86d 100644 --- a/rage/src/bin/rage-mount/cli.rs +++ b/rage/src/bin/rage-mount/cli.rs @@ -5,7 +5,7 @@ use crate::fl; #[derive(Debug, Parser)] #[command(display_name = "rage-mount")] #[command(name = "rage-mount")] -#[command(version)] +#[command(author, version)] #[command(help_template = format!("\ {{before-help}}{{about-with-newline}} {}{}:{} {{usage}} diff --git a/rage/src/bin/rage/cli.rs b/rage/src/bin/rage/cli.rs index 29189415..60c061b2 100644 --- a/rage/src/bin/rage/cli.rs +++ b/rage/src/bin/rage/cli.rs @@ -29,6 +29,15 @@ fn usage() -> String { ) } +pub(crate) fn after_help_content(keygen_name: &str) -> String { + fl!( + "rage-after-help-content", + keygen_name = keygen_name, + example_age_pubkey = "\"age1...\"", + example_ssh_pubkey = "\"ssh-ed25519 AAAA...\", \"ssh-rsa AAAA...\"", + ) +} + fn after_help() -> String { let binary_name = binary_name(); let keygen_name = format!("{}-keygen", binary_name); @@ -43,18 +52,21 @@ fn after_help() -> String { binary_name, ); - fl!( - "rage-after-help", - keygen_name = keygen_name, - example_a = example_a, - example_a_output = example_a_output, - example_b = example_b, - example_c = example_c, + format!( + "{}\n\n{}", + after_help_content(&keygen_name), + fl!( + "rage-after-help-example", + example_a = example_a, + example_a_output = example_a_output, + example_b = example_b, + example_c = example_c, + ), ) } #[derive(Debug, Parser)] -#[command(version)] +#[command(author, version)] #[command(help_template = format!("\ {{before-help}}{{about-with-newline}} {}{}:{} {{usage}} diff --git a/supply-chain/config.toml b/supply-chain/config.toml index fbc3bf8d..def62e78 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -189,6 +189,10 @@ criteria = "safe-to-deploy" version = "0.5.0" criteria = "safe-to-deploy" +[[exemptions.clap_mangen]] +version = "0.2.12" +criteria = "safe-to-deploy" + [[exemptions.console]] version = "0.15.7" criteria = "safe-to-deploy" @@ -433,10 +437,6 @@ criteria = "safe-to-deploy" version = "0.4.11" criteria = "safe-to-deploy" -[[exemptions.man]] -version = "0.3.0" -criteria = "safe-to-run" - [[exemptions.memchr]] version = "2.6.3" criteria = "safe-to-deploy" @@ -610,8 +610,8 @@ version = "0.8.37" criteria = "safe-to-run" [[exemptions.roff]] -version = "0.1.0" -criteria = "safe-to-run" +version = "0.2.1" +criteria = "safe-to-deploy" [[exemptions.rpassword]] version = "7.3.1"