hcctl/monitor: use clap derive macros (#7)
Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
parent
72c8a5d019
commit
af643d1673
|
@ -26,3 +26,6 @@ target/
|
||||||
.history
|
.history
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode
|
# End of https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode
|
||||||
|
|
||||||
|
### CLion ###
|
||||||
|
.idea/*
|
||||||
|
|
|
@ -133,7 +133,9 @@ checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
"clap_derive",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
"lazy_static",
|
||||||
"os_str_bytes",
|
"os_str_bytes",
|
||||||
"strsim",
|
"strsim",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
|
@ -142,6 +144,19 @@ dependencies = [
|
||||||
"vec_map",
|
"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]]
|
[[package]]
|
||||||
name = "const_fn"
|
name = "const_fn"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -294,6 +309,15 @@ dependencies = [
|
||||||
"healthchecks",
|
"healthchecks",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
|
@ -423,6 +447,30 @@ dependencies = [
|
||||||
"unicode-width",
|
"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]]
|
[[package]]
|
||||||
name = "proc-macro-hack"
|
name = "proc-macro-hack"
|
||||||
version = "0.5.18"
|
version = "0.5.18"
|
||||||
|
@ -810,6 +858,12 @@ dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
|
|
|
@ -9,6 +9,6 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.33"
|
anyhow = "1.0.33"
|
||||||
chrono = "0.4.19"
|
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"}
|
healthchecks = { path = "../healthchecks", version = "^1.0.2-alpha.0"}
|
||||||
prettytable-rs = "0.8.0"
|
prettytable-rs = "0.8.0"
|
||||||
|
|
|
@ -4,10 +4,9 @@ extern crate prettytable;
|
||||||
use std::env::var;
|
use std::env::var;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
|
||||||
use chrono::prelude::{DateTime, Datelike, Timelike};
|
use chrono::prelude::{DateTime, Datelike, Timelike};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use clap::{App, AppSettings, Arg};
|
use clap::{crate_version, Clap};
|
||||||
use prettytable::{format, Table};
|
use prettytable::{format, Table};
|
||||||
|
|
||||||
use healthchecks::manage;
|
use healthchecks::manage;
|
||||||
|
@ -18,6 +17,31 @@ struct Settings {
|
||||||
ua: Option<String>,
|
ua: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let ua = match var("HEALTHCHECKS_USERAGENT") {
|
let ua = match var("HEALTHCHECKS_USERAGENT") {
|
||||||
Ok(f) => Some(f),
|
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"),
|
token: var("HEALTHCHECKS_TOKEN").expect("HEALTHCHECKS_TOKEN must be set to run monitor"),
|
||||||
ua,
|
ua,
|
||||||
};
|
};
|
||||||
|
let opts = Opts::parse();
|
||||||
|
|
||||||
let matches = App::new("hcctl")
|
match opts.subcommand {
|
||||||
.about("Command-line tool for interacting with a https://healthchecks.io account")
|
SubCommand::List(_) => {
|
||||||
.version(env!("CARGO_PKG_VERSION"))
|
list(settings)?;
|
||||||
.setting(AppSettings::ColoredHelp)
|
}
|
||||||
.setting(AppSettings::DeriveDisplayOrder)
|
SubCommand::Pings(p) => {
|
||||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
pings(settings, &p.check_id)?;
|
||||||
.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)),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -14,7 +14,7 @@ readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.33"
|
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"}
|
healthchecks = { path = "../healthchecks", version = "^1.0.2-alpha.0"}
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::{App, AppSettings, Arg};
|
use clap::{crate_version, Clap};
|
||||||
use healthchecks::ping::get_config;
|
use healthchecks::ping::get_config;
|
||||||
use std::env::var;
|
use std::env::var;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
@ -10,6 +10,18 @@ struct Settings {
|
||||||
ua: Option<String>,
|
ua: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// monitor runs the given command and reports execution result to https://healthchecks.io
|
||||||
|
#[derive(Clap)]
|
||||||
|
#[clap(version = crate_version!(), author = "Harsh Shandilya <me@msfjarvis.dev>")]
|
||||||
|
struct Opts {
|
||||||
|
/// command to execute and monitor
|
||||||
|
#[clap(short = 'X', long = "exec")]
|
||||||
|
command: Vec<String>,
|
||||||
|
/// starts a timer before running the command
|
||||||
|
#[clap(short = 't', long = "timer")]
|
||||||
|
timer: bool,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let ua = match var("HEALTHCHECKS_USERAGENT") {
|
let ua = match var("HEALTHCHECKS_USERAGENT") {
|
||||||
Ok(f) => Some(f),
|
Ok(f) => Some(f),
|
||||||
|
@ -20,48 +32,27 @@ fn main() -> anyhow::Result<()> {
|
||||||
.expect("HEALTHCHECKS_CHECK_ID must be set to run monitor"),
|
.expect("HEALTHCHECKS_CHECK_ID must be set to run monitor"),
|
||||||
ua,
|
ua,
|
||||||
};
|
};
|
||||||
let app = App::new("monitor")
|
let opts = Opts::parse();
|
||||||
.version(env!("CARGO_PKG_VERSION"))
|
let commands: Vec<Vec<String>> = if opts.command.len() == 1 {
|
||||||
.about("monitor runs the given command and reports execution result to https://healthchecks.io")
|
opts.command
|
||||||
.setting(AppSettings::ColoredHelp)
|
.get(0)
|
||||||
.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::<Vec<&str>>();
|
|
||||||
let commands: Vec<Vec<&str>> = if cmds.len() == 1 {
|
|
||||||
cmds.get(0)
|
|
||||||
.expect("This definitely has one command")
|
.expect("This definitely has one command")
|
||||||
.split(';')
|
.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()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
vec![cmds]
|
vec![opts.command]
|
||||||
};
|
};
|
||||||
let mut config = get_config(&settings.check_id)?;
|
let mut config = get_config(&settings.check_id)?;
|
||||||
if let Some(user_agent) = settings.ua {
|
if let Some(user_agent) = settings.ua {
|
||||||
config = config.set_user_agent(&user_agent)
|
config = config.set_user_agent(&user_agent)
|
||||||
}
|
}
|
||||||
if matches.is_present("timer") {
|
if opts.timer {
|
||||||
config.start_timer();
|
config.start_timer();
|
||||||
}
|
}
|
||||||
for cmds in commands {
|
for cmds in commands {
|
||||||
|
|
Loading…
Reference in New Issue