notipriv/src/main.rs

110 lines
2.5 KiB
Rust

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<OsString>,
},
/// 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<OsStr>]) -> 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(())
}