use semver::Version;
use serde::Deserialize;
use std::process::Command;
const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Debug)]
pub struct UpdateInfo {
pub current: Version,
pub latest: Version,
pub url: String,
}
#[derive(Deserialize)]
struct CratesIoResponse {
#[serde(rename = "crate")]
krate: CratesIoCrate,
}
#[derive(Deserialize)]
struct CratesIoCrate {
newest_version: String,
}
pub fn check_for_update(_check_url: &str) -> Option<UpdateInfo> {
let current = Version::parse(CURRENT_VERSION).ok()?;
let user_agent = format!("rustpm/{} (https://gitlab.com/dfred26/rustpm)", CURRENT_VERSION);
let out = Command::new("curl")
.args([
"-fsSL", "--max-time", "3",
"-A", &user_agent,
"https://crates.io/api/v1/crates/rustpm",
])
.output()
.ok()?;
if !out.status.success() {
return None;
}
let data: CratesIoResponse = serde_json::from_slice(&out.stdout).ok()?;
let latest = Version::parse(&data.krate.newest_version).ok()?;
if latest > current {
Some(UpdateInfo {
current,
latest,
url: "https://crates.io/crates/rustpm".to_string(),
})
} else {
None
}
}
pub fn print_update_notice(check_url: &str) {
if let Some(info) = check_for_update(check_url) {
eprintln!(
"\n rustpm {} is available (you have {}). Run: cargo install rustpm",
info.latest, info.current
);
}
}