cli: migrate from gumdrop to clap v3 (#379)
`gumdrop` was originally chosen for its minimalist set of dependencies, but `clap` v3 has a slimmed down set of dependencies and better UX.
This commit is contained in:
committed by
GitHub
parent
bb80551324
commit
fab9d25b0a
+1
-1
@@ -15,7 +15,7 @@ edition = "2021"
|
||||
rust-version = "1.56"
|
||||
|
||||
[dependencies]
|
||||
gumdrop = "0.8"
|
||||
clap = { version = "3", features = ["derive"] }
|
||||
env_logger = "0.9"
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
unused_qualifications
|
||||
)]
|
||||
|
||||
use gumdrop::Options;
|
||||
use clap::Parser;
|
||||
use yubikey_cli::commands::YubiKeyCli;
|
||||
|
||||
fn main() {
|
||||
YubiKeyCli::parse_args_default_or_exit().run();
|
||||
YubiKeyCli::parse().run()
|
||||
}
|
||||
|
||||
+15
-80
@@ -4,62 +4,25 @@ pub mod readers;
|
||||
pub mod status;
|
||||
|
||||
use self::{readers::ReadersCmd, status::StatusCmd};
|
||||
use crate::terminal::{self, STDOUT};
|
||||
use gumdrop::Options;
|
||||
use std::{
|
||||
env,
|
||||
io::{self, Write},
|
||||
process::exit,
|
||||
};
|
||||
use termcolor::{ColorChoice, ColorSpec, WriteColor};
|
||||
use crate::terminal;
|
||||
use clap::Parser;
|
||||
use std::{env, process::exit};
|
||||
use termcolor::ColorChoice;
|
||||
use yubikey::{Serial, YubiKey};
|
||||
|
||||
/// The `yubikey` CLI utility
|
||||
#[derive(Debug, Options)]
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct YubiKeyCli {
|
||||
/// Obtain help about the current command
|
||||
#[options(short = "h", help = "print help message")]
|
||||
pub help: bool,
|
||||
|
||||
/// Specify the serial number of the YubiKey to connect to
|
||||
#[options(
|
||||
short = "s",
|
||||
long = "serial",
|
||||
help = "serial number of the YubiKey to connect to"
|
||||
)]
|
||||
/// Serial number of the YubiKey to connect to
|
||||
#[clap(short = 's', long = "serial")]
|
||||
pub serial: Option<Serial>,
|
||||
|
||||
/// Subcommand to execute.
|
||||
#[options(command)]
|
||||
pub command: Option<Commands>,
|
||||
#[clap(subcommand)]
|
||||
pub command: Commands,
|
||||
}
|
||||
|
||||
impl YubiKeyCli {
|
||||
/// Print usage information
|
||||
pub fn print_usage() -> io::Result<()> {
|
||||
let mut stdout = STDOUT.lock();
|
||||
stdout.reset()?;
|
||||
|
||||
let mut bold = ColorSpec::new();
|
||||
bold.set_bold(true);
|
||||
|
||||
stdout.set_color(&bold)?;
|
||||
writeln!(
|
||||
stdout,
|
||||
"{} {}",
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_VERSION")
|
||||
)?;
|
||||
stdout.reset()?;
|
||||
|
||||
writeln!(stdout, "{}", env!("CARGO_PKG_AUTHORS"))?;
|
||||
writeln!(stdout, "{}", env!("CARGO_PKG_DESCRIPTION").trim())?;
|
||||
writeln!(stdout)?;
|
||||
writeln!(stdout, "{}", Commands::usage())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Run the underlying command type or print usage info and exit
|
||||
pub fn run(&self) {
|
||||
// TODO(tarcieri): make this more configurable
|
||||
@@ -70,10 +33,7 @@ impl YubiKeyCli {
|
||||
env_logger::builder().format_timestamp(None).init();
|
||||
}
|
||||
|
||||
match &self.command {
|
||||
Some(cmd) => cmd.run(self.yubikey_init()),
|
||||
None => Self::print_usage().unwrap(),
|
||||
}
|
||||
self.command.run(self.yubikey_init())
|
||||
}
|
||||
|
||||
/// Initialize the YubiKey client driver
|
||||
@@ -92,22 +52,18 @@ impl YubiKeyCli {
|
||||
}
|
||||
|
||||
/// Subcommands of this application
|
||||
#[derive(Debug, Options)]
|
||||
#[derive(Debug, Parser)]
|
||||
pub enum Commands {
|
||||
/// `help` subcommand
|
||||
#[options(help = "show help for a command")]
|
||||
Help(HelpOpts),
|
||||
|
||||
/// `version` subcommand
|
||||
#[options(help = "display version information")]
|
||||
#[clap(about = "display version information")]
|
||||
Version(VersionOpts),
|
||||
|
||||
/// `readers` subcommand
|
||||
#[options(help = "list detected readers")]
|
||||
#[clap(about = "list detected readers")]
|
||||
Readers(ReadersCmd),
|
||||
|
||||
/// `status` subcommand
|
||||
#[options(help = "show yubikey status")]
|
||||
#[clap(about = "show yubikey status")]
|
||||
Status(StatusCmd),
|
||||
}
|
||||
|
||||
@@ -115,7 +71,6 @@ impl Commands {
|
||||
/// Run the given command
|
||||
pub fn run(&self, yubikey: YubiKey) {
|
||||
match self {
|
||||
Commands::Help(help) => help.run(),
|
||||
Commands::Version(version) => version.run(),
|
||||
Commands::Readers(list) => list.run(),
|
||||
Commands::Status(status) => status.run(yubikey),
|
||||
@@ -123,28 +78,8 @@ impl Commands {
|
||||
}
|
||||
}
|
||||
|
||||
/// Help options
|
||||
#[derive(Debug, Options)]
|
||||
pub struct HelpOpts {
|
||||
#[options(free, help = "subcommand to get help for")]
|
||||
free: Vec<String>,
|
||||
}
|
||||
|
||||
impl HelpOpts {
|
||||
fn run(&self) {
|
||||
if let Some(command) = self.free.first() {
|
||||
if let Some(usage) = Commands::command_usage(command) {
|
||||
println!("{}", usage);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
println!("{}", Commands::usage());
|
||||
}
|
||||
}
|
||||
|
||||
/// Version options
|
||||
#[derive(Debug, Options)]
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct VersionOpts {}
|
||||
|
||||
impl VersionOpts {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! List detected readers
|
||||
|
||||
use crate::terminal::STDOUT;
|
||||
use gumdrop::Options;
|
||||
use clap::Parser;
|
||||
use std::{
|
||||
io::{self, Write},
|
||||
process::exit,
|
||||
@@ -10,7 +10,7 @@ use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
|
||||
use yubikey::{Context, Serial};
|
||||
|
||||
/// The `readers` subcommand
|
||||
#[derive(Debug, Options)]
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct ReadersCmd {}
|
||||
|
||||
impl ReadersCmd {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Print device status
|
||||
|
||||
use crate::terminal::{print_cert_info, STDOUT};
|
||||
use gumdrop::Options;
|
||||
use clap::Parser;
|
||||
use std::io::{self, Write};
|
||||
use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
|
||||
use yubikey::{piv::*, YubiKey};
|
||||
@@ -10,7 +10,7 @@ use yubikey::{piv::*, YubiKey};
|
||||
const NONE_STR: &str = "<none>";
|
||||
|
||||
/// The `status` subcommand
|
||||
#[derive(Debug, Options)]
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct StatusCmd {}
|
||||
|
||||
impl StatusCmd {
|
||||
|
||||
Reference in New Issue
Block a user