diff --git a/NEWS b/NEWS index 846f63c8..91344d42 100644 --- a/NEWS +++ b/NEWS @@ -115,6 +115,9 @@ - The argument `sq key delete --file` now requires `--output`. - The argument `sq cert lint --cert-file` has been renamed to `--file`. + - The argument `sq key password --cert-file` has been renamed to + `--file`. + - The argument `sq key password --file` now requires `--output`. * Changes in 0.38.0 ** Notable changes diff --git a/src/cli/key/password.rs b/src/cli/key/password.rs index 6970f30a..1325cb8c 100644 --- a/src/cli/key/password.rs +++ b/src/cli/key/password.rs @@ -2,13 +2,11 @@ use std::path::PathBuf; -use clap::{ArgGroup, Args}; - -use sequoia_openpgp as openpgp; -use openpgp::KeyHandle; +use clap::Args; use crate::cli::types::*; use crate::cli::examples::*; +use crate::cli::types::cert_designator::*; #[derive(Debug, Args)] #[clap( @@ -30,25 +28,12 @@ provided, the user is prompted. ", after_help = EXAMPLES, )] -#[clap(group(ArgGroup::new("cert_input").args(&["cert_file", "cert"]).required(true)))] pub struct Command { - #[clap( - long, - help = "Change the password of the specified certificate's keys", - value_name = FileOrStdin::VALUE_NAME, - )] - pub cert: Option, - #[clap( - long, - value_name = "CERT_FILE", - help = "Change the password of the specified certificate's keys", - long_help = "\ -Change the password of the specified certificate's keys. - -Read the certificate from FILE or stdin, if `-`. It is an error \ -for the file to contain more than one certificate.", - )] - pub cert_file: Option, + #[command(flatten)] + pub cert: CertDesignators, #[clap( long, @@ -72,9 +57,9 @@ any surrounding whitespace like a trailing newline." help = FileOrStdout::HELP_OPTIONAL, long, value_name = FileOrStdout::VALUE_NAME, - conflicts_with = "cert", )] pub output: Option, + #[clap( long, requires = "output", @@ -113,3 +98,23 @@ Clear the password protection for all of Alice's keys.", ] }; test_examples!(sq_key_password, EXAMPLES); + +/// Documentation for the cert designators for the key password. +pub struct KeyPasswordDoc {} + +impl AdditionalDocs for KeyPasswordDoc { + fn help(arg: &'static str, help: &'static str) -> String { + match arg { + "file" => + "Change the password for the secret key material from the key \ + read from PATH" + .into(), + _ => { + debug_assert!(help.starts_with("Use certificates")); + help.replace("Use certificates", + "Change the password for the secret key material \ + from the key") + }, + } + } +} diff --git a/src/commands/key/password.rs b/src/commands/key/password.rs index 702fa3f8..a42e6358 100644 --- a/src/commands/key/password.rs +++ b/src/commands/key/password.rs @@ -8,14 +8,8 @@ use crate::Result; pub fn dispatch(sq: Sq, command: cli::key::password::Command) -> Result<()> { - let handle = if let Some(file) = command.cert_file { - assert!(command.cert.is_none()); - file.into() - } else if let Some(kh) = command.cert { - kh.into() - } else { - panic!("clap enforces --cert or --cert-file is set"); - }; + let handle = + sq.resolve_cert(&command.cert, sequoia_wot::FULLY_TRUSTED)?.1; password::password(sq, handle, vec![], command.clear_password, diff --git a/tests/integration/common.rs b/tests/integration/common.rs index e0623d5b..d62d2a89 100644 --- a/tests/integration/common.rs +++ b/tests/integration/common.rs @@ -693,7 +693,8 @@ impl Sq { cmd.arg("key").arg("password"); if cert_handle.is_file() { - cmd.arg("--cert-file").arg(&cert_handle); + cmd.arg("--file").arg(&cert_handle); + assert!(output_file.is_some()); } else { cmd.arg("--cert").arg(&cert_handle); };