110 lines
2.5 KiB
Rust
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(())
|
|
}
|