Skip to main content

rusty_commit/utils/
version.rs

1use anyhow::Result;
2use colored::Colorize;
3use reqwest::Client;
4use serde::Deserialize;
5use std::time::Duration;
6
7const CRATE_NAME: &str = env!("CARGO_PKG_NAME");
8const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
9
10#[derive(Deserialize)]
11struct CrateResponse {
12    version: String,
13}
14
15pub async fn check_is_latest_version() -> Result<()> {
16    // Create a client with a short timeout
17    let client = Client::builder().timeout(Duration::from_secs(2)).build()?;
18
19    // Try to fetch the latest version from crates.io
20    let url = format!("https://crates.io/api/v1/crates/{CRATE_NAME}");
21    let response = match client
22        .get(&url)
23        .header("User-Agent", format!("{CRATE_NAME}/{CURRENT_VERSION}"))
24        .send()
25        .await
26    {
27        Ok(resp) => resp,
28        Err(_) => {
29            // Silently fail if we can't reach crates.io
30            return Ok(());
31        }
32    };
33
34    if !response.status().is_success() {
35        return Ok(());
36    }
37
38    let crate_info: CrateResponse = match response.json().await {
39        Ok(info) => info,
40        Err(_) => return Ok(()),
41    };
42
43    // Compare versions
44    if crate_info.version != CURRENT_VERSION {
45        println!(
46            "{}",
47            format!(
48                "📦 A new version of {} is available: {} → {}",
49                CRATE_NAME, CURRENT_VERSION, crate_info.version
50            )
51            .yellow()
52        );
53        println!(
54            "{}",
55            format!("Run `cargo install {CRATE_NAME}` to update").yellow()
56        );
57        println!();
58    }
59
60    Ok(())
61}