From 0f35097697f2947c3b0cab70497fd7a1b157f4bd Mon Sep 17 00:00:00 2001 From: Ole Magnus Fon Johnsen Date: Mon, 9 Mar 2026 11:03:04 +0100 Subject: [PATCH] feat: add caching to version check with 24h TTL --- src/cmd/version.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/cmd/version.rs b/src/cmd/version.rs index 336b2df..45d2915 100644 --- a/src/cmd/version.rs +++ b/src/cmd/version.rs @@ -1,22 +1,72 @@ use reqwest::blocking::Client; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::PathBuf; +use std::time::{SystemTime, UNIX_EPOCH}; pub const VERSION: Option<&'static str> = option_env!("CENV_VERSION"); +const CACHE_TTL_SECS: u64 = 86400; // 24 hours + #[derive(Debug, Deserialize)] struct VersionInfo { tag_name: String, } +#[derive(Debug, Serialize, Deserialize)] +struct VersionCache { + time: u64, + tag_name: String, +} + pub fn check_latest_version_and_warn() { let _ = try_check_latest_version(); } +fn cache_path() -> PathBuf { + std::env::temp_dir().join("cenv_version_check") +} + +fn now_secs() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|d| d.as_secs()) + .unwrap_or(0) +} + +fn read_cache() -> Option { + let contents = fs::read_to_string(cache_path()).ok()?; + serde_json::from_str(&contents).ok() +} + +fn write_cache(info: &VersionInfo) { + let cache = VersionCache { + time: now_secs(), + tag_name: info.tag_name.clone(), + }; + if let Ok(json) = serde_json::to_string(&cache) { + let _ = fs::write(cache_path(), json); + } +} + // Check the latest version of cenv on GitHub and print a warning if the current version is // outdated. fn try_check_latest_version() -> Option<()> { let version = VERSION?; + if let Some(cache) = read_cache() + && now_secs().saturating_sub(cache.time) < CACHE_TTL_SECS + { + if cache.tag_name != version { + eprintln!( + "Warning: A new version of cenv is available: {} (current: {})", + cache.tag_name, version + ); + eprintln!(); + } + return Some(()); + } + let client = Client::new(); let resp = client .get("https://api.github.com/repos/echo-webkom/cenv/releases/latest") @@ -34,5 +84,7 @@ fn try_check_latest_version() -> Option<()> { eprintln!(); } + write_cache(&info); + Some(()) }