From af643d1673d16feb507bd2563ddc3124129f8c42 Mon Sep 17 00:00:00 2001 From: Aditya Wasan Date: Thu, 5 Nov 2020 00:52:33 +0530 Subject: [PATCH] hcctl/monitor: use clap derive macros (#7) Co-authored-by: Harsh Shandilya --- .gitignore | 3 +++ Cargo.lock | 54 +++++++++++++++++++++++++++++++++++++++++ hcctl/Cargo.toml | 2 +- hcctl/src/main.rs | 57 +++++++++++++++++++++++++------------------ monitor/Cargo.toml | 2 +- monitor/src/main.rs | 59 +++++++++++++++++++-------------------------- 6 files changed, 118 insertions(+), 59 deletions(-) diff --git a/.gitignore b/.gitignore index 04fcf3e..3790e70 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,6 @@ target/ .history # End of https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode + +### CLion ### +.idea/* diff --git a/Cargo.lock b/Cargo.lock index e814bb4..2cfbf23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,7 +133,9 @@ checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" dependencies = [ "atty", "bitflags", + "clap_derive", "indexmap", + "lazy_static", "os_str_bytes", "strsim", "termcolor", @@ -142,6 +144,19 @@ dependencies = [ "vec_map", ] +[[package]] +name = "clap_derive" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "const_fn" version = "0.4.2" @@ -294,6 +309,15 @@ dependencies = [ "healthchecks", ] +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.16" @@ -423,6 +447,30 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro-hack" version = "0.5.18" @@ -810,6 +858,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + [[package]] name = "unicode-width" version = "0.1.8" diff --git a/hcctl/Cargo.toml b/hcctl/Cargo.toml index e9ceee7..45a6ec2 100644 --- a/hcctl/Cargo.toml +++ b/hcctl/Cargo.toml @@ -9,6 +9,6 @@ edition = "2018" [dependencies] anyhow = "1.0.33" chrono = "0.4.19" -clap = { version = "3.0.0-beta.2", default-features = false, features = ["std", "suggestions", "color"] } +clap = "3.0.0-beta.2" healthchecks = { path = "../healthchecks", version = "^1.0.2-alpha.0"} prettytable-rs = "0.8.0" diff --git a/hcctl/src/main.rs b/hcctl/src/main.rs index 9e5a3ad..3524e36 100644 --- a/hcctl/src/main.rs +++ b/hcctl/src/main.rs @@ -4,10 +4,9 @@ extern crate prettytable; use std::env::var; use std::time::SystemTime; -use anyhow::anyhow; use chrono::prelude::{DateTime, Datelike, Timelike}; use chrono::Duration; -use clap::{App, AppSettings, Arg}; +use clap::{crate_version, Clap}; use prettytable::{format, Table}; use healthchecks::manage; @@ -18,6 +17,31 @@ struct Settings { ua: Option, } +/// Command-line tool for interacting with a https://healthchecks.io account +#[derive(Clap)] +#[clap(version = crate_version!())] +struct Opts { + #[clap(subcommand)] + subcommand: SubCommand, +} + +#[derive(Clap)] +enum SubCommand { + List(List), + Pings(Pings), +} + +/// Lists the checks in your account with their last ping +#[derive(Clap)] +struct List {} + +/// Get the last 10 pings for the given check ID +#[derive(Clap)] +struct Pings { + /// ID of the check whose pings are being fetched + check_id: String, +} + fn main() -> anyhow::Result<()> { let ua = match var("HEALTHCHECKS_USERAGENT") { Ok(f) => Some(f), @@ -27,28 +51,15 @@ fn main() -> anyhow::Result<()> { token: var("HEALTHCHECKS_TOKEN").expect("HEALTHCHECKS_TOKEN must be set to run monitor"), ua, }; + let opts = Opts::parse(); - let matches = App::new("hcctl") - .about("Command-line tool for interacting with a https://healthchecks.io account") - .version(env!("CARGO_PKG_VERSION")) - .setting(AppSettings::ColoredHelp) - .setting(AppSettings::DeriveDisplayOrder) - .setting(AppSettings::SubcommandRequiredElseHelp) - .subcommand(App::new("list").about("Lists the checks in your account with their last ping")) - .subcommand( - App::new("pings") - .about("Get the last 10 pings for the given check ID") - .args(&[Arg::new("check_id") - .about("ID of the check whose pings are being fetched") - .required(true) - .index(1)]), - ) - .get_matches(); - - match matches.subcommand().unwrap() { - ("list", _) => list(settings)?, - ("pings", matches) => pings(settings, matches.value_of("check_id").unwrap())?, - (cmd, _) => return Err(anyhow!("unknown subcommand: {}", cmd)), + match opts.subcommand { + SubCommand::List(_) => { + list(settings)?; + } + SubCommand::Pings(p) => { + pings(settings, &p.check_id)?; + } } Ok(()) diff --git a/monitor/Cargo.toml b/monitor/Cargo.toml index 6cf1b94..4abb1ee 100644 --- a/monitor/Cargo.toml +++ b/monitor/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" [dependencies] anyhow = "1.0.33" -clap = { version = "3.0.0-beta.2", default-features = false, features = ["std", "suggestions", "color"] } +clap = "3.0.0-beta.2" healthchecks = { path = "../healthchecks", version = "^1.0.2-alpha.0"} [badges] diff --git a/monitor/src/main.rs b/monitor/src/main.rs index dfa6b17..b36b269 100644 --- a/monitor/src/main.rs +++ b/monitor/src/main.rs @@ -1,5 +1,5 @@ use anyhow::Context; -use clap::{App, AppSettings, Arg}; +use clap::{crate_version, Clap}; use healthchecks::ping::get_config; use std::env::var; use std::process::Command; @@ -10,6 +10,18 @@ struct Settings { ua: Option, } +/// monitor runs the given command and reports execution result to https://healthchecks.io +#[derive(Clap)] +#[clap(version = crate_version!(), author = "Harsh Shandilya ")] +struct Opts { + /// command to execute and monitor + #[clap(short = 'X', long = "exec")] + command: Vec, + /// starts a timer before running the command + #[clap(short = 't', long = "timer")] + timer: bool, +} + fn main() -> anyhow::Result<()> { let ua = match var("HEALTHCHECKS_USERAGENT") { Ok(f) => Some(f), @@ -20,48 +32,27 @@ fn main() -> anyhow::Result<()> { .expect("HEALTHCHECKS_CHECK_ID must be set to run monitor"), ua, }; - let app = App::new("monitor") - .version(env!("CARGO_PKG_VERSION")) - .about("monitor runs the given command and reports execution result to https://healthchecks.io") - .setting(AppSettings::ColoredHelp) - .setting(AppSettings::DeriveDisplayOrder) - .arg( - Arg::new("command") - .long("exec") - .short('X') - .min_values(1) - .allow_hyphen_values(true) - .value_terminator(";") - .value_name("cmd") - .required(true) - .about("Command to execute and monitor"), - ) - .arg( - Arg::new("timer") - .long("timer") - .short('t') - .takes_value(false) - .about("Starts a timer before running the command"), - ); - let matches = app.get_matches(); - let cmds = matches - .values_of("command") - .expect("command must be passed") - .collect::>(); - let commands: Vec> = if cmds.len() == 1 { - cmds.get(0) + let opts = Opts::parse(); + let commands: Vec> = if opts.command.len() == 1 { + opts.command + .get(0) .expect("This definitely has one command") .split(';') - .map(|c| c.split(' ').filter(|x| !x.is_empty()).collect()) + .map(|c| { + c.split(' ') + .filter(|x| !x.is_empty()) + .map(|x| x.to_string()) + .collect() + }) .collect() } else { - vec![cmds] + vec![opts.command] }; let mut config = get_config(&settings.check_id)?; if let Some(user_agent) = settings.ua { config = config.set_user_agent(&user_agent) } - if matches.is_present("timer") { + if opts.timer { config.start_timer(); } for cmds in commands {