From f7176ef42c5d37c03ca6b10f99c8091f829fbbf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Christian=20Gr=C3=BCnhage?= Date: Sat, 2 Apr 2022 21:43:21 +0200 Subject: [PATCH] feat: add shell completions and man page generation --- .gitignore | 4 +++- Cargo.lock | 27 +++++++++++++++++++++++++++ Cargo.toml | 6 ++++++ README.md | 6 ++++++ build.rs | 40 ++++++++++++++++++++++++++++++++++++++++ src/cli.rs | 11 +++++++++++ src/config.rs | 15 +++------------ src/main.rs | 1 + 8 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 build.rs create mode 100644 src/cli.rs diff --git a/.gitignore b/.gitignore index 4ae822d..d22ff00 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /target **/*.rs.bk -.idea \ No newline at end of file +.idea +/complete +/man diff --git a/Cargo.lock b/Cargo.lock index b5a93e3..eaef53a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,6 +166,15 @@ dependencies = [ "textwrap", ] +[[package]] +name = "clap_complete" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df6f3613c0a3cddfd78b41b10203eb322cb29b600cbdf808a7d3db95691b8e25" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "3.1.4" @@ -179,6 +188,16 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_mangen" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0649fb4156bbd7306896025005596033879a2051f9a3aa7416ab915df1f8fdac" +dependencies = [ + "clap", + "roff", +] + [[package]] name = "crossbeam-epoch" version = "0.9.8" @@ -754,6 +773,8 @@ dependencies = [ "axum", "chrono", "clap", + "clap_complete", + "clap_mangen", "fern", "futures", "futures-util", @@ -911,6 +932,12 @@ dependencies = [ "bitflags", ] +[[package]] +name = "roff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" + [[package]] name = "rustversion" version = "1.0.6" diff --git a/Cargo.toml b/Cargo.toml index e4a693c..2f0b190 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ repository = "https://git.jcg.re/jcgruenhage/peshming" keywords = ["ping", "icmp", "prometheus"] edition = "2018" description = "Pings configured hosts in a configurable intervals and exposes metrics for prometheus." +build = "build.rs" [dependencies] toml = "0.5" @@ -25,3 +26,8 @@ async-anyhow-logger = "0.1" axum = "0.4" metrics = "0.18" metrics-exporter-prometheus = { version = "0.9", default-features = false } + +[build-dependencies] +clap = { version = "3", features = ["derive", "wrap_help"] } +clap_mangen = "0.1" +clap_complete = "3" diff --git a/README.md b/README.md index a5cda79..49fdd73 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,9 @@ For configuration options, see the included sample config file. There's two endpoints available: - `/metrics`, which serves the metrics - `/health`, which should always return a 200 status code + +### Packaging Notes +If you're packaging peshming, you might be interested in the env vars +`PESHMING_MAN_DIR` and `PESHMING_COMPLETIONS_DIR`, which when set, will cause +cargo to generate a man page and shell completions to the folder passed in +those variables. diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..f6c6f92 --- /dev/null +++ b/build.rs @@ -0,0 +1,40 @@ +use std::path::PathBuf; + +use clap::{ArgEnum, CommandFactory}; +use clap_complete::{generate_to, Shell}; + +include!("src/cli.rs"); + +fn main() -> std::io::Result<()> { + let mut cli = Cli::command(); + + if let Some(completions_dir) = std::env::var_os("PESHMING_COMPLETIONS_DIR") { + let completions_dir: PathBuf = completions_dir.into(); + + std::fs::create_dir_all(&completions_dir) + .expect("Could not create shell completions output folder."); + + for shell in Shell::value_variants() { + generate_to(*shell, &mut cli, "peshming", &completions_dir).unwrap_or_else(|err| { + panic!( + "Failed to generate shell completions for {}: {}.", + shell, err + ) + }); + } + } + + if let Some(man_dir) = std::env::var_os("PESHMING_MAN_DIR") { + let man_dir: PathBuf = man_dir.into(); + + std::fs::create_dir_all(&man_dir).expect("Could not create man page output folder."); + + let man = clap_mangen::Man::new(cli); + let mut buffer: Vec = Default::default(); + man.render(&mut buffer)?; + + std::fs::write(man_dir.join("peshming.1"), buffer)?; + } + + Ok(()) +} diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..6fd05dd --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,11 @@ +#[derive(clap::Parser)] +#[clap(author, version)] +/// Pings configured hosts in a configurable intervals and exposes metrics for prometheus. +pub struct Cli { + /// Set config file + pub config: String, + #[clap(short, long, parse(from_occurrences))] + /// Be verbose (you can add this up to 4 times for more logs). + /// By default, only errors are logged, so no output is a good thing. + pub verbose: usize, +} diff --git a/src/config.rs b/src/config.rs index 857c51e..8ed18f0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -24,8 +24,11 @@ use metrics::{describe_histogram, register_histogram, Unit}; use metrics_exporter_prometheus::{Matcher, PrometheusBuilder, PrometheusHandle}; use serde::Deserialize; use serde_with::{serde_as, DurationMilliSeconds}; + use std::{collections::HashMap, time::Duration}; +use crate::cli::Cli; + pub(crate) struct App { pub(crate) config: Config, pub(crate) handle: PrometheusHandle, @@ -75,18 +78,6 @@ impl Default for LogConfig { } } -#[derive(clap::Parser)] -#[clap(author, version)] -/// Pings configured hosts in a configurable intervals and exposes metrics for prometheus. -pub struct Cli { - /// Set config file - config: String, - #[clap(short, long, parse(from_occurrences))] - /// Be verbose (you can add this up to 4 times for more logs). - /// By default, only errors are logged, so no output is a good thing. - verbose: usize, -} - fn setup_clap() -> Cli { Cli::parse() } diff --git a/src/main.rs b/src/main.rs index 55466ec..154ace9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ use anyhow::Result; use async_anyhow_logger::catch; +mod cli; mod config; mod metrics; mod ping;