Refactor: Use PathBuf instead of String for file related CLI options
- Replace `Option<String>` and `Vec<String>` based CLI options dealing with files with `Option<PathBuf>` and `Vec<PathBuf>` based ones (respectively). This allows us to unify the use of input and output facilities using globally available CLI options while ensuring (cross-platform) type safety.
This commit is contained in:
parent
3f147af820
commit
8f57c0d9f2
@ -1,4 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
use openpgp::{
|
||||
@ -22,7 +23,7 @@ pub fn dispatch<'store>(mut config: Config<'store>, cmd: import::Command)
|
||||
-> Result<()>
|
||||
{
|
||||
let inputs = if cmd.input.is_empty() {
|
||||
vec![ "-".to_string() ]
|
||||
vec![ PathBuf::from("-") ]
|
||||
} else {
|
||||
cmd.input
|
||||
};
|
||||
@ -32,7 +33,7 @@ pub fn dispatch<'store>(mut config: Config<'store>, cmd: import::Command)
|
||||
let inner = || -> Result<()> {
|
||||
for input in inputs.into_iter() {
|
||||
let input = open_or_stdin(
|
||||
if input == "-" { None } else { Some(&input) })?;
|
||||
if input == PathBuf::from("-") { None } else { Some(&input) })?;
|
||||
let raw_certs = RawCertParser::from_reader(input)?;
|
||||
|
||||
let cert_store = config.cert_store_mut_or_else()?;
|
||||
|
@ -1,6 +1,5 @@
|
||||
use std::convert::TryFrom;
|
||||
use std::io::{self, Read};
|
||||
use std::path::Path;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use anyhow::Context;
|
||||
@ -40,7 +39,11 @@ pub fn inspect(mut config: Config, c: inspect::Command)
|
||||
let print_certifications = c.certifications;
|
||||
|
||||
let input = c.input.as_deref();
|
||||
let input_name = input.unwrap_or("-");
|
||||
let input_name = if let Some(input) = c.input.as_ref() {
|
||||
format!("{}", input.display())
|
||||
} else {
|
||||
"-".to_string()
|
||||
};
|
||||
write!(output, "{}: ", input_name)?;
|
||||
|
||||
let mut type_called = false; // Did we print the type yet?
|
||||
@ -53,11 +56,12 @@ pub fn inspect(mut config: Config, c: inspect::Command)
|
||||
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
let mut ppr = if c.cert.is_empty() {
|
||||
if let Some(input) = input.as_ref() {
|
||||
if ! Path::new(input).exists() && input.parse::<KeyHandle>().is_ok() {
|
||||
if let Some(input) = input {
|
||||
if ! input.exists() &&
|
||||
format!("{}", input.display()).parse::<KeyHandle>().is_ok() {
|
||||
eprintln!("The file {} does not exist, \
|
||||
did you mean \"sq inspect --cert {}\"?",
|
||||
input, input);
|
||||
input.display(), input.display());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use chrono::DateTime;
|
||||
use chrono::Utc;
|
||||
|
||||
@ -111,33 +113,30 @@ pub fn generate(
|
||||
}
|
||||
}
|
||||
|
||||
if command.export.is_none() {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Saving generated key to the store isn't implemented yet."
|
||||
));
|
||||
}
|
||||
|
||||
// Generate the key
|
||||
let (cert, rev) = builder.generate()?;
|
||||
|
||||
// Export
|
||||
if command.export.is_some() {
|
||||
let (key_path, rev_path) =
|
||||
match (command.export.as_deref(), command.rev_cert.as_deref()) {
|
||||
(Some("-"), Some("-")) => ("-".to_string(), "-".to_string()),
|
||||
(Some("-"), Some(ref rp)) => ("-".to_string(), rp.to_string()),
|
||||
(Some("-"), None) => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Missing arguments: --rev-cert is mandatory \
|
||||
if --export is '-'."
|
||||
))
|
||||
}
|
||||
(Some(ref kp), None) => (kp.to_string(), format!("{}.rev", kp)),
|
||||
(Some(ref kp), Some("-")) => (kp.to_string(), "-".to_string()),
|
||||
(Some(ref kp), Some(ref rp)) => {
|
||||
(kp.to_string(), rp.to_string())
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Conflicting arguments --rev-cert and \
|
||||
--export"
|
||||
))
|
||||
}
|
||||
};
|
||||
if let Some(key_path) = command.export.as_ref() {
|
||||
if &format!("{}", key_path.display()) == "-"
|
||||
&& command.rev_cert.is_none()
|
||||
{
|
||||
return Err(anyhow::anyhow!(
|
||||
"Missing arguments: --rev-cert is mandatory if --export is '-'."
|
||||
))
|
||||
}
|
||||
|
||||
let rev_path = if command.rev_cert.is_some() {
|
||||
command.rev_cert
|
||||
} else {
|
||||
Some(PathBuf::from(format!("{}.rev", key_path.display())))
|
||||
};
|
||||
|
||||
let headers = cert.armor_headers();
|
||||
|
||||
@ -148,7 +147,7 @@ pub fn generate(
|
||||
.map(|value| ("Comment", value.as_str()))
|
||||
.collect();
|
||||
|
||||
let w = config.create_or_stdout_safe(Some(&key_path))?;
|
||||
let w = config.create_or_stdout_safe(Some(key_path))?;
|
||||
let mut w = Writer::with_headers(w, Kind::SecretKey, headers)?;
|
||||
cert.as_tsk().serialize(&mut w)?;
|
||||
w.finalize()?;
|
||||
@ -162,16 +161,11 @@ pub fn generate(
|
||||
.collect();
|
||||
headers.insert(0, ("Comment", "Revocation certificate for"));
|
||||
|
||||
let w = config.create_or_stdout_safe(Some(&rev_path))?;
|
||||
let w = config.create_or_stdout_safe(rev_path.as_deref())?;
|
||||
let mut w = Writer::with_headers(w, Kind::Signature, headers)?;
|
||||
Packet::Signature(rev).serialize(&mut w)?;
|
||||
w.finalize()?;
|
||||
}
|
||||
} else {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Saving generated key to the store isn't implemented \
|
||||
yet."
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -5,6 +5,7 @@ use std::{
|
||||
io,
|
||||
path::PathBuf,
|
||||
};
|
||||
use std::ops::Deref;
|
||||
use anyhow::Context;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
@ -162,7 +163,7 @@ pub fn dispatch(config: Config, c: keyring::Command) -> Result<()> {
|
||||
config.create_or_stdout_pgp(c.output.as_deref(),
|
||||
c.binary,
|
||||
armor::Kind::PublicKey)?;
|
||||
merge(c.input, &mut output)?;
|
||||
merge(&c.input, &mut output)?;
|
||||
output.finalize()
|
||||
},
|
||||
List(c) => {
|
||||
@ -190,16 +191,16 @@ pub fn dispatch(config: Config, c: keyring::Command) -> Result<()> {
|
||||
}
|
||||
|
||||
/// Joins certificates and keyrings into a keyring, applying a filter.
|
||||
fn filter<F>(inputs: &[String], output: &mut dyn io::Write,
|
||||
fn filter<F>(inputs: &[PathBuf], output: &mut dyn io::Write,
|
||||
mut filter: F, to_certificate: bool)
|
||||
-> Result<()>
|
||||
where F: FnMut(Cert) -> Option<Cert>,
|
||||
{
|
||||
if !inputs.is_empty() {
|
||||
for name in inputs {
|
||||
for cert in CertParser::from_file(name)? {
|
||||
for cert in CertParser::from_file(name.deref())? {
|
||||
let cert = cert.context(
|
||||
format!("Malformed certificate in keyring {:?}", name))?;
|
||||
format!("Malformed certificate in keyring {:?}", name.display()))?;
|
||||
if let Some(cert) = filter(cert) {
|
||||
if to_certificate {
|
||||
cert.serialize(output)?;
|
||||
@ -318,7 +319,7 @@ fn split(input: &mut (dyn io::Read + Sync + Send), prefix: &str, binary: bool)
|
||||
}
|
||||
|
||||
/// Merge multiple keyrings.
|
||||
fn merge(inputs: Vec<String>, output: &mut dyn io::Write)
|
||||
fn merge(inputs: &[PathBuf], output: &mut dyn io::Write)
|
||||
-> Result<()>
|
||||
{
|
||||
let mut certs: HashMap<Fingerprint, Option<Cert>> = HashMap::new();
|
||||
|
@ -4,6 +4,7 @@ use std::cmp::Ordering;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use sequoia_net::pks;
|
||||
@ -962,7 +963,7 @@ pub fn join(config: Config, c: packet::JoinCommand) -> Result<()> {
|
||||
/// OUTPUT.
|
||||
fn copy(config: &Config,
|
||||
mut ppr: PacketParserResult,
|
||||
output: Option<&str>,
|
||||
output: Option<&Path>,
|
||||
sink: &mut Option<Message>)
|
||||
-> Result<()> {
|
||||
while let PacketParserResult::Some(pp) = ppr {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use anyhow::Context as _;
|
||||
use std::path::Path;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
@ -145,7 +146,7 @@ pub fn revoke_userid(config: Config, c: revoke::UseridCommand) -> Result<()> {
|
||||
}
|
||||
|
||||
/// Parse the cert from input and ensure it is only one cert.
|
||||
fn read_cert(input: Option<&str>) -> Result<Cert> {
|
||||
fn read_cert(input: Option<&Path>) -> Result<Cert> {
|
||||
let input = open_or_stdin(input)?;
|
||||
|
||||
let cert = CertParser::from_reader(input)?.collect::<Vec<_>>();
|
||||
@ -159,7 +160,7 @@ fn read_cert(input: Option<&str>) -> Result<Cert> {
|
||||
}
|
||||
|
||||
/// Parse the secret key and ensure it is at most one.
|
||||
fn read_secret(skf: Option<&str>) -> Result<Option<Cert>> {
|
||||
fn read_secret(skf: Option<&Path>) -> Result<Option<Cert>> {
|
||||
let secret = load_certs(skf.into_iter())?;
|
||||
if secret.len() > 1 {
|
||||
Err(anyhow::anyhow!("Multiple secret keys provided."))?;
|
||||
|
@ -1,6 +1,7 @@
|
||||
use anyhow::Context as _;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::time::SystemTime;
|
||||
use tempfile::NamedTempFile;
|
||||
@ -27,7 +28,7 @@ pub struct SignOpts<'a, 'certdb> {
|
||||
pub config: Config<'certdb>,
|
||||
pub private_key_store: Option<&'a str>,
|
||||
pub input: &'a mut (dyn io::Read + Sync + Send),
|
||||
pub output_path: Option<&'a str>,
|
||||
pub output_path: Option<&'a Path>,
|
||||
pub secrets: Vec<openpgp::Cert>,
|
||||
pub detached: bool,
|
||||
pub binary: bool,
|
||||
|
23
src/sq.rs
23
src/sq.rs
@ -71,19 +71,19 @@ pub mod output;
|
||||
pub use output::{wkd::WkdUrlVariant, Model, OutputFormat, OutputVersion};
|
||||
|
||||
|
||||
fn open_or_stdin(f: Option<&str>)
|
||||
fn open_or_stdin(f: Option<&Path>)
|
||||
-> Result<Box<dyn BufferedReader<()>>> {
|
||||
match f {
|
||||
Some(f) => Ok(Box::new(
|
||||
File::open(f)
|
||||
.with_context(|| format!("Failed to open {}", f))?)),
|
||||
.with_context(|| format!("Failed to open {}", f.display()))?)),
|
||||
None => Ok(Box::new(Generic::new(io::stdin(), None))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads one TSK from every given file.
|
||||
fn load_keys<'a, I>(files: I) -> openpgp::Result<Vec<Cert>>
|
||||
where I: Iterator<Item=&'a str>
|
||||
where I: Iterator<Item=&'a Path>
|
||||
{
|
||||
let mut certs = vec![];
|
||||
for f in files {
|
||||
@ -100,7 +100,7 @@ fn load_keys<'a, I>(files: I) -> openpgp::Result<Vec<Cert>>
|
||||
|
||||
/// Loads one or more certs from every given file.
|
||||
fn load_certs<'a, I>(files: I) -> openpgp::Result<Vec<Cert>>
|
||||
where I: Iterator<Item=&'a str>
|
||||
where I: Iterator<Item=&'a Path>
|
||||
{
|
||||
let mut certs = vec![];
|
||||
for f in files {
|
||||
@ -302,7 +302,7 @@ impl<'store> Config<'store> {
|
||||
///
|
||||
/// This is suitable for any kind of OpenPGP data, or decrypted or
|
||||
/// authenticated payloads.
|
||||
fn create_or_stdout_safe(&self, f: Option<&str>)
|
||||
fn create_or_stdout_safe(&self, f: Option<&Path>)
|
||||
-> Result<Box<dyn io::Write + Sync + Send>> {
|
||||
Config::create_or_stdout(f, self.force)
|
||||
}
|
||||
@ -312,7 +312,7 @@ impl<'store> Config<'store> {
|
||||
///
|
||||
/// If our heuristic detects non-interactive use, we will emit a
|
||||
/// warning.
|
||||
fn create_or_stdout_unsafe(&mut self, f: Option<&str>)
|
||||
fn create_or_stdout_unsafe(&mut self, f: Option<&Path>)
|
||||
-> Result<Box<dyn io::Write + Sync + Send>> {
|
||||
if ! self.unstable_cli_warning_emitted {
|
||||
emit_unstable_cli_warning();
|
||||
@ -323,7 +323,7 @@ impl<'store> Config<'store> {
|
||||
|
||||
/// Opens the file (or stdout) for writing data that is safe for
|
||||
/// non-interactive use because it is an OpenPGP data stream.
|
||||
fn create_or_stdout_pgp<'a>(&self, f: Option<&str>,
|
||||
fn create_or_stdout_pgp<'a>(&self, f: Option<&Path>,
|
||||
binary: bool, kind: armor::Kind)
|
||||
-> Result<Message<'a>> {
|
||||
let sink = self.create_or_stdout_safe(f)?;
|
||||
@ -337,15 +337,14 @@ impl<'store> Config<'store> {
|
||||
/// Helper function, do not use directly. Instead, use create_or_stdout_safe
|
||||
/// or create_or_stdout_unsafe.
|
||||
fn create_or_stdout(
|
||||
f: Option<&str>,
|
||||
f: Option<&Path>,
|
||||
force: bool,
|
||||
) -> Result<Box<dyn io::Write + Sync + Send>> {
|
||||
match f {
|
||||
None => Ok(Box::new(io::stdout())),
|
||||
Some(p) if p == "-" => Ok(Box::new(io::stdout())),
|
||||
Some(p) if p == Path::new("-") => Ok(Box::new(io::stdout())),
|
||||
Some(f) => {
|
||||
let p = Path::new(f);
|
||||
if !p.exists() || force {
|
||||
if !f.exists() || force {
|
||||
Ok(Box::new(
|
||||
OpenOptions::new()
|
||||
.write(true)
|
||||
@ -358,7 +357,7 @@ impl<'store> Config<'store> {
|
||||
Err(anyhow::anyhow!(format!(
|
||||
"File {:?} exists, use \"sq --force ...\" to \
|
||||
overwrite",
|
||||
p
|
||||
f.display()
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ use clap::Parser;
|
||||
use crate::sq_cli::types::{ArmorKind, IoArgs};
|
||||
|
||||
// TODO?: Option<_> conflicts with default value
|
||||
// TODO: Use PathBuf as input type for more type safety? Investigate conversion
|
||||
// TODO: use indoc to transparently (de-)indent static strings
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use crate::sq_cli::THIRD_PARTY_CERTIFICATION_VALIDITY_DURATION;
|
||||
@ -52,7 +54,7 @@ pub struct Command {
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'B',
|
||||
long,
|
||||
@ -184,7 +186,7 @@ pub struct Command {
|
||||
index = 1,
|
||||
help = "Creates the certification using CERTIFIER-KEY.",
|
||||
)]
|
||||
pub certifier: String,
|
||||
pub certifier: PathBuf,
|
||||
#[clap(
|
||||
value_name = "CERTIFICATE",
|
||||
required = true,
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
|
||||
use crate::sq_cli::types::NetworkPolicy;
|
||||
@ -66,5 +68,5 @@ pub struct GetCommand {
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE instead of importing into the certificate store"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use crate::sq_cli::types::{IoArgs, SessionKey};
|
||||
@ -62,13 +64,13 @@ pub struct Command {
|
||||
value_name = "CERT_FILE",
|
||||
help = "Verifies signatures using the certificates in CERT_FILE",
|
||||
)]
|
||||
pub sender_cert_file: Vec<String>,
|
||||
pub sender_cert_file: Vec<PathBuf>,
|
||||
#[clap(
|
||||
long = "recipient-file",
|
||||
value_name = "KEY_FILE",
|
||||
help = "Decrypts the message using the key in KEY_FILE",
|
||||
)]
|
||||
pub secret_key_file: Vec<String>,
|
||||
pub secret_key_file: Vec<PathBuf>,
|
||||
#[clap(
|
||||
long = "private-key-store",
|
||||
value_name = "KEY_STORE",
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::ArgAction::Count;
|
||||
use clap::{ValueEnum, Parser};
|
||||
|
||||
@ -71,14 +73,14 @@ pub struct Command {
|
||||
value_name = "CERT_RING_FILE",
|
||||
help = "Encrypts to all certificates in CERT_RING_FILE",
|
||||
)]
|
||||
pub recipients_file: Vec<String>,
|
||||
pub recipients_file: Vec<PathBuf>,
|
||||
|
||||
#[clap(
|
||||
long = "signer-file",
|
||||
value_name = "KEY_FILE",
|
||||
help = "Signs the message using the key in KEY_FILE",
|
||||
)]
|
||||
pub signer_key_file: Vec<String>,
|
||||
pub signer_key_file: Vec<PathBuf>,
|
||||
#[clap(
|
||||
long = "private-key-store",
|
||||
value_name = "KEY_STORE",
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
@ -16,5 +18,5 @@ $ sq import < juliet.pgp
|
||||
)]
|
||||
pub struct Command {
|
||||
#[clap(value_name = "FILE", help = "Reads from FILE or stdin if omitted")]
|
||||
pub input: Vec<String>,
|
||||
pub input: Vec<PathBuf>,
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
@ -43,7 +45,7 @@ pub struct Command {
|
||||
value_name = "FILE",
|
||||
help = "Reads from FILE or stdin if omitted",
|
||||
)]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "cert",
|
||||
value_name = "FINGERPRINT|KEYID",
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{ValueEnum, ArgGroup, Args, Parser, Subcommand};
|
||||
|
||||
use sequoia_openpgp::cert::CipherSuite as SqCipherSuite;
|
||||
@ -180,8 +182,7 @@ pub struct GenerateCommand {
|
||||
value_name = "OUTFILE",
|
||||
help = "Writes the key to OUTFILE",
|
||||
)]
|
||||
// TODO this represents a filename, so it should be a Path
|
||||
pub export: Option<String>,
|
||||
pub export: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "rev-cert",
|
||||
value_name = "FILE or -",
|
||||
@ -192,8 +193,7 @@ pub struct GenerateCommand {
|
||||
mandatory if OUTFILE is \"-\". \
|
||||
[default: <OUTFILE>.rev]",
|
||||
)]
|
||||
// TODO this represents a filename, so it should be a Path
|
||||
pub rev_cert: Option<String>
|
||||
pub rev_cert: Option<PathBuf>
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Clone, Debug)]
|
||||
@ -472,14 +472,14 @@ pub struct AdoptCommand {
|
||||
value_name = "TARGET-KEY",
|
||||
help = "Adds keys to TARGET-KEY",
|
||||
)]
|
||||
pub certificate: Option<String>,
|
||||
pub certificate: Option<PathBuf>,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'B',
|
||||
long,
|
||||
@ -532,14 +532,14 @@ pub struct AttestCertificationsCommand {
|
||||
value_name = "KEY",
|
||||
help = "Changes attestations on KEY",
|
||||
)]
|
||||
pub key: Option<String>,
|
||||
pub key: Option<PathBuf>,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'B',
|
||||
long,
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
@ -75,14 +77,14 @@ $ sq keyring filter --domain example.org --prune-certs certs.pgp
|
||||
)]
|
||||
pub struct FilterCommand {
|
||||
#[clap(value_name = "FILE", help = "Reads from FILE or stdin if omitted")]
|
||||
pub input: Vec<String>,
|
||||
pub input: Vec<PathBuf>,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "userid",
|
||||
value_name = "USERID",
|
||||
@ -173,14 +175,14 @@ $ sq keyring join juliet.pgp romeo.pgp alice.pgp
|
||||
)]
|
||||
pub struct JoinCommand {
|
||||
#[clap(value_name = "FILE", help = "Sets the input files to use")]
|
||||
pub input: Vec<String>,
|
||||
pub input: Vec<PathBuf>,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Sets the output file to use"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'B',
|
||||
long = "binary",
|
||||
@ -212,14 +214,14 @@ pub struct MergeCommand {
|
||||
value_name = "FILE",
|
||||
help = "Reads from FILE",
|
||||
)]
|
||||
pub input: Vec<String>,
|
||||
pub input: Vec<PathBuf>,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'B',
|
||||
long = "binary",
|
||||
@ -252,7 +254,7 @@ pub struct ListCommand {
|
||||
value_name = "FILE",
|
||||
help = "Reads from FILE or stdin if omitted",
|
||||
)]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "all-userids",
|
||||
help = "Lists all user ids",
|
||||
@ -289,7 +291,7 @@ pub struct SplitCommand {
|
||||
value_name = "FILE",
|
||||
help = "Reads from FILE or stdin if omitted",
|
||||
)]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'p',
|
||||
long = "prefix",
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
|
||||
use crate::sq_cli::types::NetworkPolicy;
|
||||
@ -65,7 +67,7 @@ pub struct GetCommand {
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE instead of importing into the certificate store"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'B',
|
||||
long,
|
||||
@ -87,5 +89,5 @@ pub struct GetCommand {
|
||||
)]
|
||||
pub struct SendCommand {
|
||||
#[clap(value_name = "FILE", help = "Reads from FILE or stdin if omitted")]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
|
||||
use crate::sq_cli::types::{ArmorKind, IoArgs, SessionKey};
|
||||
@ -113,7 +115,7 @@ pub struct DecryptCommand {
|
||||
value_name = "KEY_FILE",
|
||||
help = "Decrypts the message using the key in KEY_FILE",
|
||||
)]
|
||||
pub secret_key_file: Vec<String>,
|
||||
pub secret_key_file: Vec<PathBuf>,
|
||||
#[clap(
|
||||
long = "private-key-store",
|
||||
value_name = "KEY_STORE",
|
||||
@ -153,7 +155,7 @@ $ sq packet split juliet.pgp
|
||||
)]
|
||||
pub struct SplitCommand {
|
||||
#[clap(value_name = "FILE", help = "Reads from FILE or stdin if omitted")]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'p',
|
||||
long = "prefix",
|
||||
@ -187,14 +189,14 @@ $ sq packet join juliet.pgp-[0-3]*
|
||||
)]
|
||||
pub struct JoinCommand {
|
||||
#[clap(value_name = "FILE", help = "Reads from FILE or stdin if omitted")]
|
||||
pub input: Vec<String>,
|
||||
pub input: Vec<PathBuf>,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "label",
|
||||
value_name = "LABEL",
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
use clap::{ValueEnum, Args, Subcommand};
|
||||
|
||||
@ -89,7 +91,7 @@ pub struct CertificateCommand {
|
||||
"Reads the certificate to revoke from FILE or stdin, if omitted. It is \
|
||||
an error for the file to contain more than one certificate.",
|
||||
)]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "revocation-file",
|
||||
value_name = "KEY_FILE",
|
||||
@ -100,7 +102,7 @@ different from the certificate, this creates a third-party revocation. If \
|
||||
this option is not provided, and the certificate includes secret key material, \
|
||||
then that key is used to sign the revocation certificate.",
|
||||
)]
|
||||
pub secret_key_file: Option<String>,
|
||||
pub secret_key_file: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "private-key-store",
|
||||
value_name = "KEY_STORE",
|
||||
@ -234,7 +236,7 @@ pub struct SubkeyCommand {
|
||||
if omitted. It is an error for the file to contain more than one \
|
||||
certificate."
|
||||
)]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "revocation-file",
|
||||
value_name = "KEY_FILE",
|
||||
@ -246,7 +248,7 @@ is different from the certificate, this creates a third-party revocation. \
|
||||
If this option is not provided, and the certificate includes secret key \
|
||||
material, then that key is used to sign the revocation certificate.",
|
||||
)]
|
||||
pub secret_key_file: Option<String>,
|
||||
pub secret_key_file: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "private-key-store",
|
||||
value_name = "KEY_STORE",
|
||||
@ -365,7 +367,7 @@ pub struct UseridCommand {
|
||||
if omitted. It is an error for the file to contain more than one \
|
||||
certificate."
|
||||
)]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "revocation-file",
|
||||
value_name = "KEY_FILE",
|
||||
@ -376,7 +378,7 @@ different from the certificate, this creates a third-party revocation. If \
|
||||
this option is not provided, and the certificate includes secret key material, \
|
||||
then that key is used to sign the revocation certificate.",
|
||||
)]
|
||||
pub secret_key_file: Option<String>,
|
||||
pub secret_key_file: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "private-key-store",
|
||||
value_name = "KEY_STORE",
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use crate::sq_cli::types::IoArgs;
|
||||
@ -91,13 +93,13 @@ pub struct Command {
|
||||
],
|
||||
help = "Merges signatures from the input and SIGNED-MESSAGE",
|
||||
)]
|
||||
pub merge: Option<String>,
|
||||
pub merge: Option<PathBuf>,
|
||||
#[clap(
|
||||
long = "signer-file",
|
||||
value_name = "KEY_FILE",
|
||||
help = "Signs the message using the key in KEY_FILE",
|
||||
)]
|
||||
pub secret_key_file: Vec<String>,
|
||||
pub secret_key_file: Vec<PathBuf>,
|
||||
#[clap(
|
||||
long,
|
||||
value_names = &["NAME", "VALUE"],
|
||||
|
@ -1,5 +1,6 @@
|
||||
use std::fmt::Display;
|
||||
use std::fmt::Formatter;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use std::time::SystemTime;
|
||||
@ -22,14 +23,14 @@ use crate::sq_cli::SECONDS_IN_YEAR;
|
||||
#[derive(Debug, Args)]
|
||||
pub struct IoArgs {
|
||||
#[clap(value_name = "FILE", help = "Reads from FILE or stdin if omitted")]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Debug, Clone)]
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
@ -83,10 +85,7 @@ pub struct Command {
|
||||
)]
|
||||
// TODO: Should at least one sender_file be required? Verification does not make sense
|
||||
// without one, does it?
|
||||
// TODO Use PathBuf instead of String. Path representation is platform dependent, so Rust's
|
||||
// utf-8 Strings are not quite appropriate.
|
||||
// TODO: And adapt load_certs in sq.rs
|
||||
pub sender_file: Vec<String>,
|
||||
pub sender_file: Vec<PathBuf>,
|
||||
#[clap(
|
||||
long = "signer-cert",
|
||||
value_name = "FINGERPRINT|KEYID",
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
|
||||
use crate::sq_cli::types::NetworkPolicy;
|
||||
@ -92,7 +94,7 @@ pub struct GetCommand {
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE instead of importing into the certificate store"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
pub output: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@ -139,7 +141,7 @@ pub struct GenerateCommand {
|
||||
value_name = "CERT-RING",
|
||||
help = "Adds certificates from CERT-RING to the WKD",
|
||||
)]
|
||||
pub input: Option<String>,
|
||||
pub input: Option<PathBuf>,
|
||||
#[clap(
|
||||
short = 'd',
|
||||
long = "direct-method",
|
||||
|
Loading…
Reference in New Issue
Block a user