use anyhow::{Result, bail}; use clap::{Parser, Subcommand}; use reqwest::Url; use serde::{Deserialize, Serialize}; use shadow_rs::{formatcp, shadow}; use std::{ ffi::{OsStr, OsString}, process::Command, }; shadow!(build); const VERSION_INFO: &str = formatcp!( r#"{} branch: {} commit_hash: {} build_env: {},{}"#, build::PKG_VERSION, build::BRANCH, build::COMMIT_HASH, build::RUST_VERSION, build::RUST_CHANNEL ); #[derive(Parser)] #[clap(author, version = VERSION_INFO, about, long_about = None)] #[command(propagate_version = true)] struct Cli { #[clap(subcommand)] command: Commands, } #[derive(Subcommand)] enum Commands { /// Send a notification Send { /// The message to send #[clap(action)] msg: String, }, /// Run a command and send notification result at the end Run { /// The command to execute #[clap(action)] cmd: Vec, }, /// Open configuration file Config } #[derive(Debug, Serialize, Deserialize)] struct Config { endpoint: Url, } impl Default for Config { fn default() -> Self { Self { endpoint: Url::parse("https://example.net").unwrap(), } } } fn main() -> Result<()> { human_panic::setup_panic!(); let cfg: Config = confy::load("notipriv", None)?; let cli = Cli::parse(); match cli.command { Commands::Send { msg } => send_notif(cfg.endpoint, msg)?, Commands::Run { cmd } => run(cfg.endpoint, &cmd)?, Commands::Config => opener::open(confy::get_configuration_file_path("notipriv", None)?)? } Ok(()) } fn send_notif(endpoint: Url, msg: String) -> Result<()> { let client = reqwest::blocking::Client::new(); let status = client.post(endpoint).body(msg).send()?.status(); if !status.is_success() { println!("Error with status {}", status); } Ok(()) } fn run(endpoint: Url, cmd: &[impl AsRef]) -> Result<()> { if cmd.is_empty() { bail!("Empty command"); } let cmd_name = cmd[0].as_ref().to_string_lossy(); let status = Command::new(cmd[0].as_ref()) .args(cmd[1..].as_ref()) .status()?; if status.success() { send_notif(endpoint, format!("✅ {} succes", cmd_name))?; } else { let msg = if let Some(code) = status.code() { format!("❌ {} failed with code {}", cmd_name, code) } else { format!("❌ {} failed", cmd_name) }; send_notif(endpoint, msg)?; } Ok(()) }